From ce4b4a22812fef63619154a8e9b12dd44a2cbb5e Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Sun, 18 Mar 2007 06:14:55 +0000 Subject: [PATCH] Revised decryption APIs to clarify CredentialResolver/KeyResolver difference. --- xmltooling/encryption/Decrypter.h | 36 ++++++++++---------- xmltooling/encryption/EncryptedKeyResolver.h | 4 +-- xmltooling/encryption/impl/Decrypter.cpp | 39 +++++++++++----------- xmltooling/security/CredentialResolver.h | 9 +++-- .../security/impl/FilesystemCredentialResolver.cpp | 2 +- xmltoolingtest/EncryptionTest.h | 4 +-- 6 files changed, 49 insertions(+), 45 deletions(-) diff --git a/xmltooling/encryption/Decrypter.h b/xmltooling/encryption/Decrypter.h index 5abac55..0d5f27c 100644 --- a/xmltooling/encryption/Decrypter.h +++ b/xmltooling/encryption/Decrypter.h @@ -24,11 +24,14 @@ #define __xmltooling_decrypter_h__ #include -#include -#include #include +namespace xmltooling { + class XMLTOOL_API CredentialResolver; + class XMLTOOL_API KeyResolver; +}; + namespace xmlencryption { /** @@ -39,13 +42,12 @@ namespace xmlencryption { public: /** * Constructor. - * Resolvers will be deleted when Decrypter is. * - * @param KEKresolver resolves key decryption key - * @param resolver resolves data decryption key + * @param KEKresolver locked credential resolver to supply key decryption key + * @param resolver directly or indirectly resolves the data decryption key */ - Decrypter(xmltooling::KeyResolver* KEKresolver=NULL, xmltooling::KeyResolver* resolver=NULL) - : m_cipher(NULL), m_resolver(resolver), m_KEKresolver(KEKresolver) { + Decrypter(const xmltooling::CredentialResolver* KEKresolver=NULL, const xmltooling::KeyResolver* resolver=NULL) + : m_cipher(NULL), m_KEKresolver(KEKresolver), m_resolver(resolver) { } ~Decrypter(); @@ -55,18 +57,16 @@ namespace xmlencryption { * * @param resolver the KeyResolver to attach */ - void setKeyResolver(xmltooling::KeyResolver* resolver) { - delete m_resolver; + void setKeyResolver(const xmltooling::KeyResolver* resolver) { m_resolver=resolver; } /** - * Replace the current key encryption KeyResolver interface, if any, with a new one. + * Replace the current key encryption CredentialResolver interface, if any, with a new one. * - * @param resolver the KeyResolver to attach + * @param resolver the locked CredentialResolver to attach */ - void setKEKResolver(xmltooling::KeyResolver* resolver) { - delete m_KEKresolver; + void setKEKResolver(const xmltooling::CredentialResolver* resolver) { m_KEKresolver=resolver; } @@ -81,10 +81,10 @@ namespace xmlencryption { * approach should be to unmarshall the DOM and then release it, or the * DOM can also be imported into a separately owned document. * - * @param encryptedData the encrypted data to decrypt + * @param encryptedData the data to decrypt * @return the decrypted DOM fragment */ - DOMDocumentFragment* decryptData(EncryptedData* encryptedData); + DOMDocumentFragment* decryptData(EncryptedData& encryptedData); /** * Decrypts the supplied information and returns the resulting key. @@ -96,12 +96,12 @@ namespace xmlencryption { * @param algorithm the algorithm associated with the decrypted key * @return the decrypted key */ - XSECCryptoKey* decryptKey(EncryptedKey* encryptedKey, const XMLCh* algorithm); + XSECCryptoKey* decryptKey(EncryptedKey& encryptedKey, const XMLCh* algorithm); private: XENCCipher* m_cipher; - xmltooling::KeyResolver* m_resolver; - xmltooling::KeyResolver* m_KEKresolver; + const xmltooling::CredentialResolver* m_KEKresolver; + const xmltooling::KeyResolver* m_resolver; }; DECL_XMLTOOLING_EXCEPTION(DecryptionException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmlencryption,xmltooling::XMLToolingException,Exceptions in decryption processing); diff --git a/xmltooling/encryption/EncryptedKeyResolver.h b/xmltooling/encryption/EncryptedKeyResolver.h index 95c436c..73dccb3 100644 --- a/xmltooling/encryption/EncryptedKeyResolver.h +++ b/xmltooling/encryption/EncryptedKeyResolver.h @@ -36,12 +36,12 @@ namespace xmlencryption { virtual ~EncryptedKeyResolver() {} /** - * Returns an encrypted key based on the supplied KeyInfo information. + * Returns an encrypted key based on the supplied object's KeyInfo information. * * @param encryptedData an encrypted object * @return the resolved EncryptedKey object */ - virtual EncryptedKey* resolveKey(EncryptedData* encryptedData)=0; + virtual EncryptedKey* resolveKey(EncryptedData& encryptedData) const=0; }; }; diff --git a/xmltooling/encryption/impl/Decrypter.cpp b/xmltooling/encryption/impl/Decrypter.cpp index 07acd69..2f2afe2 100644 --- a/xmltooling/encryption/impl/Decrypter.cpp +++ b/xmltooling/encryption/impl/Decrypter.cpp @@ -23,6 +23,7 @@ #include "internal.h" #include "encryption/Decrypter.h" #include "encryption/EncryptedKeyResolver.h" +#include "security/CredentialResolver.h" #include #include @@ -41,45 +42,43 @@ Decrypter::~Decrypter() { if (m_cipher) XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher); - delete m_resolver; - delete m_KEKresolver; } -DOMDocumentFragment* Decrypter::decryptData(EncryptedData* encryptedData) +DOMDocumentFragment* Decrypter::decryptData(EncryptedData& encryptedData) { - if (encryptedData->getDOM()==NULL) + if (encryptedData.getDOM()==NULL) throw DecryptionException("The object must be marshalled before decryption."); // We can reuse the cipher object if the document hasn't changed. - if (m_cipher && m_cipher->getDocument()!=encryptedData->getDOM()->getOwnerDocument()) { + if (m_cipher && m_cipher->getDocument()!=encryptedData.getDOM()->getOwnerDocument()) { XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher); m_cipher=NULL; } if (!m_cipher) - m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedData->getDOM()->getOwnerDocument()); + m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedData.getDOM()->getOwnerDocument()); try { // Resolve decryption key. XSECCryptoKey* key=NULL; if (m_resolver) - key=m_resolver->resolveKey(encryptedData->getKeyInfo()); + key=m_resolver->resolveKey(encryptedData.getKeyInfo()); if (!key && m_KEKresolver) { // See if there's an encrypted key available. We'll need the algorithm... const XMLCh* algorithm= - encryptedData->getEncryptionMethod() ? encryptedData->getEncryptionMethod()->getAlgorithm() : NULL; + encryptedData.getEncryptionMethod() ? encryptedData.getEncryptionMethod()->getAlgorithm() : NULL; if (!algorithm) throw DecryptionException("No EncryptionMethod/@Algorithm set, key decryption cannot proceed."); - if (encryptedData->getKeyInfo()) { - const vector& others=const_cast(encryptedData->getKeyInfo())->getUnknownXMLObjects(); + if (encryptedData.getKeyInfo()) { + const vector& others=const_cast(encryptedData.getKeyInfo())->getUnknownXMLObjects(); for (vector::const_iterator i=others.begin(); i!=others.end(); i++) { EncryptedKey* encKey=dynamic_cast(*i); if (encKey) { try { - key=decryptKey(encKey, algorithm); + key=decryptKey(*encKey, algorithm); } catch (DecryptionException& e) { log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Decrypter").warn(e.what()); @@ -90,12 +89,12 @@ DOMDocumentFragment* Decrypter::decryptData(EncryptedData* encryptedData) if (!key) { // Check for a non-trivial resolver. - EncryptedKeyResolver* ekr=dynamic_cast(m_resolver); + const EncryptedKeyResolver* ekr=dynamic_cast(m_resolver); if (ekr) { EncryptedKey* encKey=ekr->resolveKey(encryptedData); if (encKey) { try { - key=decryptKey(encKey, algorithm); + key=decryptKey(*encKey, algorithm); } catch (DecryptionException& e) { log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Decrypter").warn(e.what()); @@ -109,7 +108,7 @@ DOMDocumentFragment* Decrypter::decryptData(EncryptedData* encryptedData) throw DecryptionException("Unable to resolve a decryption key."); m_cipher->setKey(key); - DOMNode* ret=m_cipher->decryptElementDetached(encryptedData->getDOM()); + DOMNode* ret=m_cipher->decryptElementDetached(encryptedData.getDOM()); if (ret->getNodeType()!=DOMNode::DOCUMENT_FRAGMENT_NODE) { ret->release(); throw DecryptionException("Decryption operation did not result in DocumentFragment."); @@ -125,32 +124,32 @@ DOMDocumentFragment* Decrypter::decryptData(EncryptedData* encryptedData) } } -XSECCryptoKey* Decrypter::decryptKey(EncryptedKey* encryptedKey, const XMLCh* algorithm) +XSECCryptoKey* Decrypter::decryptKey(EncryptedKey& encryptedKey, const XMLCh* algorithm) { - if (encryptedKey->getDOM()==NULL) + if (encryptedKey.getDOM()==NULL) throw DecryptionException("The object must be marshalled before decryption."); // We can reuse the cipher object if the document hasn't changed. - if (m_cipher && m_cipher->getDocument()!=encryptedKey->getDOM()->getOwnerDocument()) { + if (m_cipher && m_cipher->getDocument()!=encryptedKey.getDOM()->getOwnerDocument()) { XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher); m_cipher=NULL; } if (!m_cipher) - m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedKey->getDOM()->getOwnerDocument()); + m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedKey.getDOM()->getOwnerDocument()); try { // Resolve key decryption key. XSECCryptoKey* key=NULL; if (m_KEKresolver) - key=m_KEKresolver->resolveKey(encryptedKey->getKeyInfo()); + key=m_KEKresolver->getKey(encryptedKey.getKeyInfo()); if (!key) throw DecryptionException("Unable to resolve a key decryption key."); m_cipher->setKEK(key); XMLByte buffer[1024]; - int keySize = m_cipher->decryptKey(encryptedKey->getDOM(), buffer, 1024); + int keySize = m_cipher->decryptKey(encryptedKey.getDOM(), buffer, 1024); if (keySize > 0) { // Try to map the key. XSECAlgorithmHandler* handler = XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(algorithm); diff --git a/xmltooling/security/CredentialResolver.h b/xmltooling/security/CredentialResolver.h index 0317299..a9324ee 100644 --- a/xmltooling/security/CredentialResolver.h +++ b/xmltooling/security/CredentialResolver.h @@ -29,6 +29,10 @@ #include #include +namespace xmlsignature { + class XMLTOOL_API KeyInfo; +}; + namespace xmltooling { /** @@ -44,12 +48,13 @@ namespace xmltooling { virtual ~CredentialResolver() {} /** - * Returns a secret or private key to use for signing operations. + * Returns a secret or private key to use for signing or decryption operations. * The caller is responsible for deleting the key when finished with it. * + * @param keyInfo optional material identifying a decryption key * @return a secret or private key */ - virtual XSECCryptoKey* getKey() const=0; + virtual XSECCryptoKey* getKey(const xmlsignature::KeyInfo* keyInfo=NULL) const=0; /** * Returns a set of certificates to publish during signing operations. diff --git a/xmltooling/security/impl/FilesystemCredentialResolver.cpp b/xmltooling/security/impl/FilesystemCredentialResolver.cpp index 5d898b2..a026fdb 100644 --- a/xmltooling/security/impl/FilesystemCredentialResolver.cpp +++ b/xmltooling/security/impl/FilesystemCredentialResolver.cpp @@ -67,7 +67,7 @@ namespace xmltooling { XSECCryptoKey* loadKey(); - XSECCryptoKey* getKey() const { return m_key ? m_key->clone() : NULL; } + XSECCryptoKey* getKey(const KeyInfo* keyInfo=NULL) const { return m_key ? m_key->clone() : NULL; } const vector& getCertificates() const { return m_xseccerts; } void attach(SSL_CTX* ctx) const; diff --git a/xmltoolingtest/EncryptionTest.h b/xmltoolingtest/EncryptionTest.h index 77fc7af..4f6f0b5 100644 --- a/xmltoolingtest/EncryptionTest.h +++ b/xmltoolingtest/EncryptionTest.h @@ -75,8 +75,8 @@ public: dynamic_cast(XMLObjectBuilder::buildOneFromElement(doc2->getDocumentElement(),true)) ); - Decrypter decrypter(new KeyResolver(m_resolver->getKey())); - DOMDocumentFragment* frag = decrypter.decryptData(encData2.get()); + Decrypter decrypter(m_resolver); + DOMDocumentFragment* frag = decrypter.decryptData(*encData2.get()); XMLHelper::serialize(static_cast(frag->getFirstChild()), buf); //TS_TRACE(buf.c_str()); TS_ASSERT(doc->getDocumentElement()->isEqualNode(frag->getFirstChild())); -- 2.1.4