blautenb    2003/10/03 02:50:06

  Modified:    c/src/xenc XENCCipher.hpp XENCEncryptedType.hpp
               c/src/xenc/impl XENCAlgorithmHandlerDefault.cpp
                        XENCAlgorithmHandlerDefault.hpp XENCCipherImpl.cpp
                        XENCCipherImpl.hpp XENCEncryptedDataImpl.hpp
                        XENCEncryptedTypeImpl.cpp XENCEncryptedTypeImpl.hpp
  Log:
  Updates to support creating an EncryptedKey (AES KeyWrap)
  
  Revision  Changes    Path
  1.6       +56 -1     xml-security/c/src/xenc/XENCCipher.hpp
  
  Index: XENCCipher.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/XENCCipher.hpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XENCCipher.hpp    17 Sep 2003 10:10:21 -0000      1.5
  +++ XENCCipher.hpp    3 Oct 2003 09:50:05 -0000       1.6
  @@ -82,6 +82,7 @@
   
   class XSECCryptoKey;
   class XENCEncryptedData;
  +class XENCEncryptedKey;
   class XSECKeyInfoResolver;
   
   /**
  @@ -148,6 +149,23 @@
                XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element
        ) = 0;
   
  +     /**
  +      * \brief Decrypt a key
  +      *
  +      * Reads in the passed in KeyInfo structure for an EncryptedKey and 
  +      * decrypts the key to a buffer.
  +      *
  +      * @param encryptedKey the already loaded encryptedKey structure
  +      * @param rawKey Buffer to place the decrypted key into
  +      * @param maxKeySize Maximum number of bytes to place in the buffer
  +      */
  +
  +     virtual int decryptKey(
  +             XENCEncryptedKey * encryptedKey,
  +             XMLByte * rawKey,
  +             int maxKeySize
  +     ) = 0;
  +
        //@}
   
        /** @name Encryption Functions */
  @@ -178,6 +196,28 @@
                const XMLCh * algorithmURI = NULL
        ) = 0;
   
  +     /**
  +      * \brief Encrypt a buffer of data as a key
  +      *
  +      * Encrypts the passed in data and creates an EncryptedKey element
  +      *
  +      * @param keyBuffer The key data to encrypt
  +      * @param keyLen Bytes to encrypt
  +      * @param em The encryptionMethod to use for this encryption.  Use
  +      * ENCRYPT_NONE if a user defined type is required.
  +      * @param algorithmURI If ENCRYPT_NONE is used for em, this will be
  +      * used as the algorithm URI.
  +      *
  +      * @returns The EncryptedKey element
  +      */
  +
  +     virtual XENCEncryptedKey * encryptKey(
  +             const unsigned char * keyBuffer,
  +             unsigned int keyLen,
  +             encryptionMethod em,
  +             const XMLCh * algorithmURI = NULL
  +     ) = 0;
  +
        //@}
        /** @name Getter Functions */
        //@{
  @@ -231,6 +271,21 @@
         */
   
        virtual void setKey(XSECCryptoKey * key) = 0;
  +
  +     /**
  +      * \brief Set Key Encryption Key for next operation
  +      *
  +      * Set the passed in key for the next key decryption/encryption
  +      * operation.
  +      *
  +      * @note This key will only be used to decrypt EncryptedKey elements.
  +      * To set a key for decrypting an EncryptedData use #setKey instead.
  +      *
  +      * @param key Key to use
  +      * @note This function will take ownership of the key and delete it 
when done.
  +      */
  +
  +     virtual void setKEK(XSECCryptoKey * key) = 0;
   
        /**
         * \brief Register a KeyInfoResolver 
  
  
  
  1.6       +14 -1     xml-security/c/src/xenc/XENCEncryptedType.hpp
  
  Index: XENCEncryptedType.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/XENCEncryptedType.hpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XENCEncryptedType.hpp     17 Sep 2003 10:10:21 -0000      1.5
  +++ XENCEncryptedType.hpp     3 Oct 2003 09:50:05 -0000       1.6
  @@ -80,6 +80,7 @@
   class DSIGKeyInfoList;
   class DSIGKeyInfoName;
   class XENCEncryptionMethod;
  +class XENCEncryptedKey;
   
   /**
    * @ingroup xenc
  @@ -199,6 +200,18 @@
   
        virtual DSIGKeyInfoName * appendKeyName(const XMLCh * name, bool 
isDName = false) = 0;
   
  +     /**
  +      * \brief Append an already created EncryptedKey.
  +      *
  +      * Add an already created EncryptedKey.
  +      *
  +      * @note The encryptedKey becomes the property of the owning 
EncryptedType
  +      * object and will be deleted upon its destruction.
  +      *
  +      * @param encryptedKey A pointer to the encrypted Key
  +      */
  +
  +     virtual void appendEncryptedKey(XENCEncryptedKey * encryptedKey) = 0;
        //@}
   
   private:
  
  
  
  1.2       +345 -4    
xml-security/c/src/xenc/impl/XENCAlgorithmHandlerDefault.cpp
  
  Index: XENCAlgorithmHandlerDefault.cpp
  ===================================================================
  RCS file: 
/home/cvs/xml-security/c/src/xenc/impl/XENCAlgorithmHandlerDefault.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCAlgorithmHandlerDefault.cpp   15 Sep 2003 11:53:37 -0000      1.1
  +++ XENCAlgorithmHandlerDefault.cpp   3 Oct 2003 09:50:05 -0000       1.2
  @@ -82,9 +82,36 @@
   #include "XENCAlgorithmHandlerDefault.hpp"
   
   #include <xercesc/dom/DOM.hpp>
  +#include <xercesc/util/Janitor.hpp>
   
   XERCES_CPP_NAMESPACE_USE
   
  +#define _MY_MAX_KEY_SIZE 2048
  +
  +unsigned char s_3DES_CMS_IV [] = {
  +     0x4a,
  +     0xdd,
  +     0xa2,
  +     0x2c,
  +     0x79,
  +     0xe8,
  +     0x21,
  +     0x05
  +};
  +
  +unsigned char s_AES_IV [] = {
  +
  +     0xA6,
  +     0xA6,
  +     0xA6,
  +     0xA6,
  +     0xA6,
  +     0xA6,
  +     0xA6,
  +     0xA6
  +
  +};
  +
   // 
--------------------------------------------------------------------------------
   //                   Internal functions
   // 
--------------------------------------------------------------------------------
  @@ -106,13 +133,235 @@
   
   }
        
  +unsigned int XENCAlgorithmHandlerDefault::unwrapKeyAES(
  +             TXFMChain * cipherText,
  +             XSECCryptoKey * key,
  +             safeBuffer & result) {
  +
  +     // Cat the encrypted key
  +     XMLByte buf[_MY_MAX_KEY_SIZE];
  +     XMLByte aesBuf[16];
  +     XMLByte aesOutBuf[16];
  +     TXFMBase * b = cipherText->getLastTxfm();
  +     int sz = b->readBytes(buf, _MY_MAX_KEY_SIZE);
  +
  +     if (sz <= 0) {
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCAlgorithmHandlerDefault - AES Wrapped Key not 
found");
  +     }
  +
  +     if (sz == _MY_MAX_KEY_SIZE) {
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCAlgorithmHandlerDefault - Key to decrypt too 
big!");
  +     }
  +
  +     // Find number of blocks, and ensure we are a multiple of 64 bits
  +     if (sz % 8 != 0) {
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCAlgorithmHandlerDefault - AES wrapped key not a 
multiple of 64");
  +     }
  +
  +     // Do the decrypt - this cast will throw if wrong, but we should
  +     // not have been able to get through algorithm checks otherwise
  +     XSECCryptoSymmetricKey * sk = dynamic_cast<XSECCryptoSymmetricKey 
*>(key);
  +
  +     int blocks = sz / 8;
  +     int n = blocks - 1;
  +     for (int j = 5; j >= 0; j--) {
  +             for (int i = n ; i > 0 ; --i) {
  +
  +                     // Gather blocks to decrypt
  +                     // A
  +                     memcpy(aesBuf, buf, 8);
  +                     // Ri
  +                     memcpy(&aesBuf[8], &buf[8 * i], 8);
  +                     // A mod t
  +                     aesBuf[7] ^= ((n * j) + i);
  +
  +                     // do decrypt
  +                     sk->decryptInit();
  +                     int sz = sk->decrypt(aesBuf, aesOutBuf, 16, 16);
  +                     sz += sk->decryptFinish(&aesOutBuf[sz], 16 - sz);
  +
  +                     if (sz != 16) {
  +                             throw XSECException(XSECException::CipherError, 
  +                                     "XENCAlgorithmHandlerDefault - Error 
performing decrypt in AES Unwrap");
  +                     }
  +
  +                     // Copy back to where we are
  +                     // A
  +                     memcpy(buf, aesOutBuf, 8);
  +                     // Ri
  +                     memcpy(&buf[8 * i], &aesOutBuf[8], 8);
  +
  +             }
  +     }
  +
  +     // Check is valid
  +     if (memcmp(buf, s_AES_IV, 8) != 0) {
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCAlgorithmHandlerDefault - decrypt failed - AES IV 
is not correct");
  +     }
  +
  +     // Copy to safebuffer
  +     result.sbMemcpyIn(&buf[8], n * 8);
  +
  +     return n * 8;
  +}
  +
  +bool XENCAlgorithmHandlerDefault::wrapKeyAES(
  +             TXFMChain * cipherText,
  +             XSECCryptoKey * key,
  +             safeBuffer & result) {
  +
  +     // get the raw key
  +     XMLByte buf[_MY_MAX_KEY_SIZE + 8];
  +     memcpy(buf, s_AES_IV, 8);
  +     XMLByte aesBuf[16];
  +     XMLByte aesOutBuf[16];
  +     TXFMBase * b = cipherText->getLastTxfm();
  +     int sz = b->readBytes(&buf[8], _MY_MAX_KEY_SIZE);
  +
  +     if (sz <= 0) {
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCAlgorithmHandlerDefault - Key not found");
  +     }
  +
  +     if (sz == _MY_MAX_KEY_SIZE) {
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCAlgorithmHandlerDefault - Key to encrypt too 
big!");
  +     }
  +
  +     // Find number of blocks, and ensure we are a multiple of 64 bits
  +     if (sz % 8 != 0) {
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCAlgorithmHandlerDefault - AES wrapped key not a 
multiple of 64");
  +     }
  +
  +     // Do the decrypt - this cast will throw if wrong, but we should
  +     // not have been able to get through algorithm checks otherwise
  +     XSECCryptoSymmetricKey * sk = dynamic_cast<XSECCryptoSymmetricKey 
*>(key);
  +
  +     int n = sz / 8;
  +     int blocks = n + 1;
  +
  +     for (int j = 0; j <= 5; ++j) {
  +             for (int i = 1 ; i <= n ; ++i) {
  +
  +                     // Gather blocks to decrypt
  +                     // A
  +                     memcpy(aesBuf, buf, 8);
  +                     // Ri
  +                     memcpy(&aesBuf[8], &buf[8 * i], 8);
  +
  +                     // do encrypt
  +                     sk->encryptInit();
  +                     int sz = sk->encrypt(aesBuf, aesOutBuf, 16, 16);
  +                     sz += sk->encryptFinish(&aesOutBuf[sz], 16 - sz);
  +
  +                     if (sz != 16) {
  +                             throw XSECException(XSECException::CipherError, 
  +                                     "XENCAlgorithmHandlerDefault - Error 
performing encrypt in AES wrap");
  +                     }
  +
  +                     // Copy back to where we are
  +                     // A
  +                     memcpy(buf, aesOutBuf, 8);
  +                     // A mod t
  +                     buf[7] ^= ((n * j) + i);
  +                     // Ri
  +                     memcpy(&buf[8 * i], &aesOutBuf[8], 8);
  +
  +             }
  +     }
  +
  +     // Now we have to base64 encode
  +     XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
  +
  +     if (!b64) {
  +
  +             throw XSECException(XSECException::CryptoProviderError, 
  +                             "XENCAlgorithmHandlerDefault - Error getting 
base64 encoder in AES wrap");
  +
  +     }
  +
  +     Janitor<XSECCryptoBase64> j_b64(b64);
  +     unsigned char * b64Buffer;
  +     int bufLen = ((n + 1) * 8) * 3;
  +     XSECnew(b64Buffer, unsigned char[bufLen + 1]);// Overkill
  +     ArrayJanitor<unsigned char> j_b64Buffer(b64Buffer);
  +
  +     b64->encodeInit();
  +     int outputLen = b64->encode (buf, (n+1) * 8, b64Buffer, bufLen);
  +     outputLen += b64->encodeFinish(&b64Buffer[outputLen], bufLen - 
outputLen);
  +     b64Buffer[outputLen] = '\0';
  +
  +     // Copy to safebuffer
  +     result.sbStrcpyIn((const char *) b64Buffer);
  +
  +     return true;
  +}
  +
  +#if 0
  +
  +Keep for DES keywrap
  +
  +             // Perform an unwrap on the key
  +             safeBuffer cipherSB;
  +
  +             // Set the IV
  +             cipherSB.sbMemcpyIn(s_CMSIV, 8);
  +
  +             // Cat the encrypted key
  +             XMLByte buf[_MY_MAX_KEY_SIZE];
  +             TXFMBase * b = cipherText->getLastTxfm();
  +             int offset = 8;
  +             int sz = b->readBytes(buf, _MY_MAX_KEY_SIZE);
  +
  +             while (sz > 0) {
  +                     cipherSB.sbMemcpyIn(offset, buf, sz);
  +                     offset += sz;
  +                     sz = b->readBytes(buf, _MY_MAX_KEY_SIZE);
  +             }
  +
  +             if (offset > _MY_MAX_KEY_SIZE) {
  +                     throw XSECException(XSECException::CipherError, 
  +                             "XENCAlgorithmHandlerDefault - Key to decrypt 
too big!");
  +             }
  +
  +             // Do the decrypt - this cast will throw if wrong, but we should
  +             // not have been able to get through algorithm checks otherwise
  +             XSECCryptoSymmetricKey * sk = 
dynamic_cast<XSECCryptoSymmetricKey *>(key);
  +
  +             sk->decryptInit(false); // No padding
  +             // If key is bigger than this, then we have a problem
  +             sz = sk->decrypt(cipherSB.rawBuffer(), buf, offset, 
_MY_MAX_KEY_SIZE);
  +
  +             sz += sk->decryptFinish(&buf[sz], _MY_MAX_KEY_SIZE - sz);
  +
  +             if (sz <= 0) {
  +                     throw XSECException(XSECException::CipherError, 
  +                             "XENCAlgorithmHandlerDefault - Error decrypting 
key!");
  +             }
  +
  +             // We now have the first cut, reverse the key
  +             XMLByte buf2[_MY_MAX_KEY_SIZE];
  +             for (int i = 0; i < sz; ++ i) {
  +                     buf2[sz - i] = buf[i];
  +             }
   
  +             // decrypt again
  +             sk->decryptInit(false);
  +             offset = sk->decrypt(buf2, buf, sz, _MY_MAX_KEY_SIZE);
  +             offset += sk->decryptFinish(&buf[offset], _MY_MAX_KEY_SIZE - 
offset);
  +
  +#endif
   
   // 
--------------------------------------------------------------------------------
   //                   SafeBuffer decryption
   // 
--------------------------------------------------------------------------------
   
  -bool XENCAlgorithmHandlerDefault::decryptToSafeBuffer(
  +unsigned int XENCAlgorithmHandlerDefault::decryptToSafeBuffer(
                TXFMChain * cipherText,
                XENCEncryptionMethod * encryptionMethod,
                XSECCryptoKey * key,
  @@ -120,6 +369,32 @@
                safeBuffer & result
                ) {
   
  +     bool isAESKeyWrap = false;
  +
  +     // Is this a keyWrap URI?
  +     if (strEquals(encryptionMethod->getAlgorithm(), 
DSIGConstants::s_unicodeStrURIKW_AES128)) {
  +
  +             if (key->getKeyType() != XSECCryptoKey::KEY_SYMMETRIC || 
  +                     dynamic_cast<XSECCryptoSymmetricKey 
*>(key)->getSymmetricKeyType() !=
  +                     XSECCryptoSymmetricKey::KEY_AES_ECB_128) {
  +
  +                     throw XSECException(XSECException::CipherError, 
  +                             "XENCAlgorithmHandlerDefault - 128bit AES 
Algorithm, but not a AES (ECB) 128 bit key");
  +             
  +             }
  +
  +             isAESKeyWrap = true;
  +
  +     }
  +
  +     if (isAESKeyWrap == true) {
  +
  +             return unwrapKeyAES(cipherText, key, result);
  +
  +     }
  +
  +             
  +
   
        // The default case is to just do a standard, padded block decrypt.
        // So the only thing we have to do is ensure key type matches URI.
  @@ -136,9 +411,20 @@
        // Do the decrypt to the safeBuffer
   
        result.sbStrcpyIn("");
  -     result << cipherText->getLastTxfm();
  +     unsigned int offset = 0;
  +     XMLByte buf[1024];
  +     TXFMBase * b = cipherText->getLastTxfm();
  +
  +     int bytesRead = b->readBytes(buf, 1024);
  +     while (bytesRead > 0) {
  +             result.sbMemcpyIn(offset, buf, bytesRead);
  +             offset += bytesRead;
  +             bytesRead = b->readBytes(buf, 1024);
  +     }
   
  -     return true;
  +     result[offset] = '\0'; 
  +
  +     return offset;
   
   }
   
  @@ -154,6 +440,32 @@
                safeBuffer & result
                ) {
   
  +
  +     bool isAESKeyWrap = false;
  +
  +     // Is this a keyWrap URI?
  +     if (strEquals(encryptionMethod->getAlgorithm(), 
DSIGConstants::s_unicodeStrURIKW_AES128)) {
  +
  +             if (key->getKeyType() != XSECCryptoKey::KEY_SYMMETRIC || 
  +                     dynamic_cast<XSECCryptoSymmetricKey 
*>(key)->getSymmetricKeyType() !=
  +                     XSECCryptoSymmetricKey::KEY_AES_ECB_128) {
  +
  +                     throw XSECException(XSECException::CipherError, 
  +                             "XENCAlgorithmHandlerDefault - 128bit AES 
Algorithm, but not a AES (ECB) 128 bit key");
  +             
  +             }
  +
  +             isAESKeyWrap = true;
  +
  +     }
  +
  +     if (isAESKeyWrap == true) {
  +
  +             return wrapKeyAES(plainText, key, result);
  +
  +     }
  +     
  +     
        // Check the URI and key match
   
        mapURIToKey(encryptionMethod->getAlgorithm(), key);
  @@ -176,6 +488,35 @@
        return true;
   
   }
  +// 
--------------------------------------------------------------------------------
  +//                   Key Creation
  +// 
--------------------------------------------------------------------------------
  +
  +XSECCryptoKey * XENCAlgorithmHandlerDefault::createKeyForURI(
  +             const XMLCh * uri,
  +             unsigned char * keyBuffer,
  +             unsigned int keyLen
  +             ) {
  +
  +     if (strEquals(uri, DSIGConstants::s_unicodeStrURI3DES_CBC)) {
  +
  +             // 3 Key 3DES in CBC mode.
  +             XSECCryptoSymmetricKey * sk = 
  +                     
XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_3DES_CBC_192);
  +
  +             sk->setKey(keyBuffer, keyLen);
  +
  +             return sk;
  +
  +     }
  +
  +     throw XSECException(XSECException::CipherError, 
  +             "XENCAlgorithmHandlerDefault - URI Provided, but cannot create 
associated key");
  +
  +     return NULL;
  +
  +}
  +
   
   // 
--------------------------------------------------------------------------------
   //                   Clone
  
  
  
  1.2       +17 -2     
xml-security/c/src/xenc/impl/XENCAlgorithmHandlerDefault.hpp
  
  Index: XENCAlgorithmHandlerDefault.hpp
  ===================================================================
  RCS file: 
/home/cvs/xml-security/c/src/xenc/impl/XENCAlgorithmHandlerDefault.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCAlgorithmHandlerDefault.hpp   15 Sep 2003 11:53:37 -0000      1.1
  +++ XENCAlgorithmHandlerDefault.hpp   3 Oct 2003 09:50:05 -0000       1.2
  @@ -89,7 +89,7 @@
        virtual ~XENCAlgorithmHandlerDefault() {};
   
   
  -     virtual bool decryptToSafeBuffer(
  +     virtual unsigned int decryptToSafeBuffer(
                TXFMChain * cipherText,
                XENCEncryptionMethod * encryptionMethod,
                XSECCryptoKey * key,
  @@ -105,11 +105,26 @@
                safeBuffer & result
        );
   
  +     virtual XSECCryptoKey * createKeyForURI(
  +             const XMLCh * uri,
  +             unsigned char * keyBuffer,
  +             unsigned int keyLen
  +     );
  +
        virtual XSECAlgorithmHandler * clone(void) const;
   
   private:
   
        void mapURIToKey(const XMLCh * uri, XSECCryptoKey * key);
  +     unsigned int unwrapKeyAES(
  +             TXFMChain * cipherText,
  +             XSECCryptoKey * key,
  +             safeBuffer & result);
  +     bool wrapKeyAES(
  +             TXFMChain * cipherText,
  +             XSECCryptoKey * key,
  +             safeBuffer & result);
  +
   
   };
   
  
  
  
  1.6       +243 -2    xml-security/c/src/xenc/impl/XENCCipherImpl.cpp
  
  Index: XENCCipherImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCCipherImpl.cpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XENCCipherImpl.cpp        17 Sep 2003 10:10:22 -0000      1.5
  +++ XENCCipherImpl.cpp        3 Oct 2003 09:50:05 -0000       1.6
  @@ -74,6 +74,7 @@
   #include <xsec/transformers/TXFMChain.hpp>
   #include <xsec/transformers/TXFMBase.hpp>
   #include <xsec/transformers/TXFMC14n.hpp>
  +#include <xsec/transformers/TXFMSB.hpp>
   #include <xsec/transformers/TXFMDocObject.hpp>
   #include <xsec/utils/XSECDOMUtils.hpp>
   #include <xsec/framework/XSECEnv.hpp>
  @@ -84,6 +85,7 @@
   
   #include "XENCCipherImpl.hpp"
   #include "XENCEncryptedDataImpl.hpp"
  +#include "XENCEncryptedKeyImpl.hpp"
   #include "XENCEncryptionMethodImpl.hpp"
   #include "XENCAlgorithmHandlerDefault.hpp"
   
  @@ -143,6 +145,7 @@
   mp_doc(doc),
   mp_encryptedData(NULL),
   mp_key(NULL),
  +mp_kek(NULL),
   mp_keyInfoResolver(NULL) {
   
        XSECnew(mp_env, XSECEnv(doc));
  @@ -158,6 +161,9 @@
        if (mp_key != NULL)
                delete mp_key;
   
  +     if (mp_kek != NULL)
  +             delete mp_kek;
  +
        if (mp_env != NULL)
                delete mp_env;
   
  @@ -177,6 +183,7 @@
        // Register default encryption algorithm handlers
   
        
XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURI3DES_CBC,
 def);
  +     
XSECPlatformUtils::registerAlgorithmHandler(DSIGConstants::s_unicodeStrURIKW_AES128,
 def);
   
   }
   
  @@ -217,6 +224,27 @@
        return mp_encryptedData;
   
   }
  +// 
--------------------------------------------------------------------------------
  +//                   Keys
  +// 
--------------------------------------------------------------------------------
  +
  +void XENCCipherImpl::setKey(XSECCryptoKey * key) {
  +
  +     if (mp_key != NULL)
  +             delete mp_key;
  +
  +     mp_key = key;
  +
  +}
  +
  +void XENCCipherImpl::setKEK(XSECCryptoKey * key) {
  +
  +     if (mp_kek != NULL)
  +             delete mp_kek;
  +
  +     mp_kek = key;
  +
  +}
   
   // 
--------------------------------------------------------------------------------
   //                   Serialise/Deserialise an element
  @@ -355,6 +383,8 @@
   
   DOMDocument * XENCCipherImpl::decryptElement(DOMElement * element) {
   
  +     XSECAlgorithmHandler *handler;
  +
        // First of all load the element
        if (mp_encryptedData != NULL)
                delete mp_encryptedData;
  @@ -373,6 +403,43 @@
   
                if (mp_key == NULL) {
   
  +                     // See if we can decrypt a key in the KeyInfo list
  +                     DSIGKeyInfoList * kil = 
mp_encryptedData->getKeyInfoList();
  +                     int kLen = kil->getSize();
  +
  +                     for (int i = 0; i < kLen ; ++ i) {
  +
  +                             if (kil->item(i)->getKeyInfoType() == 
DSIGKeyInfo::KEYINFO_ENCRYPTEDKEY) {
  +
  +                                     XENCEncryptedKey * ek = 
dynamic_cast<XENCEncryptedKey*>(kil->item(i));
  +                                     XMLByte buffer[1024];
  +                                     int keySize = decryptKey(ek, buffer, 
1024);
  +
  +                                     if (keySize > 0) {
  +                                             // Try to map the key
  +
  +                                             XENCEncryptionMethod * 
encryptionMethod = 
  +                                                     
mp_encryptedData->getEncryptionMethod();
  +
  +                                             if (encryptionMethod != NULL) {
  +             
  +                                                     handler = 
  +                                                             
XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(
  +                                                                     
mp_encryptedData->getEncryptionMethod()->getAlgorithm());
  +
  +                                                     if (handler != NULL)
  +                                                             mp_key = 
handler->createKeyForURI(
  +                                                                             
        mp_encryptedData->getEncryptionMethod()->getAlgorithm(),
  +                                                                             
        buffer,
  +                                                                             
        keySize);
  +                                             }
  +                                     }
  +                             }
  +                     }
  +             }
  +
  +             if (mp_key == NULL) {
  +
                        throw XSECException(XSECException::CipherError, 
                                "XENCCipherImpl::decryptElement - No key set 
and cannot resolve");
                }
  @@ -384,7 +451,6 @@
   
        // Get the Algorithm handler for the algorithm
        XENCEncryptionMethod * encryptionMethod = 
mp_encryptedData->getEncryptionMethod();
  -     XSECAlgorithmHandler *handler;
   
        if (encryptionMethod != NULL) {
                
  @@ -442,6 +508,181 @@
   
        return mp_env->getParentDocument();
   
  +}
  +
  +// 
--------------------------------------------------------------------------------
  +//                   Decrypt a key in an XENCEncryptedKey element
  +// 
--------------------------------------------------------------------------------
  +
  +int XENCCipherImpl::decryptKey(XENCEncryptedKey * encryptedKey, XMLByte * 
rawKey, int maxKeySize) {
  +
  +     // Make sure we have a key before we do anything else too drastic
  +     if (mp_kek == NULL) {
  +
  +             if (mp_keyInfoResolver != NULL)
  +                     mp_kek = 
mp_keyInfoResolver->resolveKey(encryptedKey->getKeyInfoList());
  +
  +             if (mp_kek == NULL) {
  +
  +                     throw XSECException(XSECException::CipherError, 
  +                             "XENCCipherImpl::decryptKey - No KEK set and 
cannot resolve");
  +             }
  +     }
  +
  +     // Get the raw encrypted data
  +     TXFMChain * c = dynamic_cast<XENCEncryptedKeyImpl 
*>(encryptedKey)->createCipherTXFMChain();
  +     Janitor<TXFMChain> j_c(c);
  +
  +     // Get the Algorithm handler for the algorithm
  +     XENCEncryptionMethod * encryptionMethod = 
encryptedKey->getEncryptionMethod();
  +     XSECAlgorithmHandler *handler;
  +
  +     if (encryptionMethod != NULL) {
  +             
  +             handler = 
  +                     XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(
  +                             
encryptedKey->getEncryptionMethod()->getAlgorithm());
  +     
  +     }
  +
  +     else {
  +
  +             handler =
  +                     XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(
  +                             
XSECAlgorithmMapper::s_defaultEncryptionMapping);
  +
  +     }
  +
  +     safeBuffer sb("");
  +     unsigned int keySize;
  +
  +     if (handler != NULL) {
  +
  +             keySize = handler->decryptToSafeBuffer(c, 
  +                     encryptedKey->getEncryptionMethod(), 
  +                     mp_kek,
  +                     mp_env->getParentDocument(),
  +                     sb);
  +     }
  +     else {
  +
  +             // Very strange if we get here - any problems should throw an
  +             // exception in the AlgorithmMapper.
  +
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCCipherImpl::decryptElement - Error retrieving a 
handler for algorithm");
  +
  +     }
  +
  +     keySize = (keySize < maxKeySize ? keySize : maxKeySize);
  +     memcpy(rawKey, sb.rawBuffer(), keySize);
  +
  +     return keySize;
  +}
  +
  +// 
--------------------------------------------------------------------------------
  +//                   Encrypt a key
  +// 
--------------------------------------------------------------------------------
  +
  +XENCEncryptedKey * XENCCipherImpl::encryptKey(
  +             const unsigned char * keyBuffer,
  +             unsigned int keyLen,
  +             encryptionMethod em,
  +             const XMLCh * algorithmURI) {
  +
  +     if (mp_kek == NULL) {
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCCipherImpl::encryptKey - No KEK set");
  +     }
  +
  +     // Map the encryption method to a URI
  +     safeBuffer algorithmSB;
  +     const XMLCh * algorithm;
  +
  +     if (em == ENCRYPT_NONE) {
  +             algorithm = algorithmURI;
  +     }
  +     else {
  +             if (encryptionMethod2URI(algorithmSB, em) != true) {
  +                     throw XSECException(XSECException::CipherError, 
  +                             "XENCCipherImpl::encryptKey - Unknown 
encryption method");
  +             }
  +             algorithm = algorithmSB.sbStrToXMLCh();
  +     }
  +
  +     // Create the element with a dummy encrypted value
  +
  +     XENCEncryptedKeyImpl * encryptedKey;
  +     
  +     XSECnew(encryptedKey, XENCEncryptedKeyImpl(mp_env));
  +     Janitor<XENCEncryptedKeyImpl> j_encryptedKey(encryptedKey);
  +
  +     encryptedKey->createBlankEncryptedKey(
  +             XENCCipherData::VALUE_TYPE,
  +             algorithm,
  +             s_noData);
  +
  +
  +     // Create a transform chain to do pass the key to the encrypto
  +     
  +     safeBuffer rawKey;
  +     rawKey.isSensitive();
  +     rawKey.sbMemcpyIn(keyBuffer, keyLen);
  +
  +     TXFMSB * tsb;
  +     XSECnew(tsb, TXFMSB(mp_doc));
  +
  +     TXFMChain * c;
  +     XSECnew(c, TXFMChain(tsb));
  +     Janitor<TXFMChain> j_c(c);
  +     
  +     tsb->setInput(rawKey, keyLen);
  +
  +     // Perform the encryption
  +     XSECAlgorithmHandler *handler;
  +
  +     if (algorithm != NULL) {
  +             
  +             handler = 
  +                     
XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(algorithm);
  +     
  +     }
  +
  +     else {
  +
  +             handler =
  +                     XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(
  +                             
XSECAlgorithmMapper::s_defaultEncryptionMapping);
  +
  +     }
  +
  +     safeBuffer sb;
  +
  +     if (handler != NULL) {
  +
  +             handler->encryptToSafeBuffer(c, 
  +                     encryptedKey->getEncryptionMethod(), 
  +                     mp_kek,
  +                     mp_env->getParentDocument(),
  +                     sb);
  +     }
  +     else {
  +
  +             // Very strange if we get here - any problems should throw an
  +             // exception in the AlgorithmMapper.
  +
  +             throw XSECException(XSECException::CipherError, 
  +                     "XENCCipherImpl::encryptKey - Error retrieving a 
handler for algorithm");
  +
  +     }
  +
  +     // Set the value
  +     XENCCipherValue * val = encryptedKey->getCipherData()->getCipherValue();
  +
  +     val->setCipherString(sb.sbStrToXMLCh());
  +
  +     j_encryptedKey.release();
  +     return encryptedKey;
   }
   
   // 
--------------------------------------------------------------------------------
  
  
  
  1.7       +20 -2     xml-security/c/src/xenc/impl/XENCCipherImpl.hpp
  
  Index: XENCCipherImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCCipherImpl.hpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XENCCipherImpl.hpp        17 Sep 2003 10:10:22 -0000      1.6
  +++ XENCCipherImpl.hpp        3 Oct 2003 09:50:05 -0000       1.7
  @@ -96,12 +96,26 @@
        XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * 
                decryptElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * 
element);
   
  +     // Decrypting Keys
  +     virtual int decryptKey(XENCEncryptedKey * encryptedKey, 
  +             XMLByte * rawKey,
  +             int maxKeySize);
  +
        // Implementation for encryption Elements
        XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * encryptElement(
                XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * element,
                encryptionMethod em,
                const XMLCh * uri = NULL);
   
  +     // Encrypt a key
  +     virtual XENCEncryptedKey * encryptKey(
  +             const unsigned char * keyBuffer,
  +             unsigned int keyLen,
  +             encryptionMethod em,
  +             const XMLCh * algorithmURI = NULL
  +     );
  +
  +
        // Getter methods
        XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getDocument(void) 
                {return mp_doc;}
  @@ -109,7 +123,8 @@
        virtual XENCEncryptedData * getEncryptedData(void);
   
        // Setter methods
  -     void setKey(XSECCryptoKey * key) {mp_key = key;}
  +     void setKey(XSECCryptoKey * key);
  +     void setKEK(XSECCryptoKey * key);
        void setKeyInfoResolver(const XSECKeyInfoResolver * resolver);
   
        void setXENCNSPrefix(const XMLCh * prefix);
  @@ -149,6 +164,9 @@
   
        // Key
        XSECCryptoKey                   * mp_key;
  +
  +     // KEK
  +     XSECCryptoKey                   * mp_kek;
   
        // Environment
        XSECEnv                                 * mp_env;
  
  
  
  1.6       +3 -1      xml-security/c/src/xenc/impl/XENCEncryptedDataImpl.hpp
  
  Index: XENCEncryptedDataImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCEncryptedDataImpl.hpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XENCEncryptedDataImpl.hpp 17 Sep 2003 10:10:22 -0000      1.5
  +++ XENCEncryptedDataImpl.hpp 3 Oct 2003 09:50:05 -0000       1.6
  @@ -114,6 +114,8 @@
                {return XENCEncryptedTypeImpl::appendKeyName(name, isDName);}
        virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * getDOMNode(void)
                {return XENCEncryptedTypeImpl::getDOMNode();}
  +     virtual void appendEncryptedKey(XENCEncryptedKey * encryptedKey)
  +             {XENCEncryptedTypeImpl::appendEncryptedKey(encryptedKey);}
   
   private:
   
  
  
  
  1.6       +10 -1     xml-security/c/src/xenc/impl/XENCEncryptedTypeImpl.cpp
  
  Index: XENCEncryptedTypeImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCEncryptedTypeImpl.cpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XENCEncryptedTypeImpl.cpp 17 Sep 2003 10:10:22 -0000      1.5
  +++ XENCEncryptedTypeImpl.cpp 3 Oct 2003 09:50:05 -0000       1.6
  @@ -74,6 +74,8 @@
   #include "XENCEncryptedTypeImpl.hpp"
   #include "XENCEncryptionMethodImpl.hpp"
   
  +#include <xsec/xenc/XENCEncryptedKey.hpp>
  +
   #include <xsec/framework/XSECError.hpp>
   #include <xsec/utils/XSECDOMUtils.hpp>
   #include <xsec/transformers/TXFMBase64.hpp>
  @@ -423,5 +425,12 @@
   
        createKeyInfoElement();
        return m_keyInfoList.appendKeyName(name, isDName);
  +
  +}
  +
  +void XENCEncryptedTypeImpl::appendEncryptedKey(XENCEncryptedKey * 
encryptedKey) {
  +
  +     createKeyInfoElement();
  +     m_keyInfoList.addAndInsertKeyInfo(encryptedKey);
   
   }
  
  
  
  1.7       +3 -1      xml-security/c/src/xenc/impl/XENCEncryptedTypeImpl.hpp
  
  Index: XENCEncryptedTypeImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCEncryptedTypeImpl.hpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XENCEncryptedTypeImpl.hpp 17 Sep 2003 10:10:22 -0000      1.6
  +++ XENCEncryptedTypeImpl.hpp 3 Oct 2003 09:50:05 -0000       1.7
  @@ -117,6 +117,8 @@
        virtual DSIGKeyInfoName * appendKeyName(const XMLCh * name, bool 
isDName = false);
        virtual XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * getDOMNode(void)
                {return mp_encryptedTypeNode;}
  +     virtual void appendEncryptedKey(XENCEncryptedKey * encryptedKey);
  +
   
   
   protected:
  
  
  

Reply via email to