From 6f8dbf9e8e5519805cf28f59060b06f585e03a84 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Mon, 15 May 2006 02:23:31 +0000 Subject: [PATCH] Integrated credential resolver API with signing context. --- xmltooling/Makefile.am | 1 + xmltooling/XMLObject.h | 6 +- xmltooling/io/AbstractXMLObjectMarshaller.cpp | 4 +- xmltooling/signature/Signature.h | 2 +- xmltooling/signature/SigningContext.h | 37 ++++------ xmltooling/signature/impl/XMLSecSignatureImpl.cpp | 27 +++++--- xmltooling/util/CredentialResolver.h | 82 +++++++++++++++++++++++ xmltoolingtest/SignatureTest.h | 16 +++-- 8 files changed, 131 insertions(+), 44 deletions(-) create mode 100644 xmltooling/util/CredentialResolver.h diff --git a/xmltooling/Makefile.am b/xmltooling/Makefile.am index 044e60b..c5126d9 100644 --- a/xmltooling/Makefile.am +++ b/xmltooling/Makefile.am @@ -53,6 +53,7 @@ siginclude_HEADERS = \ signature/VerifyingContext.h utilinclude_HEADERS = \ + util/CredentialResolver.h \ util/DateTime.h \ util/NDC.h \ util/ParserPool.h \ diff --git a/xmltooling/XMLObject.h b/xmltooling/XMLObject.h index 89466a5..d32d155 100644 --- a/xmltooling/XMLObject.h +++ b/xmltooling/XMLObject.h @@ -20,7 +20,7 @@ * Abstract interface to objects that can be manipulated in and out of XML form. */ -#if !defined(__xmltooling_xmlobj_h__) +#ifndef __xmltooling_xmlobj_h__ #define __xmltooling_xmlobj_h__ #include @@ -67,12 +67,12 @@ namespace xmltooling { * @param sig a signature object * @param ctx the signing context to associate with the signature */ - MarshallingContext(xmlsignature::Signature* sig, const xmlsignature::SigningContext* ctx) { + MarshallingContext(xmlsignature::Signature* sig, xmlsignature::SigningContext* ctx) { m_signingContexts.push_back(std::make_pair(sig,ctx)); } /** Array of signing contexts, keyed off of the associated Signature */ - std::vector< std::pair > m_signingContexts; + std::vector< std::pair > m_signingContexts; #endif }; diff --git a/xmltooling/io/AbstractXMLObjectMarshaller.cpp b/xmltooling/io/AbstractXMLObjectMarshaller.cpp index 5dc6661..8567d59 100644 --- a/xmltooling/io/AbstractXMLObjectMarshaller.cpp +++ b/xmltooling/io/AbstractXMLObjectMarshaller.cpp @@ -152,9 +152,9 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(DOMElement* parentElement, Mar } #ifndef XMLTOOLING_NO_XMLSEC - class _signit : public unary_function&, void> { + class _signit : public unary_function&, void> { public: - void operator()(const pair& p) const { + void operator()(const pair& p) const { p.first->sign(*(p.second)); } }; diff --git a/xmltooling/signature/Signature.h b/xmltooling/signature/Signature.h index 8717c6f..3dba1b4 100644 --- a/xmltooling/signature/Signature.h +++ b/xmltooling/signature/Signature.h @@ -68,7 +68,7 @@ namespace xmlsignature { * @param ctx the signing context that determines the signature's content * @throws SignatureException thrown if the signing operation fails */ - virtual void sign(const SigningContext& ctx)=0; + virtual void sign(SigningContext& ctx)=0; /** * Verifies an XML signature based on the supplied context. diff --git a/xmltooling/signature/SigningContext.h b/xmltooling/signature/SigningContext.h index 520e2d3..f04b724 100644 --- a/xmltooling/signature/SigningContext.h +++ b/xmltooling/signature/SigningContext.h @@ -24,6 +24,7 @@ #define __xmltooling_signctx_h__ #include +#include #include #include @@ -46,44 +47,34 @@ namespace xmlsignature { /** * Given a "blank" native signature, asks the context to define the - * appropriate signature transforms, references, etc. - * This method MAY attach ds:KeyInfo information, or a set of X.509 - * certificates can be returned from the SigningContext::getX509Certificates() - * method instead. + * appropriate signature transforms, references, etc. The context + * should return true iff the necessary ds:KeyInfo information was + * also attached. * * @param sig native signature interface + * @return indicator whether ds:KeyInfo was created by context */ - virtual void createSignature(DSIGSignature* sig) const=0; + virtual bool createSignature(DSIGSignature* sig)=0; /** - * Gets a reference to a collection of certificates to append to - * the ds:KeyInfo element in a ds:X509Data chain. - * The certificate corresponding to the signing key SHOULD be - * first, followed by any additional intermediates to append. + * Gets a reference to a credential resolver. + * The resolver's certificates will be included in the signature only + * if the context returns false when creating the signature and returns + * NULL from the getKeyInfo() method. * - * @return an immutable collection of certificates to embed + * + * @return a resolver to the credentials to sign with */ - virtual const std::vector* getX509Certificates() const=0; + virtual xmltooling::CredentialResolver& getCredentialResolver()=0; /** * Gets a KeyInfo structure to embed. * Ownership of the object MUST be transferred to the caller. - * This method will only be called if no certificates are returned from - * the getX509Certificates() method. * * @return pointer to a KeyInfo structure, will be freed by caller */ - virtual KeyInfo* getKeyInfo() const=0; + virtual KeyInfo* getKeyInfo()=0; - /** - * Gets the signing key to use. - * Must be compatible with the intended signature algorithm. Ownership of the key - * MUST be transferred to the caller. - * - * @return pointer to a signing key, will be freed by caller - */ - virtual XSECCryptoKey* getSigningKey() const=0; - protected: SigningContext() {} }; diff --git a/xmltooling/signature/impl/XMLSecSignatureImpl.cpp b/xmltooling/signature/impl/XMLSecSignatureImpl.cpp index 2d97b94..cf3afd2 100644 --- a/xmltooling/signature/impl/XMLSecSignatureImpl.cpp +++ b/xmltooling/signature/impl/XMLSecSignatureImpl.cpp @@ -71,7 +71,7 @@ namespace xmlsignature { void setCanonicalizationMethod(const XMLCh* c14n) { m_c14n = prepareForAssignment(m_c14n,c14n); } void setSignatureAlgorithm(const XMLCh* sm) { m_sm = prepareForAssignment(m_sm,sm); } - void sign(const SigningContext& ctx); + void sign(SigningContext& ctx); void verify(const VerifyingContext& ctx) const; private: @@ -137,7 +137,7 @@ public: } }; -void XMLSecSignatureImpl::sign(const SigningContext& ctx) +void XMLSecSignatureImpl::sign(SigningContext& ctx) { Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature"); log.debug("applying signature"); @@ -147,22 +147,29 @@ void XMLSecSignatureImpl::sign(const SigningContext& ctx) try { log.debug("creating signature content"); - ctx.createSignature(m_signature); - const std::vector* certs=ctx.getX509Certificates(); - if (certs && !certs->empty()) { - DSIGKeyInfoX509* x509Data=m_signature->appendX509Data(); - for_each(certs->begin(),certs->end(),bind1st(_addcert(),x509Data)); - } - else { + CredentialResolver& cr=ctx.getCredentialResolver(); + if (!ctx.createSignature(m_signature)) { auto_ptr keyInfo(ctx.getKeyInfo()); if (keyInfo.get()) { DOMElement* domElement=keyInfo->marshall(m_signature->getParentDocument()); getDOM()->appendChild(domElement); } + else { + Locker locker1(cr); + const std::vector* certs=cr.getX509Certificates(); + if (certs && !certs->empty()) { + DSIGKeyInfoX509* x509Data=m_signature->appendX509Data(); + for_each(certs->begin(),certs->end(),bind1st(_addcert(),x509Data)); + } + } } log.debug("computing signature"); - m_signature->setSigningKey(ctx.getSigningKey()); + Locker locker2(cr); + XSECCryptoKey* key=cr.getPrivateKey(); + if (!key) + throw SignatureException(string("Unable to obtain signing key from CredentialResolver (") + cr.getId() + ")"); + m_signature->setSigningKey(key->clone()); m_signature->sign(); } catch(XSECException& e) { diff --git a/xmltooling/util/CredentialResolver.h b/xmltooling/util/CredentialResolver.h new file mode 100644 index 0000000..f325b4c --- /dev/null +++ b/xmltooling/util/CredentialResolver.h @@ -0,0 +1,82 @@ +/* + * 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 CredentialResolver.h + * + * Provides access to keys and certificates. + */ + +#if !defined(__xmltooling_credres_h__) && !defined(XMLTOOLING_NO_XMLSEC) +#define __xmltooling_credres_h__ + +#include + +#include +#include +#include + +namespace xmltooling { + + /** + * An abstract interface to credential formats like files, keystores, hardware tokens, etc. + * All non-const methods require that the interface be locked. + */ + class XMLTOOL_API CredentialResolver : public virtual Lockable + { + MAKE_NONCOPYABLE(CredentialResolver); + public: + virtual ~CredentialResolver() {} + + /** + * Returns an identifier for the credential. + * + * @return the identifier + */ + virtual const char* getId() const=0; + + /** + * Gets the public key associated with the credential. + * The caller MUST NOT modify the object. + * + * @return the public key, or NULL + */ + virtual XSECCryptoKey* getPublicKey()=0; + + /** + * Gets the private key associated with the credential. + * The caller MUST NOT modify the object. + * + * @return the private key, or NULL + */ + virtual XSECCryptoKey* getPrivateKey()=0; + + /** + * Gets the certificate chain associated with the credential. + * The caller MUST NOT modify the objects. + * The EE certificate MUST be first. + * + * @return a chain of certificates, or NULL + */ + virtual const std::vector* getX509Certificates()=0; + + protected: + CredentialResolver() {} + }; + +}; + +#endif /* __xmltooling_credres_h__ */ diff --git a/xmltoolingtest/SignatureTest.h b/xmltoolingtest/SignatureTest.h index 62009ed..62bd6a3 100644 --- a/xmltoolingtest/SignatureTest.h +++ b/xmltoolingtest/SignatureTest.h @@ -24,7 +24,7 @@ #include #include -class TestContext : public SigningContext, public VerifyingContext +class TestContext : public SigningContext, public VerifyingContext, CredentialResolver { XSECCryptoKey* m_key; vector m_certs; @@ -65,10 +65,11 @@ public: XMLString::release(&m_uri); } - void createSignature(DSIGSignature* sig) const { + bool createSignature(DSIGSignature* sig) { DSIGReference* ref=sig->createReference(m_uri); ref->appendEnvelopedSignatureTransform(); ref->appendCanonicalizationTransform(CANON_C14NE_NOC); + return false; } void verifySignature(DSIGSignature* sig) const { @@ -79,9 +80,14 @@ public: sig->verify(); } - const std::vector* getX509Certificates() const { return &m_certs; } - KeyInfo* getKeyInfo() const { return NULL; } - XSECCryptoKey* getSigningKey() const { return m_key->clone(); } + KeyInfo* getKeyInfo() { return NULL; } + CredentialResolver& getCredentialResolver() { return *this; } + const char* getId() const { return "test"; } + const std::vector* getX509Certificates() { return &m_certs; } + XSECCryptoKey* getPublicKey() { return m_key; } + XSECCryptoKey* getPrivateKey() { return m_key; } + Lockable& lock() { return *this; } + void unlock() {} }; class SignatureTest : public CxxTest::TestSuite { -- 2.1.4