From f3a43f14f9dd53428f9e879bb489d6a4cf2674a8 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Mon, 9 Apr 2007 03:42:07 +0000 Subject: [PATCH] Settable digest algorithm, enhanced prefix handling in signatures, pending xmlsec fix. --- saml/Makefile.am | 4 +- saml/binding/MessageEncoder.h | 6 +- saml/binding/impl/SimpleSigningRule.cpp | 6 +- saml/binding/impl/XMLSigningRule.cpp | 4 +- saml/saml.vcproj | 4 +- saml/saml1/binding/impl/SAML1ArtifactEncoder.cpp | 6 +- saml/saml1/binding/impl/SAML1POSTEncoder.cpp | 16 ++++-- saml/saml1/binding/impl/SAML1SOAPEncoder.cpp | 16 ++++-- saml/saml1/core/impl/AssertionsImpl.cpp | 6 +- saml/saml1/core/impl/ProtocolsImpl.cpp | 12 ++-- saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp | 15 +++-- saml/saml2/binding/impl/SAML2POSTEncoder.cpp | 24 +++++--- saml/saml2/binding/impl/SAML2RedirectEncoder.cpp | 14 +++-- saml/saml2/binding/impl/SAML2SOAPEncoder.cpp | 16 ++++-- .../metadata/impl/AbstractMetadataProvider.cpp | 13 +++++ ...rtionValidator.cpp => Assertion20Validator.cpp} | 2 +- ...idator.cpp => BrowserSSOProfile20Validator.cpp} | 2 +- saml/signature/ContentReference.cpp | 67 +++++++++++++++++----- saml/signature/ContentReference.h | 45 ++++++++++++--- samltest/saml2/binding/SAML2ArtifactTest.h | 1 + 20 files changed, 201 insertions(+), 78 deletions(-) rename saml/saml2/profile/{AssertionValidator.cpp => Assertion20Validator.cpp} (99%) rename saml/saml2/profile/{BrowserSSOProfileValidator.cpp => BrowserSSOProfile20Validator.cpp} (98%) diff --git a/saml/Makefile.am b/saml/Makefile.am index 2bb57f2..5444b1a 100644 --- a/saml/Makefile.am +++ b/saml/Makefile.am @@ -157,8 +157,8 @@ libsaml_la_SOURCES = \ saml2/binding/impl/SAML2SOAPEncoder.cpp \ saml2/binding/impl/SAML2SOAPClient.cpp \ saml2/binding/impl/SAML2MessageRule.cpp \ - saml2/profile/AssertionValidator.cpp \ - saml2/profile/BrowserSSOProfileValidator.cpp \ + saml2/profile/Assertion20Validator.cpp \ + saml2/profile/BrowserSSOProfile20Validator.cpp \ encryption/EncryptedKeyResolver.cpp \ signature/ContentReference.cpp \ signature/SignatureProfileValidator.cpp \ diff --git a/saml/binding/MessageEncoder.h b/saml/binding/MessageEncoder.h index a0e212b..ad87a08 100644 --- a/saml/binding/MessageEncoder.h +++ b/saml/binding/MessageEncoder.h @@ -108,7 +108,8 @@ namespace opensaml { * @param recipientID optional entityID of message recipient * @param relayState optional RelayState value to accompany message * @param credential optional Credential to supply signing key - * @param sigAlgorithm optional signature algorithm identifier + * @param signatureAlg optional signature algorithm identifier + * @param digestAlg optional reference digest algorithm identifier */ virtual long encode( GenericResponse& genericResponse, @@ -117,7 +118,8 @@ namespace opensaml { const char* recipientID=NULL, const char* relayState=NULL, const xmltooling::Credential* credential=NULL, - const XMLCh* sigAlgorithm=NULL + const XMLCh* signatureAlg=NULL, + const XMLCh* digestAlg=NULL ) const=0; protected: diff --git a/saml/binding/impl/SimpleSigningRule.cpp b/saml/binding/impl/SimpleSigningRule.cpp index cb8a410..f450f25 100644 --- a/saml/binding/impl/SimpleSigningRule.cpp +++ b/saml/binding/impl/SimpleSigningRule.cpp @@ -189,11 +189,9 @@ void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* auto_ptr kjanitor(keyInfo); auto_ptr_XMLCh alg(sigAlgorithm); - // Set up criteria object, including peer name to enforce cert name checking. + // Set up criteria object. MetadataCredentialCriteria cc(*(policy.getIssuerMetadata())); - auto_ptr_char pn(policy.getIssuer()->getName()); - cc.setPeerName(pn.get()); - cc.setKeyAlgorithm(sigAlgorithm); + cc.setXMLAlgorithm(alg.get()); if (!policy.getTrustEngine()->validate(alg.get(), signature, keyInfo, input.c_str(), input.length(), *(policy.getMetadataProvider()), &cc)) { log.error("unable to verify message signature with supplied trust engine"); diff --git a/saml/binding/impl/XMLSigningRule.cpp b/saml/binding/impl/XMLSigningRule.cpp index 1afb062..989cb05 100644 --- a/saml/binding/impl/XMLSigningRule.cpp +++ b/saml/binding/impl/XMLSigningRule.cpp @@ -97,10 +97,8 @@ void XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* re return; } - // Set up criteria object, including peer name to enforce cert name checking. + // Set up criteria object. MetadataCredentialCriteria cc(*(policy.getIssuerMetadata())); - auto_ptr_char pn(policy.getIssuer()->getName()); - cc.setPeerName(pn.get()); if (!policy.getTrustEngine()->validate(*(signable->getSignature()), *(policy.getMetadataProvider()), &cc)) { log.error("unable to verify message signature with supplied trust engine"); diff --git a/saml/saml.vcproj b/saml/saml.vcproj index 0494d9c..e74017e 100644 --- a/saml/saml.vcproj +++ b/saml/saml.vcproj @@ -472,7 +472,7 @@ Name="profile" > @@ -54,7 +55,8 @@ namespace opensaml { const char* recipientID=NULL, const char* relayState=NULL, const Credential* credential=NULL, - const XMLCh* sigAlgorithm=NULL + const XMLCh* signatureAlg=NULL, + const XMLCh* digestAlg=NULL ) const; protected: @@ -89,7 +91,8 @@ long SAML1POSTEncoder::encode( const char* recipientID, const char* relayState, const Credential* credential, - const XMLCh* sigAlgorithm + const XMLCh* signatureAlg, + const XMLCh* digestAlg ) const { #ifdef _DEBUG @@ -118,8 +121,13 @@ long SAML1POSTEncoder::encode( // Build a Signature. Signature* sig = SignatureBuilder::buildSignature(); response->setSignature(sig); - if (sigAlgorithm) - sig->setSignatureAlgorithm(sigAlgorithm); + if (signatureAlg) + sig->setSignatureAlgorithm(signatureAlg); + if (digestAlg) { + opensaml::ContentReference* cr = dynamic_cast(sig->getContentReference()); + if (cr) + cr->setDigestAlgorithm(digestAlg); + } // Sign response while marshalling. vector sigs(1,sig); diff --git a/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp b/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp index 3e1b026..2d0c6d4 100644 --- a/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp +++ b/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp @@ -24,6 +24,7 @@ #include "exceptions.h" #include "binding/HTTPResponse.h" #include "binding/MessageEncoder.h" +#include "signature/ContentReference.h" #include "saml1/core/Protocols.h" #include @@ -54,7 +55,8 @@ namespace opensaml { const char* recipientID=NULL, const char* relayState=NULL, const Credential* credential=NULL, - const XMLCh* sigAlgorithm=NULL + const XMLCh* signatureAlg=NULL, + const XMLCh* digestAlg=NULL ) const; }; @@ -72,7 +74,8 @@ long SAML1SOAPEncoder::encode( const char* recipientID, const char* relayState, const Credential* credential, - const XMLCh* sigAlgorithm + const XMLCh* signatureAlg, + const XMLCh* digestAlg ) const { #ifdef _DEBUG @@ -110,8 +113,13 @@ long SAML1SOAPEncoder::encode( // Build a Signature. Signature* sig = SignatureBuilder::buildSignature(); response->setSignature(sig); - if (sigAlgorithm) - sig->setSignatureAlgorithm(sigAlgorithm); + if (signatureAlg) + sig->setSignatureAlgorithm(signatureAlg); + if (digestAlg) { + opensaml::ContentReference* cr = dynamic_cast(sig->getContentReference()); + if (cr) + cr->setDigestAlgorithm(digestAlg); + } // Sign response while marshalling. vector sigs(1,sig); diff --git a/saml/saml1/core/impl/AssertionsImpl.cpp b/saml/saml1/core/impl/AssertionsImpl.cpp index 9f7998a..fa14c35 100644 --- a/saml/saml1/core/impl/AssertionsImpl.cpp +++ b/saml/saml1/core/impl/AssertionsImpl.cpp @@ -1034,9 +1034,9 @@ namespace opensaml { MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL); if (!m_AssertionID) const_cast(this)->m_AssertionID=SAMLConfig::getConfig().generateIdentifier(); - domElement->setAttributeNS(NULL, ASSERTIONID_ATTRIB_NAME, m_AssertionID); - if (*m_MinorVersion!=chDigit_0) - domElement->setIdAttributeNS(NULL, ASSERTIONID_ATTRIB_NAME); + domElement->setAttributeNS(NULL, ASSERTIONID_ATTRIB_NAME, m_AssertionID); + if (*m_MinorVersion!=chDigit_0) + domElement->setIdAttributeNS(NULL, ASSERTIONID_ATTRIB_NAME); MARSHALL_STRING_ATTRIB(Issuer,ISSUER,NULL); if (!m_IssueInstant) { const_cast(this)->m_IssueInstantEpoch=time(NULL); diff --git a/saml/saml1/core/impl/ProtocolsImpl.cpp b/saml/saml1/core/impl/ProtocolsImpl.cpp index a1300d6..dc40986 100644 --- a/saml/saml1/core/impl/ProtocolsImpl.cpp +++ b/saml/saml1/core/impl/ProtocolsImpl.cpp @@ -374,9 +374,9 @@ namespace opensaml { MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL); if (!m_RequestID) const_cast(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier(); - domElement->setAttributeNS(NULL, REQUESTID_ATTRIB_NAME, m_RequestID); - if (*m_MinorVersion!=chDigit_0) - domElement->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME); + domElement->setAttributeNS(NULL, REQUESTID_ATTRIB_NAME, m_RequestID); + if (*m_MinorVersion!=chDigit_0) + domElement->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME); if (!m_IssueInstant) { const_cast(this)->m_IssueInstantEpoch=time(NULL); const_cast(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch); @@ -703,9 +703,9 @@ namespace opensaml { MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL); if (!m_ResponseID) const_cast(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier(); - domElement->setAttributeNS(NULL, RESPONSEID_ATTRIB_NAME, m_ResponseID); - if (*m_MinorVersion!=chDigit_0) - domElement->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME); + domElement->setAttributeNS(NULL, RESPONSEID_ATTRIB_NAME, m_ResponseID); + if (*m_MinorVersion!=chDigit_0) + domElement->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME); MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL); if (!m_IssueInstant) { const_cast(this)->m_IssueInstantEpoch=time(NULL); diff --git a/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp b/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp index 5d31808..f397ebd 100644 --- a/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp @@ -57,7 +57,8 @@ namespace opensaml { const char* recipientID=NULL, const char* relayState=NULL, const Credential* credential=NULL, - const XMLCh* sigAlgorithm=NULL + const XMLCh* signatureAlg=NULL, + const XMLCh* digestAlg=NULL ) const; private: @@ -89,7 +90,8 @@ long SAML2ArtifactEncoder::encode( const char* recipientID, const char* relayState, const Credential* credential, - const XMLCh* sigAlgorithm + const XMLCh* signatureAlg, + const XMLCh* digestAlg ) const { #ifdef _DEBUG @@ -135,8 +137,13 @@ long SAML2ArtifactEncoder::encode( // Build a Signature. Signature* sig = SignatureBuilder::buildSignature(); request ? request->setSignature(sig) : response->setSignature(sig); - if (sigAlgorithm) - sig->setSignatureAlgorithm(sigAlgorithm); + if (signatureAlg) + sig->setSignatureAlgorithm(signatureAlg); + if (digestAlg) { + opensaml::ContentReference* cr = dynamic_cast(sig->getContentReference()); + if (cr) + cr->setDigestAlgorithm(digestAlg); + } // Sign response while marshalling. vector sigs(1,sig); diff --git a/saml/saml2/binding/impl/SAML2POSTEncoder.cpp b/saml/saml2/binding/impl/SAML2POSTEncoder.cpp index 736ffbb..0678a3b 100644 --- a/saml/saml2/binding/impl/SAML2POSTEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2POSTEncoder.cpp @@ -23,6 +23,7 @@ #include "internal.h" #include "exceptions.h" #include "binding/MessageEncoder.h" +#include "signature/ContentReference.h" #include "saml2/core/Protocols.h" #include @@ -54,7 +55,8 @@ namespace opensaml { const char* recipientID=NULL, const char* relayState=NULL, const Credential* credential=NULL, - const XMLCh* sigAlgorithm=NULL + const XMLCh* signatureAlg=NULL, + const XMLCh* digestAlg=NULL ) const; private: @@ -94,7 +96,8 @@ long SAML2POSTEncoder::encode( const char* recipientID, const char* relayState, const Credential* credential, - const XMLCh* sigAlgorithm + const XMLCh* signatureAlg, + const XMLCh* digestAlg ) const { #ifdef _DEBUG @@ -126,8 +129,13 @@ long SAML2POSTEncoder::encode( // Build a Signature. Signature* sig = SignatureBuilder::buildSignature(); request ? request->setSignature(sig) : response->setSignature(sig); - if (sigAlgorithm) - sig->setSignatureAlgorithm(sigAlgorithm); + if (signatureAlg) + sig->setSignatureAlgorithm(signatureAlg); + if (digestAlg) { + opensaml::ContentReference* cr = dynamic_cast(sig->getContentReference()); + if (cr) + cr->setDigestAlgorithm(digestAlg); + } // Sign response while marshalling. vector sigs(1,sig); @@ -154,15 +162,15 @@ long SAML2POSTEncoder::encode( string input = (request ? "SAMLRequest=" : "SAMLResponse=") + msg; if (relayState) input = input + "&RelayState=" + relayState; - if (!sigAlgorithm) - sigAlgorithm = DSIGConstants::s_unicodeStrURIRSA_SHA1; - auto_ptr_char alg(sigAlgorithm); + if (!signatureAlg) + signatureAlg = DSIGConstants::s_unicodeStrURIRSA_SHA1; + auto_ptr_char alg(signatureAlg); pmap.m_map["SigAlg"] = alg.get(); input = input + "&SigAlg=" + alg.get(); char sigbuf[1024]; memset(sigbuf,0,sizeof(sigbuf)); - Signature::createRawSignature(credential->getPrivateKey(), sigAlgorithm, input.c_str(), input.length(), sigbuf, sizeof(sigbuf)-1); + Signature::createRawSignature(credential->getPrivateKey(), signatureAlg, input.c_str(), input.length(), sigbuf, sizeof(sigbuf)-1); pmap.m_map["Signature"] = sigbuf; } diff --git a/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp b/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp index 9e2b3d1..147271d 100644 --- a/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp @@ -56,7 +56,8 @@ namespace opensaml { const char* recipientID=NULL, const char* relayState=NULL, const Credential* credential=NULL, - const XMLCh* sigAlgorithm=NULL + const XMLCh* signatureAlg=NULL, + const XMLCh* digestAlg=NULL ) const; }; @@ -74,7 +75,8 @@ long SAML2RedirectEncoder::encode( const char* recipientID, const char* relayState, const Credential* credential, - const XMLCh* sigAlgorithm + const XMLCh* signatureAlg, + const XMLCh* digestAlg ) const { #ifdef _DEBUG @@ -128,14 +130,14 @@ long SAML2RedirectEncoder::encode( if (credential) { // Sign the query string after adding the algorithm. - if (!sigAlgorithm) - sigAlgorithm = DSIGConstants::s_unicodeStrURIRSA_SHA1; - auto_ptr_char alg(sigAlgorithm); + if (!signatureAlg) + signatureAlg = DSIGConstants::s_unicodeStrURIRSA_SHA1; + auto_ptr_char alg(signatureAlg); xmlbuf = xmlbuf + "&SigAlg=" + escaper->encode(alg.get()); char sigbuf[1024]; memset(sigbuf,0,sizeof(sigbuf)); - Signature::createRawSignature(credential->getPrivateKey(), sigAlgorithm, xmlbuf.c_str(), xmlbuf.length(), sigbuf, sizeof(sigbuf)-1); + Signature::createRawSignature(credential->getPrivateKey(), signatureAlg, xmlbuf.c_str(), xmlbuf.length(), sigbuf, sizeof(sigbuf)-1); xmlbuf = xmlbuf + "&Signature=" + escaper->encode(sigbuf); } diff --git a/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp b/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp index 43ec706..19802e3 100644 --- a/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp @@ -24,6 +24,7 @@ #include "exceptions.h" #include "binding/HTTPResponse.h" #include "binding/MessageEncoder.h" +#include "signature/ContentReference.h" #include "saml2/core/Protocols.h" #include @@ -54,7 +55,8 @@ namespace opensaml { const char* recipientID=NULL, const char* relayState=NULL, const Credential* credential=NULL, - const XMLCh* sigAlgorithm=NULL + const XMLCh* signatureAlg=NULL, + const XMLCh* digestAlg=NULL ) const; }; @@ -74,7 +76,8 @@ long SAML2SOAPEncoder::encode( const char* recipientID, const char* relayState, const Credential* credential, - const XMLCh* sigAlgorithm + const XMLCh* signatureAlg, + const XMLCh* digestAlg ) const { #ifdef _DEBUG @@ -112,8 +115,13 @@ long SAML2SOAPEncoder::encode( // Build a Signature. Signature* sig = SignatureBuilder::buildSignature(); response->setSignature(sig); - if (sigAlgorithm) - sig->setSignatureAlgorithm(sigAlgorithm); + if (signatureAlg) + sig->setSignatureAlgorithm(signatureAlg); + if (digestAlg) { + opensaml::ContentReference* cr = dynamic_cast(sig->getContentReference()); + if (cr) + cr->setDigestAlgorithm(digestAlg); + } // Sign response while marshalling. vector sigs(1,sig); diff --git a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp index d59e8e2..4440fb4 100644 --- a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp @@ -251,6 +251,19 @@ bool AbstractMetadataProvider::matches(const pair& cre else if (criteria->getUsage()==CredentialCriteria::ENCRYPTION_CREDENTIAL && XMLString::equals(cred.first,KeyDescriptor::KEYTYPE_SIGNING)) return false; + const char* alg = criteria->getKeyAlgorithm(); + if (alg && *alg) { + const char* alg2 = cred.second->getAlgorithm(); + if (alg2 && *alg2) { + if (!XMLString::equals(alg,alg2)) + return false; + } + } + if (criteria->getKeySize()>0 && cred.second->getKeySize()>0) { + if (criteria->getKeySize() != cred.second->getKeySize()) + return false; + } + if (cred.second->getPublicKey()) { // See if we have to match a specific key. auto_ptr critcred( diff --git a/saml/saml2/profile/AssertionValidator.cpp b/saml/saml2/profile/Assertion20Validator.cpp similarity index 99% rename from saml/saml2/profile/AssertionValidator.cpp rename to saml/saml2/profile/Assertion20Validator.cpp index a7c7eee..bdc558b 100644 --- a/saml/saml2/profile/AssertionValidator.cpp +++ b/saml/saml2/profile/Assertion20Validator.cpp @@ -15,7 +15,7 @@ */ /** - * AssertionValidator.cpp + * Assertion20Validator.cpp * * SAML 2.0 basic assertion validator */ diff --git a/saml/saml2/profile/BrowserSSOProfileValidator.cpp b/saml/saml2/profile/BrowserSSOProfile20Validator.cpp similarity index 98% rename from saml/saml2/profile/BrowserSSOProfileValidator.cpp rename to saml/saml2/profile/BrowserSSOProfile20Validator.cpp index 5650306..1216dc2 100644 --- a/saml/saml2/profile/BrowserSSOProfileValidator.cpp +++ b/saml/saml2/profile/BrowserSSOProfile20Validator.cpp @@ -15,7 +15,7 @@ */ /** - * BrowserSSOProfileValidator.cpp + * BrowserSSOProfile20Validator.cpp * * SAML 2.0 Browser SSO Profile Assertion Validator */ diff --git a/saml/signature/ContentReference.cpp b/saml/signature/ContentReference.cpp index b224fcb..452ee09 100644 --- a/saml/signature/ContentReference.cpp +++ b/saml/signature/ContentReference.cpp @@ -30,18 +30,9 @@ #include using namespace opensaml; +using namespace xmltooling; using namespace std; -class _addprefix : public binary_function { -public: - void operator()(DSIGTransformC14n* t, const string& s) const { - if (s.empty()) - t->addInclusiveNamespace("#default"); - else - t->addInclusiveNamespace(s.c_str()); - } -}; - void ContentReference::createReferences(DSIGSignature* sig) { DSIGReference* ref=NULL; @@ -54,7 +45,7 @@ void ContentReference::createReferences(DSIGSignature* sig) buf[1]=chNull; XMLString::catString(buf,id); try { - ref=sig->createReference(buf); + ref=sig->createReference(buf, m_digest ? m_digest : DSIGConstants::s_unicodeStrURISHA1); delete[] buf; } catch(...) { @@ -62,7 +53,57 @@ void ContentReference::createReferences(DSIGSignature* sig) throw; } } + ref->appendEnvelopedSignatureTransform(); - DSIGTransformC14n* c14n=ref->appendCanonicalizationTransform(CANON_C14NE_NOC); - for_each(m_prefixes.begin(), m_prefixes.end(), bind1st(_addprefix(),c14n)); + DSIGTransformC14n* c14n=ref->appendCanonicalizationTransform(m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC); + if (!m_c14n || m_c14n == DSIGConstants::s_unicodeStrURIEXC_C14N_NOC || m_c14n == DSIGConstants::s_unicodeStrURIEXC_C14N_COM) { + //addPrefixes(m_signableObject); +#ifdef HAVE_GOOD_STL + xstring prefixes; + for (set::const_iterator p = m_prefixes.begin(); p!=m_prefixes.end(); ++p) + prefixes += *p + chSpace; + if (!prefixes.empty()) { + prefixes.erase(prefixes.begin() + prefixes.size() - 1); + c14n->setInclusiveNamespaces(XMLString::replicate(prefixes.c_str())); + } +#else + for (set::const_iterator p = m_prefixes.begin(); p!=m_prefixes.end(); ++p) + c14n->addInclusiveNamespace(p->c_str()); +#endif + } +} + +void ContentReference::addInclusivePrefix(const XMLCh* prefix) +{ + static const XMLCh _default[] = { chPound, chLatin_d, chLatin_e, chLatin_f, chLatin_a, chLatin_u, chLatin_l, chLatin_t, chNull }; + +#ifdef HAVE_GOOD_STL + if (prefix && *prefix) + m_prefixes.insert(prefix); + else + m_prefixes.insert(_default); +#else + if (prefix && *prefix) { + auto_ptr_char p(prefix); + m_prefixes.insert(p.get()); + } + else + m_prefixes.insert("#default"); +#endif +} + +void ContentReference::addPrefixes(const std::set& namespaces) +{ + for (set::const_iterator n = namespaces.begin(); n!=namespaces.end(); ++n) + addInclusivePrefix(n->getNamespacePrefix()); +} + +void ContentReference::addPrefixes(const XMLObject& xmlObject) +{ + addPrefixes(xmlObject.getNamespaces()); + const list& children = xmlObject.getOrderedChildren(); + for (list::const_iterator child = children.begin(); child!=children.end(); ++child) { + if (*child) + addPrefixes(*(*child)); + } } diff --git a/saml/signature/ContentReference.h b/saml/signature/ContentReference.h index f85a906..0d77133 100644 --- a/saml/signature/ContentReference.h +++ b/saml/signature/ContentReference.h @@ -24,8 +24,10 @@ #define __saml_sigref_h__ #include +#include #include +#include #include namespace opensaml { @@ -43,7 +45,8 @@ namespace opensaml { * * @param signableObject reference to object being signed */ - ContentReference(const SignableObject& signableObject) : m_signableObject(signableObject) { + ContentReference(const SignableObject& signableObject) + : m_signableObject(signableObject), m_digest(NULL), m_c14n(NULL) { } virtual ~ContentReference() {} @@ -57,22 +60,46 @@ namespace opensaml { virtual void createReferences(DSIGSignature* sig); /** - * Adds a namespace prefix for "inclusive" processing by the + * Adds a namespace prefix for "inclusive" processing by an * Exclusive C14N Transform applied to the object. * An empty string will be transformed into "#default". * * @param prefix the prefix to add */ - void addInclusivePrefix(const char* prefix) { - m_prefixes.push_back(prefix); + void addInclusivePrefix(const XMLCh* prefix); + + /** + * Sets the digest algorithm for the signature reference, + * using a constant. + * + * @param digest the digest algorithm + */ + void setDigestAlgorithm(const XMLCh* digest) { + m_digest = digest; } - protected: - /** Reference to object to sign. */ - const SignableObject& m_signableObject; + /** + * Sets the canonicalization method to include in the reference, + * using a constant. + * + * @param c14n the canonicalization method + */ + void setCanonicalizationMethod(const XMLCh* c14n) { + m_c14n = c14n; + } + + private: + void addPrefixes(const std::set& namespaces); + void addPrefixes(const xmltooling::XMLObject& xmlObject); - /** Inclusive prefixes. */ - std::vector m_prefixes; + const SignableObject& m_signableObject; +#ifdef HAVE_GOOD_STL + std::set m_prefixes; +#else + std::set m_prefixes; +#endif + const XMLCh* m_digest; + const XMLCh* m_c14n; }; }; diff --git a/samltest/saml2/binding/SAML2ArtifactTest.h b/samltest/saml2/binding/SAML2ArtifactTest.h index b869867..ee5b5f0 100644 --- a/samltest/saml2/binding/SAML2ArtifactTest.h +++ b/samltest/saml2/binding/SAML2ArtifactTest.h @@ -119,6 +119,7 @@ public: SAMLConfig::getConfig().getArtifactMap()->retrieveContent(&artifact, "https://sp.example.org/"); Response* payload = dynamic_cast(xmlObject); TSM_ASSERT("Not a response.", payload!=NULL); + auto_ptr response(ArtifactResponseBuilder::buildArtifactResponse()); response->setPayload(payload); Status* status = StatusBuilder::buildStatus(); -- 2.1.4