From 9b45afa3e58ec1acac364a2c13088b62093d28cf Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Mon, 22 May 2006 15:44:13 +0000 Subject: [PATCH] Added key-based Signature validator. --- xmltooling/Makefile.am | 4 +- xmltooling/signature/SignatureValidator.h | 70 ++++++++++++++++++++++++ xmltooling/signature/impl/SignatureValidator.cpp | 59 ++++++++++++++++++++ xmltooling/xmltooling.vcproj | 8 +++ xmltoolingtest/SignatureTest.h | 34 +++++------- 5 files changed, 154 insertions(+), 21 deletions(-) create mode 100644 xmltooling/signature/SignatureValidator.h create mode 100644 xmltooling/signature/impl/SignatureValidator.cpp diff --git a/xmltooling/Makefile.am b/xmltooling/Makefile.am index 963fa87..bfa51fa 100644 --- a/xmltooling/Makefile.am +++ b/xmltooling/Makefile.am @@ -47,9 +47,10 @@ ioinclude_HEADERS = \ io/AbstractXMLObjectUnmarshaller.h siginclude_HEADERS = \ + signature/ContentReference.h \ signature/KeyInfo.h \ signature/Signature.h \ - signature/ContentReference.h + signature/SignatureValidator.h utilinclude_HEADERS = \ util/CredentialResolver.h \ @@ -70,6 +71,7 @@ noinst_HEADERS = \ if BUILD_XMLSEC xmlsec_sources = \ + signature/impl/SignatureValidator.cpp \ signature/impl/XMLSecSignatureImpl.cpp else xmlsec_sources = diff --git a/xmltooling/signature/SignatureValidator.h b/xmltooling/signature/SignatureValidator.h new file mode 100644 index 0000000..6a09ef4 --- /dev/null +++ b/xmltooling/signature/SignatureValidator.h @@ -0,0 +1,70 @@ +/* + * 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 SignatureValidator.h + * + * Validator for signatures based on an externally-supplied key + */ + +#if !defined(__xmltooling_sigval_h__) && !defined(XMLTOOLING_NO_XMLSEC) +#define __xmltooling_sigval_h__ + +#include +#include + +namespace xmlsignature { + + /** + * Validator for signatures based on an externally-supplied key. + */ + class XMLTOOL_API SignatureValidator : public virtual xmltooling::Validator + { + public: + /** + * Constructor + * + * @param key the verification key to use, will be freed by Validator + */ + SignatureValidator(XSECCryptoKey* key) : m_key(key) { + if (!key) + throw xmltooling::ValidationException("Verification key cannot be NULL."); + } + + virtual ~SignatureValidator() { + delete m_key; + } + + void validate(const xmltooling::XMLObject* xmlObject) const; + + virtual void validate(const Signature* signature) const; + + SignatureValidator* clone() const { + return new SignatureValidator(*this); + } + + protected: + SignatureValidator(const SignatureValidator& src) { + m_key=src.m_key->clone(); + } + + private: + XSECCryptoKey* m_key; + }; + +}; + +#endif /* __xmltooling_sigval_h__ */ diff --git a/xmltooling/signature/impl/SignatureValidator.cpp b/xmltooling/signature/impl/SignatureValidator.cpp new file mode 100644 index 0000000..e6b1cec --- /dev/null +++ b/xmltooling/signature/impl/SignatureValidator.cpp @@ -0,0 +1,59 @@ +/* + * 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. + */ + +/** + * SignatureValidator.cpp + * + * Validator for signatures based on an externally-supplied key + */ + +#include "internal.h" +#include "signature/SignatureValidator.h" + +#include +#include + +using namespace xmlsignature; +using namespace xmltooling; +using namespace std; + +void SignatureValidator::validate(const XMLObject* xmlObject) const +{ + const Signature* sigObj=dynamic_cast(xmlObject); + if (!sigObj) + throw ValidationException("Validator only applies to Signature objects."); + validate(sigObj); +} + +void SignatureValidator::validate(const Signature* sigObj) const +{ + DSIGSignature* sig=sigObj->getXMLSignature(); + if (!sig) + throw ValidationException("Signature does not exist yet."); + + try { + sig->setSigningKey(m_key->clone()); + if (!sig->verify()) + throw ValidationException("Digital signature does not validate with the given key."); + } + catch(XSECException& e) { + auto_ptr_char temp(e.getMsg()); + throw ValidationException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get()); + } + catch(XSECCryptoException& e) { + throw ValidationException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg()); + } +} diff --git a/xmltooling/xmltooling.vcproj b/xmltooling/xmltooling.vcproj index 146d950..3035be2 100644 --- a/xmltooling/xmltooling.vcproj +++ b/xmltooling/xmltooling.vcproj @@ -300,6 +300,10 @@ > + + @@ -486,6 +490,10 @@ RelativePath=".\signature\Signature.h" > + + + #include #include #include @@ -46,12 +48,16 @@ public: } }; -class TestValidator : public Validator +class TestValidator : public SignatureValidator { XMLCh* m_uri; + TestValidator(const TestValidator& src) : SignatureValidator(src) { + m_uri=XMLString::replicate(src.m_uri); + } + public: - TestValidator(const XMLCh* uri) { + TestValidator(const XMLCh* uri, XSECCryptoKey* key) : SignatureValidator(key) { m_uri=XMLString::replicate(uri); } @@ -59,29 +65,17 @@ public: XMLString::release(&m_uri); } - Validator* clone() const { - return new TestValidator(m_uri); + TestValidator* clone() const { + return new TestValidator(*this); } - void validate(const XMLObject* xmlObject) const { - DSIGSignature* sig=dynamic_cast(xmlObject)->getXMLSignature(); + void validate(const Signature* sigObj) const { + DSIGSignature* sig=sigObj->getXMLSignature(); if (!sig) throw SignatureException("Only a marshalled Signature object can be verified."); const XMLCh* uri=sig->getReferenceList()->item(0)->getURI(); TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri)); - XSECKeyInfoResolverDefault resolver; - sig->setKeyInfoResolver(&resolver); // It will clone the resolver for us. - try { - if (!sig->verify()) - throw SignatureException("Signature did not verify."); - } - catch(XSECException& e) { - auto_ptr_char temp(e.getMsg()); - throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get()); - } - catch(XSECCryptoException& e) { - throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg()); - } + SignatureValidator::validate(sigObj); } }; @@ -191,7 +185,7 @@ public: auto_ptr sxObject2(dynamic_cast(b->buildFromDocument(doc))); TS_ASSERT(sxObject2.get()!=NULL); TS_ASSERT(sxObject2->getSignature()!=NULL); - sxObject2->getSignature()->registerValidator(new TestValidator(&chNull)); + sxObject2->getSignature()->registerValidator(new TestValidator(&chNull,m_key->clone())); try { sxObject2->getSignature()->validate(false); -- 2.1.4