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/11/03 07:55:45 UTC

cvs commit: xml-security/c/src/tools/xtest xtest.cpp

blautenb    2003/11/02 22:55:45

  Modified:    c/src/enc XSECCryptoProvider.hpp
               c/src/enc/OpenSSL OpenSSLCryptoKeyRSA.cpp
                        OpenSSLCryptoProvider.cpp OpenSSLCryptoProvider.hpp
               c/src/enc/WinCAPI WinCAPICryptoKeyRSA.cpp
                        WinCAPICryptoKeyRSA.hpp WinCAPICryptoProvider.cpp
                        WinCAPICryptoProvider.hpp
                        WinCAPICryptoSymmetricKey.cpp
               c/src/tools/cipher MerlinFiveInteropResolver.cpp
               c/src/tools/xtest xtest.cpp
  Log:
  Implemented RSA (PKCS1.5 padding)/3DES/AES key wraps in Windows Crypto API
  
  Revision  Changes    Path
  1.12      +12 -1     xml-security/c/src/enc/XSECCryptoProvider.hpp
  
  Index: XSECCryptoProvider.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/XSECCryptoProvider.hpp,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- XSECCryptoProvider.hpp	3 Oct 2003 09:54:46 -0000	1.11
  +++ XSECCryptoProvider.hpp	3 Nov 2003 06:55:45 -0000	1.12
  @@ -329,6 +329,17 @@
   
   	//@}
   
  +	/** @name Information Functions */
  +	//@{
  +
  +	/**
  +	 * \brief Returns a string that identifies the Crypto Provider
  +	 */
  +
  +	virtual const XMLCh * getProviderName() = 0;
  +
  +	//@}
  +
   	/*\@}*/
   };
   
  
  
  
  1.9       +2 -2      xml-security/c/src/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp
  
  Index: OpenSSLCryptoKeyRSA.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/OpenSSL/OpenSSLCryptoKeyRSA.cpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- OpenSSLCryptoKeyRSA.cpp	19 Oct 2003 10:57:54 -0000	1.8
  +++ OpenSSLCryptoKeyRSA.cpp	3 Nov 2003 06:55:45 -0000	1.9
  @@ -378,7 +378,7 @@
   	if (mp_rsaKey == NULL) {
   
   		throw XSECCryptoException(XSECCryptoException::RSAError,
  -			"OpenSSL:RSA - Attempt to encrypt data with empty key");
  +			"OpenSSL:RSA - Attempt to decrypt data with empty key");
   	}
   
   	int decryptSize;
  
  
  
  1.9       +6 -1      xml-security/c/src/enc/OpenSSL/OpenSSLCryptoProvider.cpp
  
  Index: OpenSSLCryptoProvider.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/OpenSSL/OpenSSLCryptoProvider.cpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- OpenSSLCryptoProvider.cpp	3 Oct 2003 09:54:46 -0000	1.8
  +++ OpenSSLCryptoProvider.cpp	3 Nov 2003 06:55:45 -0000	1.9
  @@ -96,6 +96,11 @@
   
   OpenSSLCryptoProvider::~OpenSSLCryptoProvider() {}
   
  +const XMLCh * OpenSSLCryptoProvider::getProviderName() {
  +
  +	return DSIGConstants::s_unicodeStrPROVOpenSSL;
  +
  +}
   	// Hashing classes
   
   XSECCryptoHash	* OpenSSLCryptoProvider::hashSHA1() {
  
  
  
  1.9       +12 -1     xml-security/c/src/enc/OpenSSL/OpenSSLCryptoProvider.hpp
  
  Index: OpenSSLCryptoProvider.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/OpenSSL/OpenSSLCryptoProvider.hpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- OpenSSLCryptoProvider.hpp	3 Oct 2003 09:54:46 -0000	1.8
  +++ OpenSSLCryptoProvider.hpp	3 Nov 2003 06:55:45 -0000	1.9
  @@ -246,6 +246,17 @@
   
   	//@}
   
  +	/** @name Information Functions */
  +	//@{
  +
  +	/**
  +	 * \brief Returns a string that identifies the Crypto Provider
  +	 */
  +
  +	virtual const XMLCh * getProviderName();
  +
  +	//@}
  +
   	/*\@}*/
   
   };
  
  
  
  1.5       +121 -2    xml-security/c/src/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp
  
  Index: WinCAPICryptoKeyRSA.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- WinCAPICryptoKeyRSA.cpp	19 Oct 2003 10:57:54 -0000	1.4
  +++ WinCAPICryptoKeyRSA.cpp	3 Nov 2003 06:55:45 -0000	1.5
  @@ -134,7 +134,12 @@
   		
   	}
   
  -	m_key = 0;
  +	if (!CryptGetUserKey(prov, keySpec, &m_key)) {
  +		throw XSECCryptoException(XSECCryptoException::RSAError,
  +			"WinCAPI:RSA Unable to retrieve user key");
  +	}
  +
  +	//m_key = 0;
   	m_keySpec = keySpec;
   
   	mp_exponent = mp_modulus = NULL;
  @@ -494,6 +499,120 @@
   	return ret;
   
   }
  +
  +// --------------------------------------------------------------------------------
  +//           decrypt a buffer
  +// --------------------------------------------------------------------------------
  +
  +unsigned int WinCAPICryptoKeyRSA::privateDecrypt(const unsigned char * inBuf,
  +								 unsigned char * plainBuf, 
  +								 unsigned int inLength,
  +								 unsigned int maxOutLength,
  +								 PaddingType padding,
  +								 hashMethod hm,
  +								 const unsigned char * OEAPParam,
  +								 unsigned int OAPEParamLen) {
  +
  +	// Perform a decrypt
  +	if (m_key == 0) {
  +
  +		throw XSECCryptoException(XSECCryptoException::RSAError,
  +			"WinCAPI:RSA - Attempt to decrypt data with empty key");
  +	}
  +
  +	DWORD decryptSize = inLength;
  +	memcpy(plainBuf, inBuf, inLength);
  +
  +	switch (padding) {
  +
  +	case XSECCryptoKeyRSA::PAD_PKCS_1_5 :
  +
  +		if (!CryptDecrypt(m_key,
  +						 0,
  +						 TRUE,
  +						 0,
  +						 plainBuf,
  +						 &decryptSize)) {
  +
  +			throw XSECCryptoException(XSECCryptoException::RSAError,
  +				"WinCAPI:RSA privateKeyDecrypt - Error Decrypting PKCS1_5 padded RSA encrypt");
  +
  +		}
  +
  +		break;
  +
  +	default :
  +
  +		throw XSECCryptoException(XSECCryptoException::RSAError,
  +			"OpenSSL:RSA - Unknown padding method");
  +
  +	}
  +
  +
  +	return decryptSize;
  +
  +}
  +
  +// --------------------------------------------------------------------------------
  +//           encrypt a buffer
  +// --------------------------------------------------------------------------------
  +
  +unsigned int WinCAPICryptoKeyRSA::publicEncrypt(const unsigned char * inBuf,
  +								 unsigned char * cipherBuf, 
  +								 unsigned int inLength,
  +								 unsigned int maxOutLength,
  +								 PaddingType padding,
  +								 hashMethod hm,
  +								 const unsigned char * OEAPParam,
  +								 unsigned int OAPEParamLen) {
  +
  +	// Perform an encrypt
  +	if (m_key == 0) {
  +
  +		throw XSECCryptoException(XSECCryptoException::RSAError,
  +			"WinCAPI:RSA - Attempt to encrypt data with empty key");
  +	}
  +
  +	DWORD encryptSize = inLength;
  +	memcpy(cipherBuf, inBuf, inLength);
  +
  +	switch (padding) {
  +
  +	case XSECCryptoKeyRSA::PAD_PKCS_1_5 :
  +
  +		if (!CryptEncrypt(m_key,
  +						  0,			/* No Hash */
  +						  TRUE,			/* Is Final */
  +						  0,			/* No flags */
  +						  cipherBuf,
  +						  &encryptSize,
  +						  maxOutLength)) {
  +
  +			throw XSECCryptoException(XSECCryptoException::RSAError,
  +				"WinCAPI:RSA publicKeyEncrypt - Error performing encrypt");
  +		}
  +
  +		if (encryptSize <= 0) {
  +
  +			throw XSECCryptoException(XSECCryptoException::RSAError,
  +				"WinCAPI:RSA publicKeyEncrypt - Error performing PKCS1_5 padded RSA encrypt");
  +
  +		}
  +
  +		break;
  +
  +	default :
  +
  +		throw XSECCryptoException(XSECCryptoException::RSAError,
  +			"WinCAPI:RSA - Unknown padding method");
  +
  +	}
  +
  +
  +	return encryptSize;
  +
  +}
  +
   // --------------------------------------------------------------------------------
   //           Size in bytes
   // --------------------------------------------------------------------------------
  
  
  
  1.6       +3 -3      xml-security/c/src/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp
  
  Index: WinCAPICryptoKeyRSA.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- WinCAPICryptoKeyRSA.hpp	19 Oct 2003 10:57:54 -0000	1.5
  +++ WinCAPICryptoKeyRSA.hpp	3 Nov 2003 06:55:45 -0000	1.6
  @@ -236,7 +236,7 @@
   								 PaddingType padding,
   								 hashMethod hm,
   								 const unsigned char * OEAPParam,
  -								 unsigned int OAPEParamLen) { return 0; /* Not implementd */}
  +								 unsigned int OAPEParamLen);
   
   	/**
   	 * \brief Encrypt using a public key
  @@ -261,7 +261,7 @@
   								 PaddingType padding,
   								 hashMethod hm,
   								 const unsigned char * OEAPParam,
  -								 unsigned int OAPEParamLen) {return 0; /* Not implemented */}
  +								 unsigned int OAPEParamLen);
   
   	/**
   	 * \brief Obtain the length of an RSA key
  
  
  
  1.10      +8 -1      xml-security/c/src/enc/WinCAPI/WinCAPICryptoProvider.cpp
  
  Index: WinCAPICryptoProvider.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/WinCAPI/WinCAPICryptoProvider.cpp,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- WinCAPICryptoProvider.cpp	13 Oct 2003 11:07:17 -0000	1.9
  +++ WinCAPICryptoProvider.cpp	3 Nov 2003 06:55:45 -0000	1.10
  @@ -193,6 +193,13 @@
   
   }
   
  +const XMLCh * WinCAPICryptoProvider::getProviderName() {
  +
  +	return DSIGConstants::s_unicodeStrPROVWinCAPI;
  +
  +}
  +
  +
   // Hashing classes
   
   XSECCryptoHash	* WinCAPICryptoProvider::hashSHA1() {
  
  
  
  1.10      +13 -1     xml-security/c/src/enc/WinCAPI/WinCAPICryptoProvider.hpp
  
  Index: WinCAPICryptoProvider.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/WinCAPI/WinCAPICryptoProvider.hpp,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- WinCAPICryptoProvider.hpp	13 Oct 2003 11:07:17 -0000	1.9
  +++ WinCAPICryptoProvider.hpp	3 Nov 2003 06:55:45 -0000	1.10
  @@ -343,6 +343,18 @@
   
   	//@}
   
  +	/** @name Information Functions */
  +	//@{
  +
  +	/**
  +	 * \brief Returns a string that identifies the Crypto Provider
  +	 */
  +
  +	virtual const XMLCh * getProviderName();
  +
  +	//@}
  +
  +
   private:
   
   	HCRYPTPROV		m_provDSS;
  
  
  
  1.4       +111 -57   xml-security/c/src/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp
  
  Index: WinCAPICryptoSymmetricKey.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- WinCAPICryptoSymmetricKey.cpp	28 Oct 2003 09:33:18 -0000	1.3
  +++ WinCAPICryptoSymmetricKey.cpp	3 Nov 2003 06:55:45 -0000	1.4
  @@ -193,33 +193,49 @@
   
   	}
   
  -	int ret = 0;
  -
  -	// Set up the context according to the required cipher type
   	DWORD cryptMode;
  -	switch (m_keyType) {
  +	if (m_keyMode == MODE_CBC) {
   
  -	case (XSECCryptoSymmetricKey::KEY_3DES_192) :
  +		if (iv == NULL) {
   
  -		// A 3DES CBC key
  +			return 0;	// Cannot initialise without an IV
   
  -		if (m_keyMode == MODE_CBC) {
  -			
  -			if (iv == NULL) {
  +		}
  +		
  +		cryptMode = CRYPT_MODE_CBC;
   
  -				return 0;	// Cannot initialise without an IV
  +		if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
   
  -			}
  +			throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +				"WinCAPI:SymmetricKey - Error setting cipher mode"); 
   
  -			if (!CryptSetKeyParam(m_k, KP_IV, (unsigned char *) iv, 0)) {
  +		}
  +		
  +		if (!CryptSetKeyParam(m_k, KP_IV, (unsigned char *) iv, 0)) {
   
  -				throw XSECCryptoException(XSECCryptoException::SymmetricError,
  -				"WinCAPI:SymmetricKey - Error setting IV"); 
  +			throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +			"WinCAPI:SymmetricKey - Error setting IV"); 
   
  -			}
  +		}
  +
  +	}
  +	else {
  +		cryptMode = CRYPT_MODE_ECB;
  +
  +		if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
  +
  +			throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +				"WinCAPI:SymmetricKey - Error setting cipher mode"); 
   
  -			ret = 8;
   		}
  +	}
  +
  +	// Set up the context according to the required cipher type
  +	switch (m_keyType) {
  +
  +	case (XSECCryptoSymmetricKey::KEY_3DES_192) :
  +
  +		// A 3DES CBC key
   
   		m_blockSize = 8;
   		m_bytesInLastBlock = 0;
  @@ -228,22 +244,10 @@
   		break;
   
   	case (XSECCryptoSymmetricKey::KEY_AES_128) :
  +	case (XSECCryptoSymmetricKey::KEY_AES_192) :
  +	case (XSECCryptoSymmetricKey::KEY_AES_256) :
   
  -		// An 128bit AES key
  -
  -		if (m_keyMode == MODE_ECB)
  -			cryptMode = CRYPT_MODE_ECB;
  -		else {
  -			cryptMode = CRYPT_MODE_CBC;
  -			ret = 16;
  -		}
  -
  -		if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
  -
  -			throw XSECCryptoException(XSECCryptoException::SymmetricError,
  -			"WinCAPI:SymmetricKey - Error setting cipher mode"); 
  -
  -		}
  +		// An AES key
   
   		m_blockSize = 16;
   		m_bytesInLastBlock = 0;
  @@ -259,7 +263,7 @@
   
   	}
   
  -	return ret;
  +	return (m_keyMode == MODE_CBC ? m_blockSize : 0);
   }
   
   
  @@ -356,6 +360,10 @@
   
   	}
   
  +	// This is just to reset the key, and does nothing else useful.
  +	DWORD tmpout = maxOutLength - outl;
  +	CryptDecrypt(m_k, 0, TRUE, 0, &plainBuf[outl], &tmpout);
  +
   	return outl;
   }
   
  @@ -383,55 +391,83 @@
   
   	const unsigned char * usedIV;
   	unsigned char genIV[256];
  +	DWORD cryptMode;
   
   	// Tell the library that the IV still has to be sent
   
  -	switch (m_keyType) {
  +	if (m_keyMode == MODE_CBC) {
   
  -	case (XSECCryptoSymmetricKey::KEY_3DES_192) :
  +		if (iv == NULL) {
  +			
  +			BOOL res = CryptGenRandom(m_p, 256, genIV);
  +			if (res == FALSE) {
  +				throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +					"WinCAPI:SymmetricKey - Error generating random IV");
  +			}
   
  -		// A 3DES key
  +			usedIV = genIV;
  +			//return 0;	// Cannot initialise without an IV
   
  -		if (m_keyMode == MODE_CBC) {
  +		}
  +		else
  +			usedIV = iv;
   
  -			if (iv == NULL) {
  -				
  -				BOOL res = CryptGenRandom(m_p, 256, genIV);
  -				if (res == FALSE) {
  -					throw XSECCryptoException(XSECCryptoException::SymmetricError,
  -						"WinCAPI:SymmetricKey - Error generating random IV");
  -				}
  +		cryptMode = CRYPT_MODE_CBC;
   
  -				usedIV = genIV;
  -				//return 0;	// Cannot initialise without an IV
  +		if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
   
  -			}
  -			else
  -				usedIV = iv;
  +			throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +				"WinCAPI:SymmetricKey - Error setting cipher mode"); 
   
  -			// Set the IV parameter
  -			if (!CryptSetKeyParam(m_k, KP_IV, (unsigned char *) usedIV, 0)) {
  +		}
   
  -				throw XSECCryptoException(XSECCryptoException::SymmetricError,
  -				"WinCAPI:SymmetricKey - Error setting IV"); 
  +		// Set the IV parameter
  +		if (!CryptSetKeyParam(m_k, KP_IV, (unsigned char *) usedIV, 0)) {
   
  -			}
  +			throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +			"WinCAPI:SymmetricKey - Error setting IV"); 
   
   		}
   
  +	}
  +	else {
  +
  +		cryptMode = CRYPT_MODE_ECB;
  +
  +		if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
  +
  +			throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +				"WinCAPI:SymmetricKey - Error setting cipher mode"); 
  +
  +		}
  +	}
  +
  +	switch (m_keyType) {
  +
  +	case (XSECCryptoSymmetricKey::KEY_3DES_192) :
  +
  +		// A 3DES key
  +
   		m_blockSize = 8;
  -		m_ivSize = 8;
  -		memcpy(m_lastBlock, usedIV, m_ivSize);
  +		if (m_keyMode == MODE_CBC)
  +			m_ivSize = 8;
  +		else 
  +			m_ivSize = 0;
   		m_bytesInLastBlock = 0;
   
   		break;
   
   	case (XSECCryptoSymmetricKey::KEY_AES_128) :
  +	case (XSECCryptoSymmetricKey::KEY_AES_192) :
  +	case (XSECCryptoSymmetricKey::KEY_AES_256) :
   
   		// An AES key
   
   		m_blockSize = 16;
  -		m_ivSize = 0;
  +		if (m_keyMode == MODE_CBC)
  +			m_ivSize = 16;
  +		else 
  +			m_ivSize = 0;
   		m_bytesInLastBlock = 0;
   
   		break;
  @@ -444,6 +480,9 @@
   
   	}
   
  +	memcpy(m_lastBlock, usedIV, m_ivSize);
  +
  +
   }
   bool WinCAPICryptoSymmetricKey::encryptInit(bool doPad, 
   											SymmetricKeyMode mode, 
  @@ -479,6 +518,13 @@
   	
   	if (m_ivSize > 0) {
   
  +		DWORD len = 16;
  +		if (!CryptGetKeyParam(m_k, KP_IV, (unsigned char *) m_lastBlock, &len, 0)) {
  +
  +			throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +			"WinCAPI:SymmetricKey - Error setting IV"); 
  +
  +		}
   		memcpy(cipherBuf, m_lastBlock, m_ivSize);
   		offset = m_ivSize;
   		outl += m_ivSize;
  @@ -655,6 +701,14 @@
   	case (XSECCryptoSymmetricKey::KEY_AES_128) :
   					blobHeader->aiKeyAlg = CALG_AES_128;
   					expectedLength = 16;
  +					break;
  +	case (XSECCryptoSymmetricKey::KEY_AES_192) :
  +					blobHeader->aiKeyAlg = CALG_AES_192;
  +					expectedLength = 24;
  +					break;
  +	case (XSECCryptoSymmetricKey::KEY_AES_256) :
  +					blobHeader->aiKeyAlg = CALG_AES_256;
  +					expectedLength = 32;
   					break;
   	default :
   
  
  
  
  1.7       +12 -4     xml-security/c/src/tools/cipher/MerlinFiveInteropResolver.cpp
  
  Index: MerlinFiveInteropResolver.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/tools/cipher/MerlinFiveInteropResolver.cpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- MerlinFiveInteropResolver.cpp	28 Oct 2003 09:33:18 -0000	1.6
  +++ MerlinFiveInteropResolver.cpp	3 Nov 2003 06:55:45 -0000	1.7
  @@ -338,16 +338,24 @@
   					}*/
   
   				}
  +#if defined (HAVE_WINCAPI)
  +				else {
  +#endif /* HAVE_WINCAPI */
  +#endif /* HAVE_OPENSSL */
  +
  +#if defined (HAVE_WINCAPI)
  +					std::cerr << "WARNING - Unable to load PKCS8 private key file into Windows CAPI" << std::endl;
  +#if defined (HAVE_OPENSSL)
  +				}
  +#endif /* HAVE_WINCAPI */
  +#endif /* HAVE_OPENSSL */
   			}
  -#endif
   		}
   	}
   
   	return NULL;
   
   }
  -
  -
   
   XSECKeyInfoResolver * MerlinFiveInteropResolver::clone(void) const {
   
  
  
  
  1.29      +127 -44   xml-security/c/src/tools/xtest/xtest.cpp
  
  Index: xtest.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/tools/xtest/xtest.cpp,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- xtest.cpp	2 Nov 2003 23:11:30 -0000	1.28
  +++ xtest.cpp	3 Nov 2003 06:55:45 -0000	1.29
  @@ -138,6 +138,8 @@
   #endif
   #if defined (HAVE_WINCAPI)
   #	include <xsec/enc/WinCAPI/WinCAPICryptoKeyHMAC.hpp>
  +#	include <xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp>
  +#	include <xsec/enc/WinCAPI/WinCAPICryptoProvider.hpp>
   #endif
   
   using std::ostream;
  @@ -158,6 +160,8 @@
   // --------------------------------------------------------------------------------
   
   bool	g_printDocs = false;
  +bool	g_useWinCAPI = false;
  +
   // --------------------------------------------------------------------------------
   //           Known "Good" Values
   // --------------------------------------------------------------------------------
  @@ -328,22 +332,42 @@
   
   	// Create the HMAC key
   	static bool first = true;
  +	XSECCryptoKeyHMAC * hmacKey;
   
  -#if defined (HAVE_OPENSSL)
  -	OpenSSLCryptoKeyHMAC * hmacKey = new OpenSSLCryptoKeyHMAC();
  -	if (first) {
  -		cerr << "Using OpenSSL as the cryptography provider" << endl;
  -		first = false;
  +#if defined (HAVE_OPENSSL) && defined(HAVE_WINCAPI)
  +
  +	if (g_useWinCAPI == true) {
  +		hmacKey = new WinCAPICryptoKeyHMAC(0);
  +		if (first) {
  +			cerr << "Using Windows Crypto API as the cryptography provider" << endl;
  +			first = false;
  +		}
   	}
  -#else
  -#	if defined (HAVE_WINCAPI)
  -	WinCAPICryptoKeyHMAC * hmacKey = new WinCAPICryptoKeyHMAC(0);
  -	if (first) {
  -		cerr << "Using Windows Crypto API as the cryptography provider" << endl;
  -		first = false;
  +	else {
  +		hmacKey = new OpenSSLCryptoKeyHMAC();
  +		if (first) {
  +			cerr << "Using OpenSSL as the cryptography provider" << endl;
  +			first = false;
  +		}
   	}
  +#else
  +#	if defined (HAVE_OPENSSL)
  +		OpenSSLCryptoKeyHMAC * hmacKey = new OpenSSLCryptoKeyHMAC();
  +		if (first) {
  +			cerr << "Using OpenSSL as the cryptography provider" << endl;
  +			first = false;
  +		}
  +#	else
  +#		if defined (HAVE_WINCAPI)
  +		WinCAPICryptoKeyHMAC * hmacKey = new WinCAPICryptoKeyHMAC(0);
  +		if (first) {
  +			cerr << "Using Windows Crypto API as the cryptography provider" << endl;
  +			first = false;
  +		}
  +#		endif
   #	endif
   #endif
  +
   	hmacKey->setKey((unsigned char *) str, strlen((char *)str));
   
   	return hmacKey;
  @@ -892,52 +916,85 @@
   
   void unitTestEncrypt(DOMImplementation *impl) {
   
  -	// Key wraps
  -	cerr << "RSA key wrap... ";
  -	
  +	try {
  +		// Key wraps
  +		cerr << "RSA key wrap... ";
  +
  +#if defined (HAVE_OPENSSL) && defined (HAVE_WINCAPI)
  +		if (!g_useWinCAPI) {
  +#endif
  +
   #if defined (HAVE_OPENSSL)
  -	// Load the key
  -	BIO * bioMem = BIO_new(BIO_s_mem());
  -	BIO_puts(bioMem, s_tstRSAPrivateKey);
  -	EVP_PKEY * pk = PEM_read_bio_PrivateKey(bioMem, NULL, NULL, NULL);
  +		// Load the key
  +		BIO * bioMem = BIO_new(BIO_s_mem());
  +		BIO_puts(bioMem, s_tstRSAPrivateKey);
  +		EVP_PKEY * pk = PEM_read_bio_PrivateKey(bioMem, NULL, NULL, NULL);
   
  -	OpenSSLCryptoKeyRSA * k = new OpenSSLCryptoKeyRSA(pk);
  +		OpenSSLCryptoKeyRSA * k = new OpenSSLCryptoKeyRSA(pk);
   
  -	BIO_free(bioMem);
  -	EVP_PKEY_free(pk);
  +		BIO_free(bioMem);
  +		EVP_PKEY_free(pk);
   
  -	unitTestKeyEncrypt(impl, k, ENCRYPT_RSA_15);
  +		unitTestKeyEncrypt(impl, k, ENCRYPT_RSA_15);
   
   #endif
   
  -	cerr << "AES 128 key wrap... ";
  +#if defined (HAVE_OPENSSL) && defined (HAVE_WINCAPI)
  +		} else {
  +#endif
   
  -	XSECCryptoSymmetricKey * ks =
  -			XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_128);
  -	ks->setKey((unsigned char *) s_keyStr, 16);
  -	
  -	unitTestKeyEncrypt(impl, ks, ENCRYPT_KW_AES128);
  +#if defined (HAVE_WINCAPI)
   
  -	cerr << "AES 192 key wrap... ";
  +		// Use the internal key
  +		WinCAPICryptoProvider *cp = dynamic_cast<WinCAPICryptoProvider *>(XSECPlatformUtils::g_cryptoProvider);
  +		HCRYPTPROV p = cp->getApacheKeyStore();
  +		WinCAPICryptoKeyRSA * rsaKey = new WinCAPICryptoKeyRSA(p, AT_KEYEXCHANGE, true);
  +		unitTestKeyEncrypt(impl, rsaKey, ENCRYPT_RSA_15);
   
  -	ks = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_192);
  -	ks->setKey((unsigned char *) s_keyStr, 24);
  -	
  -	unitTestKeyEncrypt(impl, ks, ENCRYPT_KW_AES192);
  +#endif
   
  -	cerr << "AES 256 key wrap... ";
  +#if defined (HAVE_OPENSSL) && defined (HAVE_WINCAPI)
  +		}
  +#endif
   
  -	ks = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_256);
  -	ks->setKey((unsigned char *) s_keyStr, 32);
  -	
  -	unitTestKeyEncrypt(impl, ks, ENCRYPT_KW_AES256);
   
  -	cerr << "Triple DES key wrap... ";
  +		cerr << "AES 128 key wrap... ";
  +
  +		XSECCryptoSymmetricKey * ks =
  +				XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_128);
  +		ks->setKey((unsigned char *) s_keyStr, 16);
  +		
  +		unitTestKeyEncrypt(impl, ks, ENCRYPT_KW_AES128);
  +
  +		cerr << "AES 192 key wrap... ";
  +
  +		ks = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_192);
  +		ks->setKey((unsigned char *) s_keyStr, 24);
  +		
  +		unitTestKeyEncrypt(impl, ks, ENCRYPT_KW_AES192);
  +
  +		cerr << "AES 256 key wrap... ";
  +
  +		ks = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_AES_256);
  +		ks->setKey((unsigned char *) s_keyStr, 32);
  +		
  +		unitTestKeyEncrypt(impl, ks, ENCRYPT_KW_AES256);
  +
  +		cerr << "Triple DES key wrap... ";
  +
  +		ks = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_3DES_192);
  +		ks->setKey((unsigned char *) s_keyStr, 24);
  +		
  +		unitTestKeyEncrypt(impl, ks, ENCRYPT_KW_3DES);
  +	}
  +	catch (XSECCryptoException &e)
  +	{
  +		cerr << "failed\n";
  +		cerr << "A cryptographic error occured during encryption unit tests\n   Message: "
  +		<< e.getMsg() << endl;
  +		exit(1);
  +	}
   
  -	ks = XSECPlatformUtils::g_cryptoProvider->keySymmetric(XSECCryptoSymmetricKey::KEY_3DES_192);
  -	ks->setKey((unsigned char *) s_keyStr, 24);
  -	
  -	unitTestKeyEncrypt(impl, ks, ENCRYPT_KW_3DES);
   
   }
   // --------------------------------------------------------------------------------
  @@ -1143,6 +1200,10 @@
   	cerr << "     Where options are :\n\n";
   	cerr << "     --help/-h\n";
   	cerr << "         This help message\n\n";
  +#if defined (HAVE_WINCAPI)  && defined (HAVE_OPENSSL)
  +	cerr << "     --wincapi/-w\n";
  +	cerr << "         Use Windows Crypto API for crypto functionality\n\n";
  +#endif
   	cerr << "     --print-docs/-p\n";
   	cerr << "         Print the test documents\n\n";
   	cerr << "     --signature-only/-s\n";
  @@ -1182,6 +1243,12 @@
   			g_printDocs = true;
   			paramCount++;
   		}
  +#if defined(HAVE_WINCAPI) && defined(HAVE_OPENSSL)
  +		else if (stricmp(argv[paramCount], "--wincapi") == 0 || stricmp(argv[paramCount], "-w") == 0) {
  +			g_useWinCAPI = true;
  +			paramCount++;
  +		}
  +#endif
   		else if (stricmp(argv[paramCount], "--signature-only") == 0 || stricmp(argv[paramCount], "-s") == 0) {
   			doEncryptionTest = false;
   			doEncryptionUnitTests = false;
  @@ -1228,6 +1295,17 @@
   #endif
   		XSECPlatformUtils::Initialise();
   
  +#if defined (HAVE_OPENSSL) && defined (HAVE_WINCAPI)
  +		if (g_useWinCAPI) {
  +			// Setup for Windows Crypt API
  +			WinCAPICryptoProvider * cp;
  +			// First set windows as the crypto provider
  +			cp = new WinCAPICryptoProvider();
  +			XSECPlatformUtils::SetCryptoProvider(cp);
  +		}
  +#endif
  +
  +
   	}
   	catch (const XMLException &e) {
   
  @@ -1244,6 +1322,11 @@
   		XMLCh tempStr[100];
   		XMLString::transcode("Core", tempStr, 99);    
   		DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);
  +
  +		// Output some info
  +		char * provName = XMLString::transcode(XSECPlatformUtils::g_cryptoProvider->getProviderName());
  +		cerr << "Crypto Provider string : " << provName << endl;
  +		delete[] provName;
   
   		// Test signature functions
   		if (doSignatureTest) {