X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=xmltooling%2Fsecurity%2Fimpl%2FInlineKeyResolver.cpp;h=4dba33f00dfcc874c958a59a73d82ffd9057c73e;hb=a5e86d37cf40004e6a43a21ab67d26695fa8619c;hp=311fd064e77b50e6a9626b80e134454bb61fac96;hpb=085daff2d0c1d078f006f23808b4092130110eb9;p=shibboleth%2Fcpp-xmltooling.git diff --git a/xmltooling/security/impl/InlineKeyResolver.cpp b/xmltooling/security/impl/InlineKeyResolver.cpp index 311fd06..4dba33f 100644 --- a/xmltooling/security/impl/InlineKeyResolver.cpp +++ b/xmltooling/security/impl/InlineKeyResolver.cpp @@ -21,14 +21,17 @@ */ #include "internal.h" -#include "security/CachingKeyResolver.h" +#include "logging.h" +#include "security/BasicX509Credential.h" +#include "security/KeyInfoCredentialContext.h" +#include "security/KeyInfoResolver.h" #include "signature/KeyInfo.h" +#include "signature/Signature.h" #include "util/NDC.h" #include "util/Threads.h" #include "util/XMLConstants.h" #include "validation/ValidatorSuite.h" -#include #include #include #include @@ -39,120 +42,195 @@ #include using namespace xmlsignature; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; +using namespace xercesc; using namespace std; namespace xmltooling { - class XMLTOOL_DLLLOCAL InlineKeyResolver : public CachingKeyResolver + + class XMLTOOL_DLLLOCAL InlineCredential : public BasicX509Credential { public: - InlineKeyResolver(const DOMElement* e); - virtual ~InlineKeyResolver(); - - XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const; - XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const; - vector::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const; - vector::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const; - XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const; - XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const; - - void clearCache() { - if (m_lock) - m_lock->wrlock(); - m_cache.clear(); - if (m_lock) - m_lock->unlock(); + InlineCredential(const KeyInfo* keyInfo=NULL) : BasicX509Credential(keyInfo!=NULL), m_credctx(new KeyInfoCredentialContext(keyInfo)) { + } + InlineCredential(DSIGKeyInfoList* keyInfo) : BasicX509Credential(false), m_credctx(new KeyInfoCredentialContext(keyInfo)) { + } + InlineCredential(KeyInfoCredentialContext* context) : BasicX509Credential(context->getKeyInfo()!=NULL), m_credctx(NULL) { + } + virtual ~InlineCredential() { + delete m_credctx; + } + + XSECCryptoKey* getPrivateKey() const { + return NULL; + } + + KeyInfo* getKeyInfo(bool compact=false) const { + KeyInfo* ret = m_credctx->getKeyInfo() ? m_credctx->getKeyInfo()->cloneKeyInfo() : NULL; + if (ret) { + ret->setId(NULL); + ret->getRetrievalMethods().clear(); + if (compact) { + ret->getKeyValues().clear(); + ret->getSPKIDatas().clear(); + ret->getPGPDatas().clear(); + ret->getUnknownXMLObjects().clear(); + VectorOf(X509Data) x509Datas=ret->getX509Datas(); + for (VectorOf(X509Data)::size_type pos = 0; pos < x509Datas.size();) { + x509Datas[pos]->getX509Certificates().clear(); + x509Datas[pos]->getX509CRLs().clear(); + x509Datas[pos]->getUnknownXMLObjects().clear(); + if (x509Datas[pos]->hasChildren()) + ++pos; + else + x509Datas.erase(x509Datas.begin() + pos); + } + } + } + if (!ret->hasChildren()) { + delete ret; + ret = NULL; + } + return ret; } + const CredentialContext* getCredentialContext() const { + return m_credctx; + } + + void setCredentialContext(KeyInfoCredentialContext* context) { + m_credctx = context; + } + + void resolve(const KeyInfo* keyInfo, int types=0); + void resolve(DSIGKeyInfoList* keyInfo, int types=0); + private: - struct XMLTOOL_DLLLOCAL CacheEntry { - CacheEntry() : m_key(NULL), m_crl(NULL) {} - ~CacheEntry() { - delete m_key; - for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup()); - delete m_crl; - } - XSECCryptoKey* m_key; - vector m_certs; - XSECCryptoX509CRL* m_crl; - }; - - void _resolve(const KeyInfo* keyInfo, CacheEntry& entry) const; - XSECCryptoKey* _resolveKey(const KeyInfo* keyInfo) const; - vector::size_type _resolveCertificates(const KeyInfo* keyInfo, vector& certs) const; - XSECCryptoX509CRL* _resolveCRL(const KeyInfo* keyInfo) const; - - RWLock* m_lock; - mutable map m_cache; + bool resolveCerts(const KeyInfo* keyInfo); + bool resolveKey(const KeyInfo* keyInfo); + bool resolveCRLs(const KeyInfo* keyInfo); + + KeyInfoCredentialContext* m_credctx; + }; + + class XMLTOOL_DLLLOCAL InlineKeyResolver : public KeyInfoResolver + { + public: + InlineKeyResolver() {} + virtual ~InlineKeyResolver() {} + + Credential* resolve(const KeyInfo* keyInfo, int types=0) const { + if (!keyInfo) + return NULL; + if (types == 0) + types = Credential::RESOLVE_KEYS|X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS; + auto_ptr credential(new InlineCredential(keyInfo)); + credential->resolve(keyInfo, types); + return credential.release(); + } + Credential* resolve(DSIGKeyInfoList* keyInfo, int types=0) const { + if (!keyInfo) + return NULL; + if (types == 0) + types = Credential::RESOLVE_KEYS|X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS; + auto_ptr credential(new InlineCredential(keyInfo)); + credential->resolve(keyInfo, types); + return credential.release(); + } + Credential* resolve(KeyInfoCredentialContext* context, int types=0) const { + if (!context) + return NULL; + if (types == 0) + types = Credential::RESOLVE_KEYS|X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS; + auto_ptr credential(new InlineCredential(context)); + if (context->getKeyInfo()) + credential->resolve(context->getKeyInfo(), types); + else if (context->getNativeKeyInfo()) + credential->resolve(context->getNativeKeyInfo(), types); + credential->setCredentialContext(context); + return credential.release(); + } }; - KeyResolver* XMLTOOL_DLLLOCAL InlineKeyResolverFactory(const DOMElement* const & e) + KeyInfoResolver* XMLTOOL_DLLLOCAL InlineKeyInfoResolverFactory(const DOMElement* const & e) { - return new InlineKeyResolver(e); + return new InlineKeyResolver(); } }; -static const XMLCh cache[] = UNICODE_LITERAL_5(c,a,c,h,e); - -InlineKeyResolver::InlineKeyResolver(const DOMElement* e) : m_lock(NULL) -{ - const XMLCh* flag = e ? e->getAttributeNS(NULL,cache) : NULL; - if (flag && XMLString::equals(flag,xmlconstants::XML_TRUE) || XMLString::equals(flag,xmlconstants::XML_ONE)) - m_lock=RWLock::create(); -} - -InlineKeyResolver::~InlineKeyResolver() -{ - clearCache(); - delete m_lock; -} - -void InlineKeyResolver::_resolve(const KeyInfo* keyInfo, CacheEntry& entry) const -{ - if (_resolveCertificates(keyInfo, entry.m_certs)>0) - entry.m_key = entry.m_certs.front()->clonePublicKey(); - else - entry.m_key = _resolveKey(keyInfo); - entry.m_crl = _resolveCRL(keyInfo); -} - -XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const +void InlineCredential::resolve(const KeyInfo* keyInfo, int types) { #ifdef _DEBUG - NDC ndc("_resolveKey"); + NDC ndc("resolve"); #endif - Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver"); - if (!keyInfo) - return NULL; + if (types & X509Credential::RESOLVE_CERTS) + resolveCerts(keyInfo); + + if (types & Credential::RESOLVE_KEYS) { + if (types & X509Credential::RESOLVE_CERTS) { + // If we have a cert, just use it. + if (!m_xseccerts.empty()) + m_key = m_xseccerts.front()->clonePublicKey(); + else + resolveKey(keyInfo); + } + // Otherwise try directly for a key and then go for certs if none is found. + else if (!resolveKey(keyInfo) && resolveCerts(keyInfo)) { + m_key = m_xseccerts.front()->clonePublicKey(); + } + } - // Check for ds:X509Data - const vector& x509Datas=keyInfo->getX509Datas(); - for (vector::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) { - try { - const vector x509Certs=const_cast(*j)->getX509Certificates(); - if (!x509Certs.empty()) { - auto_ptr_char x(x509Certs.front()->getValue()); - if (!x.get()) { - log.warn("skipping empty ds:X509Certificate"); - } - else { - log.debug("resolving ds:X509Certificate"); - auto_ptr x509(XSECPlatformUtils::g_cryptoProvider->X509()); - x509->loadX509Base64Bin(x.get(), strlen(x.get())); - return x509->clonePublicKey(); - } - } + if (types & X509Credential::RESOLVE_CRLS) + resolveCRLs(keyInfo); + + const XMLCh* n; + char* kn; + const vector& knames=keyInfo->getKeyNames(); + for (vector::const_iterator kn_i=knames.begin(); kn_i!=knames.end(); ++kn_i) { + n=(*kn_i)->getName(); + if (n && *n) { + kn=toUTF8(n); + m_keyNames.insert(kn); + delete[] kn; } - catch(XSECException& e) { - auto_ptr_char temp(e.getMsg()); - log.error("caught XML-Security exception loading certificate: %s", temp.get()); + } + const vector datas=keyInfo->getX509Datas(); + for (vector::const_iterator x_i=datas.begin(); x_i!=datas.end(); ++x_i) { + const vector snames = const_cast(*x_i)->getX509SubjectNames(); + for (vector::const_iterator sn_i = snames.begin(); sn_i!=snames.end(); ++sn_i) { + n = (*sn_i)->getName(); + if (n && *n) { + kn=toUTF8(n); + m_keyNames.insert(kn); + m_subjectName = kn; + delete[] kn; + } } - catch(XSECCryptoException& e) { - log.error("caught XML-Security exception loading certificate: %s", e.getMsg()); + + const vector inames = const_cast(*x_i)->getX509IssuerSerials(); + if (!inames.empty()) { + const X509IssuerName* iname = inames.front()->getX509IssuerName(); + if (iname) { + kn = toUTF8(iname->getName()); + if (kn) + m_issuerName = kn; + delete[] kn; + } + + const X509SerialNumber* ser = inames.front()->getX509SerialNumber(); + if (ser) { + auto_ptr_char sn(ser->getSerialNumber()); + m_serial = sn.get(); + } } } +} + +bool InlineCredential::resolveKey(const KeyInfo* keyInfo) +{ + Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver."INLINE_KEYINFO_RESOLVER); // Check for ds:KeyValue const vector& keyValues = keyInfo->getKeyValues(); @@ -167,7 +245,8 @@ XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const auto_ptr rsa(XSECPlatformUtils::g_cryptoProvider->keyRSA()); rsa->loadPublicModulusBase64BigNums(mod.get(), strlen(mod.get())); rsa->loadPublicExponentBase64BigNums(exp.get(), strlen(exp.get())); - return rsa.release(); + m_key = rsa.release(); + return true; } DSAKeyValue* dsakv = (*i)->getDSAKeyValue(); if (dsakv) { @@ -187,7 +266,8 @@ XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const auto_ptr_char g(dsakv->getG()->getValue()); dsa->loadGBase64BigNums(g.get(), strlen(g.get())); } - return dsa.release(); + m_key = dsa.release(); + return true; } } catch (ValidationException& ex) { @@ -202,55 +282,16 @@ XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const } } - // Check for RetrievalMethod. - const XMLCh* fragID=NULL; - const XMLObject* treeRoot=NULL; - XSECCryptoKey* remote=NULL; - const vector methods=keyInfo->getRetrievalMethods(); - for (vector::const_iterator m=methods.begin(); m!=methods.end(); ++m) { - if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_X509DATA) && - !XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_RSAKEYVALUE) && - !XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_DSAKEYVALUE)) - continue; - fragID = (*m)->getURI(); - if (!fragID || *fragID != chPound || !*(fragID+1)) { - log.warn("skipping ds:RetrievalMethod with an empty or non-local reference"); - continue; - } - if (!treeRoot) { - treeRoot = keyInfo; - while (treeRoot->getParent()) - treeRoot = treeRoot->getParent(); - } - keyInfo = dynamic_cast(XMLHelper::getXMLObjectById(*treeRoot, fragID+1)); - if (!keyInfo) { - log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo"); - continue; - } - remote = _resolveKey(keyInfo); - if (remote) - return remote; - } - - log.warn("unable to resolve key"); - return NULL; + return false; } -vector::size_type InlineKeyResolver::_resolveCertificates( - const KeyInfo* keyInfo, vector& certs - ) const +bool InlineCredential::resolveCerts(const KeyInfo* keyInfo) { -#ifdef _DEBUG - NDC ndc("_resolveCertificates"); -#endif - Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver"); - - if (!keyInfo) - return 0; + Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver."INLINE_KEYINFO_RESOLVER); // Check for ds:X509Data const vector& x509Datas=keyInfo->getX509Datas(); - for (vector::const_iterator j=x509Datas.begin(); certs.empty() && j!=x509Datas.end(); ++j) { + for (vector::const_iterator j=x509Datas.begin(); m_xseccerts.empty() && j!=x509Datas.end(); ++j) { const vector x509Certs=const_cast(*j)->getX509Certificates(); for (vector::const_iterator k=x509Certs.begin(); k!=x509Certs.end(); ++k) { try { @@ -262,7 +303,7 @@ vector::size_type InlineKeyResolver::_resolveCertificates( log.debug("resolving ds:X509Certificate"); auto_ptr x509(XSECPlatformUtils::g_cryptoProvider->X509()); x509->loadX509Base64Bin(x.get(), strlen(x.get())); - certs.push_back(x509.release()); + m_xseccerts.push_back(x509.release()); } } catch(XSECException& e) { @@ -275,48 +316,13 @@ vector::size_type InlineKeyResolver::_resolveCertificates( } } - if (certs.empty()) { - // Check for RetrievalMethod. - const XMLCh* fragID=NULL; - const XMLObject* treeRoot=NULL; - const vector methods=keyInfo->getRetrievalMethods(); - for (vector::const_iterator m=methods.begin(); certs.empty() && m!=methods.end(); ++m) { - if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_X509DATA)) - continue; - fragID = (*m)->getURI(); - if (!fragID || *fragID != chPound || !*(fragID+1)) { - log.warn("skipping ds:RetrievalMethod with an empty or non-local reference"); - continue; - } - if (!treeRoot) { - treeRoot = keyInfo; - while (treeRoot->getParent()) - treeRoot = treeRoot->getParent(); - } - keyInfo = dynamic_cast(XMLHelper::getXMLObjectById(*treeRoot, fragID+1)); - if (!keyInfo) { - log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo"); - continue; - } - _resolveCertificates(keyInfo, certs); - } - } - - if (log.isDebugEnabled()) { - log.debug("resolved %d certificate%s", certs.size(), certs.size()==1 ? "" : "s"); - } - return certs.size(); + log.debug("resolved %d certificate(s)", m_xseccerts.size()); + return !m_xseccerts.empty(); } -XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const +bool InlineCredential::resolveCRLs(const KeyInfo* keyInfo) { -#ifdef _DEBUG - NDC ndc("_resolveCRL"); -#endif - Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver"); - - if (!keyInfo) - return NULL; + Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver."INLINE_KEYINFO_RESOLVER); // Check for ds:X509Data const vector& x509Datas=keyInfo->getX509Datas(); @@ -332,219 +338,120 @@ XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const log.debug("resolving ds:X509CRL"); auto_ptr crl(XMLToolingConfig::getConfig().X509CRL()); crl->loadX509CRLBase64Bin(x.get(), strlen(x.get())); - return crl.release(); + m_crls.push_back(crl.release()); } } catch(XSECException& e) { auto_ptr_char temp(e.getMsg()); - log.error("caught XML-Security exception loading certificate: %s", temp.get()); + log.error("caught XML-Security exception loading CRL: %s", temp.get()); } catch(XSECCryptoException& e) { - log.error("caught XML-Security exception loading certificate: %s", e.getMsg()); + log.error("caught XML-Security exception loading CRL: %s", e.getMsg()); } } } - // Check for RetrievalMethod. - const XMLCh* fragID=NULL; - const XMLObject* treeRoot=NULL; - XSECCryptoX509CRL* remote=NULL; - const vector methods=keyInfo->getRetrievalMethods(); - for (vector::const_iterator m=methods.begin(); m!=methods.end(); ++m) { - if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_X509DATA)) - continue; - fragID = (*m)->getURI(); - if (!fragID || *fragID != chPound || !*(fragID+1)) { - log.warn("skipping ds:RetrievalMethod with an empty or non-local reference"); - continue; - } - if (!treeRoot) { - treeRoot = keyInfo; - while (treeRoot->getParent()) - treeRoot = treeRoot->getParent(); - } - keyInfo = dynamic_cast(XMLHelper::getXMLObjectById(*treeRoot, fragID+1)); - if (!keyInfo) { - log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo"); - continue; - } - remote = _resolveCRL(keyInfo); - if (remote) - return remote; - } - - return NULL; + log.debug("resolved %d CRL(s)", m_crls.size()); + return !m_crls.empty(); } -XSECCryptoKey* InlineKeyResolver::resolveKey(const KeyInfo* keyInfo) const +void InlineCredential::resolve(DSIGKeyInfoList* keyInfo, int types) { - // Caching? - if (m_lock) { - // Get read lock. - m_lock->rdlock(); - map::iterator i=m_cache.find(keyInfo); - if (i != m_cache.end()) { - // Found in cache, so just return the results. - SharedLock locker(m_lock,false); - return i->second.m_key ? i->second.m_key->clone() : NULL; - } - else { - // Elevate lock. - m_lock->unlock(); - m_lock->wrlock(); - SharedLock locker(m_lock,false); - // Recheck cache. - i=m_cache.find(keyInfo); - if (i == m_cache.end()) { - i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first; - _resolve(i->first, i->second); - } - return i->second.m_key ? i->second.m_key->clone() : NULL; - } - } - return _resolveKey(keyInfo); -} +#ifdef _DEBUG + NDC ndc("resolve"); +#endif -XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(const KeyInfo* keyInfo) const -{ - // Caching? - if (m_lock) { - // Get read lock. - m_lock->rdlock(); - map::iterator i=m_cache.find(keyInfo); - if (i != m_cache.end()) { - // Found in cache, so just return the results. - SharedLock locker(m_lock,false); - return i->second.m_crl ? i->second.m_crl->clone() : NULL; - } - else { - // Elevate lock. - m_lock->unlock(); - m_lock->wrlock(); - SharedLock locker(m_lock,false); - // Recheck cache. - i=m_cache.find(keyInfo); - if (i == m_cache.end()) { - i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first; - _resolve(i->first, i->second); - } - return i->second.m_crl ? i->second.m_crl->clone() : NULL; + if (types & Credential::RESOLVE_KEYS) { + // Default resolver handles RSA/DSAKeyValue and X509Certificate elements. + try { + XSECKeyInfoResolverDefault def; + m_key = def.resolveKey(keyInfo); } - } - return _resolveCRL(keyInfo); -} - -vector::size_type InlineKeyResolver::resolveCertificates( - const KeyInfo* keyInfo, ResolvedCertificates& certs - ) const -{ - // Caching? - if (m_lock) { - // Get read lock. - m_lock->rdlock(); - map::iterator i=m_cache.find(keyInfo); - if (i != m_cache.end()) { - // Found in cache, so just return the results. - SharedLock locker(m_lock,false); - accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end()); - accessOwned(certs) = false; - return accessCertificates(certs).size(); + catch(XSECException& e) { + auto_ptr_char temp(e.getMsg()); + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading certificate: %s", temp.get()); } - else { - // Elevate lock. - m_lock->unlock(); - m_lock->wrlock(); - SharedLock locker(m_lock,false); - // Recheck cache. - i=m_cache.find(keyInfo); - if (i == m_cache.end()) { - i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first; - _resolve(i->first, i->second); - } - accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end()); - accessOwned(certs) = false; - return accessCertificates(certs).size(); + catch(XSECCryptoException& e) { + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading certificate: %s", e.getMsg()); } } - accessOwned(certs) = true; - return _resolveCertificates(keyInfo, accessCertificates(certs)); -} -XSECCryptoKey* InlineKeyResolver::resolveKey(DSIGKeyInfoList* keyInfo) const -{ -#ifdef _DEBUG - NDC ndc("resolveKey"); -#endif - - if (!keyInfo) - return NULL; + DSIGKeyInfoList::size_type sz = keyInfo->getSize(); - // Default resolver handles RSA/DSAKeyValue and X509Certificate elements. - try { - XSECKeyInfoResolverDefault def; - return def.resolveKey(keyInfo); - } - catch(XSECException& e) { - auto_ptr_char temp(e.getMsg()); - Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", temp.get()); - } - catch(XSECCryptoException& e) { - Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", e.getMsg()); + if (types & X509Credential::RESOLVE_CERTS) { + for (DSIGKeyInfoList::size_type i=0; iitem(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) { + DSIGKeyInfoX509* x509 = static_cast(keyInfo->item(i)); + int count = x509->getCertificateListSize(); + if (count) { + for (int j=0; jgetCertificateCryptoItem(j)); + break; + } + } + } } - return NULL; -} - -vector::size_type InlineKeyResolver::resolveCertificates( - DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs - ) const -{ - accessCertificates(certs).clear(); - accessOwned(certs) = false; - if (!keyInfo) - return 0; - - DSIGKeyInfoList::size_type sz = keyInfo->getSize(); - for (DSIGKeyInfoList::size_type i=0; accessCertificates(certs).empty() && iitem(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) { - DSIGKeyInfoX509* x509 = static_cast(keyInfo->item(i)); - int count = x509->getCertificateListSize(); - for (int j=0; jgetCertificateCryptoItem(j)); + if (types & X509Credential::RESOLVE_CRLS) { + DOMNode* x509Node; + DOMElement* crlElement; + for (DSIGKeyInfoList::size_type i=0; iitem(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) { + // The current xmlsec API is limited to one CRL per KeyInfo. + // For now, I'm going to process the DOM directly. + x509Node = keyInfo->item(i)->getKeyInfoDOMNode(); + crlElement = x509Node ? XMLHelper::getFirstChildElement(x509Node, xmlconstants::XMLSIG_NS, X509CRL::LOCAL_NAME) : NULL; + while (crlElement) { + if (crlElement->hasChildNodes()) { + auto_ptr_char buf(crlElement->getFirstChild()->getNodeValue()); + if (buf.get()) { + try { + auto_ptr crlobj(XMLToolingConfig::getConfig().X509CRL()); + crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get())); + m_crls.push_back(crlobj.release()); + } + catch(XSECException& e) { + auto_ptr_char temp(e.getMsg()); + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", temp.get()); + } + catch(XSECCryptoException& e) { + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", e.getMsg()); + } + } + } + crlElement = XMLHelper::getNextSiblingElement(crlElement, xmlconstants::XMLSIG_NS, X509CRL::LOCAL_NAME); + } } } } - return accessCertificates(certs).size(); -} -XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const -{ -#ifdef _DEBUG - NDC ndc("resolveCRL"); -#endif + char* kn; + const XMLCh* n; + + for (size_t s=0; sgetSize(); s++) { + DSIGKeyInfo* dki = keyInfo->item(s); + n=dki->getKeyName(); + if (n && *n) { + kn=toUTF8(n); + m_keyNames.insert(kn); + if (dki->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) + m_subjectName = kn; + delete[] kn; + } - if (!keyInfo) - return NULL; - - DSIGKeyInfoList::size_type sz = keyInfo->getSize(); - for (DSIGKeyInfoList::size_type i=0; iitem(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) { - auto_ptr_char buf(static_cast(keyInfo->item(i))->getX509CRL()); - if (buf.get()) { - try { - auto_ptr crlobj(XMLToolingConfig::getConfig().X509CRL()); - crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get())); - return crlobj.release(); - } - catch(XSECException& e) { - auto_ptr_char temp(e.getMsg()); - Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", temp.get()); - } - catch(XSECCryptoException& e) { - Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", e.getMsg()); - } + if (dki->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) { + DSIGKeyInfoX509* kix = static_cast(dki); + n = kix->getX509IssuerName(); + if (n && *n) { + kn=toUTF8(n); + m_issuerName = kn; + delete[] kn; + } + n = kix->getX509IssuerSerialNumber(); + if (n && *n) { + auto_ptr_char sn(n); + m_serial = sn.get(); } } } - return NULL; }