From: Scott Cantor Date: Mon, 26 Mar 2007 06:00:11 +0000 (+0000) Subject: Major revamp of credential and trust handling code, PKIX engine still needs work. X-Git-Tag: 2.0-alpha1~61 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=commitdiff_plain;h=b1614d3c1fc1f4230ab2a123f43994127c25462c Major revamp of credential and trust handling code, PKIX engine still needs work. --- diff --git a/saml/Makefile.am b/saml/Makefile.am index aed243e..b0f0d75 100644 --- a/saml/Makefile.am +++ b/saml/Makefile.am @@ -90,8 +90,8 @@ saml2mdinclude_HEADERS = \ saml2/metadata/ChainingMetadataProvider.h \ saml2/metadata/EndpointManager.h \ saml2/metadata/Metadata.h \ + saml2/metadata/MetadataCredentialCriteria.h \ saml2/metadata/MetadataFilter.h \ - saml2/metadata/MetadataKeyInfoIterator.h \ saml2/metadata/MetadataProvider.h \ saml2/metadata/ObservableMetadataProvider.h diff --git a/saml/SAMLConfig.cpp b/saml/SAMLConfig.cpp index d429d96..a03b172 100644 --- a/saml/SAMLConfig.cpp +++ b/saml/SAMLConfig.cpp @@ -33,6 +33,7 @@ #include "saml1/core/Protocols.h" #include "saml2/core/Protocols.h" #include "saml2/metadata/Metadata.h" +#include "saml2/metadata/MetadataFilter.h" #include "saml2/metadata/MetadataProvider.h" #include "util/SAMLConstants.h" diff --git a/saml/binding/MessageEncoder.h b/saml/binding/MessageEncoder.h index d5e987b..a0e212b 100644 --- a/saml/binding/MessageEncoder.h +++ b/saml/binding/MessageEncoder.h @@ -27,7 +27,7 @@ #include #include -#include +#include namespace opensaml { @@ -107,7 +107,7 @@ namespace opensaml { * @param destination destination URL for message * @param recipientID optional entityID of message recipient * @param relayState optional RelayState value to accompany message - * @param credResolver optional CredentialResolver instance to supply signing material + * @param credential optional Credential to supply signing key * @param sigAlgorithm optional signature algorithm identifier */ virtual long encode( @@ -116,26 +116,13 @@ namespace opensaml { const char* destination, const char* recipientID=NULL, const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, + const xmltooling::Credential* credential=NULL, const XMLCh* sigAlgorithm=NULL ) const=0; protected: MessageEncoder() : m_artifactGenerator(NULL) {} - /** - * Helper function to build a new XML Signature with KeyInfo, based - * on the supplied CredentialResolver. - * - * @param credResolver CredentialResolver instance to supply signing material - * @param sigAlgorithm optional signature algorithm identifier - * @return a new Signature object - */ - xmlsignature::Signature* buildSignature( - const xmltooling::CredentialResolver* credResolver, - const XMLCh* sigAlgorithm=NULL - ) const; - /** Pointer to an ArtifactGenerator implementation. */ const ArtifactGenerator* m_artifactGenerator; }; diff --git a/saml/binding/SOAPClient.h b/saml/binding/SOAPClient.h index 433e44a..ddbe2e1 100644 --- a/saml/binding/SOAPClient.h +++ b/saml/binding/SOAPClient.h @@ -24,6 +24,7 @@ #define __saml_soap11client_h__ #include +#include #include namespace opensaml { @@ -41,9 +42,11 @@ namespace opensaml { * @param validating controls schema validation */ SOAPClient(SecurityPolicy& policy) - : soap11::SOAPClient(policy.getValidating()), m_policy(policy), m_force(true), m_peer(NULL) {} + : soap11::SOAPClient(policy.getValidating()), m_policy(policy), m_force(true), m_peer(NULL), m_criteria(NULL) { + } - virtual ~SOAPClient() {} + virtual ~SOAPClient() { + } /** * Controls whether to force transport/peer authentication via an X509TrustEngine. @@ -57,14 +60,15 @@ namespace opensaml { } /** - * Override prepares the SecurityPolicy by clearing Issuer identity, in case the policy - * is reused. + * SAML-specific method uses a RoleDescriptor to determine the peer name and prepare the + * transport layer with peer credential information. The SecurityPolicy is also reset, + * in case the policy is reused. * * @param env SOAP envelope to send - * @param peer peer to send message to, expressed in TrustEngine terms + * @param peer peer to send message to, expressed in metadata criteria terms * @param endpoint URL of endpoint to recieve message */ - void send(const soap11::Envelope& env, const xmltooling::KeyInfoSource& peer, const char* endpoint); + void send(const soap11::Envelope& env, saml2md::MetadataCredentialCriteria& peer, const char* endpoint); /** * Override applies SecurityPolicy to envelope before returning it. @@ -101,6 +105,9 @@ namespace opensaml { /** Metadata-based peer identity. */ const saml2md::RoleDescriptor* m_peer; + + /** Metadata-based CredentialCriteria for supplying credentials to TrustEngine. */ + saml2md::MetadataCredentialCriteria* m_criteria; }; }; diff --git a/saml/binding/impl/ClientCertAuthRule.cpp b/saml/binding/impl/ClientCertAuthRule.cpp index f185090..072761b 100644 --- a/saml/binding/impl/ClientCertAuthRule.cpp +++ b/saml/binding/impl/ClientCertAuthRule.cpp @@ -24,6 +24,7 @@ #include "exceptions.h" #include "binding/SecurityPolicyRule.h" #include "saml2/metadata/Metadata.h" +#include "saml2/metadata/MetadataCredentialCriteria.h" #include "saml2/metadata/MetadataProvider.h" #include @@ -74,8 +75,13 @@ void ClientCertAuthRule::evaluate(const XMLObject& message, const GenericRequest if (chain.empty()) return; - if (!x509trust->validate(chain.front(), chain, *(policy.getIssuerMetadata()), true, - policy.getMetadataProvider()->getKeyResolver())) { + // Set up criteria object, including peer name to enforce cert name checking. + MetadataCredentialCriteria cc(*(policy.getIssuerMetadata())); + auto_ptr_char pn(policy.getIssuer()->getName()); + cc.setPeerName(pn.get()); + cc.setUsage(CredentialCriteria::TLS_CREDENTIAL); + + if (!x509trust->validate(chain.front(), chain, *(policy.getMetadataProvider()), &cc)) { log.error("unable to verify certificate chain with supplied trust engine"); return; } diff --git a/saml/binding/impl/MessageEncoder.cpp b/saml/binding/impl/MessageEncoder.cpp index c0d2a8d..8a8bee3 100644 --- a/saml/binding/impl/MessageEncoder.cpp +++ b/saml/binding/impl/MessageEncoder.cpp @@ -60,36 +60,3 @@ void SAML_API opensaml::registerMessageEncoders() conf.MessageEncoderManager.registerFactory(samlconstants::SAML20_BINDING_HTTP_REDIRECT, saml2p::SAML2RedirectEncoderFactory); conf.MessageEncoderManager.registerFactory(samlconstants::SAML20_BINDING_SOAP, saml2p::SAML2SOAPEncoderFactory); } - -namespace { - class SAML_DLLLOCAL _addcert : public binary_function { - public: - void operator()(X509Data* bag, XSECCryptoX509* cert) const { - safeBuffer& buf=cert->getDEREncodingSB(); - X509Certificate* x=X509CertificateBuilder::buildX509Certificate(); - x->setValue(buf.sbStrToXMLCh()); - bag->getX509Certificates().push_back(x); - } - }; -}; - -Signature* MessageEncoder::buildSignature(const CredentialResolver* credResolver, const XMLCh* sigAlgorithm) const -{ - // Build a Signature. - Signature* sig = SignatureBuilder::buildSignature(); - if (sigAlgorithm) - sig->setSignatureAlgorithm(sigAlgorithm); - sig->setSigningKey(credResolver->getKey()); - - // Build KeyInfo. - const vector& certs = credResolver->getCertificates(); - if (!certs.empty()) { - KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo(); - X509Data* x509Data=X509DataBuilder::buildX509Data(); - keyInfo->getX509Datas().push_back(x509Data); - for_each(certs.begin(),certs.end(),bind1st(_addcert(),x509Data)); - sig->setKeyInfo(keyInfo); - } - - return sig; -} diff --git a/saml/binding/impl/SOAPClient.cpp b/saml/binding/impl/SOAPClient.cpp index 79e1c51..feff377 100644 --- a/saml/binding/impl/SOAPClient.cpp +++ b/saml/binding/impl/SOAPClient.cpp @@ -37,22 +37,22 @@ using namespace opensaml; using namespace xmltooling; using namespace std; -void SOAPClient::send(const soap11::Envelope& env, const KeyInfoSource& peer, const char* endpoint) +void SOAPClient::send(const soap11::Envelope& env, MetadataCredentialCriteria& peer, const char* endpoint) { // Clear policy. m_policy.reset(); + + m_criteria = &peer; + m_peer = &(peer.getRole()); - if (!m_peer) - m_peer = dynamic_cast(&peer); - if (m_peer) { - const QName& role = m_peer->getElementQName(); - if (XMLString::equals(role.getLocalPart(),RoleDescriptor::LOCAL_NAME)) - m_policy.setRole(m_peer->getSchemaType()); - else - m_policy.setRole(&role); - } - - soap11::SOAPClient::send(env, peer, endpoint); + const QName& role = m_peer->getElementQName(); + if (XMLString::equals(role.getLocalPart(),RoleDescriptor::LOCAL_NAME)) + m_policy.setRole(m_peer->getSchemaType()); + else + m_policy.setRole(&role); + + auto_ptr_char pn(dynamic_cast(m_peer->getParent())->getEntityID()); + soap11::SOAPClient::send(env, pn.get(), endpoint); } void SOAPClient::prepareTransport(xmltooling::SOAPTransport& transport) @@ -67,8 +67,7 @@ void SOAPClient::prepareTransport(xmltooling::SOAPTransport& transport) const X509TrustEngine* engine = dynamic_cast(m_policy.getTrustEngine()); if (engine) { - const MetadataProvider* metadata = m_policy.getMetadataProvider(); - if (!transport.setTrustEngine(engine, m_force, metadata ? metadata->getKeyResolver() : NULL)) + if (!transport.setTrustEngine(engine, m_policy.getMetadataProvider(), m_criteria, m_force)) throw BindingException("Unable to install X509TrustEngine into SOAPTransport."); } } @@ -79,12 +78,9 @@ soap11::Envelope* SOAPClient::receive() if (env.get()) { if (m_peer && m_transport->isSecure()) { // Set issuer based on peer identity. - EntityDescriptor* parent = dynamic_cast(m_peer->getParent()); - if (parent) { - m_policy.setIssuer(parent->getEntityID()); - m_policy.setIssuerMetadata(m_peer); - m_policy.setSecure(true); - } + m_policy.setIssuer(dynamic_cast(m_peer->getParent())->getEntityID()); + m_policy.setIssuerMetadata(m_peer); + m_policy.setSecure(true); } m_policy.evaluate(*(env.get())); } @@ -93,6 +89,7 @@ soap11::Envelope* SOAPClient::receive() void SOAPClient::reset() { + m_criteria = NULL; m_peer = NULL; soap11::SOAPClient::reset(); m_policy.reset(); diff --git a/saml/binding/impl/SimpleSigningRule.cpp b/saml/binding/impl/SimpleSigningRule.cpp index 82f98d9..cb8a410 100644 --- a/saml/binding/impl/SimpleSigningRule.cpp +++ b/saml/binding/impl/SimpleSigningRule.cpp @@ -26,6 +26,7 @@ #include "binding/SecurityPolicyRule.h" #include "saml2/core/Assertions.h" #include "saml2/metadata/Metadata.h" +#include "saml2/metadata/MetadataCredentialCriteria.h" #include "saml2/metadata/MetadataProvider.h" #include @@ -187,11 +188,14 @@ void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* auto_ptr kjanitor(keyInfo); auto_ptr_XMLCh alg(sigAlgorithm); - - if (!policy.getTrustEngine()->validate( - alg.get(), signature, keyInfo, input.c_str(), input.length(), - *(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver() - )) { + + // Set up criteria object, including peer name to enforce cert name checking. + MetadataCredentialCriteria cc(*(policy.getIssuerMetadata())); + auto_ptr_char pn(policy.getIssuer()->getName()); + cc.setPeerName(pn.get()); + cc.setKeyAlgorithm(sigAlgorithm); + + 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"); if (m_errorsFatal) throw SignatureException("Message was signed, but signature could not be verified."); diff --git a/saml/binding/impl/XMLSigningRule.cpp b/saml/binding/impl/XMLSigningRule.cpp index bd2c5e6..1afb062 100644 --- a/saml/binding/impl/XMLSigningRule.cpp +++ b/saml/binding/impl/XMLSigningRule.cpp @@ -25,6 +25,7 @@ #include "binding/SecurityPolicyRule.h" #include "saml2/core/Assertions.h" #include "saml2/metadata/Metadata.h" +#include "saml2/metadata/MetadataCredentialCriteria.h" #include "saml2/metadata/MetadataProvider.h" #include "signature/SignatureProfileValidator.h" @@ -96,9 +97,12 @@ void XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* re return; } - if (!policy.getTrustEngine()->validate( - *(signable->getSignature()), *(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver() - )) { + // Set up criteria object, including peer name to enforce cert name checking. + 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"); if (m_errorsFatal) throw SignatureException("Message was signed, but signature could not be verified."); diff --git a/saml/encryption/EncryptedKeyResolver.cpp b/saml/encryption/EncryptedKeyResolver.cpp index 6a8f81b..8831717 100644 --- a/saml/encryption/EncryptedKeyResolver.cpp +++ b/saml/encryption/EncryptedKeyResolver.cpp @@ -22,15 +22,16 @@ #include "internal.h" #include "encryption/EncryptedKeyResolver.h" +#include "saml2/core/Assertions.h" using namespace xmlencryption; using namespace std; -EncryptedKey* opensaml::EncryptedKeyResolver::resolveKey(EncryptedData& encryptedData) const +const EncryptedKey* opensaml::EncryptedKeyResolver::resolveKey(const EncryptedData& encryptedData, const XMLCh* recipient) const { const vector& keys=m_ref.getEncryptedKeys(); for (vector::const_iterator i=keys.begin(); i!=keys.end(); i++) { - if (XMLString::equals(m_recipient,(*i)->getRecipient())) + if (XMLString::equals(recipient,(*i)->getRecipient())) return (*i); } return NULL; diff --git a/saml/encryption/EncryptedKeyResolver.h b/saml/encryption/EncryptedKeyResolver.h index 51f74ba..8063c1c 100644 --- a/saml/encryption/EncryptedKeyResolver.h +++ b/saml/encryption/EncryptedKeyResolver.h @@ -24,11 +24,14 @@ #define __saml_enckeyres_h__ #include -#include #include namespace opensaml { + namespace saml2 { + class SAML_API EncryptedElementType; + }; + /** * SAML-specific encrypted key resolver. * @@ -38,19 +41,15 @@ namespace opensaml { class SAML_API EncryptedKeyResolver : public xmlencryption::EncryptedKeyResolver { public: - EncryptedKeyResolver(const saml2::EncryptedElementType& ref, const XMLCh* recipient=NULL) - : m_ref(ref), m_recipient(XMLString::replicate(recipient)) { + EncryptedKeyResolver(const saml2::EncryptedElementType& ref) : m_ref(ref) { } - virtual ~EncryptedKeyResolver() { - XMLString::release(&m_recipient); - } + virtual ~EncryptedKeyResolver() {} - xmlencryption::EncryptedKey* resolveKey(xmlencryption::EncryptedData& encryptedData) const; + const xmlencryption::EncryptedKey* resolveKey(const xmlencryption::EncryptedData& encryptedData, const XMLCh* recipient=NULL) const; protected: const saml2::EncryptedElementType& m_ref; - XMLCh* m_recipient; }; }; diff --git a/saml/saml.vcproj b/saml/saml.vcproj index f601468..63aa25d 100644 --- a/saml/saml.vcproj +++ b/saml/saml.vcproj @@ -766,11 +766,11 @@ > namespace opensaml { + namespace saml1p { class SAML_API Request; @@ -57,10 +58,10 @@ namespace opensaml { *

The request will be freed by the client object regardless of the outcome. * * @param request SAML request to send - * @param peer peer to send message to, expressed in metadata terms + * @param peer peer to send message to, expressed in metadata criteria terms * @param endpoint URL of endpoint to recieve message */ - virtual void sendSAML(Request* request, const saml2md::RoleDescriptor& peer, const char* endpoint); + virtual void sendSAML(Request* request, saml2md::MetadataCredentialCriteria& peer, const char* endpoint); /** * Specialized method for receiving SAML 1.x responses. The SOAP layer will be diff --git a/saml/saml1/binding/impl/SAML1ArtifactEncoder.cpp b/saml/saml1/binding/impl/SAML1ArtifactEncoder.cpp index 8531df2..37ff757 100644 --- a/saml/saml1/binding/impl/SAML1ArtifactEncoder.cpp +++ b/saml/saml1/binding/impl/SAML1ArtifactEncoder.cpp @@ -52,11 +52,11 @@ namespace opensaml { long encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, const char* recipientID=NULL, const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, + const Credential* credential=NULL, const XMLCh* sigAlgorithm=NULL ) const; }; @@ -74,7 +74,7 @@ long SAML1ArtifactEncoder::encode( const char* destination, const char* recipientID, const char* relayState, - const CredentialResolver* credResolver, + const Credential* credential, const XMLCh* sigAlgorithm ) const { diff --git a/saml/saml1/binding/impl/SAML1POSTEncoder.cpp b/saml/saml1/binding/impl/SAML1POSTEncoder.cpp index de3b377..2a68bb4 100644 --- a/saml/saml1/binding/impl/SAML1POSTEncoder.cpp +++ b/saml/saml1/binding/impl/SAML1POSTEncoder.cpp @@ -49,17 +49,17 @@ namespace opensaml { long encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, const char* recipientID=NULL, const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, + const Credential* credential=NULL, const XMLCh* sigAlgorithm=NULL ) const; protected: /** Pathname of HTML template for transmission of message via POST. */ - std::string m_template; + string m_template; }; MessageEncoder* SAML_DLLLOCAL SAML1POSTEncoderFactory(const DOMElement* const & e) @@ -88,7 +88,7 @@ long SAML1POSTEncoder::encode( const char* destination, const char* recipientID, const char* relayState, - const CredentialResolver* credResolver, + const Credential* credential, const XMLCh* sigAlgorithm ) const { @@ -107,7 +107,7 @@ long SAML1POSTEncoder::encode( throw BindingException("SAML 1.x POST Encoder requires relay state (TARGET) value."); DOMElement* rootElement = NULL; - if (credResolver) { + if (credential) { // Signature based on native XML signing. if (response->getSignature()) { log.debug("response already signed, skipping signature operation"); @@ -116,12 +116,14 @@ long SAML1POSTEncoder::encode( log.debug("signing and marshalling the response"); // Build a Signature. - Signature* sig = buildSignature(credResolver, sigAlgorithm); + Signature* sig = SignatureBuilder::buildSignature(); response->setSignature(sig); + if (sigAlgorithm) + sig->setSignatureAlgorithm(sigAlgorithm); // Sign response while marshalling. vector sigs(1,sig); - rootElement = response->marshall((DOMDocument*)NULL,&sigs); + rootElement = response->marshall((DOMDocument*)NULL,&sigs,credential); } } else { diff --git a/saml/saml1/binding/impl/SAML1SOAPClient.cpp b/saml/saml1/binding/impl/SAML1SOAPClient.cpp index d1d6ef4..77b5eb8 100644 --- a/saml/saml1/binding/impl/SAML1SOAPClient.cpp +++ b/saml/saml1/binding/impl/SAML1SOAPClient.cpp @@ -37,7 +37,7 @@ using namespace xmltooling; using namespace log4cpp; using namespace std; -void SAML1SOAPClient::sendSAML(Request* request, const RoleDescriptor& peer, const char* endpoint) +void SAML1SOAPClient::sendSAML(Request* request, MetadataCredentialCriteria& peer, const char* endpoint) { auto_ptr env(EnvelopeBuilder::buildEnvelope()); Body* body = BodyBuilder::buildBody(); diff --git a/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp b/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp index 086aef1..3e1b026 100644 --- a/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp +++ b/saml/saml1/binding/impl/SAML1SOAPEncoder.cpp @@ -49,11 +49,11 @@ namespace opensaml { long encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, const char* recipientID=NULL, const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, + const Credential* credential=NULL, const XMLCh* sigAlgorithm=NULL ) const; }; @@ -71,7 +71,7 @@ long SAML1SOAPEncoder::encode( const char* destination, const char* recipientID, const char* relayState, - const CredentialResolver* credResolver, + const Credential* credential, const XMLCh* sigAlgorithm ) const { @@ -99,7 +99,7 @@ long SAML1SOAPEncoder::encode( Body* body = BodyBuilder::buildBody(); env->setBody(body); body->getUnknownXMLObjects().push_back(response); - if (credResolver ) { + if (credential) { if (response->getSignature()) { log.debug("response already signed, skipping signature operation"); rootElement = env->marshall(); @@ -108,12 +108,14 @@ long SAML1SOAPEncoder::encode( log.debug("signing and marshalling the response"); // Build a Signature. - Signature* sig = buildSignature(credResolver, sigAlgorithm); - response->setSignature(sig); + Signature* sig = SignatureBuilder::buildSignature(); + response->setSignature(sig); + if (sigAlgorithm) + sig->setSignatureAlgorithm(sigAlgorithm); // Sign response while marshalling. vector sigs(1,sig); - rootElement = env->marshall((DOMDocument*)NULL,&sigs); + rootElement = env->marshall((DOMDocument*)NULL,&sigs,credential); } } else { diff --git a/saml/saml2/binding/SAML2SOAPClient.h b/saml/saml2/binding/SAML2SOAPClient.h index 0fb8dfc..eae1030 100644 --- a/saml/saml2/binding/SAML2SOAPClient.h +++ b/saml/saml2/binding/SAML2SOAPClient.h @@ -26,6 +26,7 @@ #include namespace opensaml { + namespace saml2p { class SAML_API RequestAbstractType; @@ -57,10 +58,10 @@ namespace opensaml { *

The request will be freed by the client object regardless of the outcome. * * @param request SAML request to send - * @param peer peer to send message to, expressed in metadata terms + * @param peer peer to send message to, expressed in metadata criteria terms * @param endpoint URL of endpoint to recieve message */ - virtual void sendSAML(RequestAbstractType* request, const saml2md::RoleDescriptor& peer, const char* endpoint); + virtual void sendSAML(RequestAbstractType* request, saml2md::MetadataCredentialCriteria& peer, const char* endpoint); /** * Specialized method for receiving SAML 2.0 responses. The SOAP layer will be diff --git a/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp b/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp index f142132..5d31808 100644 --- a/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp @@ -52,16 +52,16 @@ namespace opensaml { long encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, const char* recipientID=NULL, const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, + const Credential* credential=NULL, const XMLCh* sigAlgorithm=NULL ) const; private: - std::string m_template; + string m_template; }; MessageEncoder* SAML_DLLLOCAL SAML2ArtifactEncoderFactory(const DOMElement* const & e) @@ -84,11 +84,11 @@ SAML2ArtifactEncoder::SAML2ArtifactEncoder(const DOMElement* e) long SAML2ArtifactEncoder::encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, const char* recipientID, const char* relayState, - const CredentialResolver* credResolver, + const Credential* credential, const XMLCh* sigAlgorithm ) const { @@ -124,7 +124,7 @@ long SAML2ArtifactEncoder::encode( log.debug("obtaining new artifact for relying party (%s)", recipientID ? recipientID : "unknown"); auto_ptr artifact(m_artifactGenerator->generateSAML2Artifact(recipientID)); - if (credResolver) { + if (credential) { // Signature based on native XML signing. if (request ? request->getSignature() : response->getSignature()) { log.debug("message already signed, skipping signature operation"); @@ -133,14 +133,14 @@ long SAML2ArtifactEncoder::encode( log.debug("signing the message"); // Build a Signature. - Signature* sig = buildSignature(credResolver, sigAlgorithm); - - // Append Signature. + Signature* sig = SignatureBuilder::buildSignature(); request ? request->setSignature(sig) : response->setSignature(sig); - + if (sigAlgorithm) + sig->setSignatureAlgorithm(sigAlgorithm); + // Sign response while marshalling. vector sigs(1,sig); - xmlObject->marshall((DOMDocument*)NULL,&sigs); + xmlObject->marshall((DOMDocument*)NULL,&sigs,credential); } } diff --git a/saml/saml2/binding/impl/SAML2POSTEncoder.cpp b/saml/saml2/binding/impl/SAML2POSTEncoder.cpp index 1f30f5b..736ffbb 100644 --- a/saml/saml2/binding/impl/SAML2POSTEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2POSTEncoder.cpp @@ -49,16 +49,16 @@ namespace opensaml { long encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, const char* recipientID=NULL, const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, + const Credential* credential=NULL, const XMLCh* sigAlgorithm=NULL ) const; private: - std::string m_template; + string m_template; bool m_simple; }; @@ -93,7 +93,7 @@ long SAML2POSTEncoder::encode( const char* destination, const char* recipientID, const char* relayState, - const CredentialResolver* credResolver, + const Credential* credential, const XMLCh* sigAlgorithm ) const { @@ -115,8 +115,7 @@ long SAML2POSTEncoder::encode( } DOMElement* rootElement = NULL; - vector sigs; - if (credResolver && !m_simple) { + if (credential && !m_simple) { // Signature based on native XML signing. if (request ? request->getSignature() : response->getSignature()) { log.debug("message already signed, skipping signature operation"); @@ -125,21 +124,21 @@ long SAML2POSTEncoder::encode( log.debug("signing and marshalling the message"); // Build a Signature. - Signature* sig = buildSignature(credResolver, sigAlgorithm); - - // Append Signature. + Signature* sig = SignatureBuilder::buildSignature(); request ? request->setSignature(sig) : response->setSignature(sig); - + if (sigAlgorithm) + sig->setSignatureAlgorithm(sigAlgorithm); + // Sign response while marshalling. - sigs.push_back(sig); + vector sigs(1,sig); + rootElement = xmlObject->marshall((DOMDocument*)NULL,&sigs,credential); } } else { log.debug("marshalling the message"); + rootElement = xmlObject->marshall((DOMDocument*)NULL); } - rootElement = xmlObject->marshall((DOMDocument*)NULL,&sigs); - // Start tracking data. TemplateEngine::TemplateParameters pmap; if (relayState) @@ -150,7 +149,7 @@ long SAML2POSTEncoder::encode( XMLHelper::serialize(rootElement, msg); // SimpleSign. - if (credResolver && m_simple) { + if (credential && m_simple) { log.debug("applying simple signature to message data"); string input = (request ? "SAMLRequest=" : "SAMLResponse=") + msg; if (relayState) @@ -163,8 +162,7 @@ long SAML2POSTEncoder::encode( char sigbuf[1024]; memset(sigbuf,0,sizeof(sigbuf)); - auto_ptr key(credResolver->getKey()); - Signature::createRawSignature(key.get(), sigAlgorithm, input.c_str(), input.length(), sigbuf, sizeof(sigbuf)-1); + Signature::createRawSignature(credential->getPrivateKey(), sigAlgorithm, 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 82308f9..9e2b3d1 100644 --- a/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2RedirectEncoder.cpp @@ -51,11 +51,11 @@ namespace opensaml { long encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, const char* recipientID=NULL, const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, + const Credential* credential=NULL, const XMLCh* sigAlgorithm=NULL ) const; }; @@ -73,7 +73,7 @@ long SAML2RedirectEncoder::encode( const char* destination, const char* recipientID, const char* relayState, - const CredentialResolver* credResolver, + const Credential* credential, const XMLCh* sigAlgorithm ) const { @@ -126,7 +126,7 @@ long SAML2RedirectEncoder::encode( if (relayState) xmlbuf = xmlbuf + "&RelayState=" + escaper->encode(relayState); - if (credResolver) { + if (credential) { // Sign the query string after adding the algorithm. if (!sigAlgorithm) sigAlgorithm = DSIGConstants::s_unicodeStrURIRSA_SHA1; @@ -135,8 +135,7 @@ long SAML2RedirectEncoder::encode( char sigbuf[1024]; memset(sigbuf,0,sizeof(sigbuf)); - auto_ptr key(credResolver->getKey()); - Signature::createRawSignature(key.get(), sigAlgorithm, xmlbuf.c_str(), xmlbuf.length(), sigbuf, sizeof(sigbuf)-1); + Signature::createRawSignature(credential->getPrivateKey(), sigAlgorithm, xmlbuf.c_str(), xmlbuf.length(), sigbuf, sizeof(sigbuf)-1); xmlbuf = xmlbuf + "&Signature=" + escaper->encode(sigbuf); } diff --git a/saml/saml2/binding/impl/SAML2SOAPClient.cpp b/saml/saml2/binding/impl/SAML2SOAPClient.cpp index 66189cc..4b077ba 100644 --- a/saml/saml2/binding/impl/SAML2SOAPClient.cpp +++ b/saml/saml2/binding/impl/SAML2SOAPClient.cpp @@ -37,7 +37,7 @@ using namespace xmltooling; using namespace log4cpp; using namespace std; -void SAML2SOAPClient::sendSAML(RequestAbstractType* request, const RoleDescriptor& peer, const char* endpoint) +void SAML2SOAPClient::sendSAML(RequestAbstractType* request, MetadataCredentialCriteria& peer, const char* endpoint) { auto_ptr env(EnvelopeBuilder::buildEnvelope()); Body* body = BodyBuilder::buildBody(); diff --git a/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp b/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp index 7a5bfef..43ec706 100644 --- a/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp +++ b/saml/saml2/binding/impl/SAML2SOAPEncoder.cpp @@ -49,11 +49,11 @@ namespace opensaml { long encode( GenericResponse& genericResponse, - xmltooling::XMLObject* xmlObject, + XMLObject* xmlObject, const char* destination, const char* recipientID=NULL, const char* relayState=NULL, - const xmltooling::CredentialResolver* credResolver=NULL, + const Credential* credential=NULL, const XMLCh* sigAlgorithm=NULL ) const; }; @@ -73,7 +73,7 @@ long SAML2SOAPEncoder::encode( const char* destination, const char* recipientID, const char* relayState, - const CredentialResolver* credResolver, + const Credential* credential, const XMLCh* sigAlgorithm ) const { @@ -101,7 +101,7 @@ long SAML2SOAPEncoder::encode( Body* body = BodyBuilder::buildBody(); env->setBody(body); body->getUnknownXMLObjects().push_back(response); - if (credResolver ) { + if (credential) { if (response->getSignature()) { log.debug("response already signed, skipping signature operation"); rootElement = env->marshall(); @@ -110,12 +110,14 @@ long SAML2SOAPEncoder::encode( log.debug("signing and marshalling the response"); // Build a Signature. - Signature* sig = buildSignature(credResolver, sigAlgorithm); - response->setSignature(sig); + Signature* sig = SignatureBuilder::buildSignature(); + response->setSignature(sig); + if (sigAlgorithm) + sig->setSignatureAlgorithm(sigAlgorithm); // Sign response while marshalling. vector sigs(1,sig); - rootElement = env->marshall((DOMDocument*)NULL,&sigs); + rootElement = env->marshall((DOMDocument*)NULL,&sigs,credential); } } else { diff --git a/saml/saml2/core/Assertions.h b/saml/saml2/core/Assertions.h index 31d11cf..febf744 100644 --- a/saml/saml2/core/Assertions.h +++ b/saml/saml2/core/Assertions.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -61,17 +62,19 @@ namespace opensaml { static const XMLCh TYPE_NAME[]; /** - * Decrypts the element using a standard approach based on a wrapped decryption key - * inside the message. The key decryption key should be supplied using the provided - * resolver. The recipient name may be used when multiple encrypted keys are found. - * The object returned will be unmarshalled around the decrypted DOM element, but the + * Decrypts the element using the supplied CredentialResolver. + * + *

The object returned will be unmarshalled around the decrypted DOM element, but the * DOM itself will be released. * - * @param KEKresolver locked resolver supplying key decryption key + * @param credResolver locked resolver supplying decryption keys * @param recipient identifier naming the recipient (the entity performing the decryption) + * @param criteria optional external criteria to use with resolver * @return the decrypted and unmarshalled object */ - virtual xmltooling::XMLObject* decrypt(const xmltooling::CredentialResolver* KEKresolver, const XMLCh* recipient) const=0; + virtual xmltooling::XMLObject* decrypt( + const xmltooling::CredentialResolver& credResolver, const XMLCh* recipient, xmltooling::CredentialCriteria* criteria=NULL + ) const=0; END_XMLOBJECT; BEGIN_XMLOBJECT(SAML_API,EncryptedID,EncryptedElementType,SAML 2.0 EncryptedID element); diff --git a/saml/saml2/core/impl/Assertions20Impl.cpp b/saml/saml2/core/impl/Assertions20Impl.cpp index a26a275..fe7a7b0 100644 --- a/saml/saml2/core/impl/Assertions20Impl.cpp +++ b/saml/saml2/core/impl/Assertions20Impl.cpp @@ -192,13 +192,13 @@ namespace opensaml { } } - XMLObject* decrypt(const CredentialResolver* KEKresolver, const XMLCh* recipient) const + XMLObject* decrypt(const CredentialResolver& credResolver, const XMLCh* recipient, CredentialCriteria* criteria) const { if (!m_EncryptedData) throw DecryptionException("No encrypted data present."); - EncryptedKeyResolver ekr(*this, recipient); - Decrypter decrypter(KEKresolver, &ekr); - DOMDocumentFragment* frag = decrypter.decryptData(*m_EncryptedData); + EncryptedKeyResolver ekr(*this); + Decrypter decrypter(&credResolver, criteria, &ekr); + DOMDocumentFragment* frag = decrypter.decryptData(*m_EncryptedData, recipient); if (frag->hasChildNodes() && frag->getFirstChild()==frag->getLastChild()) { DOMNode* plaintext=frag->getFirstChild(); if (plaintext->getNodeType()==DOMNode::ELEMENT_NODE) { diff --git a/saml/saml2/core/impl/Protocols20Impl.cpp b/saml/saml2/core/impl/Protocols20Impl.cpp index ab3b970..800400b 100644 --- a/saml/saml2/core/impl/Protocols20Impl.cpp +++ b/saml/saml2/core/impl/Protocols20Impl.cpp @@ -1288,13 +1288,13 @@ namespace opensaml { } } - XMLObject* decrypt(const CredentialResolver* KEKresolver, const XMLCh* recipient) const + XMLObject* decrypt(const CredentialResolver& credResolver, const XMLCh* recipient, CredentialCriteria* criteria) const { if (!m_EncryptedData) throw DecryptionException("No encrypted data present."); - EncryptedKeyResolver ekr(*this, recipient); - Decrypter decrypter(KEKresolver, &ekr); - DOMDocumentFragment* frag = decrypter.decryptData(*m_EncryptedData); + EncryptedKeyResolver ekr(*this); + Decrypter decrypter(&credResolver, criteria, &ekr); + DOMDocumentFragment* frag = decrypter.decryptData(*m_EncryptedData, recipient); if (frag->hasChildNodes() && frag->getFirstChild()==frag->getLastChild()) { DOMNode* plaintext=frag->getFirstChild(); if (plaintext->getNodeType()==DOMNode::ELEMENT_NODE) { diff --git a/saml/saml2/metadata/AbstractMetadataProvider.h b/saml/saml2/metadata/AbstractMetadataProvider.h index c0bc64b..db6427b 100644 --- a/saml/saml2/metadata/AbstractMetadataProvider.h +++ b/saml/saml2/metadata/AbstractMetadataProvider.h @@ -25,10 +25,15 @@ #include -namespace opensaml { +#include +#include +#include +namespace opensaml { namespace saml2md { + class SAML_API MetadataFilter; + /** * Base class for caching metadata providers. */ @@ -39,12 +44,12 @@ namespace opensaml { * Constructor. * * If a DOM is supplied, a set of default logic will be used to identify - * and build a KeyResolver plugin and install it into the provider. + * and build a KeyInfoResolver plugin and install it into the provider. * * The following XML content is supported: * *

    - *
  • <KeyResolver> elements with a type attribute + *
  • <KeyInfoResolver> elements with a type attribute *
* * XML namespaces are ignored in the processing of these elements. @@ -53,22 +58,21 @@ namespace opensaml { */ AbstractMetadataProvider(const DOMElement* e=NULL); - void emitChangeEvent(); - public: virtual ~AbstractMetadataProvider(); - virtual const xmltooling::KeyResolver* getKeyResolver() const { - return m_resolver; - } - - virtual const EntityDescriptor* getEntityDescriptor(const char* id, bool requireValidMetadata=true) const; - virtual const EntityDescriptor* getEntityDescriptor(const SAMLArtifact* artifact) const; - virtual const EntitiesDescriptor* getEntitiesDescriptor(const char* name, bool requireValidMetadata=true) const; + void emitChangeEvent(); + const EntityDescriptor* getEntityDescriptor(const char* id, bool requireValidMetadata=true) const; + const EntityDescriptor* getEntityDescriptor(const SAMLArtifact* artifact) const; + const EntitiesDescriptor* getEntitiesDescriptor(const char* name, bool requireValidMetadata=true) const; + const xmltooling::Credential* resolve(const xmltooling::CredentialCriteria* criteria=NULL) const; + std::vector::size_type resolve( + std::vector& results, const xmltooling::CredentialCriteria* criteria=NULL + ) const; protected: - /** Embedded KeyResolver instance. */ - xmltooling::KeyResolver* m_resolver; + /** Embedded KeyInfoResolver instance. */ + xmltooling::KeyInfoResolver* m_resolver; /** * Loads an entity into the cache for faster lookup. This includes @@ -91,15 +95,29 @@ namespace opensaml { * Clear the cache of known entities and groups. */ virtual void clearDescriptorIndex(); + + /** + * Returns true iff the Credential matches the criteria supplied, if any. + * + * @param cred Credential plus KeyDescriptor usage information + * @param criteria criteria for Credential selection + * @return true iff the Credential applies + */ + virtual bool matches( + const std::pair& cred, const xmltooling::CredentialCriteria* criteria + ) const; private: - std::vector m_filters; - typedef std::multimap sitemap_t; typedef std::multimap groupmap_t; sitemap_t m_sites; sitemap_t m_sources; groupmap_t m_groups; + + mutable xmltooling::Mutex* m_credentialLock; + typedef std::map > > credmap_t; + mutable credmap_t m_credentialMap; + const credmap_t::mapped_type& resolveCredentials(const RoleDescriptor& role) const; }; }; diff --git a/saml/saml2/metadata/ChainingMetadataProvider.h b/saml/saml2/metadata/ChainingMetadataProvider.h index 4c4e089..2de6229 100644 --- a/saml/saml2/metadata/ChainingMetadataProvider.h +++ b/saml/saml2/metadata/ChainingMetadataProvider.h @@ -28,7 +28,12 @@ namespace opensaml { namespace saml2md { - + +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4251 ) +#endif + /** * MetadataProvider that uses multiple providers in sequence. */ @@ -84,18 +89,27 @@ namespace opensaml { xmltooling::Lockable* lock(); void unlock(); void init(); - const xmltooling::KeyResolver* getKeyResolver() const; const xmltooling::XMLObject* getMetadata() const; const EntitiesDescriptor* getEntitiesDescriptor(const char* name, bool requireValidMetadata=true) const; const EntityDescriptor* getEntityDescriptor(const char* id, bool requireValidMetadata=true) const; const EntityDescriptor* getEntityDescriptor(const SAMLArtifact* artifact) const; void onEvent(MetadataProvider& provider); + const xmltooling::Credential* resolve(const xmltooling::CredentialCriteria* criteria=NULL) const; + std::vector::size_type resolve( + std::vector& results, const xmltooling::CredentialCriteria* criteria=NULL + ) const; + private: xmltooling::ThreadKey* m_tlsKey; std::vector m_providers; }; - }; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + + }; }; #endif /* __saml_chainmeta_h__ */ diff --git a/saml/saml2/metadata/Metadata.h b/saml/saml2/metadata/Metadata.h index cdb06b4..9fcb4e2 100644 --- a/saml/saml2/metadata/Metadata.h +++ b/saml/saml2/metadata/Metadata.h @@ -26,7 +26,6 @@ #include #include -#include #define DECL_SAML2MDOBJECTBUILDER(cname) \ DECL_XMLOBJECTBUILDER(SAML_API,cname,samlconstants::SAML20MD_NS,samlconstants::SAML20MD_PREFIX) @@ -158,9 +157,8 @@ namespace opensaml { static const XMLCh KEYTYPE_SIGNING[]; END_XMLOBJECT; - BEGIN_XMLOBJECT5(SAML_API,RoleDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject, - CacheableSAMLObject,TimeBoundSAMLObject,xmltooling::KeyInfoSource, - SAML 2.0 RoleDescriptor abstract element); + BEGIN_XMLOBJECT4(SAML_API,RoleDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject, + CacheableSAMLObject,TimeBoundSAMLObject,SAML 2.0 RoleDescriptor abstract element); DECL_STRING_ATTRIB(ID,ID); DECL_STRING_ATTRIB(ProtocolSupportEnumeration,PROTOCOLSUPPORTENUMERATION); /** Searches the ProtocolSupportEnumeration attribute for the indicated protocol. */ diff --git a/saml/saml2/metadata/MetadataCredentialCriteria.h b/saml/saml2/metadata/MetadataCredentialCriteria.h new file mode 100644 index 0000000..910b6f0 --- /dev/null +++ b/saml/saml2/metadata/MetadataCredentialCriteria.h @@ -0,0 +1,64 @@ +/* + * Copyright 2001-2007 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file saml/saml2/metadata/MetadataCredentialCriteria.h + * + * Metadata-based CredentialCriteria subclass. + */ + +#ifndef __saml_metacred_h__ +#define __saml_metacred_h__ + +#include +#include + +namespace opensaml { + namespace saml2md { + + class SAML_API RoleDescriptor; + + /** + * Metadata-based CredentialCriteria subclass. + */ + class SAML_API MetadataCredentialCriteria : public xmltooling::CredentialCriteria + { + public: + /* + * Constructor. + * + * @param role source of metadata-supplied credentials + */ + MetadataCredentialCriteria(const RoleDescriptor& role) : m_role(role) {} + + virtual ~MetadataCredentialCriteria() {} + + /** + * Return the metadata role associated with the credentials. + * + * @return the associated metadata role + */ + const RoleDescriptor& getRole() const { + return m_role; + } + + private: + const RoleDescriptor& m_role; + }; + }; +}; + +#endif /* __saml_metacred_h__ */ diff --git a/saml/saml2/metadata/MetadataFilter.h b/saml/saml2/metadata/MetadataFilter.h index fe287a8..a4482d9 100644 --- a/saml/saml2/metadata/MetadataFilter.h +++ b/saml/saml2/metadata/MetadataFilter.h @@ -22,6 +22,8 @@ #include #include +#include + #include #ifndef __saml2_metadatafilt_h__ @@ -76,7 +78,6 @@ namespace opensaml { /** MetadataFilter that verifies signatures and filters out any that don't pass. */ #define SIGNATURE_METADATA_FILTER "Signature" - DECL_XMLTOOLING_EXCEPTION(MetadataException,SAML_EXCEPTIONAPI(SAML_API),opensaml::saml2md,xmltooling::XMLToolingException,Exceptions related to metadata use); DECL_XMLTOOLING_EXCEPTION(MetadataFilterException,SAML_EXCEPTIONAPI(SAML_API),opensaml::saml2md,MetadataException,Exceptions related to metadata filtering); }; }; diff --git a/saml/saml2/metadata/MetadataKeyInfoIterator.h b/saml/saml2/metadata/MetadataKeyInfoIterator.h deleted file mode 100644 index 72643ba..0000000 --- a/saml/saml2/metadata/MetadataKeyInfoIterator.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2001-2007 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * MetadataKeyInfoIterator.h - * - * Adapter between SAML metadata and TrustEngine KeyInfoIterator interface. - */ - -#ifndef __saml_keyiter_h__ -#define __saml_keyiter_h__ - -#include - -namespace opensaml { - namespace saml2md { - - /** - * Adapter between SAML metadata and TrustEngine KeyInfoIterator interface. - */ - class SAML_API MetadataKeyInfoIterator : public xmltooling::KeyInfoIterator - { - const std::vector& m_keys; - std::vector::const_iterator m_iter; - - void advance() { - while (hasNext()) { - const XMLCh* use=(*m_iter)->getUse(); - if ((!use || !*use || XMLString::equals(use,KeyDescriptor::KEYTYPE_SIGNING)) && (*m_iter)->getKeyInfo()) - return; - m_iter++; - } - } - - public: - MetadataKeyInfoIterator(const RoleDescriptor& role) : m_keys(role.getKeyDescriptors()) { - m_iter=m_keys.begin(); - advance(); - } - - virtual ~MetadataKeyInfoIterator() {} - - /** - * Indicates whether additional KeyInfo objects are available. - * - * @return true iff another KeyInfo object can be fetched - */ - virtual bool hasNext() const { - return m_iter!=m_keys.end(); - } - - /** - * Returns the next KeyInfo object available. - * - * @return the next KeyInfo object, or NULL if none are left - */ - virtual const xmlsignature::KeyInfo* next() { - xmlsignature::KeyInfo* ret = (*m_iter)->getKeyInfo(); - m_iter++; - advance(); - return ret; - } - }; - }; -}; - -#endif /* __saml_keyiter_h__ */ diff --git a/saml/saml2/metadata/MetadataProvider.h b/saml/saml2/metadata/MetadataProvider.h index 7c927a1..bf5df48 100644 --- a/saml/saml2/metadata/MetadataProvider.h +++ b/saml/saml2/metadata/MetadataProvider.h @@ -23,10 +23,8 @@ #ifndef __saml2_metadataprov_h__ #define __saml2_metadataprov_h__ -#include - -#include -#include +#include +#include namespace opensaml { @@ -36,7 +34,15 @@ namespace opensaml { class SAML_API EntityDescriptor; class SAML_API EntitiesDescriptor; - + class SAML_API RoleDescriptor; + class SAML_API MetadataCredentialResolver; + class SAML_API MetadataFilter; + +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4251 ) +#endif + /** * Supplies an individual source of metadata. * @@ -44,10 +50,9 @@ namespace opensaml { * dynamic lookup, can include local caching, etc. Providers * MUST be locked before any lookup operations. */ - class SAML_API MetadataProvider : public virtual xmltooling::Lockable + class SAML_API MetadataProvider : public virtual xmltooling::CredentialResolver { MAKE_NONCOPYABLE(MetadataProvider); - protected: /** * Constructor. @@ -114,13 +119,6 @@ namespace opensaml { virtual void init()=0; /** - * Returns a KeyResolver associated with this metadata provider, if any. - * - * @return an associated KeyResolver, or NULL - */ - virtual const xmltooling::KeyResolver* getKeyResolver() const=0; - - /** * Gets the entire metadata tree, after the registered filter has been applied. * The caller MUST unlock the provider when finished with the data. * @@ -198,7 +196,11 @@ namespace opensaml { private: std::vector m_filters; }; - + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + /** * Registers MetadataProvider classes into the runtime. */ @@ -209,6 +211,8 @@ namespace opensaml { /** MetadataProvider that wraps a sequence of metadata providers. */ #define CHAINING_METADATA_PROVIDER "Chaining" + + DECL_XMLTOOLING_EXCEPTION(MetadataException,SAML_EXCEPTIONAPI(SAML_API),opensaml::saml2md,xmltooling::XMLToolingException,Exceptions related to metadata use); }; }; diff --git a/saml/saml2/metadata/ObservableMetadataProvider.h b/saml/saml2/metadata/ObservableMetadataProvider.h index 7409eb3..76fe77f 100644 --- a/saml/saml2/metadata/ObservableMetadataProvider.h +++ b/saml/saml2/metadata/ObservableMetadataProvider.h @@ -29,6 +29,10 @@ namespace opensaml { namespace saml2md { +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4251 ) +#endif /** * A metadata provider that notifies interested parties of changes. */ @@ -100,6 +104,11 @@ namespace opensaml { private: std::vector m_observers; }; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + }; }; diff --git a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp index aad86ed..d59e8e2 100644 --- a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp @@ -24,46 +24,48 @@ #include "binding/SAMLArtifact.h" #include "saml2/metadata/Metadata.h" #include "saml2/metadata/AbstractMetadataProvider.h" +#include "saml2/metadata/MetadataCredentialCriteria.h" #include -#include +#include #include using namespace opensaml::saml2md; -using namespace opensaml; using namespace xmltooling; using namespace std; +using opensaml::SAMLArtifact; -static const XMLCh _KeyResolver[] = UNICODE_LITERAL_11(K,e,y,R,e,s,o,l,v,e,r); -static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e); +static const XMLCh _KeyInfoResolver[] = UNICODE_LITERAL_15(K,e,y,I,n,f,o,R,e,s,o,l,v,e,r); +static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e); -AbstractMetadataProvider::AbstractMetadataProvider(const DOMElement* e) : ObservableMetadataProvider(e), m_resolver(NULL) +AbstractMetadataProvider::AbstractMetadataProvider(const DOMElement* e) + : ObservableMetadataProvider(e), m_resolver(NULL), m_credentialLock(NULL) { - e = e ? XMLHelper::getFirstChildElement(e, _KeyResolver) : NULL; + e = e ? XMLHelper::getFirstChildElement(e, _KeyInfoResolver) : NULL; if (e) { auto_ptr_char t(e->getAttributeNS(NULL,type)); if (t.get()) - m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(t.get(),e); + m_resolver = XMLToolingConfig::getConfig().KeyInfoResolverManager.newPlugin(t.get(),e); else - throw UnknownExtensionException(" element found with no type attribute"); - } - - if (!m_resolver) { - m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER, NULL); + throw UnknownExtensionException(" element found with no type attribute"); } + m_credentialLock = Mutex::create(); } AbstractMetadataProvider::~AbstractMetadataProvider() { + for (credmap_t::iterator c = m_credentialMap.begin(); c!=m_credentialMap.end(); ++c) + for_each(c->second.begin(), c->second.end(), cleanup_pair()); + delete m_credentialLock; delete m_resolver; } void AbstractMetadataProvider::emitChangeEvent() { - CachingKeyResolver* ckr=dynamic_cast(m_resolver); - if (ckr) - ckr->clearCache(); - ObservableMetadataProvider::emitChangeEvent(); + for (credmap_t::iterator c = m_credentialMap.begin(); c!=m_credentialMap.end(); ++c) + for_each(c->second.begin(), c->second.end(), cleanup_pair()); + m_credentialMap.clear(); + ObservableMetadataProvider::emitChangeEvent(); } void AbstractMetadataProvider::index(EntityDescriptor* site, time_t validUntil) @@ -188,3 +190,76 @@ const EntityDescriptor* AbstractMetadataProvider::getEntityDescriptor(const SAML return NULL; } + +const Credential* AbstractMetadataProvider::resolve(const CredentialCriteria* criteria) const +{ + const MetadataCredentialCriteria* metacrit = dynamic_cast(criteria); + if (!metacrit) + throw MetadataException("Cannot resolve credentials without a MetadataCredentialCriteria object."); + + Lock lock(m_credentialLock); + const credmap_t::mapped_type& creds = resolveCredentials(metacrit->getRole()); + + for (credmap_t::mapped_type::const_iterator c = creds.begin(); c!=creds.end(); ++c) + if (matches(*c,criteria)) + return c->second; + return NULL; +} + +vector::size_type AbstractMetadataProvider::resolve( + vector& results, const CredentialCriteria* criteria + ) const +{ + const MetadataCredentialCriteria* metacrit = dynamic_cast(criteria); + if (!metacrit) + throw MetadataException("Cannot resolve credentials without a MetadataCredentialCriteria object."); + + Lock lock(m_credentialLock); + const credmap_t::mapped_type& creds = resolveCredentials(metacrit->getRole()); + + for (credmap_t::mapped_type::const_iterator c = creds.begin(); c!=creds.end(); ++c) + if (matches(*c,criteria)) + results.push_back(c->second); + return results.size(); +} + +const AbstractMetadataProvider::credmap_t::mapped_type& AbstractMetadataProvider::resolveCredentials(const RoleDescriptor& role) const +{ + credmap_t::const_iterator i = m_credentialMap.find(&role); + if (i!=m_credentialMap.end()) + return i->second; + + const KeyInfoResolver* resolver = m_resolver ? m_resolver : XMLToolingConfig::getConfig().getKeyInfoResolver(); + const vector& keys = role.getKeyDescriptors(); + AbstractMetadataProvider::credmap_t::mapped_type& resolved = m_credentialMap[&role]; + for (vector::const_iterator k = keys.begin(); k!=keys.end(); ++k) { + if ((*k)->getKeyInfo()) { + Credential* c = resolver->resolve((*k)->getKeyInfo()); + resolved.push_back(make_pair((*k)->getUse(), c)); + } + } + return resolved; +} + +bool AbstractMetadataProvider::matches(const pair& cred, const CredentialCriteria* criteria) const +{ + if (criteria) { + // Check for a usage mismatch. + if ((criteria->getUsage()==CredentialCriteria::SIGNING_CREDENTIAL || criteria->getUsage()==CredentialCriteria::TLS_CREDENTIAL) && + XMLString::equals(cred.first,KeyDescriptor::KEYTYPE_ENCRYPTION)) + return false; + else if (criteria->getUsage()==CredentialCriteria::ENCRYPTION_CREDENTIAL && XMLString::equals(cred.first,KeyDescriptor::KEYTYPE_SIGNING)) + return false; + + if (cred.second->getPublicKey()) { + // See if we have to match a specific key. + auto_ptr critcred( + XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(*criteria,Credential::RESOLVE_KEYS) + ); + if (critcred.get()) + if (!critcred->isEqual(*(cred.second->getPublicKey()))) + return false; + } + } + return true; +} diff --git a/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp b/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp index de5eb81..2f222fd 100644 --- a/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp @@ -88,7 +88,7 @@ void ChainingMetadataProvider::onEvent(MetadataProvider& provider) void ChainingMetadataProvider::init() { - for_each(m_providers.begin(), m_providers.end(), mem_fun(&MetadataProvider::init)); + for_each(m_providers.begin(), m_providers.end(), mem_fun(&MetadataProvider::init)); } Lockable* ChainingMetadataProvider::lock() @@ -106,14 +106,6 @@ void ChainingMetadataProvider::unlock() } } -const KeyResolver* ChainingMetadataProvider::getKeyResolver() const -{ - // Check for a locked provider. - void* ptr=m_tlsKey->getData(); - return ptr ? reinterpret_cast(ptr)->getKeyResolver() : NULL; - -} - const XMLObject* ChainingMetadataProvider::getMetadata() const { throw XMLToolingException("getMetadata operation not implemented on this provider."); @@ -178,3 +170,25 @@ const EntityDescriptor* ChainingMetadataProvider::getEntityDescriptor(const SAML return NULL; } + +const Credential* ChainingMetadataProvider::resolve(const CredentialCriteria* criteria) const +{ + // Check for a locked provider. + void* ptr=m_tlsKey->getData(); + if (!ptr) + throw MetadataException("No locked MetadataProvider, where did the role object come from?"); + + return reinterpret_cast(ptr)->resolve(criteria); +} + +vector::size_type ChainingMetadataProvider::resolve( + vector& results, const CredentialCriteria* criteria + ) const +{ + // Check for a locked provider. + void* ptr=m_tlsKey->getData(); + if (!ptr) + throw MetadataException("No locked MetadataProvider, where did the role object come from?"); + + return reinterpret_cast(ptr)->resolve(results, criteria); +} diff --git a/saml/saml2/metadata/impl/MetadataImpl.cpp b/saml/saml2/metadata/impl/MetadataImpl.cpp index f6503ec..43162ec 100644 --- a/saml/saml2/metadata/impl/MetadataImpl.cpp +++ b/saml/saml2/metadata/impl/MetadataImpl.cpp @@ -23,7 +23,6 @@ #include "internal.h" #include "exceptions.h" #include "saml2/metadata/Metadata.h" -#include "saml2/metadata/MetadataKeyInfoIterator.h" #include #include @@ -956,23 +955,6 @@ namespace opensaml { m_Signature->setContentReference(new opensaml::ContentReference(*this)); } - KeyInfoIterator* getKeyInfoIterator() const { - return new MetadataKeyInfoIterator(*this); - } - - std::string getName() const { - const EntityDescriptor* parent = dynamic_cast(getParent()); - if (parent) { - char* ch = toUTF8(parent->getEntityID()); - if (ch) { - string s(ch); - delete[] ch; - return s; - } - } - return ""; - } - IMPL_ID_ATTRIB(ID); IMPL_STRING_ATTRIB(ProtocolSupportEnumeration); IMPL_STRING_ATTRIB(ErrorURL); diff --git a/saml/saml2/metadata/impl/MetadataProvider.cpp b/saml/saml2/metadata/impl/MetadataProvider.cpp index f79eec0..ea68656 100644 --- a/saml/saml2/metadata/impl/MetadataProvider.cpp +++ b/saml/saml2/metadata/impl/MetadataProvider.cpp @@ -21,6 +21,7 @@ */ #include "internal.h" +#include "saml2/metadata/MetadataFilter.h" #include "saml2/metadata/MetadataProvider.h" #include diff --git a/saml/saml2/metadata/impl/SignatureMetadataFilter.cpp b/saml/saml2/metadata/impl/SignatureMetadataFilter.cpp index 26ad62f..59fb7f5 100644 --- a/saml/saml2/metadata/impl/SignatureMetadataFilter.cpp +++ b/saml/saml2/metadata/impl/SignatureMetadataFilter.cpp @@ -27,8 +27,11 @@ #include -#include +#include +#include +#include #include +#include using namespace opensaml::saml2md; using namespace opensaml; @@ -45,7 +48,7 @@ namespace opensaml { public: SignatureMetadataFilter(const DOMElement* e); ~SignatureMetadataFilter() { - delete m_sigValidator; + delete m_credResolver; } const char* getId() const { return SIGNATURE_METADATA_FILTER; } @@ -56,12 +59,13 @@ namespace opensaml { void verifySignature(Signature* sig) const { if (sig) { m_profileValidator.validate(sig); - m_sigValidator->validate(sig); + m_sigValidator.validate(sig); } } + CredentialResolver* m_credResolver; SignatureProfileValidator m_profileValidator; - SignatureValidator* m_sigValidator; + mutable SignatureValidator m_sigValidator; }; MetadataFilter* SAML_DLLLOCAL SignatureMetadataFilterFactory(const DOMElement* const & e) @@ -72,20 +76,18 @@ namespace opensaml { }; }; -static const XMLCh GenericKeyResolver[] = UNICODE_LITERAL_11(K,e,y,R,e,s,o,l,v,e,r); +static const XMLCh _CredentialResolver[] = UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r); static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e); -SignatureMetadataFilter::SignatureMetadataFilter(const DOMElement* e) : m_sigValidator(NULL) +SignatureMetadataFilter::SignatureMetadataFilter(const DOMElement* e) : m_credResolver(NULL) { - e = XMLHelper::getFirstChildElement(e, GenericKeyResolver); + e = XMLHelper::getFirstChildElement(e, _CredentialResolver); auto_ptr_char t(e ? e->getAttributeNS(NULL,type) : NULL); if (t.get()) { - auto_ptr kr(XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(t.get(),e)); - m_sigValidator = new SignatureValidator(kr.get()); - kr.release(); + m_credResolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(t.get(),e); } else - throw MetadataFilterException("missing element, or no type attribute found"); + throw MetadataFilterException("Missing element, or no type attribute found"); } void SignatureMetadataFilter::doFilter(XMLObject& xmlObject) const @@ -94,6 +96,11 @@ void SignatureMetadataFilter::doFilter(XMLObject& xmlObject) const NDC ndc("doFilter"); #endif + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker locker(m_credResolver); + m_sigValidator.setCredential(m_credResolver->resolve(&cc)); + try { EntitiesDescriptor& entities = dynamic_cast(xmlObject); doFilter(entities, true); diff --git a/saml/saml2/metadata/impl/XMLMetadataProvider.cpp b/saml/saml2/metadata/impl/XMLMetadataProvider.cpp index 6a8ef4f..cf3f743 100644 --- a/saml/saml2/metadata/impl/XMLMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/XMLMetadataProvider.cpp @@ -22,6 +22,7 @@ #include "internal.h" #include "saml2/metadata/Metadata.h" +#include "saml2/metadata/MetadataFilter.h" #include "saml2/metadata/AbstractMetadataProvider.h" #include diff --git a/samltest/data/incommon.pem b/samltest/data/incommon.pem new file mode 100644 index 0000000..dfd1680 --- /dev/null +++ b/samltest/data/incommon.pem @@ -0,0 +1,36 @@ + +MD5 Fingerprint=E8:E6:70:BC:CF:50:67:7A:B3:27:69:81:AF:C2:4D:B1 + +-----BEGIN CERTIFICATE----- +MIIFsjCCBJqgAwIBAgIBIDANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTSW5Db21tb24gRmVkZXJhdGlvbjEpMCcGA1UEAxMgSW5Db21tb24g +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDUwMzI5MTUwMTM2WhcNMDYwMzI5 +MTUwMTM2WjBSMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTSW5Db21tb24gRmVkZXJh +dGlvbjElMCMGA1UEAxMcZmVkb3AuaW5jb21tb25mZWRlcmF0aW9uLm9yZzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAoXZK5/nRuWY+S91CMPsXloDc5 +vGo8O/xcqkUNUow+C34NlgnZX4zq2BjZ1WTAk3yLaF00qYOK18R0LMpHjYmEbtvt +NrjEvtaZwalo83TyRNKHfqvBG3bxOkoYpo8jZ9MkHxskCgjXWLnPu+TCB7GiDgBL +Q2VEk/UneKHlNc0Y1drBr1HfiRR73lAIUXNG/iRGXyBLqvyyFPasZv/oBWmsJZqI +2T8jlmdSZbMG66yWGMp9dKoJyb44fYGVlyo5j8arxyiXAEz4QIdoFhmm1k1wSQnJ +DHtYaxwpf72wywps9P6GLqGkg8z+sxPWEgP8QqZWhwNJqAtVbNh+TDkBpXsCAwEA +AaOCAo0wggKJMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU5ij9YLU5zQ6K75kPgVpy +Q2N/lPswfgYDVR0jBHcwdYAUky3IYRitY+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJ +BgNVBAYTAlVTMRwwGgYDVQQKExNJbkNvbW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQD +EyBJbkNvbW1vbiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eYIBADCBugYIKwYBBQUH +AQEEga0wgaowgacGCCsGAQUFBzAChoGaaHR0cDovL2luY29tbW9uY2ExLmluY29t +bW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdlL2NlcnRzL2NhLWNlcnRzLnA3YgoJCUNB +IElzc3VlcnMgLSBVUkk6aHR0cDovL2luY29tbW9uY2EyLmluY29tbW9uZmVkZXJh +dGlvbi5vcmcvYnJpZGdlL2NlcnRzL2NhLWNlcnRzLnA3YjCBjQYDVR0fBIGFMIGC +MD+gPaA7hjlodHRwOi8vaW5jb21tb25jcmwxLmluY29tbW9uZmVkZXJhdGlvbi5v +cmcvY3JsL2VlY3Jscy5jcmwwP6A9oDuGOWh0dHA6Ly9pbmNvbW1vbmNybDIuaW5j +b21tb25mZWRlcmF0aW9uLm9yZy9jcmwvZWVjcmxzLmNybDBeBgNVHSAEVzBVMFMG +CysGAQQBriMBBAEBMEQwQgYIKwYBBQUHAgEWNmh0dHA6Ly9pbmNvbW1vbmNhLmlu +Y29tbW9uZmVkZXJhdGlvbi5vcmcvcHJhY3RpY2VzLnBkZjANBgkqhkiG9w0BAQUF +AAOCAQEAemwo7fVSkdlClp7lFXVX1wmANoBAmAOf5F6zEAxTR9zbwEvcT5WwzSOD +ikRKHBkP3A2qKJjuPNg46xpX2EFFdcqFc0KBD0KvBsROGwDwLWZZDwW4MFqDLkNa +6AM0OW1o6zn8J5KapRTRZ8SKf1r8rPYWwvyigo+ECHREmJWgTqExVW03MTbuIXFG +o3djIpXUplL91mni06UuefyOY6BQqVcesLf8ncwG2P3gHSLRmoIej7oUXpKkejEI +S1DTdX1OcjEeFlY3hXPx1uN95u5reoa78inWVjmJMDnF0oz7YF0TOIzz8dS+LUKR +TcKnG6jJL2KcSpgsqN/MxV3laz52hg== +-----END CERTIFICATE----- diff --git a/samltest/data/saml2/metadata/XMLMetadataProvider.xml b/samltest/data/saml2/metadata/XMLMetadataProvider.xml index a2d1823..8302ff0 100644 --- a/samltest/data/saml2/metadata/XMLMetadataProvider.xml +++ b/samltest/data/saml2/metadata/XMLMetadataProvider.xml @@ -1,6 +1,10 @@ - + + + ../samltest/data/incommon.pem + + diff --git a/samltest/data/security/FilesystemKeyResolver.xml b/samltest/data/security/FilesystemCredentialResolver.xml similarity index 66% rename from samltest/data/security/FilesystemKeyResolver.xml rename to samltest/data/security/FilesystemCredentialResolver.xml index e37fb88..da9484d 100644 --- a/samltest/data/security/FilesystemKeyResolver.xml +++ b/samltest/data/security/FilesystemCredentialResolver.xml @@ -1,6 +1,6 @@ - + ../samltest/data/cert.pem - + diff --git a/samltest/data/signature/SAML1Assertion.xml b/samltest/data/signature/SAML1Assertion.xml index f2a85fd..47513be 100644 --- a/samltest/data/signature/SAML1Assertion.xml +++ b/samltest/data/signature/SAML1Assertion.xml @@ -18,7 +18,7 @@ AuthenticationMethod="method" AA5098JC4gfdAf2bvPQRZ9Ld/VehXAB3uhp0r4js4i6fMB3hGMs4VnE9iEJEsPDD 0Kj4cfewxHij/kHrWcxpKMMqIgGlqKYZhuQHfFt8GzDeeFIgu1R675jcN4uCOoWl 3aRVd9hgPRsXzf7/RkMiXHIsU/NjUPRKf7GjNt2jNT0= -MIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV +sp.example.orgMIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV BAYTAlVTMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDnNwLmV4YW1wbGUu b3JnMB4XDTA1MDYyMDE1NDgzNFoXDTMyMTEwNTE1NDgzNFowOjELMAkGA1UEBhMC VVMxEjAQBgNVBAoTCUludGVybmV0MjEXMBUGA1UEAxMOc3AuZXhhbXBsZS5vcmcw diff --git a/samltest/data/signature/SAML1Request.xml b/samltest/data/signature/SAML1Request.xml index ee47ffc..f6e1c30 100644 --- a/samltest/data/signature/SAML1Request.xml +++ b/samltest/data/signature/SAML1Request.xml @@ -15,7 +15,7 @@ MajorVersion="1" MinorVersion="1" RequestID="ident"> -58F0tbYfjW1fw6qvD3SFvhQlg/o= +TfMZL9tjX6BFJb1whHodLQw94aE= -C9U3y5+GJYi+e2kHn2VBYFuE0L/CVDMxiRygammXuDiOo3jQslf8GifLDxinnI33 -+sky4f/Kv5mjVFd6aYs9ad3JANzuDF6zdMBVnQkrCAkfzKXjif1coXZWIcDc0To9 -qp6fegEuvFJrJyEJw9xyKkc93Mk6+gXLyxe1oynOkkI= -MIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV +SvahDxYpqSJI16CjJt2YWQO6DHvrtL9aNCsxwpEG4rRjkUshipwUHMngulnQHyX6 +BiJ5NrdAWd2HMaUOIiwg1e0Xi/H5BGwdyPPOM7kA05EOdnNO2wWcWgjRSUTa7f9g +a3SHSk63QckMJBkm1neUijbktD2sk0yX6Zm0oyKWlYI= +sp.example.orgMIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV BAYTAlVTMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDnNwLmV4YW1wbGUu b3JnMB4XDTA1MDYyMDE1NDgzNFoXDTMyMTEwNTE1NDgzNFowOjELMAkGA1UEBhMC VVMxEjAQBgNVBAoTCUludGVybmV0MjEXMBUGA1UEAxMOc3AuZXhhbXBsZS5vcmcw @@ -48,7 +48,7 @@ AuthenticationMethod="method">John Doed4SsRgDSjboTRA2YUD68TPp+17AqRmxbY/LrWJhueIC/JY+Ct7+Fd6bugUXliIeD NVRDACsEB7PqYWZ99+Ecf8XAmQYCw5elj8mWxPp0o+UVHtBZOR2bC+/YjNitSM+x G/F3JgZqfunUcg7mcj6WEAUt4pjKhjaTY8Z7QJltdKc= -MIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV +sp.example.orgMIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV BAYTAlVTMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDnNwLmV4YW1wbGUu b3JnMB4XDTA1MDYyMDE1NDgzNFoXDTMyMTEwNTE1NDgzNFowOjELMAkGA1UEBhMC VVMxEjAQBgNVBAoTCUludGVybmV0MjEXMBUGA1UEAxMOc3AuZXhhbXBsZS5vcmcw diff --git a/samltest/data/signature/SAML2Assertion.xml b/samltest/data/signature/SAML2Assertion.xml index 63ab75a..6ad4709 100644 --- a/samltest/data/signature/SAML2Assertion.xml +++ b/samltest/data/signature/SAML2Assertion.xml @@ -15,7 +15,7 @@ Version="2.0">issuer encoder( SAMLConfig::getConfig().MessageEncoderManager.newPlugin(samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT, NULL) ); encoder->setArtifactGenerator(this); - encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",m_creds); + encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",cred); toSend.release(); // Decode message. @@ -106,25 +100,6 @@ public: throw BindingException("Not implemented."); } - Signature* buildSignature(const CredentialResolver* credResolver) const - { - // Build a Signature. - Signature* sig = SignatureBuilder::buildSignature(); - sig->setSigningKey(credResolver->getKey()); - - // Build KeyInfo. - const vector& certs = credResolver->getCertificates(); - if (!certs.empty()) { - KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo(); - X509Data* x509Data=X509DataBuilder::buildX509Data(); - keyInfo->getX509Datas().push_back(x509Data); - for_each(certs.begin(),certs.end(),bind1st(_addcert(),x509Data)); - sig->setKeyInfo(keyInfo); - } - - return sig; - } - Response* resolve( const vector& artifacts, const IDPSSODescriptor& idpDescriptor, @@ -142,9 +117,14 @@ public: StatusCode* sc = StatusCodeBuilder::buildStatusCode(); status->setStatusCode(sc); sc->setValue(&StatusCode::SUCCESS); - response->setSignature(buildSignature(m_creds)); + response->setSignature(SignatureBuilder::buildSignature()); vector sigs(1,response->getSignature()); - response->marshall((DOMDocument*)NULL,&sigs); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker clocker(m_creds); + const Credential* cred = m_creds->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + response->marshall((DOMDocument*)NULL,&sigs,cred); SchemaValidators.validate(response.get()); policy.evaluate(*(response.get()), this); return response.release(); diff --git a/samltest/saml1/binding/SAML1POSTTest.h b/samltest/saml1/binding/SAML1POSTTest.h index c6284df..eb8278c 100644 --- a/samltest/saml1/binding/SAML1POSTTest.h +++ b/samltest/saml1/binding/SAML1POSTTest.h @@ -46,6 +46,12 @@ public: ); janitor.release(); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker clocker(m_creds); + const Credential* cred = m_creds->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + // Freshen timestamp and ID. toSend->setIssueInstant(time(NULL)); toSend->setResponseID(NULL); @@ -64,7 +70,7 @@ public: samlconstants::SAML1_PROFILE_BROWSER_POST, encoder_config->getDocumentElement() ) ); - encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",m_creds); + encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",cred); toSend.release(); // Decode message. diff --git a/samltest/saml2/binding/SAML2ArtifactTest.h b/samltest/saml2/binding/SAML2ArtifactTest.h index e763ff3..b869867 100644 --- a/samltest/saml2/binding/SAML2ArtifactTest.h +++ b/samltest/saml2/binding/SAML2ArtifactTest.h @@ -50,6 +50,12 @@ public: ); janitor.release(); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker clocker(m_creds); + const Credential* cred = m_creds->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + // Freshen timestamp. toSend->setIssueInstant(time(NULL)); @@ -58,7 +64,7 @@ public: SAMLConfig::getConfig().MessageEncoderManager.newPlugin(samlconstants::SAML20_BINDING_HTTP_ARTIFACT, NULL) ); encoder->setArtifactGenerator(this); - encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",m_creds); + encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",cred); toSend.release(); // Decode message. diff --git a/samltest/saml2/binding/SAML2POSTTest.h b/samltest/saml2/binding/SAML2POSTTest.h index 776c95f..814873e 100644 --- a/samltest/saml2/binding/SAML2POSTTest.h +++ b/samltest/saml2/binding/SAML2POSTTest.h @@ -46,6 +46,12 @@ public: ); janitor.release(); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker clocker(m_creds); + const Credential* cred = m_creds->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + // Freshen timestamp and ID. toSend->setIssueInstant(time(NULL)); toSend->setID(NULL); @@ -64,7 +70,7 @@ public: samlconstants::SAML20_BINDING_HTTP_POST, encoder_config->getDocumentElement() ) ); - encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",m_creds); + encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",cred); toSend.release(); // Decode message. @@ -108,6 +114,12 @@ public: ); janitor.release(); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker clocker(m_creds); + const Credential* cred = m_creds->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + // Freshen timestamp and ID. toSend->setIssueInstant(time(NULL)); toSend->setID(NULL); @@ -126,7 +138,7 @@ public: samlconstants::SAML20_BINDING_HTTP_POST_SIMPLESIGN, encoder_config->getDocumentElement() ) ); - encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",m_creds); + encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",cred); toSend.release(); // Decode message. diff --git a/samltest/saml2/binding/SAML2RedirectTest.h b/samltest/saml2/binding/SAML2RedirectTest.h index 5fda95a..59e51fd 100644 --- a/samltest/saml2/binding/SAML2RedirectTest.h +++ b/samltest/saml2/binding/SAML2RedirectTest.h @@ -46,6 +46,12 @@ public: ); janitor.release(); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker clocker(m_creds); + const Credential* cred = m_creds->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + // Freshen timestamp and ID. toSend->setIssueInstant(time(NULL)); toSend->setID(NULL); @@ -54,7 +60,7 @@ public: auto_ptr encoder( SAMLConfig::getConfig().MessageEncoderManager.newPlugin(samlconstants::SAML20_BINDING_HTTP_REDIRECT, NULL) ); - encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",m_creds); + encoder->encode(*this,toSend.get(),"https://sp.example.org/SAML/SSO","https://sp.example.org/","state",cred); toSend.release(); // Decode message. diff --git a/samltest/security/AbstractPKIXTrustEngineTest.h b/samltest/security/AbstractPKIXTrustEngineTest.h index 745a97d..5e746a3 100644 --- a/samltest/security/AbstractPKIXTrustEngineTest.h +++ b/samltest/security/AbstractPKIXTrustEngineTest.h @@ -17,8 +17,10 @@ #include "internal.h" #include #include +#include #include #include +#include using namespace opensaml::saml2; using namespace opensaml::saml2md; @@ -31,24 +33,23 @@ namespace { ~SampleTrustEngine() {} class SampleIterator : public PKIXValidationInfoIterator { - vector m_crls; - KeyResolver::ResolvedCertificates m_certs; - KeyResolver* m_resolver; + CredentialResolver* m_resolver; + mutable vector m_crls; bool m_done; public: - SampleIterator(const KeyResolver& keyResolver) - : PKIXValidationInfoIterator(keyResolver), m_resolver(NULL), m_done(false) { - string config = data_path + "security/FilesystemKeyResolver.xml"; + SampleIterator() : m_resolver(NULL), m_done(false) { + string config = data_path + "security/FilesystemCredentialResolver.xml"; ifstream in(config.c_str()); DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in); XercesJanitor janitor(doc); - m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin( - FILESYSTEM_KEY_RESOLVER,doc->getDocumentElement() + m_resolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin( + FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement() ); - m_resolver->resolveCertificates((KeyInfo*)NULL,m_certs); + m_resolver->lock(); } ~SampleIterator() { + m_resolver->unlock(); delete m_resolver; } @@ -64,20 +65,22 @@ namespace { } const vector& getTrustAnchors() const { - return m_certs.v(); + return dynamic_cast(m_resolver->resolve())->getEntityCertificateChain(); } const vector& getCRLs() const { + XSECCryptoX509CRL* crl = dynamic_cast(m_resolver->resolve())->getCRL(); + if (crl) + m_crls.push_back(crl); return m_crls; } }; PKIXValidationInfoIterator* getPKIXValidationInfoIterator( - const KeyInfoSource& keyInfoSource, - const KeyResolver& keyResolver + const CredentialResolver& credResolver, CredentialCriteria* criteria=NULL, const KeyInfoResolver* keyInfoResolver=NULL ) const { - dynamic_cast(keyInfoSource); - return new SampleIterator(keyResolver); + dynamic_cast(criteria); + return new SampleIterator(); } }; }; @@ -92,7 +95,7 @@ public: SAMLObjectBaseTestCase::tearDown(); } - void testExplicitKeyTrustEngine() { + void testAbstractPKIXTrustEngine() { string config = data_path + "security/XMLMetadataProvider.xml"; ifstream in(config.c_str()); DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in); @@ -135,7 +138,10 @@ public: Signature* sig=assertion->getSignature(); TSM_ASSERT("Signature not present", sig!=NULL); - TSM_ASSERT("Signature failed to validate.", trustEngine->validate(*sig, *role, metadataProvider->getKeyResolver())); + + MetadataCredentialCriteria cc(*role); + cc.setPeerName("https://idp.example.org"); + TSM_ASSERT("Signature failed to validate.", trustEngine->validate(*sig, *metadataProvider, &cc)); descriptor = metadataProvider->getEntityDescriptor("https://idp2.example.org"); TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); @@ -143,6 +149,8 @@ public: role=descriptor->getIDPSSODescriptors().front(); TSM_ASSERT("Role not present", role!=NULL); - TSM_ASSERT("Signature validated.", !trustEngine->validate(*sig, *role, metadataProvider->getKeyResolver())); + MetadataCredentialCriteria cc2(*role); + cc2.setPeerName("https://idp2.example.org"); + TSM_ASSERT("Signature validated.", !trustEngine->validate(*sig, *metadataProvider, &cc2)); } }; diff --git a/samltest/security/ExplicitKeyTrustEngineTest.h b/samltest/security/ExplicitKeyTrustEngineTest.h index a172a49..5753c45 100644 --- a/samltest/security/ExplicitKeyTrustEngineTest.h +++ b/samltest/security/ExplicitKeyTrustEngineTest.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -80,7 +81,10 @@ public: Signature* sig=assertion->getSignature(); TSM_ASSERT("Signature not present", sig!=NULL); - TSM_ASSERT("Signature failed to validate.", trustEngine->validate(*sig, *role, metadataProvider->getKeyResolver())); + + MetadataCredentialCriteria cc(*role); + cc.setPeerName("https://idp.example.org"); + TSM_ASSERT("Signature failed to validate.", trustEngine->validate(*sig, *metadataProvider, &cc)); descriptor = metadataProvider->getEntityDescriptor("https://idp2.example.org"); TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); @@ -88,6 +92,8 @@ public: role=descriptor->getIDPSSODescriptors().front(); TSM_ASSERT("Role not present", role!=NULL); - TSM_ASSERT("Signature validated.", !trustEngine->validate(*sig, *role, metadataProvider->getKeyResolver())); + MetadataCredentialCriteria cc2(*role); + cc2.setPeerName("https://idp2.example.org"); + TSM_ASSERT("Signature validated.", !trustEngine->validate(*sig, *metadataProvider, &cc2)); } }; diff --git a/samltest/signature/SAML1AssertionTest.h b/samltest/signature/SAML1AssertionTest.h index 274cec3..51cb1f1 100644 --- a/samltest/signature/SAML1AssertionTest.h +++ b/samltest/signature/SAML1AssertionTest.h @@ -58,21 +58,18 @@ public: // Append a Signature. Signature* sig=SignatureBuilder::buildSignature(); assertion->setSignature(sig); - Locker locker(m_resolver); - sig->setSigningKey(m_resolver->getKey()); - - // Build KeyInfo. - KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo(); - X509Data* x509Data=X509DataBuilder::buildX509Data(); - keyInfo->getX509Datas().push_back(x509Data); - for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data)); - sig->setKeyInfo(keyInfo); // Sign while marshalling. vector sigs(1,sig); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker locker(m_resolver); + const Credential* cred = m_resolver->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + DOMElement* rootElement = NULL; try { - rootElement=assertion->marshall((DOMDocument*)NULL,&sigs); + rootElement=assertion->marshall((DOMDocument*)NULL,&sigs,cred); } catch (XMLToolingException& e) { TS_TRACE(e.what()); @@ -90,7 +87,7 @@ public: try { opensaml::SignatureProfileValidator spv; - SignatureValidator sv(new KeyResolver(m_resolver->getKey())); + SignatureValidator sv(cred); spv.validate(dynamic_cast(assertion2.get())->getSignature()); sv.validate(dynamic_cast(assertion2.get())->getSignature()); } diff --git a/samltest/signature/SAML1RequestTest.h b/samltest/signature/SAML1RequestTest.h index 2909ad8..cebe076 100644 --- a/samltest/signature/SAML1RequestTest.h +++ b/samltest/signature/SAML1RequestTest.h @@ -58,21 +58,18 @@ public: // Append a Signature. Signature* sig=SignatureBuilder::buildSignature(); request->setSignature(sig); - Locker locker(m_resolver); - sig->setSigningKey(m_resolver->getKey()); - - // Build KeyInfo. - KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo(); - X509Data* x509Data=X509DataBuilder::buildX509Data(); - keyInfo->getX509Datas().push_back(x509Data); - for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data)); - sig->setKeyInfo(keyInfo); // Sign while marshalling. vector sigs(1,sig); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker locker(m_resolver); + const Credential* cred = m_resolver->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + DOMElement* rootElement = NULL; try { - rootElement=request->marshall((DOMDocument*)NULL,&sigs); + rootElement=request->marshall((DOMDocument*)NULL,&sigs,cred); } catch (XMLToolingException& e) { TS_TRACE(e.what()); @@ -90,7 +87,7 @@ public: try { opensaml::SignatureProfileValidator spv; - SignatureValidator sv(new KeyResolver(m_resolver->getKey())); + SignatureValidator sv(cred); spv.validate(dynamic_cast(request2.get())->getSignature()); sv.validate(dynamic_cast(request2.get())->getSignature()); } diff --git a/samltest/signature/SAML1ResponseTest.h b/samltest/signature/SAML1ResponseTest.h index 5f07967..6a67106 100644 --- a/samltest/signature/SAML1ResponseTest.h +++ b/samltest/signature/SAML1ResponseTest.h @@ -61,21 +61,18 @@ public: // Append a Signature. assertion->setSignature(SignatureBuilder::buildSignature()); - Locker locker(m_resolver); - assertion->getSignature()->setSigningKey(m_resolver->getKey()); - - // Build KeyInfo. - KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo(); - X509Data* x509Data=X509DataBuilder::buildX509Data(); - keyInfo->getX509Datas().push_back(x509Data); - for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data)); - assertion->getSignature()->setKeyInfo(keyInfo); // Sign assertion while marshalling. vector sigs(1,assertion->getSignature()); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker locker(m_resolver); + const Credential* cred = m_resolver->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + DOMElement* rootElement = NULL; try { - rootElement=assertion->marshall((DOMDocument*)NULL,&sigs); + rootElement=assertion->marshall((DOMDocument*)NULL,&sigs,cred); } catch (XMLToolingException& e) { TS_TRACE(e.what()); @@ -94,15 +91,13 @@ public: response->setStatus(status); response->getAssertions().push_back(assertion); response->setSignature(SignatureBuilder::buildSignature()); - response->getSignature()->setSigningKey(m_resolver->getKey()); - response->getSignature()->setKeyInfo(keyInfo->cloneKeyInfo()); // Sign response while marshalling. sigs.clear(); sigs.push_back(response->getSignature()); rootElement = NULL; try { - rootElement=response->marshall((DOMDocument*)NULL,&sigs); + rootElement=response->marshall((DOMDocument*)NULL,&sigs,cred); } catch (XMLToolingException& e) { TS_TRACE(e.what()); @@ -123,7 +118,7 @@ public: spv.validate(dynamic_cast(response2.get())->getAssertions().front()->getSignature()); spv.validate(dynamic_cast(response2.get())->getSignature()); - SignatureValidator sv(new KeyResolver(m_resolver->getKey())); + SignatureValidator sv(cred); sv.validate(dynamic_cast(response2.get())->getAssertions().front()->getSignature()); sv.validate(dynamic_cast(response2.get())->getSignature()); } diff --git a/samltest/signature/SAML2AssertionTest.h b/samltest/signature/SAML2AssertionTest.h index 14fa1a9..1c5f2c6 100644 --- a/samltest/signature/SAML2AssertionTest.h +++ b/samltest/signature/SAML2AssertionTest.h @@ -66,21 +66,18 @@ public: // Append a Signature. Signature* sig=SignatureBuilder::buildSignature(); assertion->setSignature(sig); - Locker locker(m_resolver); - sig->setSigningKey(m_resolver->getKey()); - - // Build KeyInfo. - KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo(); - X509Data* x509Data=X509DataBuilder::buildX509Data(); - keyInfo->getX509Datas().push_back(x509Data); - for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data)); - sig->setKeyInfo(keyInfo); // Sign while marshalling. vector sigs(1,sig); + CredentialCriteria cc; + cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL); + Locker locker(m_resolver); + const Credential* cred = m_resolver->resolve(&cc); + TSM_ASSERT("Retrieved credential was null", cred!=NULL); + DOMElement* rootElement = NULL; try { - rootElement=assertion->marshall((DOMDocument*)NULL,&sigs); + rootElement=assertion->marshall((DOMDocument*)NULL,&sigs,cred); } catch (XMLToolingException& e) { TS_TRACE(e.what()); @@ -98,7 +95,7 @@ public: try { opensaml::SignatureProfileValidator spv; - SignatureValidator sv(new KeyResolver(m_resolver->getKey())); + SignatureValidator sv(cred); spv.validate(dynamic_cast(assertion2.get())->getSignature()); sv.validate(dynamic_cast(assertion2.get())->getSignature()); } diff --git a/samltest/signature/SAMLSignatureTestBase.h b/samltest/signature/SAMLSignatureTestBase.h index 2d40dab..3c8d8ce 100644 --- a/samltest/signature/SAMLSignatureTestBase.h +++ b/samltest/signature/SAMLSignatureTestBase.h @@ -17,22 +17,13 @@ #include "internal.h" #include +#include #include #include #include using namespace xmlsignature; -class _addcert : public std::binary_function { -public: - void operator()(X509Data* bag, XSECCryptoX509* cert) const { - safeBuffer& buf=cert->getDEREncodingSB(); - X509Certificate* x=X509CertificateBuilder::buildX509Certificate(); - x->setValue(buf.sbStrToXMLCh()); - bag->getX509Certificates().push_back(x); - } -}; - class SAMLSignatureTestBase : public SAMLObjectBaseTestCase { protected: CredentialResolver* m_resolver;