Refined ElementProxy/ElementExtensible interfaces to match Java.
[shibboleth/xmltooling.git] / xmltooling / encryption / impl / Decrypter.cpp
index 0788761..7a8d553 100644 (file)
  */
 
 /**
- * Encrypter.cpp
+ * Decrypter.cpp
  * 
- * Methods for encrypting XMLObjects and other data.
+ * Methods for decrypting XMLObjects and other data.
  */
 
 #include "internal.h"
 #include "encryption/Decrypter.h"
+#include "encryption/EncryptedKeyResolver.h"
 
 #include <log4cpp/Category.hh>
 #include <xsec/enc/XSECCryptoException.hpp>
@@ -38,7 +39,8 @@ using namespace std;
 
 Decrypter::~Decrypter()
 {
-    XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
+    if (m_cipher)
+        XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
     delete m_resolver;
     delete m_KEKresolver;
 }
@@ -63,15 +65,16 @@ DOMDocumentFragment* Decrypter::decryptData(EncryptedData* encryptedData)
         XSECCryptoKey* key=NULL;
         if (m_resolver)
             key=m_resolver->resolveKey(encryptedData->getKeyInfo());
-        if (!key) {
-            // See if there's an encrypted key present. We'll need the algorithm...
+
+        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;
             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())->getOthers();
+                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) {
@@ -85,9 +88,25 @@ DOMDocumentFragment* Decrypter::decryptData(EncryptedData* encryptedData)
                 }
             }
             
-            if (!key)
-                throw DecryptionException("Unable to resolve a decryption key.");
+            if (!key) {
+                // Check for a non-trivial resolver.
+                EncryptedKeyResolver* ekr=dynamic_cast<EncryptedKeyResolver*>(m_resolver);
+                if (ekr) {
+                    EncryptedKey* encKey=ekr->resolveKey(encryptedData);
+                    if (encKey) {
+                        try {
+                            key=decryptKey(encKey, algorithm);
+                        }
+                        catch (DecryptionException& e) {
+                            log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Decrypter").warn(e.what());
+                        }
+                    }
+                }
+            }
         }
+
+        if (!key)
+            throw DecryptionException("Unable to resolve a decryption key.");
         
         m_cipher->setKey(key);
         DOMNode* ret=m_cipher->decryptElementDetached(encryptedData->getDOM());