2 * Copyright 2001-2006 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.
20 * Shibboleth-specific PKIX-validation TrustEngine
24 #include "metadata/MetadataExt.h"
25 #include "security/PKIXTrustEngine.h"
27 #include <saml/saml2/metadata/Metadata.h>
28 #include <xmltooling/XMLToolingConfig.h>
29 #include <xmltooling/security/AbstractPKIXTrustEngine.h>
31 using namespace shibsp;
32 using namespace opensaml::saml2md;
33 using namespace xmlsignature;
34 using namespace xmltooling;
39 * Adapter between shibmd:KeyAuthority extension and the PKIXValidationInfoIterator interface.
41 class SHIBSP_API MetadataPKIXIterator : public AbstractPKIXTrustEngine::PKIXValidationInfoIterator
43 const XMLObject* m_obj;
44 const Extensions* m_extBlock;
45 const KeyAuthority* m_current;
46 vector<XMLObject*>::const_iterator m_iter;
49 vector<XSECCryptoX509*> m_certs;
50 vector<XSECCryptoX509CRL*> m_crls;
53 MetadataPKIXIterator(const RoleDescriptor& role, const KeyResolver& keyResolver)
54 : PKIXValidationInfoIterator(keyResolver), m_obj(role.getParent()), m_extBlock(NULL), m_current(NULL), m_certsOwned(false) {
57 virtual ~MetadataPKIXIterator() {
63 int getVerificationDepth() const {
64 pair<bool,int> vd = m_current->getVerifyDepth();
65 return vd.first ? vd.second : 1;
68 const vector<XSECCryptoX509*>& getTrustAnchors() const {
72 const vector<XSECCryptoX509CRL*>& getCRLs() const {
81 for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup<XSECCryptoX509>());
83 for_each(m_crls.begin(), m_crls.end(), xmltooling::cleanup<XSECCryptoX509CRL>());
88 class SHIBSP_DLLLOCAL PKIXTrustEngine : public xmltooling::AbstractPKIXTrustEngine
91 PKIXTrustEngine(const DOMElement* e=NULL) : AbstractPKIXTrustEngine(e) {}
92 virtual ~PKIXTrustEngine() {}
94 xmltooling::AbstractPKIXTrustEngine::PKIXValidationInfoIterator* getPKIXValidationInfoIterator(
95 const xmltooling::KeyInfoSource& pkixSource, const xmlsignature::KeyResolver& keyResolver
99 SHIBSP_DLLLOCAL PluginManager<TrustEngine,const DOMElement*>::Factory PKIXTrustEngineFactory;
101 TrustEngine* SHIBSP_DLLLOCAL PKIXTrustEngineFactory(const DOMElement* const & e)
\r
103 return new PKIXTrustEngine(e);
\r
107 void shibsp::registerPKIXTrustEngine()
109 XMLToolingConfig::getConfig().TrustEngineManager.registerFactory(SHIBBOLETH_PKIX_TRUSTENGINE, PKIXTrustEngineFactory);
112 AbstractPKIXTrustEngine::PKIXValidationInfoIterator* PKIXTrustEngine::getPKIXValidationInfoIterator(
113 const KeyInfoSource& pkixSource, const KeyResolver& keyResolver
116 return new MetadataPKIXIterator(dynamic_cast<const RoleDescriptor&>(pkixSource),keyResolver);
119 bool MetadataPKIXIterator::next()
121 // If we had an active block, look for another in the same block.
123 // Keep going until we hit the end of the block.
124 vector<XMLObject*>::const_iterator end = m_extBlock->getUnknownXMLObjects().end();
125 while (m_iter != end) {
126 // If we hit a KeyAuthority, remember it and signal.
127 if (m_current=dynamic_cast<KeyAuthority*>(*m_iter++)) {
133 // If we get here, we hit the end of this Extensions block.
134 // Climb a level, if possible.
135 m_obj = m_obj->getParent();
140 // If we get here, we try and find an Extensions block.
142 const EntityDescriptor* entity = dynamic_cast<const EntityDescriptor*>(m_obj);
144 m_extBlock = entity->getExtensions();
147 const EntitiesDescriptor* entities = dynamic_cast<const EntitiesDescriptor*>(m_obj);
149 m_extBlock = entities->getExtensions();
154 m_iter = m_extBlock->getUnknownXMLObjects().begin();
158 // Jump a level and try again.
159 m_obj = m_obj->getParent();
165 void MetadataPKIXIterator::populate()
167 // Dump anything old.
170 // We have to aggregate the resolution results.
171 KeyResolver::ResolvedCertificates certs;
172 XSECCryptoX509CRL* crl;
173 const vector<KeyInfo*>& keyInfos = m_current->getKeyInfos();
174 for (vector<KeyInfo*>::const_iterator k = keyInfos.begin(); k!=keyInfos.end(); ++k) {
175 vector<XSECCryptoX509*>::size_type count = m_keyResolver.resolveCertificates(*k,certs);
177 // Transfer certificates out of wrapper.
178 bool own = certs.release(m_certs);
179 if (!m_certs.empty() && own != m_certsOwned) {
180 // Ugh. We have a mashup of "owned" and "unowned".
181 // The ones we just added need to be removed and perhaps freed.
184 delete m_certs.back();
186 } while (--count > 0);
191 crl = m_keyResolver.resolveCRL(*k);
193 m_crls.push_back(crl);