X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fopensaml2.git;a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FXMLSigningRule.cpp;h=029f14c681e3e4e01f6856623a9ce273fa6ece1c;hp=56c22500b8ffcc535b8ee736296f56f75106bbce;hb=694b587ec84095f2d7c0987724956673fe7eb2b5;hpb=a1474e51327e165749f9c77701d3b82d5d2e61b8 diff --git a/saml/binding/impl/XMLSigningRule.cpp b/saml/binding/impl/XMLSigningRule.cpp index 56c2250..029f14c 100644 --- a/saml/binding/impl/XMLSigningRule.cpp +++ b/saml/binding/impl/XMLSigningRule.cpp @@ -23,15 +23,11 @@ #include "internal.h" #include "exceptions.h" #include "binding/XMLSigningRule.h" -#include "saml1/core/Assertions.h" -#include "saml1/core/Protocols.h" -#include "saml2/core/Protocols.h" +#include "saml2/core/Assertions.h" #include "saml2/metadata/Metadata.h" #include "saml2/metadata/MetadataProvider.h" #include "signature/SignatureProfileValidator.h" -#include -#include #include using namespace opensaml::saml2md; @@ -47,128 +43,42 @@ namespace opensaml { } }; -pair XMLSigningRule::evaluate( - const XMLObject& message, - const GenericRequest* request, - const MetadataProvider* metadataProvider, - const QName* role, - const TrustEngine* trustEngine - ) const +void XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.XMLSigning"); log.debug("evaluating message signing policy"); - pair ret = pair(NULL,NULL); + if (!policy.getIssuerMetadata()) { + log.debug("ignoring message, no issuer metadata supplied"); + return; + } + else if (!policy.getTrustEngine()) { + log.debug("ignoring message, no TrustEngine supplied"); + return; + } - if (!metadataProvider || !role || !trustEngine) { - log.debug("ignoring message, no metadata or trust information supplied"); - return ret; + const SignableObject* signable = dynamic_cast(&message); + if (!signable || !signable->getSignature()) { + log.debug("ignoring unsigned or unrecognized message"); + return; } + log.debug("validating signature profile"); try { - 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 = getIssuerAndProtocol(message); - - auto_ptr issuer(issuerInfo.first); - if (!issuerInfo.first || !issuerInfo.second || - (issuer->getFormat() && !XMLString::equals(issuer->getFormat(), saml2::NameIDType::ENTITY))) { - log.warn("issuer identity not estabished, or was not an entityID"); - return ret; - } - - log.debug("searching metadata for message issuer..."); - const EntityDescriptor* entity = metadataProvider->getEntityDescriptor(issuer->getName()); - if (!entity) { - auto_ptr_char temp(issuer->getName()); - log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get()); - return ret; - } - - log.debug("matched message issuer against metadata, searching for applicable role..."); - const RoleDescriptor* roledesc=entity->getRoleDescriptor(*role, issuerInfo.second); - if (!roledesc) { - log.warn("unable to find compatible role (%s) in metadata", role->toString().c_str()); - return ret; - } - - if (!trustEngine->validate(*(signable->getSignature()), *roledesc, metadataProvider->getKeyResolver())) { - log.error("unable to verify signature on message with supplied trust engine"); - return ret; - } - - if (log.isDebugEnabled()) { - auto_ptr_char iname(entity->getEntityID()); - log.debug("message from (%s), signature verified", iname.get()); - } - - ret.first = issuer.release(); - ret.second = roledesc; + SignatureProfileValidator sigval; + sigval.validate(signable->getSignature()); } - catch (bad_cast&) { - // Just trap it. - log.warn("caught a bad_cast while extracting issuer"); + catch (ValidationException& ve) { + log.error("signature profile failed to validate: %s", ve.what()); + return; } - 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 - ); - } - } - } + if (!policy.getTrustEngine()->validate( + *(signable->getSignature()), *(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver() + )) { + log.error("unable to verify message signature with supplied trust engine"); + return; } - return pair(NULL,NULL); + + log.debug("signature verified against message issuer"); }