*/\r
\r
#include "internal.h"\r
-#include "signature/KeyResolver.h"\r
+#include "signature/CachingKeyResolver.h"\r
+#include "signature/KeyInfo.h"\r
#include "util/NDC.h"\r
#include "util/Threads.h"\r
+#include "util/XMLConstants.h"\r
+#include "validation/ValidatorSuite.h"\r
\r
-#include <algorithm>\r
#include <log4cpp/Category.hh>\r
#include <xercesc/util/XMLUniDefs.hpp>\r
#include <xsec/dsig/DSIGKeyInfoX509.hpp>\r
using namespace std;\r
\r
namespace xmlsignature {\r
- class XMLTOOL_DLLLOCAL InlineKeyResolver : public KeyResolver\r
+ class XMLTOOL_DLLLOCAL InlineKeyResolver : public CachingKeyResolver\r
{\r
public:\r
InlineKeyResolver(const DOMElement* e);\r
\r
XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const;\r
XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const;\r
- vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs) const;\r
- vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, vector<XSECCryptoX509*>& certs) const;\r
+ vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const;\r
+ vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const;\r
+ XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;\r
+ XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;\r
+ \r
+ void clearCache() {\r
+ if (m_lock)\r
+ m_lock->wrlock();\r
+ m_cache.clear();\r
+ if (m_lock)\r
+ m_lock->unlock();\r
+ }\r
\r
private:\r
struct XMLTOOL_DLLLOCAL CacheEntry {\r
- CacheEntry() : m_key(NULL) {}\r
+ CacheEntry() : m_key(NULL), m_crl(NULL) {}\r
~CacheEntry() {\r
delete m_key;\r
for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
+ delete m_crl;\r
}\r
XSECCryptoKey* m_key;\r
vector<XSECCryptoX509*> m_certs;\r
+ XSECCryptoX509CRL* m_crl;\r
};\r
\r
void _resolve(const KeyInfo* keyInfo, CacheEntry& entry) const;\r
XSECCryptoKey* _resolveKey(const KeyInfo* keyInfo) const;\r
vector<XSECCryptoX509*>::size_type _resolveCertificates(const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs) const;\r
+ XSECCryptoX509CRL* _resolveCRL(const KeyInfo* keyInfo) const;\r
\r
RWLock* m_lock;\r
mutable map<const KeyInfo*,CacheEntry> m_cache;\r
\r
InlineKeyResolver::~InlineKeyResolver()\r
{\r
- m_cache.clear();\r
+ clearCache();\r
delete m_lock;\r
}\r
\r
entry.m_key = entry.m_certs.front()->clonePublicKey();\r
else\r
entry.m_key = _resolveKey(keyInfo);\r
+ entry.m_crl = _resolveCRL(keyInfo);\r
}\r
\r
XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const\r
#endif\r
Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");\r
\r
+ if (!keyInfo)\r
+ return NULL;\r
+\r
// Check for ds:X509Data\r
const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();\r
for (vector<X509Data*>::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) {\r
const vector<KeyValue*>& keyValues = keyInfo->getKeyValues();\r
for (vector<KeyValue*>::const_iterator i=keyValues.begin(); i!=keyValues.end(); ++i) {\r
try {\r
- KeyInfoSchemaValidators.validate(*i); // see if it's a "valid" key\r
+ SchemaValidators.validate(*i); // see if it's a "valid" key\r
RSAKeyValue* rsakv = (*i)->getRSAKeyValue();\r
if (rsakv) {\r
log.debug("resolving ds:RSAKeyValue");\r
#endif\r
Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");\r
\r
+ if (!keyInfo)\r
+ return 0;\r
+\r
// Check for ds:X509Data\r
const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();\r
for (vector<X509Data*>::const_iterator j=x509Datas.begin(); certs.empty() && j!=x509Datas.end(); ++j) {\r
return certs.size();\r
}\r
\r
+XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const\r
+{\r
+#ifdef _DEBUG\r
+ NDC ndc("_resolveCRL");\r
+#endif\r
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");\r
+\r
+ if (!keyInfo)\r
+ return NULL;\r
+\r
+ // Check for ds:X509Data\r
+ const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();\r
+ for (vector<X509Data*>::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) {\r
+ const vector<X509CRL*> x509CRLs=const_cast<const X509Data*>(*j)->getX509CRLs();\r
+ for (vector<X509CRL*>::const_iterator k=x509CRLs.begin(); k!=x509CRLs.end(); ++k) {\r
+ try {\r
+ auto_ptr_char x((*k)->getValue());\r
+ if (!x.get()) {\r
+ log.warn("skipping empty ds:X509CRL");\r
+ }\r
+ else {\r
+ log.debug("resolving ds:X509CRL");\r
+ auto_ptr<XSECCryptoX509CRL> crl(XMLToolingConfig::getConfig().X509CRL());\r
+ crl->loadX509CRLBase64Bin(x.get(), strlen(x.get()));\r
+ return crl.release();\r
+ }\r
+ }\r
+ catch(XSECException& e) {\r
+ auto_ptr_char temp(e.getMsg());\r
+ log.error("caught XML-Security exception loading certificate: %s", temp.get());\r
+ }\r
+ catch(XSECCryptoException& e) {\r
+ log.error("caught XML-Security exception loading certificate: %s", e.getMsg());\r
+ }\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
XSECCryptoKey* InlineKeyResolver::resolveKey(const KeyInfo* keyInfo) const\r
{\r
// Caching?\r
return _resolveKey(keyInfo);\r
}\r
\r
+XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(const KeyInfo* keyInfo) const\r
+{\r
+ // Caching?\r
+ if (m_lock) {\r
+ // Get read lock.\r
+ m_lock->rdlock();\r
+ map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);\r
+ if (i != m_cache.end()) {\r
+ // Found in cache, so just return the results.\r
+ SharedLock locker(m_lock,false);\r
+ return i->second.m_crl ? i->second.m_crl->clone() : NULL;\r
+ }\r
+ else {\r
+ // Elevate lock.\r
+ m_lock->unlock();\r
+ m_lock->wrlock();\r
+ SharedLock locker(m_lock,false);\r
+ // Recheck cache.\r
+ i=m_cache.find(keyInfo);\r
+ if (i == m_cache.end()) {\r
+ i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;\r
+ _resolve(i->first, i->second);\r
+ }\r
+ return i->second.m_crl ? i->second.m_crl->clone() : NULL;\r
+ }\r
+ }\r
+ return _resolveCRL(keyInfo);\r
+}\r
+\r
vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(\r
- const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs\r
+ const KeyInfo* keyInfo, ResolvedCertificates& certs\r
) const\r
{\r
// Caching?\r
if (i != m_cache.end()) {\r
// Found in cache, so just return the results.\r
SharedLock locker(m_lock,false);\r
- certs.assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
- return certs.size();\r
+ accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
+ accessOwned(certs) = false;\r
+ return accessCertificates(certs).size();\r
}\r
else {\r
// Elevate lock.\r
i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;\r
_resolve(i->first, i->second);\r
}\r
- certs.assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
- return certs.size();\r
+ accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
+ accessOwned(certs) = false;\r
+ return accessCertificates(certs).size();\r
}\r
}\r
- return _resolveCertificates(keyInfo, certs);\r
+ accessOwned(certs) = true;\r
+ return _resolveCertificates(keyInfo, accessCertificates(certs));\r
}\r
\r
XSECCryptoKey* InlineKeyResolver::resolveKey(DSIGKeyInfoList* keyInfo) const\r
{\r
#ifdef _DEBUG\r
- NDC ndc("_resolveKey");\r
+ NDC ndc("resolveKey");\r
#endif\r
\r
+ if (!keyInfo)\r
+ return NULL;\r
+\r
// Default resolver handles RSA/DSAKeyValue and X509Certificate elements.\r
try {\r
XSECKeyInfoResolverDefault def;\r
}\r
\r
vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(\r
- DSIGKeyInfoList* keyInfo, vector<XSECCryptoX509*>& certs\r
+ DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs\r
) const\r
{\r
- certs.clear();\r
+ accessCertificates(certs).clear();\r
+ accessOwned(certs) = false;\r
+\r
+ if (!keyInfo)\r
+ return 0;\r
+\r
DSIGKeyInfoList::size_type sz = keyInfo->getSize();\r
- for (DSIGKeyInfoList::size_type i=0; certs.empty() && i<sz; ++i) {\r
+ for (DSIGKeyInfoList::size_type i=0; accessCertificates(certs).empty() && i<sz; ++i) {\r
if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {\r
DSIGKeyInfoX509* x509 = static_cast<DSIGKeyInfoX509*>(keyInfo->item(i));\r
int count = x509->getCertificateListSize();\r
for (int j=0; j<count; ++j) {\r
- certs.push_back(x509->getCertificateCryptoItem(j));\r
+ accessCertificates(certs).push_back(x509->getCertificateCryptoItem(j));\r
}\r
}\r
}\r
- return certs.size();\r
+ return accessCertificates(certs).size();\r
+}\r
+\r
+XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const\r
+{\r
+#ifdef _DEBUG\r
+ NDC ndc("resolveCRL");\r
+#endif\r
+\r
+ if (!keyInfo)\r
+ return NULL;\r
+\r
+ DSIGKeyInfoList::size_type sz = keyInfo->getSize();\r
+ for (DSIGKeyInfoList::size_type i=0; i<sz; ++i) {\r
+ if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {\r
+ auto_ptr_char buf(static_cast<DSIGKeyInfoX509*>(keyInfo->item(i))->getX509CRL());\r
+ if (buf.get()) {\r
+ try {\r
+ auto_ptr<XSECCryptoX509CRL> crlobj(XMLToolingConfig::getConfig().X509CRL());\r
+ crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get()));\r
+ return crlobj.release();\r
+ }\r
+ catch(XSECException& e) {\r
+ auto_ptr_char temp(e.getMsg());\r
+ Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", temp.get());\r
+ }\r
+ catch(XSECCryptoException& e) {\r
+ Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", e.getMsg());\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return NULL;\r
}\r