Convert from NULL macro to nullptr.
[shibboleth/cpp-xmltooling.git] / xmltooling / encryption / impl / Decrypter.cpp
index 47ed588..3f4adb9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Internet2
+ *  Copyright 2001-2010 Internet2
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
 #include "logging.h"
 #include "encryption/Decrypter.h"
 #include "encryption/EncryptedKeyResolver.h"
+#include "encryption/Encryption.h"
 #include "security/Credential.h"
 #include "security/CredentialCriteria.h"
 #include "security/CredentialResolver.h"
 #include <xsec/framework/XSECAlgorithmMapper.hpp>
 #include <xsec/framework/XSECAlgorithmHandler.hpp>
 #include <xsec/utils/XSECBinTXFMInputStream.hpp>
+#include <xsec/xenc/XENCCipher.hpp>
 #include <xsec/xenc/XENCEncryptedData.hpp>
 #include <xsec/xenc/XENCEncryptedKey.hpp>
 
 using namespace xmlencryption;
 using namespace xmlsignature;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
+Decrypter::Decrypter(const CredentialResolver* credResolver, CredentialCriteria* criteria, const EncryptedKeyResolver* EKResolver)
+    : m_cipher(nullptr), m_credResolver(credResolver), m_criteria(criteria), m_EKResolver(EKResolver)
+{
+}
+
 Decrypter::~Decrypter()
 {
     if (m_cipher)
         XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
 }
 
+void Decrypter::setEncryptedKeyResolver(const EncryptedKeyResolver* EKResolver)
+{
+    m_EKResolver=EKResolver;
+}
+
+void Decrypter::setKEKResolver(const CredentialResolver* resolver, CredentialCriteria* criteria)
+{
+    m_credResolver=resolver;
+    m_criteria=criteria;
+}
+
 DOMDocumentFragment* Decrypter::decryptData(const EncryptedData& encryptedData, XSECCryptoKey* key)
 {
-    if (encryptedData.getDOM()==NULL)
+    if (encryptedData.getDOM()==nullptr)
         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()) {
         XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
-        m_cipher=NULL;
+        m_cipher=nullptr;
     }
     
     if (!m_cipher)
@@ -87,12 +106,9 @@ DOMDocumentFragment* Decrypter::decryptData(const EncryptedData& encryptedData,
 
     // Resolve a decryption key directly.
     vector<const Credential*> creds;
-    int types =
-        CredentialCriteria::KEYINFO_EXTRACTION_KEY |
-        CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES |
-        CredentialCriteria::KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES;
+    int types = CredentialCriteria::KEYINFO_EXTRACTION_KEY | CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES;
     if (m_criteria) {
-        m_criteria->setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        m_criteria->setUsage(Credential::ENCRYPTION_CREDENTIAL);
         m_criteria->setKeyInfo(encryptedData.getKeyInfo(), types);
         const EncryptionMethod* meth = encryptedData.getEncryptionMethod();
         if (meth)
@@ -101,7 +117,7 @@ DOMDocumentFragment* Decrypter::decryptData(const EncryptedData& encryptedData,
     }
     else {
         CredentialCriteria criteria;
-        criteria.setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        criteria.setUsage(Credential::ENCRYPTION_CREDENTIAL);
         criteria.setKeyInfo(encryptedData.getKeyInfo(), types);
         const EncryptionMethod* meth = encryptedData.getEncryptionMethod();
         if (meth)
@@ -125,12 +141,12 @@ DOMDocumentFragment* Decrypter::decryptData(const EncryptedData& encryptedData,
 
     // We need to find an encrypted decryption key somewhere. We'll need the underlying algorithm...
     const XMLCh* algorithm=
-        encryptedData.getEncryptionMethod() ? encryptedData.getEncryptionMethod()->getAlgorithm() : NULL;
+        encryptedData.getEncryptionMethod() ? encryptedData.getEncryptionMethod()->getAlgorithm() : nullptr;
     if (!algorithm)
         throw DecryptionException("No EncryptionMethod/@Algorithm set, key decryption cannot proceed.");
     
     // Check for external resolver.
-    const EncryptedKey* encKey=NULL;
+    const EncryptedKey* encKey=nullptr;
     if (m_EKResolver)
         encKey = m_EKResolver->resolveKey(encryptedData, recipient);
     else {
@@ -149,14 +165,14 @@ DOMDocumentFragment* Decrypter::decryptData(const EncryptedData& encryptedData,
 
 void Decrypter::decryptData(ostream& out, const EncryptedData& encryptedData, XSECCryptoKey* key)
 {
-    if (encryptedData.getDOM()==NULL)
+    if (encryptedData.getDOM()==nullptr)
         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()) {
         XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
-        m_cipher=NULL;
+        m_cipher=nullptr;
     }
     
     if (!m_cipher)
@@ -167,7 +183,7 @@ void Decrypter::decryptData(ostream& out, const EncryptedData& encryptedData, XS
         auto_ptr<XSECBinTXFMInputStream> in(m_cipher->decryptToBinInputStream(encryptedData.getDOM()));
         
         XMLByte buf[8192];
-        unsigned int count = in->readBytes(buf, sizeof(buf));
+        xsecsize_t count = in->readBytes(buf, sizeof(buf));
         while (count > 0)
             out.write(reinterpret_cast<char*>(buf),count);
     }
@@ -187,12 +203,9 @@ void Decrypter::decryptData(ostream& out, const EncryptedData& encryptedData, co
 
     // Resolve a decryption key directly.
     vector<const Credential*> creds;
-    int types =
-        CredentialCriteria::KEYINFO_EXTRACTION_KEY |
-        CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES |
-        CredentialCriteria::KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES;
+    int types = CredentialCriteria::KEYINFO_EXTRACTION_KEY | CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES;
     if (m_criteria) {
-        m_criteria->setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        m_criteria->setUsage(Credential::ENCRYPTION_CREDENTIAL);
         m_criteria->setKeyInfo(encryptedData.getKeyInfo(), types);
         const EncryptionMethod* meth = encryptedData.getEncryptionMethod();
         if (meth)
@@ -201,7 +214,7 @@ void Decrypter::decryptData(ostream& out, const EncryptedData& encryptedData, co
     }
     else {
         CredentialCriteria criteria;
-        criteria.setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        criteria.setUsage(Credential::ENCRYPTION_CREDENTIAL);
         criteria.setKeyInfo(encryptedData.getKeyInfo(), types);
         const EncryptionMethod* meth = encryptedData.getEncryptionMethod();
         if (meth)
@@ -225,12 +238,12 @@ void Decrypter::decryptData(ostream& out, const EncryptedData& encryptedData, co
 
     // We need to find an encrypted decryption key somewhere. We'll need the underlying algorithm...
     const XMLCh* algorithm=
-        encryptedData.getEncryptionMethod() ? encryptedData.getEncryptionMethod()->getAlgorithm() : NULL;
+        encryptedData.getEncryptionMethod() ? encryptedData.getEncryptionMethod()->getAlgorithm() : nullptr;
     if (!algorithm)
         throw DecryptionException("No EncryptionMethod/@Algorithm set, key decryption cannot proceed.");
     
     // Check for external resolver.
-    const EncryptedKey* encKey=NULL;
+    const EncryptedKey* encKey=nullptr;
     if (m_EKResolver)
         encKey = m_EKResolver->resolveKey(encryptedData, recipient);
     else {
@@ -252,31 +265,38 @@ XSECCryptoKey* Decrypter::decryptKey(const EncryptedKey& encryptedKey, const XML
     if (!m_credResolver)
         throw DecryptionException("No CredentialResolver supplied to provide decryption keys.");
 
-    if (encryptedKey.getDOM()==NULL)
+    if (encryptedKey.getDOM()==nullptr)
         throw DecryptionException("The object must be marshalled before decryption.");
 
-    XSECAlgorithmHandler* handler = XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(algorithm);
-    if (!handler)
-        throw DecryptionException("Unrecognized algorithm, no way to build object around decrypted key.");
+    XSECAlgorithmHandler* handler;
+    try {
+        handler = XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(algorithm);
+        if (!handler)
+            throw DecryptionException("Unrecognized algorithm, no way to build object around decrypted key.");
+    }
+    catch(XSECException& e) {
+        auto_ptr_char temp(e.getMsg());
+        throw DecryptionException(string("XMLSecurity exception while decrypting key: ") + temp.get());
+    }
+    catch(XSECCryptoException& e) {
+        throw DecryptionException(string("XMLSecurity exception while decrypting key: ") + e.getMsg());
+    }
     
     // We can reuse the cipher object if the document hasn't changed.
 
     if (m_cipher && m_cipher->getDocument()!=encryptedKey.getDOM()->getOwnerDocument()) {
         XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
-        m_cipher=NULL;
+        m_cipher=nullptr;
     }
     
     if (!m_cipher)
         m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedKey.getDOM()->getOwnerDocument());
     
     // Resolve key decryption keys.
-    int types =
-        CredentialCriteria::KEYINFO_EXTRACTION_KEY |
-        CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES |
-        CredentialCriteria::KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES;
+    int types = CredentialCriteria::KEYINFO_EXTRACTION_KEY | CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES;
     vector<const Credential*> creds;
     if (m_criteria) {
-        m_criteria->setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        m_criteria->setUsage(Credential::ENCRYPTION_CREDENTIAL);
         m_criteria->setKeyInfo(encryptedKey.getKeyInfo(), types);
         const EncryptionMethod* meth = encryptedKey.getEncryptionMethod();
         if (meth)
@@ -285,7 +305,7 @@ XSECCryptoKey* Decrypter::decryptKey(const EncryptedKey& encryptedKey, const XML
     }
     else {
         CredentialCriteria criteria;
-        criteria.setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        criteria.setUsage(Credential::ENCRYPTION_CREDENTIAL);
         criteria.setKeyInfo(encryptedKey.getKeyInfo(), types);
         const EncryptionMethod* meth = encryptedKey.getEncryptionMethod();
         if (meth)