Revised decryption APIs to clarify CredentialResolver/KeyResolver difference.
authorScott Cantor <cantor.2@osu.edu>
Sun, 18 Mar 2007 06:14:55 +0000 (06:14 +0000)
committerScott Cantor <cantor.2@osu.edu>
Sun, 18 Mar 2007 06:14:55 +0000 (06:14 +0000)
xmltooling/encryption/Decrypter.h
xmltooling/encryption/EncryptedKeyResolver.h
xmltooling/encryption/impl/Decrypter.cpp
xmltooling/security/CredentialResolver.h
xmltooling/security/impl/FilesystemCredentialResolver.cpp
xmltoolingtest/EncryptionTest.h

index 5abac55..0d5f27c 100644 (file)
 #define __xmltooling_decrypter_h__
 
 #include <xmltooling/encryption/Encryption.h>
-#include <xmltooling/security/KeyResolver.h>
 
-#include <xsec/enc/XSECCryptoKey.hpp>
 #include <xsec/xenc/XENCCipher.hpp>
 
+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);
index 95c436c..73dccb3 100644 (file)
@@ -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;
     };
 
 };
index 07acd69..2f2afe2 100644 (file)
@@ -23,6 +23,7 @@
 #include "internal.h"
 #include "encryption/Decrypter.h"
 #include "encryption/EncryptedKeyResolver.h"
+#include "security/CredentialResolver.h"
 
 #include <log4cpp/Category.hh>
 #include <xsec/enc/XSECCryptoException.hpp>
@@ -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<XMLObject*>& others=const_cast<const KeyInfo*>(encryptedData->getKeyInfo())->getUnknownXMLObjects();
+            if (encryptedData.getKeyInfo()) {
+                const vector<XMLObject*>& others=const_cast<const KeyInfo*>(encryptedData.getKeyInfo())->getUnknownXMLObjects();
                 for (vector<XMLObject*>::const_iterator i=others.begin(); i!=others.end(); i++) {
                     EncryptedKey* encKey=dynamic_cast<EncryptedKey*>(*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<EncryptedKeyResolver*>(m_resolver);
+                const EncryptedKeyResolver* ekr=dynamic_cast<const EncryptedKeyResolver*>(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);
index 0317299..a9324ee 100644 (file)
 #include <xsec/enc/XSECCryptoKey.hpp>
 #include <xsec/enc/XSECCryptoX509.hpp>
 
+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.
index 5d898b2..a026fdb 100644 (file)
@@ -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<XSECCryptoX509*>& getCertificates() const { return m_xseccerts; }
         void attach(SSL_CTX* ctx) const;
         
index 77fc7af..4f6f0b5 100644 (file)
@@ -75,8 +75,8 @@ public:
                 dynamic_cast<EncryptedData*>(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<DOMElement*>(frag->getFirstChild()), buf);
             //TS_TRACE(buf.c_str());
             TS_ASSERT(doc->getDocumentElement()->isEqualNode(frag->getFirstChild()));