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;
32 using namespace log4cpp;
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 BasicTrust::BasicTrust(const DOMElement* e)
49 // Find any KeyResolver plugins.
50 e=saml::XML::getFirstChildElement(e);
52 if (!XMLString::compareString(resolver,e->getLocalName()) && e->hasAttributeNS(NULL,type)) {
54 auto_ptr_char temp(e->getAttributeNS(NULL,type));
55 m_resolvers.push_back(KeyInfoResolver::getInstance(temp.get(),e));
57 catch (SAMLException& ex) {
58 Category::getInstance(SHIB_LOGCAT".Trust.Basic").error(
59 "caught SAML exception building KeyInfoResolver plugin: %s",ex.what()
64 Category::getInstance(SHIB_LOGCAT".Trust.Basic").error("caught unknown exception building KeyInfoResolver plugin");
68 e=saml::XML::getNextSiblingElement(e);
70 m_resolvers.push_back(KeyInfoResolver::getInstance(e));
73 BasicTrust::~BasicTrust()
75 for (vector<KeyInfoResolver*>::iterator i=m_resolvers.begin(); i!=m_resolvers.end(); i++)
79 bool BasicTrust::validate(void* certEE, const Iterator<void*>& certChain, const IRoleDescriptor* role, bool checkName)
82 saml::NDC ndc("validate");
84 Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Basic");
87 log.error("no certificate provided for comparison");
91 // The new "basic" trust implementation relies solely on certificates living within the
92 // role interface to verify the EE certificate.
94 log.debug("comparing certificate to KeyDescriptors");
95 Iterator<const IKeyDescriptor*> kd_i=role->getKeyDescriptors();
96 while (kd_i.hasNext()) {
97 const IKeyDescriptor* kd=kd_i.next();
98 if (kd->getUse()==IKeyDescriptor::encryption)
100 DSIGKeyInfoList* KIL=kd->getKeyInfo();
103 Iterator<KeyInfoResolver*> resolvers(m_resolvers);
104 while (resolvers.hasNext()) {
105 XSECCryptoX509* cert=resolvers.next()->resolveCert(KIL);
107 log.debug("KeyDescriptor resolved into a certificate, comparing it...");
108 if (cert->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
109 log.warn("only the OpenSSL XSEC provider is supported");
112 else if (!X509_cmp(reinterpret_cast<X509*>(certEE),static_cast<OpenSSLCryptoX509*>(cert)->getOpenSSLX509())) {
113 log.info("certificate match found in KeyDescriptor");
117 log.debug("certificate did not match");
122 log.debug("failed to find an exact match for certificate in KeyDescriptors");
126 bool BasicTrust::validate(const saml::SAMLSignedObject& token, const IRoleDescriptor* role, ITrust* certValidator)
129 saml::NDC ndc("validate");
131 Category& log=Category::getInstance(SHIB_LOGCAT".Trust.Basic");
133 // The new "basic" trust implementation relies solely on keys living within the
134 // role interface to verify the token. No indirection of any sort is allowed,
135 // unless an alternate key resolver is involved.
137 log.debug("validating signature with KeyDescriptors");
138 Iterator<const IKeyDescriptor*> kd_i=role->getKeyDescriptors();
139 while (kd_i.hasNext()) {
140 const IKeyDescriptor* kd=kd_i.next();
141 if (kd->getUse()!=IKeyDescriptor::signing)
143 DSIGKeyInfoList* KIL=kd->getKeyInfo();
146 Iterator<KeyInfoResolver*> resolvers(m_resolvers);
147 while (resolvers.hasNext()) {
148 XSECCryptoKey* key=((XSECKeyInfoResolver*)*resolvers.next())->resolveKey(KIL);
150 log.debug("KeyDescriptor resolved into a key, trying it...");
153 log.info("signature verified with KeyDescriptor");
156 catch (SAMLException& e) {
157 log.debug("verification with KeyDescriptor failed: %s", e.what());
163 log.debug("failed to validate signature with KeyDescriptors");