Support RetrievalMethod local references.
authorScott Cantor <cantor.2@osu.edu>
Mon, 27 Nov 2006 02:03:43 +0000 (02:03 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 27 Nov 2006 02:03:43 +0000 (02:03 +0000)
xmltooling/signature/KeyInfo.h
xmltooling/signature/impl/InlineKeyResolver.cpp
xmltooling/signature/impl/KeyInfoImpl.cpp

index 8dacd00..410403e 100644 (file)
@@ -101,6 +101,12 @@ namespace xmlsignature {
         DECL_TYPED_CHILD(Transforms);
         /** RetrievalMethodType local name */
         static const XMLCh TYPE_NAME[];
+        /** DSAKeyValue RetrievalMethod Type */
+        static const XMLCh TYPE_DSAKEYVALUE[];
+        /** RSAKeyValue RetrievalMethod Type */
+        static const XMLCh TYPE_RSAKEYVALUE[];
+        /** X509Data RetrievalMethod Type */
+        static const XMLCh TYPE_X509DATA[];
     END_XMLOBJECT;
 
     BEGIN_XMLOBJECT(XMLTOOL_API,X509IssuerSerial,xmltooling::XMLObject,XML Digital Signature version 20020212 X509IssuerSerial element);
index 686b170..d1b06e7 100644 (file)
@@ -202,6 +202,36 @@ XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const
         }
     }
 
+    // Check for RetrievalMethod.
+    const XMLCh* fragID=NULL;
+    const XMLObject* treeRoot=NULL;
+    XSECCryptoKey* remote=NULL;
+    const vector<RetrievalMethod*> methods=keyInfo->getRetrievalMethods();
+    for (vector<RetrievalMethod*>::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<const KeyInfo*>(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;
 }
@@ -244,6 +274,34 @@ vector<XSECCryptoX509*>::size_type InlineKeyResolver::_resolveCertificates(
             }
         }
     }
+    
+    if (certs.empty()) {
+        // Check for RetrievalMethod.
+        const XMLCh* fragID=NULL;
+        const XMLObject* treeRoot=NULL;
+        const vector<RetrievalMethod*> methods=keyInfo->getRetrievalMethods();
+        for (vector<RetrievalMethod*>::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<const KeyInfo*>(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");
     }
@@ -286,6 +344,35 @@ XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const
             }
         }
     }
+
+    // Check for RetrievalMethod.
+    const XMLCh* fragID=NULL;
+    const XMLObject* treeRoot=NULL;
+    XSECCryptoX509CRL* remote=NULL;
+    const vector<RetrievalMethod*> methods=keyInfo->getRetrievalMethods();
+    for (vector<RetrievalMethod*>::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<const KeyInfo*>(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;
 }
 
index 62d033f..215392f 100644 (file)
@@ -877,3 +877,27 @@ const XMLCh X509Certificate::LOCAL_NAME[] = {
     };
 const XMLCh X509CRL::LOCAL_NAME[] = { XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(C), XCH(R), XCH(L), chNull };
 
+const XMLCh RetrievalMethod::TYPE_DSAKEYVALUE[] = {
+    chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+    chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+    chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash, chDigit_0, chDigit_9, chForwardSlash,
+    chLatin_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chPound,
+    chLatin_D, chLatin_S, chLatin_A, chLatin_K, chLatin_e, chLatin_y, chLatin_V, chLatin_a, chLatin_l, chLatin_u, chLatin_e, chNull
+    };
+
+const XMLCh RetrievalMethod::TYPE_RSAKEYVALUE[] = {
+    chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+    chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+    chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash, chDigit_0, chDigit_9, chForwardSlash,
+    chLatin_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chPound,
+    chLatin_R, chLatin_S, chLatin_A, chLatin_K, chLatin_e, chLatin_y, chLatin_V, chLatin_a, chLatin_l, chLatin_u, chLatin_e, chNull
+    };
+
+const XMLCh RetrievalMethod::TYPE_X509DATA[] = {
+    chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+    chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+    chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash, chDigit_0, chDigit_9, chForwardSlash,
+    chLatin_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chPound,
+    chLatin_X, chDigit_5, chDigit_0, chDigit_9, chLatin_D, chLatin_a, chLatin_t, chLatin_a, chNull
+    };
+    
\ No newline at end of file