X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FXMLSigningRule.cpp;h=047de8684436bf8a75f1b071f5b89a76e0b35bff;hb=42780648201c0ef5d4c63ba7d79cea4af91eade9;hp=552cef88a12e453febfac70e7f4c908361a9f467;hpb=a22a5e16b79b7a40e139b75ebe8d95a9a6aed51c;p=shibboleth%2Fopensaml2.git diff --git a/saml/binding/impl/XMLSigningRule.cpp b/saml/binding/impl/XMLSigningRule.cpp index 552cef8..047de86 100644 --- a/saml/binding/impl/XMLSigningRule.cpp +++ b/saml/binding/impl/XMLSigningRule.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006 Internet2 + * 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. @@ -22,96 +22,97 @@ #include "internal.h" #include "exceptions.h" -#include "binding/XMLSigningRule.h" +#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 "security/TrustEngine.h" +#include "signature/SignatureProfileValidator.h" -#include -#include -#include +#include +#include using namespace opensaml::saml2md; using namespace opensaml; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; using namespace std; +using xmlsignature::SignatureException; + namespace opensaml { + class SAML_DLLLOCAL XMLSigningRule : public SecurityPolicyRule + { + public: + XMLSigningRule(const DOMElement* e); + virtual ~XMLSigningRule() {} + + const char* getType() const { + return XMLSIGNING_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + + private: + bool m_errorFatal; + }; + SecurityPolicyRule* SAML_DLLLOCAL XMLSigningRuleFactory(const DOMElement* const & e) { return new XMLSigningRule(e); } + + static const XMLCh errorFatal[] = UNICODE_LITERAL_10(e,r,r,o,r,F,a,t,a,l); }; -pair XMLSigningRule::evaluate( - const GenericRequest& request, - const XMLObject& message, - const MetadataProvider* metadataProvider, - const QName* role, - const opensaml::TrustEngine* trustEngine, - const MessageExtractor& extractor - ) const +XMLSigningRule::XMLSigningRule(const DOMElement* e) : m_errorFatal(false) +{ + if (e) { + const XMLCh* flag = e->getAttributeNS(NULL, errorFatal); + m_errorFatal = (flag && (*flag==chLatin_t || *flag==chDigit_1)); + } +} + +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 (!metadataProvider || !role || !trustEngine) { - log.debug("ignoring message, no metadata or trust information supplied"); - return ret; + if (!policy.getIssuerMetadata()) { + log.debug("ignoring message, no issuer metadata supplied"); + return; + } + + const SignatureTrustEngine* sigtrust; + if (!(sigtrust=dynamic_cast(policy.getTrustEngine()))) { + log.debug("ignoring message, no SignatureTrustEngine supplied"); + return; } + const SignableObject* signable = dynamic_cast(&message); + if (!signable || !signable->getSignature()) + return; + + log.debug("validating signature profile"); try { - const RootObject& root = dynamic_cast(message); - if (!root.getSignature()) { - log.debug("ignoring unsigned message"); - return ret; - } - - log.debug("extracting issuer from message"); - pair issuerInfo = extractor.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(*(root.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.validateSignature(*(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()); + if (m_errorFatal) + throw; + return; } - return ret; + + // Set up criteria object. + MetadataCredentialCriteria cc(*(policy.getIssuerMetadata())); + + if (!sigtrust->validate(*(signable->getSignature()), *(policy.getMetadataProvider()), &cc)) { + log.error("unable to verify message signature with supplied trust engine"); + if (m_errorFatal) + throw SecurityPolicyException("Message was signed, but signature could not be verified."); + return; + } + + log.debug("signature verified against message issuer"); + policy.setAuthenticated(true); }