X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FClientCertAuthRule.cpp;h=5d5715beb337f1622f1ca69eb23b923ac82eb469;hb=c072b75e6f6e05e24a1c35b952008b38d0d375c1;hp=f1850903fe1c6e88c267d3c04586b2229186e573;hpb=bf32f9265ac717ee1537ec442e5a2d54e169d486;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/binding/impl/ClientCertAuthRule.cpp b/saml/binding/impl/ClientCertAuthRule.cpp index f185090..5d5715b 100644 --- a/saml/binding/impl/ClientCertAuthRule.cpp +++ b/saml/binding/impl/ClientCertAuthRule.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,64 +22,92 @@ #include "internal.h" #include "exceptions.h" +#include "binding/SecurityPolicy.h" #include "binding/SecurityPolicyRule.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; namespace opensaml { class SAML_DLLLOCAL ClientCertAuthRule : public SecurityPolicyRule { public: - ClientCertAuthRule(const DOMElement* e) {} + ClientCertAuthRule(const DOMElement* e); virtual ~ClientCertAuthRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return CLIENTCERTAUTH_POLICY_RULE; + } + bool evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + + private: + bool m_errorFatal; }; SecurityPolicyRule* SAML_DLLLOCAL ClientCertAuthRuleFactory(const DOMElement* const & e) { return new ClientCertAuthRule(e); } + + static const XMLCh errorFatal[] = UNICODE_LITERAL_10(e,r,r,o,r,F,a,t,a,l); }; -void ClientCertAuthRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +ClientCertAuthRule::ClientCertAuthRule(const DOMElement* e) : m_errorFatal(false) +{ + if (e) { + const XMLCh* flag = e->getAttributeNS(NULL, errorFatal); + m_errorFatal = (flag && (*flag==chLatin_t || *flag==chDigit_1)); + } +} + +bool ClientCertAuthRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.ClientCertAuth"); if (!request) - return; + return false; if (!policy.getIssuerMetadata()) { log.debug("ignoring message, no issuer metadata supplied"); - return; + return false; } const X509TrustEngine* x509trust; if (!(x509trust=dynamic_cast(policy.getTrustEngine()))) { log.debug("ignoring message, no X509TrustEngine supplied"); - return; + return false; } - const std::vector& chain = request->getClientCertificates(); + const vector& chain = request->getClientCertificates(); if (chain.empty()) - return; + return false; - if (!x509trust->validate(chain.front(), chain, *(policy.getIssuerMetadata()), true, - 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()); + cc.setUsage(Credential::TLS_CREDENTIAL); + + if (!x509trust->validate(chain.front(), chain, *(policy.getMetadataProvider()), &cc)) { + if (m_errorFatal) + throw SecurityPolicyException("Client certificate supplied, but could not be verified."); log.error("unable to verify certificate chain with supplied trust engine"); - return; + return false; } log.debug("client certificate verified against message issuer"); - policy.setSecure(true); + policy.setAuthenticated(true); + return true; }