Settable digest algorithm, enhanced prefix handling in signatures, pending xmlsec...
authorScott Cantor <cantor.2@osu.edu>
Mon, 9 Apr 2007 03:42:07 +0000 (03:42 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 9 Apr 2007 03:42:07 +0000 (03:42 +0000)
20 files changed:
saml/Makefile.am
saml/binding/MessageEncoder.h
saml/binding/impl/SimpleSigningRule.cpp
saml/binding/impl/XMLSigningRule.cpp
saml/saml.vcproj
saml/saml1/binding/impl/SAML1ArtifactEncoder.cpp
saml/saml1/binding/impl/SAML1POSTEncoder.cpp
saml/saml1/binding/impl/SAML1SOAPEncoder.cpp
saml/saml1/core/impl/AssertionsImpl.cpp
saml/saml1/core/impl/ProtocolsImpl.cpp
saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp
saml/saml2/binding/impl/SAML2POSTEncoder.cpp
saml/saml2/binding/impl/SAML2RedirectEncoder.cpp
saml/saml2/binding/impl/SAML2SOAPEncoder.cpp
saml/saml2/metadata/impl/AbstractMetadataProvider.cpp
saml/saml2/profile/Assertion20Validator.cpp [moved from saml/saml2/profile/AssertionValidator.cpp with 99% similarity]
saml/saml2/profile/BrowserSSOProfile20Validator.cpp [moved from saml/saml2/profile/BrowserSSOProfileValidator.cpp with 98% similarity]
saml/signature/ContentReference.cpp
saml/signature/ContentReference.h
samltest/saml2/binding/SAML2ArtifactTest.h

index 2bb57f2..5444b1a 100644 (file)
@@ -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 \
index a0e212b..ad87a08 100644 (file)
@@ -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:
index cb8a410..f450f25 100644 (file)
@@ -189,11 +189,9 @@ void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest*
     auto_ptr<KeyInfo> 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");
index 1afb062..989cb05 100644 (file)
@@ -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");
index 0494d9c..e74017e 100644 (file)
                                        Name="profile"\r
                                        >\r
                                        <File\r
-                                               RelativePath=".\saml2\profile\AssertionValidator.cpp"\r
+                                               RelativePath=".\saml2\profile\Assertion20Validator.cpp"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug|Win32"\r
                                                </FileConfiguration>\r
                                        </File>\r
                                        <File\r
-                                               RelativePath=".\saml2\profile\BrowserSSOProfileValidator.cpp"\r
+                                               RelativePath=".\saml2\profile\BrowserSSOProfile20Validator.cpp"\r
                                                >\r
                                                <FileConfiguration\r
                                                        Name="Debug|Win32"\r
index 37ff757..0435136 100644 (file)
@@ -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;
         };                
 
@@ -75,7 +76,8 @@ long SAML1ArtifactEncoder::encode(
     const char* recipientID,
     const char* relayState,
     const Credential* credential,
-    const XMLCh* sigAlgorithm
+    const XMLCh* signatureAlg,
+    const XMLCh* digestAlg
     ) const
 {
 #ifdef _DEBUG
index 2a68bb4..6b4a7d4 100644 (file)
@@ -23,6 +23,7 @@
 #include "internal.h"
 #include "exceptions.h"
 #include "binding/MessageEncoder.h"
+#include "signature/ContentReference.h"
 #include "saml1/core/Protocols.h"
 
 #include <fstream>
@@ -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<opensaml::ContentReference*>(sig->getContentReference());
+                if (cr)
+                    cr->setDigestAlgorithm(digestAlg);
+            }
     
             // Sign response while marshalling.
             vector<Signature*> sigs(1,sig);
index 3e1b026..2d0c6d4 100644 (file)
@@ -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 <sstream>
@@ -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<opensaml::ContentReference*>(sig->getContentReference());
+                        if (cr)
+                            cr->setDigestAlgorithm(digestAlg);
+                    }
             
                     // Sign response while marshalling.
                     vector<Signature*> sigs(1,sig);
index 9f7998a..fa14c35 100644 (file)
@@ -1034,9 +1034,9 @@ namespace opensaml {
                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
                 if (!m_AssertionID)
                     const_cast<AssertionImpl*>(this)->m_AssertionID=SAMLConfig::getConfig().generateIdentifier();
-                domElement->setAttributeNS(NULL, ASSERTIONID_ATTRIB_NAME, m_AssertionID);\r
-                if (*m_MinorVersion!=chDigit_0)\r
-                    domElement->setIdAttributeNS(NULL, ASSERTIONID_ATTRIB_NAME);\r
+                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<AssertionImpl*>(this)->m_IssueInstantEpoch=time(NULL);
index a1300d6..dc40986 100644 (file)
@@ -374,9 +374,9 @@ namespace opensaml {
                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
                 if (!m_RequestID)
                     const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
-                domElement->setAttributeNS(NULL, REQUESTID_ATTRIB_NAME, m_RequestID);\r
-                if (*m_MinorVersion!=chDigit_0)\r
-                    domElement->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME);\r
+                domElement->setAttributeNS(NULL, REQUESTID_ATTRIB_NAME, m_RequestID);
+                if (*m_MinorVersion!=chDigit_0)
+                    domElement->setIdAttributeNS(NULL, REQUESTID_ATTRIB_NAME);
                 if (!m_IssueInstant) {
                     const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
                     const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
@@ -703,9 +703,9 @@ namespace opensaml {
                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
                 if (!m_ResponseID)
                     const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
-                domElement->setAttributeNS(NULL, RESPONSEID_ATTRIB_NAME, m_ResponseID);\r
-                if (*m_MinorVersion!=chDigit_0)\r
-                    domElement->setIdAttributeNS(NULL, RESPONSEID_ATTRIB_NAME);\r
+                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<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
index 5d31808..f397ebd 100644 (file)
@@ -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<opensaml::ContentReference*>(sig->getContentReference());
+                if (cr)
+                    cr->setDigestAlgorithm(digestAlg);
+            }
             
             // Sign response while marshalling.
             vector<Signature*> sigs(1,sig);
index 736ffbb..0678a3b 100644 (file)
@@ -23,6 +23,7 @@
 #include "internal.h"
 #include "exceptions.h"
 #include "binding/MessageEncoder.h"
+#include "signature/ContentReference.h"
 #include "saml2/core/Protocols.h"
 
 #include <fstream>
@@ -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<opensaml::ContentReference*>(sig->getContentReference());
+                if (cr)
+                    cr->setDigestAlgorithm(digestAlg);
+            }
             
             // Sign response while marshalling.
             vector<Signature*> 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;
     }
     
index 9e2b3d1..147271d 100644 (file)
@@ -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);
     }
     
index 43ec706..19802e3 100644 (file)
@@ -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 <sstream>
@@ -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<opensaml::ContentReference*>(sig->getContentReference());
+                        if (cr)
+                            cr->setDigestAlgorithm(digestAlg);
+                    }
             
                     // Sign response while marshalling.
                     vector<Signature*> sigs(1,sig);
index d59e8e2..4440fb4 100644 (file)
@@ -251,6 +251,19 @@ bool AbstractMetadataProvider::matches(const pair<const XMLCh*,Credential*>& 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<Credential> critcred(
similarity index 99%
rename from saml/saml2/profile/AssertionValidator.cpp
rename to saml/saml2/profile/Assertion20Validator.cpp
index a7c7eee..bdc558b 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 /**
- * AssertionValidator.cpp
+ * Assertion20Validator.cpp
  * 
  * SAML 2.0 basic assertion validator
  */
@@ -15,7 +15,7 @@
  */
 
 /**
- * BrowserSSOProfileValidator.cpp
+ * BrowserSSOProfile20Validator.cpp
  * 
  * SAML 2.0 Browser SSO Profile Assertion Validator
  */
index b224fcb..452ee09 100644 (file)
 #include <xsec/dsig/DSIGTransformC14n.hpp>
 
 using namespace opensaml;
+using namespace xmltooling;
 using namespace std;
 
-class _addprefix : public binary_function<DSIGTransformC14n*,string,void> {
-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<xstring>::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<string>::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<Namespace>& namespaces)
+{
+    for (set<Namespace>::const_iterator n = namespaces.begin(); n!=namespaces.end(); ++n)
+        addInclusivePrefix(n->getNamespacePrefix());
+}
+
+void ContentReference::addPrefixes(const XMLObject& xmlObject)
+{
+    addPrefixes(xmlObject.getNamespaces());
+    const list<XMLObject*>& children = xmlObject.getOrderedChildren();
+    for (list<XMLObject*>::const_iterator child = children.begin(); child!=children.end(); ++child) {
+        if (*child)
+            addPrefixes(*(*child));
+    }
 }
index f85a906..0d77133 100644 (file)
 #define __saml_sigref_h__
 
 #include <saml/base.h>
+#include <xmltooling/XMLObject.h>
 #include <xmltooling/signature/ContentReference.h>
 
+#include <set>
 #include <string>
 
 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<xmltooling::Namespace>& namespaces);
+        void addPrefixes(const xmltooling::XMLObject& xmlObject);
 
-        /** Inclusive prefixes. */
-        std::vector<std::string> m_prefixes;
+        const SignableObject& m_signableObject;
+#ifdef HAVE_GOOD_STL
+        std::set<xmltooling::xstring> m_prefixes;
+#else
+        std::set<std::string> m_prefixes;
+#endif
+        const XMLCh* m_digest;
+        const XMLCh* m_c14n;
     };
 
 };
index b869867..ee5b5f0 100644 (file)
@@ -119,6 +119,7 @@ public:
             SAMLConfig::getConfig().getArtifactMap()->retrieveContent(&artifact, "https://sp.example.org/");\r
         Response* payload = dynamic_cast<Response*>(xmlObject);\r
         TSM_ASSERT("Not a response.", payload!=NULL);\r
+\r
         auto_ptr<ArtifactResponse> response(ArtifactResponseBuilder::buildArtifactResponse());\r
         response->setPayload(payload);\r
         Status* status = StatusBuilder::buildStatus();\r