2 * Copyright 2001-2005 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /* BasicTrust.cpp - a trust implementation that relies solely on standard SAML metadata
27 #include <openssl/x509.h>
28 #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
30 using namespace shibboleth::logging;
31 using namespace shibboleth;
35 IPlugIn* BasicTrustFactory(const DOMElement* e)
37 return new BasicTrust(e);
40 static const XMLCh resolver[] =
41 { chLatin_K, chLatin_e, chLatin_y, chLatin_I, chLatin_n, chLatin_f, chLatin_o,
42 chLatin_R, chLatin_e, chLatin_s, chLatin_o, chLatin_l, chLatin_v, chLatin_e, chLatin_r, chNull
44 static const XMLCh type[] =
45 { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };
47 static const XMLCh debug[] =
48 { chLatin_d, chLatin_e, chLatin_b, chLatin_u, chLatin_g, chNull };
50 BasicTrust::BasicTrust(const DOMElement* e) : m_debug(false)
53 const XMLCh* flag=e->getAttributeNS(NULL,debug);
54 if (flag && (*flag==chLatin_t || *flag==chDigit_1))
57 // Find any KeyResolver plugins.
58 e=saml::XML::getFirstChildElement(e);
60 if (!XMLString::compareString(resolver,e->getLocalName()) && e->hasAttributeNS(NULL,type)) {
62 auto_ptr_char temp(e->getAttributeNS(NULL,type));
63 m_resolvers.push_back(KeyInfoResolver::getInstance(temp.get(),e));
65 catch (SAMLException& ex) {
66 Category::getInstance(SHIB_LOGCAT".Trust.Basic").error(
67 "caught SAML exception building KeyInfoResolver plugin: %s",ex.what()
72 Category::getInstance(SHIB_LOGCAT".Trust.Basic").error("caught unknown exception building KeyInfoResolver plugin");
76 e=saml::XML::getNextSiblingElement(e);
78 m_resolvers.push_back(KeyInfoResolver::getInstance(e));
81 BasicTrust::~BasicTrust()
83 for (vector<KeyInfoResolver*>::iterator i=m_resolvers.begin(); i!=m_resolvers.end(); i++)
87 bool BasicTrust::validate(void* certEE, const Iterator<void*>& certChain, const IRoleDescriptor* role, bool checkName)
90 saml::NDC ndc("validate");
92 Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Basic");
95 log.error("no certificate provided for comparison");
100 log.warn("running in debug mode, we accept anything!");
104 // The new "basic" trust implementation relies solely on certificates living within the
105 // role interface to verify the EE certificate.
107 log.debug("comparing certificate to KeyDescriptors");
108 Iterator<const IKeyDescriptor*> kd_i=role->getKeyDescriptors();
109 while (kd_i.hasNext()) {
110 const IKeyDescriptor* kd=kd_i.next();
111 if (kd->getUse()==IKeyDescriptor::encryption)
113 DSIGKeyInfoList* KIL=kd->getKeyInfo();
116 Iterator<KeyInfoResolver*> resolvers(m_resolvers);
117 while (resolvers.hasNext()) {
118 XSECCryptoX509* cert=resolvers.next()->resolveCert(KIL);
120 log.debug("KeyDescriptor resolved into a certificate, comparing it...");
121 if (cert->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
122 log.warn("only the OpenSSL XSEC provider is supported");
125 else if (!X509_cmp(reinterpret_cast<X509*>(certEE),static_cast<OpenSSLCryptoX509*>(cert)->getOpenSSLX509())) {
126 log.info("certificate match found in KeyDescriptor");
130 log.debug("certificate did not match");
135 log.debug("failed to find an exact match for certificate in KeyDescriptors");
139 bool BasicTrust::validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role, ITrust* certValidator)
142 saml::NDC ndc("validate");
144 Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Basic");
147 log.warn("running in debug mode, we accept anything!");
151 // The new "basic" trust implementation relies solely on keys living within the
152 // role interface to verify the token. No indirection of any sort is allowed,
153 // unless an alternate key resolver is involved.
155 log.debug("validating signature with KeyDescriptors");
156 Iterator<const IKeyDescriptor*> kd_i=role->getKeyDescriptors();
157 while (kd_i.hasNext()) {
158 const IKeyDescriptor* kd=kd_i.next();
159 if (kd->getUse()==IKeyDescriptor::encryption)
161 DSIGKeyInfoList* KIL=kd->getKeyInfo();
164 Iterator<KeyInfoResolver*> resolvers(m_resolvers);
165 while (resolvers.hasNext()) {
166 XSECCryptoKey* key=((XSECKeyInfoResolver*)*resolvers.next())->resolveKey(KIL);
168 log.debug("KeyDescriptor resolved into a key, trying it...");
171 log.info("signature verified with KeyDescriptor");
174 catch (SAMLException& e) {
175 log.debug("verification with KeyDescriptor failed: %s", e.what());
181 log.debug("failed to validate signature with KeyDescriptors");