X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FXMLSigningRule.cpp;h=1afb062c3104dabf5fb8421695bef351d7921ea0;hb=b1614d3c1fc1f4230ab2a123f43994127c25462c;hp=697c49a16dbc987db0518249065a9ffebdafa69b;hpb=932cfaae2176c2eba1a9938dc420591a9551a7f3;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/binding/impl/XMLSigningRule.cpp b/saml/binding/impl/XMLSigningRule.cpp index 697c49a..1afb062 100644 --- a/saml/binding/impl/XMLSigningRule.cpp +++ b/saml/binding/impl/XMLSigningRule.cpp @@ -22,9 +22,10 @@ #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 "signature/SignatureProfileValidator.h" @@ -36,17 +37,40 @@ 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() {} + + void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + + private: + bool m_errorsFatal; + }; + SecurityPolicyRule* SAML_DLLLOCAL XMLSigningRuleFactory(const DOMElement* const & e) { return new XMLSigningRule(e); } + + static const XMLCh errorsFatal[] = UNICODE_LITERAL_11(e,r,r,o,r,s,F,a,t,a,l); }; +XMLSigningRule::XMLSigningRule(const DOMElement* e) : m_errorsFatal(false) +{ + if (e) { + const XMLCh* flag = e->getAttributeNS(NULL, errorsFatal); + m_errorsFatal = (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"); if (!policy.getIssuerMetadata()) { log.debug("ignoring message, no issuer metadata supplied"); @@ -58,25 +82,30 @@ void XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* re } const SignableObject* signable = dynamic_cast(&message); - if (!signable || !signable->getSignature()) { - log.debug("ignoring unsigned or unrecognized message"); + if (!signable || !signable->getSignature()) return; - } log.debug("validating signature profile"); try { SignatureProfileValidator sigval; - sigval.validate(signable->getSignature()); + sigval.validateSignature(*(signable->getSignature())); } catch (ValidationException& ve) { log.error("signature profile failed to validate: %s", ve.what()); + if (m_errorsFatal) + throw; 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."); return; }