X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FSimpleSigningRule.cpp;h=a48f040f212868ab50e926e217193a8d45ab2999;hb=c072b75e6f6e05e24a1c35b952008b38d0d375c1;hp=82f98d9b35f0f6a77d94016652d7f4e05667d9f8;hpb=bf32f9265ac717ee1537ec442e5a2d54e169d486;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/binding/impl/SimpleSigningRule.cpp b/saml/binding/impl/SimpleSigningRule.cpp index 82f98d9..a48f040 100644 --- a/saml/binding/impl/SimpleSigningRule.cpp +++ b/saml/binding/impl/SimpleSigningRule.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Internet2 + * Copyright 2001-2009 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,19 +22,23 @@ #include "internal.h" #include "exceptions.h" -#include "binding/HTTPRequest.h" +#include "binding/SecurityPolicy.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 #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::KeyInfo; @@ -47,13 +51,16 @@ namespace opensaml { SimpleSigningRule(const DOMElement* e); virtual ~SimpleSigningRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return SIMPLESIGNING_POLICY_RULE; + } + bool evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; private: // Appends a raw parameter=value pair to the string. static bool appendParameter(string& s, const char* data, const char* name); - bool m_errorsFatal; + bool m_errorFatal; }; SecurityPolicyRule* SAML_DLLLOCAL SimpleSigningRuleFactory(const DOMElement* const & e) @@ -61,7 +68,7 @@ namespace opensaml { return new SimpleSigningRule(e); } - static const XMLCh errorsFatal[] = UNICODE_LITERAL_11(e,r,r,o,r,s,F,a,t,a,l); + static const XMLCh errorFatal[] = UNICODE_LITERAL_10(e,r,r,o,r,F,a,t,a,l); }; bool SimpleSigningRule::appendParameter(string& s, const char* data, const char* name) @@ -79,39 +86,41 @@ bool SimpleSigningRule::appendParameter(string& s, const char* data, const char* return true; } -SimpleSigningRule::SimpleSigningRule(const DOMElement* e) : m_errorsFatal(false) +SimpleSigningRule::SimpleSigningRule(const DOMElement* e) : m_errorFatal(false) { if (e) { - const XMLCh* flag = e->getAttributeNS(NULL, errorsFatal); - m_errorsFatal = (flag && (*flag==chLatin_t || *flag==chDigit_1)); + const XMLCh* flag = e->getAttributeNS(NULL, errorFatal); + m_errorFatal = (flag && (*flag==chLatin_t || *flag==chDigit_1)); } } -void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +bool SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SimpleSigning"); if (!policy.getIssuerMetadata()) { log.debug("ignoring message, no issuer metadata supplied"); - return; + return false; } - else if (!policy.getTrustEngine()) { - log.debug("ignoring message, no TrustEngine supplied"); - return; + + const SignatureTrustEngine* sigtrust; + if (!(sigtrust=dynamic_cast(policy.getTrustEngine()))) { + log.debug("ignoring message, no SignatureTrustEngine supplied"); + return false; } const HTTPRequest* httpRequest = dynamic_cast(request); if (!request || !httpRequest) - return; + return false; const char* signature = request->getParameter("Signature"); if (!signature) - return; + return false; const char* sigAlgorithm = request->getParameter("SigAlg"); if (!sigAlgorithm) { log.error("SigAlg parameter not found, no way to verify the signature"); - return; + return false; } string input; @@ -139,26 +148,34 @@ void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* // Serializing the XMLObject doesn't guarantee the signature will verify (this is // why XMLSignature exists, and why this isn't really "simpler"). - unsigned int x; + xsecsize_t x; pch = httpRequest->getParameter("SAMLRequest"); if (pch) { XMLByte* decoded=Base64::decode(reinterpret_cast(pch),&x); if (!decoded) { log.warn("unable to decode base64 in POST binding message"); - return; + return false; } input = string("SAMLRequest=") + reinterpret_cast(decoded); +#ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE XMLString::release(&decoded); +#else + XMLString::release((char**)&decoded); +#endif } else { pch = httpRequest->getParameter("SAMLResponse"); XMLByte* decoded=Base64::decode(reinterpret_cast(pch),&x); if (!decoded) { log.warn("unable to decode base64 in POST binding message"); - return; + return false; } input = string("SAMLResponse=") + reinterpret_cast(decoded); +#ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE XMLString::release(&decoded); +#else + XMLString::release((char**)&decoded); +#endif } pch = httpRequest->getParameter("RelayState"); @@ -171,33 +188,47 @@ void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* KeyInfo* keyInfo=NULL; pch = request->getParameter("KeyInfo"); if (pch) { - try { - istringstream kstrm(pch); - DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(kstrm); - XercesJanitor janitor(doc); - XMLObject* kxml = XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true); - janitor.release(); - if (!(keyInfo=dynamic_cast(kxml))) - delete kxml; + xsecsize_t x; + XMLByte* decoded=Base64::decode(reinterpret_cast(pch),&x); + if (decoded) { + try { + istringstream kstrm((char*)decoded); + DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(kstrm); + XercesJanitor janitor(doc); + XMLObject* kxml = XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true); + janitor.release(); + if (!(keyInfo=dynamic_cast(kxml))) + delete kxml; + } + catch (XMLToolingException& ex) { + log.warn("Failed to load KeyInfo from message: %s", ex.what()); + } +#ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE + XMLString::release(&decoded); +#else + XMLString::release((char**)&decoded); +#endif } - catch (XMLToolingException& ex) { - log.warn("Failed to load KeyInfo from message: %s", ex.what()); + else { + log.warn("Failed to load KeyInfo from message: Unable to decode base64-encoded KeyInfo."); } } 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. + MetadataCredentialCriteria cc(*(policy.getIssuerMetadata())); + cc.setXMLAlgorithm(alg.get()); + + if (!sigtrust->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."); - return; + if (m_errorFatal) + throw SecurityPolicyException("Message was signed, but signature could not be verified."); + return false; } log.debug("signature verified against message issuer"); - policy.setSecure(true); + policy.setAuthenticated(true); + return true; }