From beb1ff4a677a8268af627a3a558f46c09f59267c Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Mon, 21 Aug 2006 23:02:33 +0000 Subject: [PATCH] Extended KeyResolver to handle CRLs. --- xmltooling/security/XSECCryptoX509CRL.h | 9 ++ xmltooling/security/impl/OpenSSLCryptoX509CRL.h | 7 ++ xmltooling/signature/KeyResolver.h | 19 +++++ xmltooling/signature/impl/InlineKeyResolver.cpp | 104 +++++++++++++++++++++++- xmltooling/signature/impl/KeyResolver.cpp | 10 +++ xmltoolingtest/InlineKeyResolverTest.h | 3 + xmltoolingtest/data/KeyInfo1.xml | 9 ++ 7 files changed, 159 insertions(+), 2 deletions(-) diff --git a/xmltooling/security/XSECCryptoX509CRL.h b/xmltooling/security/XSECCryptoX509CRL.h index 3a06261..4bca77b 100644 --- a/xmltooling/security/XSECCryptoX509CRL.h +++ b/xmltooling/security/XSECCryptoX509CRL.h @@ -23,6 +23,8 @@ #if !defined(__xmltooling_x509crl_h__) && !defined(XMLTOOLING_NO_XMLSEC) #define __xmltooling_x509crl_h__ +#include + #include #include @@ -53,6 +55,13 @@ namespace xmltooling { * @param len number of bytes of data in the CRL buffer */ + /** + * Returns a duplicate of the original object. + * + * @return the duplicate + */ + virtual XSECCryptoX509CRL* clone() const=0; + virtual void loadX509CRLBase64Bin(const char* buf, unsigned int len)=0; /** diff --git a/xmltooling/security/impl/OpenSSLCryptoX509CRL.h b/xmltooling/security/impl/OpenSSLCryptoX509CRL.h index e59d073..8490362 100644 --- a/xmltooling/security/impl/OpenSSLCryptoX509CRL.h +++ b/xmltooling/security/impl/OpenSSLCryptoX509CRL.h @@ -48,6 +48,13 @@ namespace xmltooling { X509_CRL* getOpenSSLX509CRL(void) { return mp_X509CRL; } + + XSECCryptoX509CRL* clone() const { + OpenSSLCryptoX509CRL* copy = new OpenSSLCryptoX509CRL(); + copy->mp_X509CRL = X509_CRL_dup(mp_X509CRL); + copy->m_DERX509CRL = m_DERX509CRL; + return copy; + } private: X509_CRL* mp_X509CRL; diff --git a/xmltooling/signature/KeyResolver.h b/xmltooling/signature/KeyResolver.h index 8a4774b..b75ab2b 100644 --- a/xmltooling/signature/KeyResolver.h +++ b/xmltooling/signature/KeyResolver.h @@ -24,6 +24,7 @@ #if !defined(__xmltooling_keyres_h__) && !defined(XMLTOOLING_NO_XMLSEC) #define __xmltooling_keyres_h__ +#include #include #include @@ -101,6 +102,24 @@ namespace xmlsignature { DSIGKeyInfoList* keyInfo, std::vector& certs ) const; + /** + * Returns a CRL based on the supplied KeyInfo information. + * The caller must delete the CRL when done with it. + * + * @param keyInfo the key information + * @return the resolved CRL + */ + virtual xmltooling::XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const; + + /** + * Returns a CRL based on the supplied KeyInfo information. + * The caller must delete the CRL when done with it. + * + * @param keyInfo the key information + * @return the resolved CRL + */ + virtual xmltooling::XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const; + protected: XSECCryptoKey* m_key; }; diff --git a/xmltooling/signature/impl/InlineKeyResolver.cpp b/xmltooling/signature/impl/InlineKeyResolver.cpp index 8a4ffcf..82f0433 100644 --- a/xmltooling/signature/impl/InlineKeyResolver.cpp +++ b/xmltooling/signature/impl/InlineKeyResolver.cpp @@ -52,6 +52,8 @@ namespace xmlsignature { XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const; vector::size_type resolveCertificates(const KeyInfo* keyInfo, vector& certs) const; vector::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, vector& certs) const; + XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const; + XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const; void clearCache() { if (m_lock) @@ -63,18 +65,21 @@ namespace xmlsignature { private: struct XMLTOOL_DLLLOCAL CacheEntry { - CacheEntry() : m_key(NULL) {} + 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; @@ -107,6 +112,7 @@ void InlineKeyResolver::_resolve(const KeyInfo* keyInfo, CacheEntry& entry) cons 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 @@ -236,6 +242,42 @@ vector::size_type InlineKeyResolver::_resolveCertificates( return certs.size(); } +XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const +{ +#ifdef _DEBUG + NDC ndc("_resolveCRL"); +#endif + Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver"); + + // Check for ds:X509Data + const vector& x509Datas=keyInfo->getX509Datas(); + for (vector::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) { + const vector x509CRLs=const_cast(*j)->getX509CRLs(); + for (vector::const_iterator k=x509CRLs.begin(); k!=x509CRLs.end(); ++k) { + try { + auto_ptr_char x((*k)->getValue()); + if (!x.get()) { + log.warn("skipping empty ds:X509CRL"); + } + else { + log.debug("resolving ds:X509CRL"); + auto_ptr crl(XMLToolingConfig::getConfig().X509CRL()); + crl->loadX509CRLBase64Bin(x.get(), strlen(x.get())); + return crl.release(); + } + } + catch(XSECException& e) { + auto_ptr_char temp(e.getMsg()); + log.error("caught XML-Security exception loading certificate: %s", temp.get()); + } + catch(XSECCryptoException& e) { + log.error("caught XML-Security exception loading certificate: %s", e.getMsg()); + } + } + } + return NULL; +} + XSECCryptoKey* InlineKeyResolver::resolveKey(const KeyInfo* keyInfo) const { // Caching? @@ -265,6 +307,35 @@ XSECCryptoKey* InlineKeyResolver::resolveKey(const KeyInfo* keyInfo) const return _resolveKey(keyInfo); } +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; + } + } + return _resolveCRL(keyInfo); +} + vector::size_type InlineKeyResolver::resolveCertificates( const KeyInfo* keyInfo, vector& certs ) const @@ -301,7 +372,7 @@ vector::size_type InlineKeyResolver::resolveCertificates( XSECCryptoKey* InlineKeyResolver::resolveKey(DSIGKeyInfoList* keyInfo) const { #ifdef _DEBUG - NDC ndc("_resolveKey"); + NDC ndc("resolveKey"); #endif // Default resolver handles RSA/DSAKeyValue and X509Certificate elements. @@ -336,3 +407,32 @@ vector::size_type InlineKeyResolver::resolveCertificates( } return certs.size(); } + +XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const +{ +#ifdef _DEBUG + NDC ndc("resolveCRL"); +#endif + + 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()); + } + } + } + } + return NULL; +} diff --git a/xmltooling/signature/impl/KeyResolver.cpp b/xmltooling/signature/impl/KeyResolver.cpp index 65925e0..994d900 100644 --- a/xmltooling/signature/impl/KeyResolver.cpp +++ b/xmltooling/signature/impl/KeyResolver.cpp @@ -52,3 +52,13 @@ vector::size_type KeyResolver::resolveCertificates( { return 0; } + +XSECCryptoX509CRL* KeyResolver::resolveCRL(const KeyInfo* keyInfo) const +{ + return NULL; +} + +XSECCryptoX509CRL* KeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const +{ + return NULL; +} diff --git a/xmltoolingtest/InlineKeyResolverTest.h b/xmltoolingtest/InlineKeyResolverTest.h index 1c9e39e..5010fde 100644 --- a/xmltoolingtest/InlineKeyResolverTest.h +++ b/xmltoolingtest/InlineKeyResolverTest.h @@ -53,6 +53,9 @@ public: TSM_ASSERT("Unable to resolve public key.", key.get()!=NULL); TSM_ASSERT_EQUALS("Unexpected key type.", key->getKeyType(), XSECCryptoKey::KEY_RSA_PUBLIC); + auto_ptr crl(m_resolver->resolveCRL(kiObject.get())); + TSM_ASSERT("Unable to resolve CRL.", crl.get()!=NULL); + vector certs; TSM_ASSERT_EQUALS("Wrong certificate count.", m_resolver->resolveCertificates(kiObject.get(), certs), 1); } diff --git a/xmltoolingtest/data/KeyInfo1.xml b/xmltoolingtest/data/KeyInfo1.xml index cc62cb8..e31ab73 100644 --- a/xmltoolingtest/data/KeyInfo1.xml +++ b/xmltoolingtest/data/KeyInfo1.xml @@ -10,5 +10,14 @@ MIIEYTCCA8qgAwIBAgIDPbIoMA0GCSqGSIb3DQEBBQUAMIHsMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEwMC4GA1UECxMnaHR0cDovL3d3dy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5MTEwLwYDVQQDEyhTdGFyZmllbGQgU2VjdXJlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSowKAYJKoZIhvcNAQkBFhtwcmFjdGljZXNAc3RhcmZpZWxkdGVjaC5jb20wHhcNMDYwMzI5MjAwNzIxWhcNMDcwMzI5MjAwNzIxWjBNMRMwEQYDVQQKEwp4bWxkYXAub3JnMSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0ZWQxEzARBgNVBAMTCnhtbGRhcC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANCxWwHKKOzwCtsbZUhhzQjXcyKHA7zrl8UqoCyu7haKzrEmI7udl7B6L+zxgnmVRz4zsw1PJsVYUt9zG6ABC+P7Xtx46Tk/h5gO6hWL4XBzFUuKwsMRZ0RB0sAv6iQtz6TCyH47OBSJSN24h7e/viUQ0ZtKYsJo/r8BHrnoiJk1AgMBAAGjggGtMIIBqTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NlcnRpZmljYXRlcy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5L3N0YXJmaWVsZGlzc3VpbmcuY3JsME8GA1UdIARIMEYwRAYLYIZIAYb4RQEHFwMwNTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5MIGGBggrBgEFBQcBAQR6MHgwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnN0YXJmaWVsZHRlY2guY29tMEsGCCsGAQUFBzAChj9odHRwOi8vY2VydGlmaWNhdGVzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkvc2ZfaXNzdWluZy5jcnQwHQYDVR0OBBYEFMcfOhkD6X5rEFFGmj1aV4Rg7Nr9MB8GA1UdIwQYMBaAFKxV3rfqE+v8mGjiU2Ae8SU+jO7nMA0GCSqGSIb3DQEBBQUAA4GBAB0qT6gCXzgWua2P9/CPqsbXztwJAMPVx2zyAVYuZwgThsEmg53EhpqhUFz6DssNFzIxGT8vMrOMJs0hgndBTtWVfdJbrhbgtdc7/Zp10WO/6ioX3lIzJq+un2MA9Rdwk3QQyHCH9baYgHbcPEOj3N+dk2nzCzK34IbPpjYzE7H0 + + MIIBNjCBoDANBgkqhkiG9w0BAQQFADBbMQswCQYDVQQGEwJVUzELMAkGA1UECBMC + VE4xEDAOBgNVBAcTB01lbXBoaXMxEjAQBgNVBAoTCVdhc3NhLk9yRzEZMBcGA1UE + AxMQV2FsdGVyJ3MgVGVzdCBDQRcNMDUwNDA4MDQwMTU2WhcNMDUwNTA4MDQwMTU2 + WjAUMBICAQEXDTA1MDQwODA0MDA1MVowDQYJKoZIhvcNAQEEBQADgYEAETadhKU8 + nrxii0wwkbdfBZ5lmlBu0z9wqobPCH/oSlkMZ9FlE/LmADEclR2hqOgczMRz/BwL + kghUXSJe4yuXl2gvGrTd/Mn36HQ/rvr6dbgLzpuNWHRAW99o4Wpf5o+Hi9iEyF2J + /50cy2EUSe6YtzA8pGXzSP67YC/3U0D8U4A= + -- 2.1.4