Extended KeyResolver to handle CRLs.
authorScott Cantor <cantor.2@osu.edu>
Mon, 21 Aug 2006 23:02:33 +0000 (23:02 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 21 Aug 2006 23:02:33 +0000 (23:02 +0000)
xmltooling/security/XSECCryptoX509CRL.h
xmltooling/security/impl/OpenSSLCryptoX509CRL.h
xmltooling/signature/KeyResolver.h
xmltooling/signature/impl/InlineKeyResolver.cpp
xmltooling/signature/impl/KeyResolver.cpp
xmltoolingtest/InlineKeyResolverTest.h
xmltoolingtest/data/KeyInfo1.xml

index 3a06261..4bca77b 100644 (file)
@@ -23,6 +23,8 @@
 #if !defined(__xmltooling_x509crl_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
 #define __xmltooling_x509crl_h__\r
 \r
+#include <xmltooling/base.h>\r
+\r
 #include <xsec/framework/XSECDefs.hpp>\r
 #include <xsec/utils/XSECSafeBuffer.hpp>\r
 \r
@@ -53,6 +55,13 @@ namespace xmltooling {
         * @param len number of bytes of data in the CRL buffer\r
         */\r
     \r
+        /**\r
+         * Returns a duplicate of the original object.\r
+         *\r
+         * @return  the duplicate\r
+         */\r
+        virtual XSECCryptoX509CRL* clone() const=0;\r
+\r
        virtual void loadX509CRLBase64Bin(const char* buf, unsigned int len)=0;\r
     \r
        /**\r
index e59d073..8490362 100644 (file)
@@ -48,6 +48,13 @@ namespace xmltooling {
        X509_CRL* getOpenSSLX509CRL(void) {\r
             return mp_X509CRL;\r
         }\r
+\r
+        XSECCryptoX509CRL* clone() const {\r
+            OpenSSLCryptoX509CRL* copy = new OpenSSLCryptoX509CRL();\r
+            copy->mp_X509CRL = X509_CRL_dup(mp_X509CRL);\r
+            copy->m_DERX509CRL = m_DERX509CRL;\r
+            return copy;\r
+        }\r
     \r
     private:\r
        X509_CRL* mp_X509CRL;\r
index 8a4774b..b75ab2b 100644 (file)
@@ -24,6 +24,7 @@
 #if !defined(__xmltooling_keyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
 #define __xmltooling_keyres_h__\r
 \r
+#include <xmltooling/security/XSECCryptoX509CRL.h>\r
 #include <xmltooling/signature/KeyInfo.h>\r
 \r
 #include <xsec/dsig/DSIGKeyInfoList.hpp>\r
@@ -101,6 +102,24 @@ namespace xmlsignature {
             DSIGKeyInfoList* keyInfo, std::vector<XSECCryptoX509*>& certs \r
             ) const;\r
 \r
+        /**\r
+         * Returns a CRL based on the supplied KeyInfo information.\r
+         * The caller must delete the CRL when done with it.\r
+         * \r
+         * @param keyInfo   the key information\r
+         * @return  the resolved CRL\r
+         */\r
+        virtual xmltooling::XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;\r
+        \r
+        /**\r
+         * Returns a CRL based on the supplied KeyInfo information.\r
+         * The caller must delete the CRL when done with it.\r
+         * \r
+         * @param keyInfo   the key information\r
+         * @return  the resolved CRL\r
+         */\r
+        virtual xmltooling::XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;\r
+\r
     protected:\r
         XSECCryptoKey* m_key;\r
     };\r
index 8a4ffcf..82f0433 100644 (file)
@@ -52,6 +52,8 @@ namespace xmlsignature {
         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
+        XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;\r
+        XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;\r
         \r
         void clearCache() {\r
             if (m_lock)\r
@@ -63,18 +65,21 @@ namespace xmlsignature {
         \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
@@ -107,6 +112,7 @@ void InlineKeyResolver::_resolve(const KeyInfo* keyInfo, CacheEntry& entry) cons
         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
@@ -236,6 +242,42 @@ vector<XSECCryptoX509*>::size_type InlineKeyResolver::_resolveCertificates(
     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
+    // 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
@@ -265,6 +307,35 @@ XSECCryptoKey* InlineKeyResolver::resolveKey(const KeyInfo* keyInfo) const
     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\r
@@ -301,7 +372,7 @@ vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(
 XSECCryptoKey* InlineKeyResolver::resolveKey(DSIGKeyInfoList* keyInfo) const\r
 {\r
 #ifdef _DEBUG\r
-    NDC ndc("_resolveKey");\r
+    NDC ndc("resolveKey");\r
 #endif\r
 \r
     // Default resolver handles RSA/DSAKeyValue and X509Certificate elements.\r
@@ -336,3 +407,32 @@ vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(
     }\r
     return certs.size();\r
 }\r
+\r
+XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const\r
+{\r
+#ifdef _DEBUG\r
+    NDC ndc("resolveCRL");\r
+#endif\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
index 65925e0..994d900 100644 (file)
@@ -52,3 +52,13 @@ vector<XSECCryptoX509*>::size_type KeyResolver::resolveCertificates(
 {
     return 0;
 }
+
+XSECCryptoX509CRL* KeyResolver::resolveCRL(const KeyInfo* keyInfo) const
+{
+    return NULL;
+}
+
+XSECCryptoX509CRL* KeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const
+{
+    return NULL;
+}
index 1c9e39e..5010fde 100644 (file)
@@ -53,6 +53,9 @@ public:
         TSM_ASSERT("Unable to resolve public key.", key.get()!=NULL);\r
         TSM_ASSERT_EQUALS("Unexpected key type.", key->getKeyType(), XSECCryptoKey::KEY_RSA_PUBLIC);\r
 \r
+        auto_ptr<XSECCryptoX509CRL> crl(m_resolver->resolveCRL(kiObject.get()));\r
+        TSM_ASSERT("Unable to resolve CRL.", crl.get()!=NULL);\r
+\r
         vector<XSECCryptoX509*> certs;\r
         TSM_ASSERT_EQUALS("Wrong certificate count.", m_resolver->resolveCertificates(kiObject.get(), certs), 1);\r
     }\r
index cc62cb8..e31ab73 100644 (file)
     </ds:KeyValue>
     <ds:X509Data>
         <ds:X509Certificate>MIIEYTCCA8qgAwIBAgIDPbIoMA0GCSqGSIb3DQEBBQUAMIHsMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEwMC4GA1UECxMnaHR0cDovL3d3dy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5MTEwLwYDVQQDEyhTdGFyZmllbGQgU2VjdXJlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSowKAYJKoZIhvcNAQkBFhtwcmFjdGljZXNAc3RhcmZpZWxkdGVjaC5jb20wHhcNMDYwMzI5MjAwNzIxWhcNMDcwMzI5MjAwNzIxWjBNMRMwEQYDVQQKEwp4bWxkYXAub3JnMSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0ZWQxEzARBgNVBAMTCnhtbGRhcC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANCxWwHKKOzwCtsbZUhhzQjXcyKHA7zrl8UqoCyu7haKzrEmI7udl7B6L+zxgnmVRz4zsw1PJsVYUt9zG6ABC+P7Xtx46Tk/h5gO6hWL4XBzFUuKwsMRZ0RB0sAv6iQtz6TCyH47OBSJSN24h7e/viUQ0ZtKYsJo/r8BHrnoiJk1AgMBAAGjggGtMIIBqTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NlcnRpZmljYXRlcy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5L3N0YXJmaWVsZGlzc3VpbmcuY3JsME8GA1UdIARIMEYwRAYLYIZIAYb4RQEHFwMwNTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5MIGGBggrBgEFBQcBAQR6MHgwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnN0YXJmaWVsZHRlY2guY29tMEsGCCsGAQUFBzAChj9odHRwOi8vY2VydGlmaWNhdGVzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkvc2ZfaXNzdWluZy5jcnQwHQYDVR0OBBYEFMcfOhkD6X5rEFFGmj1aV4Rg7Nr9MB8GA1UdIwQYMBaAFKxV3rfqE+v8mGjiU2Ae8SU+jO7nMA0GCSqGSIb3DQEBBQUAA4GBAB0qT6gCXzgWua2P9/CPqsbXztwJAMPVx2zyAVYuZwgThsEmg53EhpqhUFz6DssNFzIxGT8vMrOMJs0hgndBTtWVfdJbrhbgtdc7/Zp10WO/6ioX3lIzJq+un2MA9Rdwk3QQyHCH9baYgHbcPEOj3N+dk2nzCzK34IbPpjYzE7H0</ds:X509Certificate>
+        <ds:X509CRL>
+            MIIBNjCBoDANBgkqhkiG9w0BAQQFADBbMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
+            VE4xEDAOBgNVBAcTB01lbXBoaXMxEjAQBgNVBAoTCVdhc3NhLk9yRzEZMBcGA1UE
+            AxMQV2FsdGVyJ3MgVGVzdCBDQRcNMDUwNDA4MDQwMTU2WhcNMDUwNTA4MDQwMTU2
+            WjAUMBICAQEXDTA1MDQwODA0MDA1MVowDQYJKoZIhvcNAQEEBQADgYEAETadhKU8
+            nrxii0wwkbdfBZ5lmlBu0z9wqobPCH/oSlkMZ9FlE/LmADEclR2hqOgczMRz/BwL
+            kghUXSJe4yuXl2gvGrTd/Mn36HQ/rvr6dbgLzpuNWHRAW99o4Wpf5o+Hi9iEyF2J
+            /50cy2EUSe6YtzA8pGXzSP67YC/3U0D8U4A=
+        </ds:X509CRL>
     </ds:X509Data>
 </ds:KeyInfo>