From 4a86d7a4e0a5bd67d42b18fd57f7ece439a870a2 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Mon, 27 Nov 2006 02:03:43 +0000 Subject: [PATCH] Support RetrievalMethod local references. --- xmltooling/signature/KeyInfo.h | 6 ++ xmltooling/signature/impl/InlineKeyResolver.cpp | 87 +++++++++++++++++++++++++ xmltooling/signature/impl/KeyInfoImpl.cpp | 24 +++++++ 3 files changed, 117 insertions(+) diff --git a/xmltooling/signature/KeyInfo.h b/xmltooling/signature/KeyInfo.h index 8dacd00..410403e 100644 --- a/xmltooling/signature/KeyInfo.h +++ b/xmltooling/signature/KeyInfo.h @@ -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); diff --git a/xmltooling/signature/impl/InlineKeyResolver.cpp b/xmltooling/signature/impl/InlineKeyResolver.cpp index 686b170..d1b06e7 100644 --- a/xmltooling/signature/impl/InlineKeyResolver.cpp +++ b/xmltooling/signature/impl/InlineKeyResolver.cpp @@ -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 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; } @@ -244,6 +274,34 @@ 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"); } @@ -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 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; } diff --git a/xmltooling/signature/impl/KeyInfoImpl.cpp b/xmltooling/signature/impl/KeyInfoImpl.cpp index 62d033f..215392f 100644 --- a/xmltooling/signature/impl/KeyInfoImpl.cpp +++ b/xmltooling/signature/impl/KeyInfoImpl.cpp @@ -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 -- 2.1.4