You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by bl...@apache.org on 2003/10/03 11:50:06 UTC

cvs commit: xml-security/c/src/xenc/impl XENCAlgorithmHandlerDefault.cpp XENCAlgorithmHandlerDefault.hpp XENCCipherImpl.cpp XENCCipherImpl.hpp XENCEncryptedDataImpl.hpp XENCEncryptedTypeImpl.cpp XENCEncryptedTypeImpl.hpp

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: