From f4f8c0b26fb6094729fab0899f19ef189877bbe4 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Wed, 27 Dec 2006 23:28:24 +0000 Subject: [PATCH] PKIX trust engine using metadata exts. --- shibsp/Makefile.am | 8 +- shibsp/MetadataExt.h | 2 +- shibsp/PKIXTrustEngine.cpp | 208 +++++++++++++++++++++++++++++++++++++++++++++ shibsp/PKIXTrustEngine.h | 38 +++++++++ shibsp/SPConfig.cpp | 2 + shibsp/shibsp.vcproj | 8 ++ 6 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 shibsp/PKIXTrustEngine.cpp create mode 100644 shibsp/PKIXTrustEngine.h diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am index a2f9493..24dc1a9 100644 --- a/shibsp/Makefile.am +++ b/shibsp/Makefile.am @@ -15,6 +15,7 @@ libshibspinclude_HEADERS = \ ListenerService.h \ MetadataExt.h \ paths.h \ + PKIXTrustEngine.h \ PropertySet.h \ version.h \ SocketListener.h \ @@ -30,11 +31,12 @@ libshibsp_la_SOURCES = \ ListenerService.cpp \ MetadataExtImpl.cpp \ MetadataExtSchemaValidators.cpp \ + PKIXTrustEngine.cpp \ + SPConfig.cpp \ + SPConstants.cpp \ SocketListener.cpp \ TCPListener.cpp \ - UnixListener.cpp \ - SPConfig.cpp \ - SPConstants.cpp + UnixListener.cpp # this is different from the project version # http://sources.redhat.com/autobook/autobook/autobook_91.html diff --git a/shibsp/MetadataExt.h b/shibsp/MetadataExt.h index 7473025..e0a0d6d 100644 --- a/shibsp/MetadataExt.h +++ b/shibsp/MetadataExt.h @@ -15,7 +15,7 @@ */ /** - * @file shibsp/MetadataExt + * @file shibsp/MetadataExt.h * * XMLObjects representing Shibboleth metadata extensions */ diff --git a/shibsp/PKIXTrustEngine.cpp b/shibsp/PKIXTrustEngine.cpp new file mode 100644 index 0000000..c277fb8 --- /dev/null +++ b/shibsp/PKIXTrustEngine.cpp @@ -0,0 +1,208 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * PKIXTrustEngine.cpp + * + * Shibboleth-specific PKIX-validation TrustEngine + */ + +#include "internal.h" +#include "MetadataExt.h" +#include "PKIXTrustEngine.h" + +#include +#include +#include + +using namespace shibsp; +using namespace opensaml::saml2md; +using namespace xmlsignature; +using namespace xmltooling; +using namespace std; + +namespace shibsp { + /** + * Adapter between shibmd:KeyAuthority extension and the PKIXValidationInfoIterator interface. + */ + class SHIBSP_API MetadataPKIXIterator : public AbstractPKIXTrustEngine::PKIXValidationInfoIterator + { + const XMLObject* m_obj; + const Extensions* m_extBlock; + const KeyAuthority* m_current; + vector::const_iterator m_iter; + + bool m_certsOwned; + vector m_certs; + vector m_crls; + + public: + MetadataPKIXIterator(const RoleDescriptor& role, const KeyResolver& keyResolver) + : PKIXValidationInfoIterator(keyResolver), m_obj(role.getParent()), m_extBlock(NULL), m_current(NULL), m_certsOwned(false) { + } + + virtual ~MetadataPKIXIterator() { + clear(); + } + + bool next(); + + int getVerificationDepth() const { + pair vd = m_current->getVerifyDepth(); + return vd.first ? vd.second : 1; + } + + const vector& getTrustAnchors() const { + return m_certs; + } + + const vector& getCRLs() const { + return m_crls; + } + + private: + void populate(); + + void clear() { + if (m_certsOwned) + for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup()); + m_certs.clear(); + for_each(m_crls.begin(), m_crls.end(), xmltooling::cleanup()); + m_crls.clear(); + } + }; + + class SHIBSP_DLLLOCAL PKIXTrustEngine : public xmltooling::AbstractPKIXTrustEngine + { + public: + PKIXTrustEngine(const DOMElement* e=NULL) : AbstractPKIXTrustEngine(e) {} + virtual ~PKIXTrustEngine() {} + + xmltooling::AbstractPKIXTrustEngine::PKIXValidationInfoIterator* getPKIXValidationInfoIterator( + const xmltooling::KeyInfoSource& pkixSource, const xmlsignature::KeyResolver& keyResolver + ) const; + }; + + SHIBSP_DLLLOCAL PluginManager::Factory PKIXTrustEngineFactory; + + TrustEngine* SHIBSP_DLLLOCAL PKIXTrustEngineFactory(const DOMElement* const & e) + { + return new PKIXTrustEngine(e); + } +}; + +void shibsp::registerPKIXTrustEngine() +{ + XMLToolingConfig::getConfig().TrustEngineManager.registerFactory(SHIBBOLETH_PKIX_TRUSTENGINE, PKIXTrustEngineFactory); +} + +AbstractPKIXTrustEngine::PKIXValidationInfoIterator* PKIXTrustEngine::getPKIXValidationInfoIterator( + const KeyInfoSource& pkixSource, const KeyResolver& keyResolver + ) const +{ + return new MetadataPKIXIterator(dynamic_cast(pkixSource),keyResolver); +} + +bool MetadataPKIXIterator::next() +{ + // If we had a KeyAuthority, look for another in the same block. + if (m_current) { + // Keep going until we hit the end of the Extensions. + vector::const_iterator end = m_extBlock->getUnknownXMLObjects().end(); + while (++m_iter != end) { + // If we hit another KeyAuthority, remember it and signal. + if (m_current=dynamic_cast(*m_iter)) { + populate(); + return true; + } + } + + // If we get here, we hit the end of this Extensions block. + // Climb a level, if possible. + m_obj = m_extBlock->getParent()->getParent(); + m_current = NULL; + m_extBlock = NULL; + } + + // If we get here, we try and find an Extensions block. + if (m_obj) { + const EntityDescriptor* entity = dynamic_cast(m_obj); + if (entity) { + m_extBlock = entity->getExtensions(); + } + else { + const EntitiesDescriptor* entities = dynamic_cast(m_obj); + if (entities) { + m_extBlock = entities->getExtensions(); + } + else { + // Jump a level and try again. + m_obj = m_obj->getParent(); + return next(); + } + } + } + + if (m_extBlock) { + // We're starting over at a new block. + const vector& exts = m_extBlock->getUnknownXMLObjects(); + for (m_iter=exts.begin(); m_iter!=exts.end(); ++m_iter) { + // If we hit a KeyAuthority, remember it and signal. + if (m_current=dynamic_cast(*m_iter)) { + populate(); + return true; + } + } + + // Jump a level and try again. + m_obj = m_obj->getParent(); + return next(); + } + + return false; +} + +void MetadataPKIXIterator::populate() +{ + // Dump anything old. + clear(); + + // We have to aggregate the resolution results. + KeyResolver::ResolvedCertificates certs; + XSECCryptoX509CRL* crl; + const vector& keyInfos = m_current->getKeyInfos(); + for (vector::const_iterator k = keyInfos.begin(); k!=keyInfos.end(); ++k) { + vector::size_type count = m_keyResolver.resolveCertificates(*k,certs); + if (count > 0) { + // Transfer certificates out of wrapper. + bool own = certs.release(m_certs); + if (!m_certs.empty() && own != m_certsOwned) { + // Ugh. We have a mashup of "owned" and "unowned". + // The ones we just added need to be removed and perhaps freed. + do { + if (own) + delete m_certs.back(); + m_certs.pop_back(); + } while (--count > 0); + } + m_certsOwned = own; + } + + crl = m_keyResolver.resolveCRL(*k); + if (crl) + m_crls.push_back(crl); + } +} diff --git a/shibsp/PKIXTrustEngine.h b/shibsp/PKIXTrustEngine.h new file mode 100644 index 0000000..49cd2c0 --- /dev/null +++ b/shibsp/PKIXTrustEngine.h @@ -0,0 +1,38 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file shibsp/PKIXTrustEngine.h + * + * Shibboleth-specific PKIX-validation TrustEngine + */ + +#ifndef __shibsp_pkixtrust_h__ +#define __shibsp_pkixtrust_h__ + +#include + +namespace shibsp { + /** + * Registers trust engine plugin. + */ + void SHIBSP_API registerPKIXTrustEngine(); + + /** TrustEngine based on Shibboleth PKIX metadata extension. */ + #define SHIBBOLETH_PKIX_TRUSTENGINE "edu.internet2.middleware.shibboleth.security.provider.PKIXTrustEngine" +}; + +#endif /* __shibsp_pkixtrust_h__ */ diff --git a/shibsp/SPConfig.cpp b/shibsp/SPConfig.cpp index 34728fb..9e37be3 100644 --- a/shibsp/SPConfig.cpp +++ b/shibsp/SPConfig.cpp @@ -25,6 +25,7 @@ #include "exceptions.h" #include "ListenerService.h" #include "MetadataExt.h" +#include "PKIXTrustEngine.h" #include "SPConfig.h" #include @@ -89,6 +90,7 @@ bool SPInternalConfig::init(const char* catalog_path) registerListenerServices(); registerMetadataExtClasses(); + registerPKIXTrustEngine(); log.info("library initialization complete"); return true; diff --git a/shibsp/shibsp.vcproj b/shibsp/shibsp.vcproj index 022e889..ba0d212 100644 --- a/shibsp/shibsp.vcproj +++ b/shibsp/shibsp.vcproj @@ -205,6 +205,10 @@ > + + @@ -251,6 +255,10 @@ > + + -- 2.1.4