X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FXMLSigningRule.cpp;h=56c22500b8ffcc535b8ee736296f56f75106bbce;hb=750aa26530f9e8993eae37cd9e68e25497be66b5;hp=552cef88a12e453febfac70e7f4c908361a9f467;hpb=b951e528ad7d0764ddc4ced037a8bd53bd3c9890;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/binding/impl/XMLSigningRule.cpp b/saml/binding/impl/XMLSigningRule.cpp index 552cef8..56c2250 100644 --- a/saml/binding/impl/XMLSigningRule.cpp +++ b/saml/binding/impl/XMLSigningRule.cpp @@ -23,10 +23,12 @@ #include "internal.h" #include "exceptions.h" #include "binding/XMLSigningRule.h" -#include "saml2/core/Assertions.h" +#include "saml1/core/Assertions.h" +#include "saml1/core/Protocols.h" +#include "saml2/core/Protocols.h" #include "saml2/metadata/Metadata.h" #include "saml2/metadata/MetadataProvider.h" -#include "security/TrustEngine.h" +#include "signature/SignatureProfileValidator.h" #include #include @@ -46,12 +48,11 @@ namespace opensaml { }; pair XMLSigningRule::evaluate( - const GenericRequest& request, const XMLObject& message, + const GenericRequest* request, const MetadataProvider* metadataProvider, const QName* role, - const opensaml::TrustEngine* trustEngine, - const MessageExtractor& extractor + const TrustEngine* trustEngine ) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.XMLSigning"); @@ -65,14 +66,25 @@ pair XMLSigningRule::evaluate( } try { - const RootObject& root = dynamic_cast(message); - if (!root.getSignature()) { - log.debug("ignoring unsigned message"); + const SignableObject* signable = dynamic_cast(&message); + if (!signable || !signable->getSignature()) { + log.debug("ignoring unsigned or unrecognized message"); return ret; } + log.debug("validating signature profile"); + try { + SignatureProfileValidator sigval; + sigval.validate(signable->getSignature()); + } + catch (ValidationException& ve) { + log.error("signature profile failed to validate: %s", ve.what()); + return ret; + } + + log.debug("extracting issuer from message"); - pair issuerInfo = extractor.getIssuerAndProtocol(message); + pair issuerInfo = getIssuerAndProtocol(message); auto_ptr issuer(issuerInfo.first); if (!issuerInfo.first || !issuerInfo.second || @@ -96,7 +108,7 @@ pair XMLSigningRule::evaluate( return ret; } - if (!trustEngine->validate(*(root.getSignature()), *roledesc, metadataProvider->getKeyResolver())) { + if (!trustEngine->validate(*(signable->getSignature()), *roledesc, metadataProvider->getKeyResolver())) { log.error("unable to verify signature on message with supplied trust engine"); return ret; } @@ -115,3 +127,48 @@ pair XMLSigningRule::evaluate( } return ret; } + +pair XMLSigningRule::getIssuerAndProtocol(const XMLObject& message) const +{ + // We just let any bad casts throw here. + + saml2::Issuer* issuer; + + // Shortcuts some of the casting. + const XMLCh* ns = message.getElementQName().getNamespaceURI(); + if (ns) { + if (XMLString::equals(ns, samlconstants::SAML20P_NS) || XMLString::equals(ns, samlconstants::SAML20_NS)) { + // 2.0 namespace should be castable to a specialized 2.0 root. + const saml2::RootObject& root = dynamic_cast(message); + issuer = root.getIssuer(); + if (issuer && issuer->getName()) { + return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS); + } + + // No issuer in the message, so we have to try the Response approach. + const vector& assertions = dynamic_cast(message).getAssertions(); + if (!assertions.empty()) { + issuer = assertions.front()->getIssuer(); + if (issuer && issuer->getName()) + return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS); + } + } + else if (XMLString::equals(ns, samlconstants::SAML1P_NS)) { + // Should be a samlp:Response, at least in OpenSAML. + const vector& assertions = dynamic_cast(message).getAssertions(); + if (!assertions.empty()) { + const saml1::Assertion* a = assertions.front(); + if (a->getIssuer()) { + issuer = saml2::IssuerBuilder::buildIssuer(); + issuer->setName(a->getIssuer()); + pair minor = a->getMinorVersion(); + return make_pair( + issuer, + (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM + ); + } + } + } + } + return pair(NULL,NULL); +}