handlecontainer.cpp
资源名称:pkcs11.rar [点击查看]
上传用户:filter2008
上传日期:2013-02-01
资源大小:101k
文件大小:40k
源码类别:
CA认证
开发平台:
C/C++
- /****************************************************************************
- * library : pkcs_csp.dll
- * Purpose : It is a cryptographic service provider which is an independent
- * software module that actually performs cryptography algorithms for
- * authentication, encoding, and encryption.
- * This DLL can be interfaced on any PKCS#11 module.
- *
- * Copyright (C) 2003 Ilex Syst鑝es Informatiques
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Contact :
- * Ilex
- * 51 boulevard Voltaire
- * 92600 Asni鑢es-sur-Seine
- * pkizy@ilex.fr
- *
- * Author: Delouvrier Antoine
- *
- *******************************************************************************/
- /*
- %----------------------------------------------------------------------------
- % PROJECT : CSP_PKCS
- %
- % MODULE : HandleContainer
- %
- % VERSION : 1.00
- %
- % FILE : HandleContainer.cpp
- %
- % this Class allows to manage a container. When an application obtains a context
- % on a container it is this class which deals with thereafter all the entrance
- % points of the DLL for this specific container. The entrance points are redirected to
- % PKCS#11 functions or to Microsoft Provider functions.
- %----------------------------------------------------------------------------
- % Version 1.00
- %
- % CPX-31/03/2003-Creation
- %----------------------------------------------------------------------------
- % You can find wincrypt.h in the CSPDK which is downloadable at the adress :
- % http://www.microsoft.com/downloads/details.aspx?FamilyId=0F436C75-2304-42BB-B81A-BA0C2C47BAC2&displaylang=en
- */
- /*
- % Libraries ANSI or system
- %------------------------------
- */
- #include <windows.h>
- #include <stdio.h>
- #include "assert.h"
- /*
- % HEADER Files include
- %-----------------------
- */
- #include "handlecontainer.h"
- #include "csp_pkcs_const.h"
- #include "resource.h"
- #define CONTAINER_NAME TEXT("PKCS_CSP")
- extern "C" extern HINSTANCE g_hModule;
- typedef struct SessionKeyHeader
- {
- BLOBHEADER blobHeader;
- ALG_ID algid;
- } SessionKeyHeader, *pSessionKeyHeader;
- //Initialization of static member variable
- TableOfHandle HandleContainer::handles_Container;
- /*
- %--------------------------------------------------------------------------
- % HandleContainer()
- %
- % R鬺e : HandleContainer() is the constructor of the class handlecontainer
- %
- %---------------------------------------------------------------------------
- */
- HandleContainer::HandleContainer()
- {
- }
- /*
- %--------------------------------------------------------------------------
- % ~HandleContainer()
- %
- % destructor
- %---------------------------------------------------------------------------
- */
- HandleContainer::~HandleContainer()
- {
- TRACE(__LINE__,"~HandleContainer() ",NULL);
- handles_Container.RemoveEntry(this);
- }
- /*
- %--------------------------------------------------------------------------
- % Initialize
- %
- % R鬺e : Initialize est utilis閑 pour initialiser l'objet handlecontainer
- %
- % Parameters of entry :
- % IN pszContainer Name of the container
- % IN dwFlags Value of a flag of the type(CRYPT_VERIFYCONTEXTCRYPT_NEWKEYSET),according to this value one can or not to make certain operations on the container
- % IN pVTable Pointer on a VTableProvStruc structure containing a list of functions callback provided by the operating software for the use of the CSP.
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::CreateHandleContainer(const CHAR IN * const pszContainer,const DWORD IN dwFlags, PVTableProvStruc IN pVTable)
- {
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer BEGIN : %d %d %d",pszContainer,dwFlags,pVTable);
- if(!AcquireMicrosoftContext()){
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
- return FALSE;
- }
- if((dwFlags & CRYPT_MACHINE_KEYSET) == CRYPT_MACHINE_KEYSET)
- {
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
- SetLastError(NTE_BAD_FLAGS);
- return FALSE;
- }
- if((dwFlags & CRYPT_VERIFYCONTEXT) == CRYPT_VERIFYCONTEXT){
- if(!handles_Container.AddEntry(this))
- {
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
- SetLastError(NTE_NO_MEMORY);
- return FALSE;
- }
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer TRUE : %d %d %d",pszContainer,dwFlags,pVTable);
- return TRUE;
- }
- if((dwFlags & CRYPT_NEWKEYSET) == CRYPT_NEWKEYSET)
- {
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
- SetLastError(NTE_EXISTS);
- return FALSE;
- }
- else if((dwFlags&CRYPT_DELETEKEYSET) == CRYPT_DELETEKEYSET)
- {
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
- SetLastError(NTE_BAD_KEYSET);
- return FALSE;
- }
- else
- {
- currentPContainer = Pkcs::GetContainer(pszContainer);
- if(!currentPContainer)
- {
- /* If the table of the containers do not exist or if it must change to release that of front*/
- Pkcs::FreeContainer();
- /* recreate a table*/
- Pkcs::CreateContainerTable();
- currentPContainer = Pkcs::GetContainer(pszContainer);
- int ret;
- while(!currentPContainer){
- ret=MessageBox(NULL,"Please insert the card corresponding to the selected certificate.","Insert your card",MB_OKCANCEL|MB_ICONQUESTION|MB_SYSTEMMODAL);
- if(ret==IDCANCEL){
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
- SetLastError(NTE_BAD_KEYSET);
- return FALSE;
- }
- /* If the table of the containers do not exist or if it must change to release that of front*/
- Pkcs::FreeContainer();
- /* recreate a table*/
- Pkcs::CreateContainerTable();
- currentPContainer = Pkcs::GetContainer(pszContainer);
- }
- }
- }
- if(!handles_Container.AddEntry(this))
- {
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
- SetLastError(NTE_NO_MEMORY);
- return FALSE;
- }
- TRACE(__LINE__,"HandleContainer::CreateHandleContainer TRUE : %d %d %d",pszContainer,dwFlags,pVTable);
- return TRUE;
- }
- /*
- %--------------------------------------------------------------------------
- % AcquireMicrosoftContext
- %
- % AcquireMicrosoftContext is used to acquire a context to a microsoft provider
- %
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::AcquireMicrosoftContext()
- {
- CHAR szProviderName[MAX_PATH] = {0};
- /* Try first with enhanced provider , if it fails , try with base provider */
- strcpy(szProviderName,MS_ENHANCED_PROV);
- if(CryptAcquireContext(µsoft_Provider, CONTAINER_NAME, szProviderName, PROV_RSA_FULL, CRYPT_NEWKEYSET))
- {
- return TRUE;
- }
- /* if the container already exists, try to open it */
- if(NTE_EXISTS == GetLastError())
- {
- if(CryptAcquireContext(µsoft_Provider, CONTAINER_NAME, szProviderName, PROV_RSA_FULL,0))
- {
- return TRUE;
- }
- }
- /* the Enhanded provider is not found , try the base provider */
- strcpy(szProviderName, MS_DEF_PROV);
- if(CryptAcquireContext(µsoft_Provider, CONTAINER_NAME, szProviderName, PROV_RSA_FULL, CRYPT_NEWKEYSET))
- {
- return TRUE;
- }
- /* if the container already exists, try to open it */
- if(NTE_EXISTS == GetLastError())
- {
- if(CryptAcquireContext(µsoft_Provider, CONTAINER_NAME, szProviderName, PROV_RSA_FULL, 0))
- {
- return TRUE;
- }
- }
- microsoft_Provider = NULL;
- return FALSE;
- }
- /*
- %--------------------------------------------------------------------------
- % VerifyHandleContainer
- %
- % VerifyHandleContainer allows to check the existence of a context
- %
- % Parameters of entry :
- % IN handleContainer handle to verify
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- bool HandleContainer::VerifyHandleContainer(HandleContainer* handleContainer)
- {
- TRACE(__LINE__,"HandleContainer::VerifyHandleContainer : %d ",handleContainer);
- return handles_Container.VerifyEntry(handleContainer);
- }
- /*
- %--------------------------------------------------------------------------
- % CreateHash
- %
- % CreateHash is used to return a handle on the creation of a hash object:
- % managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN Algid - Algorithm used for the hashing
- % IN hKey - If the type of hash algorithm is a keyed hash, such as the HMAC or MAC algorithm, the key for the hash is passed in this parameter. For nonkeyed algorithms, this parameter must be set to zero
- % IN dwFlags - not used
- % OUT phHash - address to which one copies the handle hashed object
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::CreateHash(ALG_ID Algid, HCRYPTKEY hCryptKey, DWORD dwFlags, HCRYPTHASH* phHash)
- {
- TRACE(__LINE__,"HandleContainer::CreateHash ",NULL);
- return CryptCreateHash(microsoft_Provider,Algid, hCryptKey, dwFlags, phHash);
- }
- /*
- %--------------------------------------------------------------------------
- % DestroyHash
- %
- % DestroyHash is used to destroy a hash object: managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN hHash - Handle on a hash object to be destroyed
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::DestroyHash(HCRYPTHASH hHash)
- {
- TRACE(__LINE__,"HandleContainer::DestroyHash ",NULL);
- return CryptDestroyHash(hHash);
- }
- /*
- %--------------------------------------------------------------------------
- % GetHashParam
- %
- % GetHashParam seeks data about the operations of a hash object. The actual
- % value of the hashing can be obtained by using this function:
- % managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN hHash - Handle on a hashed object
- % IN ulParametre - value of the parameter
- % IN pulDataLen - Length of the parameter pucData
- % IN ulFlags - Values of the flag
- %
- % Parameters of exit :
- % OUT pucData - Address to which the function copies the data corresponding to the ulParametre
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::GetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE* pbData, DWORD*pdwDataLen, DWORD dwFlags)
- {
- TRACE(__LINE__,"HandleContainer::GetHashParam ",NULL);
- return CryptGetHashParam(hHash, dwParam, pbData, pdwDataLen, dwFlags);
- }
- /*
- %--------------------------------------------------------------------------
- % HashData
- %
- % HashData is used to carry out a hashing starting from a handle on a hash object:
- % managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN hHash - Handle on a hashed object
- % IN pbData - address containing the data to be hashed
- % IN cbDataLen - length in bytes of the data to be hashed
- % IN dwFlags - not used
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::HashData(HCRYPTHASH hHash, CONST BYTE* pbData, DWORD dwDatalen, DWORD dwFlags)
- {
- TRACE(__LINE__,"HandleContainer::HashData ",NULL);
- return CryptHashData(hHash, pbData, dwDatalen, dwFlags);
- }
- /*
- %--------------------------------------------------------------------------
- % SetHashParam
- %
- % SetHashParam adapts the operations to the customer requirements of the hashed data:
- % managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN hHash - Handle on a hash object
- % IN ulParametre - value of the parameter
- % IN pucData - Pointer on data corresponding to the last ulParametre
- % IN ulFlags - Values of the flag
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::SetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE*pbData, DWORD dwFlags)
- {
- TRACE(__LINE__,"HandleContainer::SetHashParam ",NULL);
- return CryptSetHashParam(hHash,dwParam,pbData,dwFlags);
- }
- BOOL HandleContainer::GetProvParam(DWORD dwParam, BYTE* pbData, DWORD* pdwDataLen, DWORD dwFlags)
- {
- switch(dwParam)
- {
- case PP_ENUMALGS:
- TRACE(__LINE__,"HandleContainer::CryptGetProvParam PP_ENUMALGS",NULL);
- return CryptGetProvParam(microsoft_Provider, PP_ENUMALGS, pbData, pdwDataLen, dwFlags);
- case PP_ENUMALGS_EX:
- TRACE(__LINE__,"HandleContainer::CryptGetProvParam PP_ENUMALGS_EX",NULL);
- return CryptGetProvParam(microsoft_Provider, PP_ENUMALGS_EX, pbData, pdwDataLen, dwFlags);
- case PP_PROVTYPE :
- TRACE(__LINE__,"HandleContainer::CryptGetProvParam PP_PROVTYPE",NULL);
- return FALSE;
- default:
- SetLastError(NTE_BAD_TYPE);
- return FALSE;
- }
- return FALSE;
- }
- /*
- %--------------------------------------------------------------------------
- % Encrypt
- %
- % Encrypt is used to cipher data: managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN hKey - Handle on a key of session used for coding
- % IN hHash - Handle on a hash object if one wants to carry out a hash data before coding
- % IN Final - Boolean allowing to know if it is the last part to be ciphered
- % IN dwFlags - not used
- % INOUT pbData - data to be ciphered
- % INOUT pdwDataLen - length of data to be ciphered
- % IN dwBufLen - length of the data pbData in bytes
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::Encrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE* pbData, DWORD*pdwDataLen, DWORD dwBufLen)
- {
- TRACE(__LINE__,"HandleContainer::Encrypt ",NULL);
- return CryptEncrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
- }
- /*
- %--------------------------------------------------------------------------
- % Decrypt
- %
- % Decrypt is used to decipher data: managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN hKey - Handle on a key of session used for the deciphering
- % IN hHash - Handle on a hash object if one wants to carry out a hash data after the deciphering
- % IN Final - Boolean allowing to know if it is the last part to be deciphered
- % IN dwFlags - not used
- % INOUT pbData -data to be deciphereddata deciphered
- % INOUT pdwDataLen -length of data to be deciphereddata deciphered
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::Decrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE*pbData, DWORD*pdwDataLen)
- {
- TRACE(__LINE__,"HandleContainer::Decrypt ",NULL);
- return CryptDecrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
- }
- /*
- %--------------------------------------------------------------------------
- % SignHash
- %
- % SignHash is used to carry out the signature of one starting from a handle on a hash object.
- %
- % Parameters of entry :
- % IN hHash - Handle on the hash object to be signed
- % IN dwKeySpec -type of key to use to sign(AT_KEYEXCHANGEAT_SIGNATURE)
- % IN szDescription - not used
- % IN dwFlags - not used
- % OUT pbSignature - pointer on the signed data
- % OUT pdwSigLen - address of a DWORD containing the length of the signed data
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::SignHash(HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE*pbSignature, DWORD* pdwSigLen)
- {
- TRACE(__LINE__,"HandleContainer::SignHash BEGIN ",NULL);
- ALG_ID algidHash;
- unsigned long dwBufferLen;
- LPBYTE pbyHash = NULL;
- unsigned long dwHashLen;
- const BYTE * pbyOID = NULL;
- unsigned long dwOIDLen = 0;
- BOOL bRet = FALSE;
- dwBufferLen = sizeof(algidHash);
- if(!CryptGetHashParam(hHash, HP_ALGID, (LPBYTE)&algidHash, &dwBufferLen, 0))
- {
- TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
- SetLastError(NTE_BAD_HASH);
- return FALSE;
- }
- dwBufferLen = sizeof(dwHashLen);
- if(!CryptGetHashParam(hHash, HP_HASHSIZE, (LPBYTE)&dwHashLen, &dwBufferLen, 0))
- {
- TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
- SetLastError(NTE_BAD_HASH);
- return FALSE;
- }
- switch(algidHash)
- {
- case CALG_SSL3_SHAMD5:
- dwOIDLen = 0;
- break;
- case CALG_MD2:
- pbyOID = &derEncodedMD2[0];
- dwOIDLen = sizeof(derEncodedMD2);
- break;
- case CALG_MD5:
- pbyOID = &derEncodedMD5[0];
- dwOIDLen = sizeof(derEncodedMD5);
- break;
- case CALG_SHA1:
- pbyOID = &derEncodedSHA1[0];
- dwOIDLen = sizeof(derEncodedSHA1);
- break;
- default:
- SetLastError(NTE_BAD_ALGID);
- return FALSE;
- }
- pbyHash = new BYTE[dwHashLen + dwOIDLen];
- if(!pbyHash)
- {
- TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
- SetLastError(NTE_FAIL);
- return FALSE;
- }
- if(pbyOID)
- memcpy(pbyHash, pbyOID, dwOIDLen);
- if(!CryptGetHashParam(hHash, HP_HASHVAL, pbyHash+dwOIDLen, &dwHashLen, 0))
- {
- TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
- SetLastError(NTE_BAD_HASH);
- if(pbyHash)
- free(pbyHash);
- return FALSE;
- }
- if(!Pkcs::DoSign(currentPContainer,dwHashLen + dwOIDLen, pbyHash, dwKeySpec,pbSignature,pdwSigLen))
- {
- TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
- SetLastError(NTE_FAIL);
- if(pbyHash)
- free(pbyHash);
- return FALSE;
- }
- TRACE(__LINE__,"HandleContainer::SignHash TRUE ",NULL);
- return TRUE;
- }
- /*
- %--------------------------------------------------------------------------
- % VerifySignature
- %
- % VerifySignature is used to check a signature: managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN hHash - Handle on a hash object to be checked
- % IN pbSignature - buffer containing the signature
- % IN dwSigLen - length in bytes of the signature
- % IN hPubKey - Handle on the public key with used to check the signature
- % IN sDescription - not used
- % IN dwFlags - not used
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::VerifySignature(HCRYPTHASH hHash, CONST BYTE* pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey,LPCTSTR sDescription, DWORD dwFlags)
- {
- TRACE(__LINE__,"HandleContainer::VerifySignature ",NULL);
- return CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey,sDescription, dwFlags);
- }
- /*
- %--------------------------------------------------------------------------
- % DestroyKey
- %
- % The DestroyKey function releases the handle referred by the parameter hKey: managed by Provider Microsoft
- %
- % Parameters of entry :
- % IN phKey - Handle on the key
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::DestroyKey(HCRYPTKEY hKey)
- {
- TRACE(__LINE__,"HandleContainer::DestroyKey ",NULL);
- return CryptDestroyKey(hKey);
- }
- /*
- %--------------------------------------------------------------------------
- % ImportKey
- %
- % ImportKey import keys of a "Keyblob" towards a container of key
- %
- % Parameters of entry :
- % IN pbData - data of "Keyblob"
- % IN dwDataLen - length of data
- % IN hPubKey - Handle on a key public of exchange of the user recipient
- % IN dwFlags - Flags values
- %
- % Parameters of exit :
- % OUT phKey - Address to which the function copies the handle key to be imported
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::ImportKey(BYTE* pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY* phKey)
- {
- DWORD i,j;
- HCRYPTPROV hProv_m = 0;
- HCRYPTKEY hPubPrivKey = 0;
- BOOL fResult;
- TRACE(__LINE__,"HandleContainer::ImportKey BEGIN ",NULL);
- if(!pbData)
- {
- TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
- SetLastError(NTE_FAIL);
- return FALSE;
- }
- /*If it's a PUBLICKEYBLOB import it into the base provider.*/
- pSessionKeyHeader pskh = (pSessionKeyHeader)pbData;
- if(PUBLICKEYBLOB == pskh->blobHeader.bType || !hPubKey)
- return CryptImportKey(microsoft_Provider, pbData, dwDataLen, hPubKey, dwFlags, phKey);
- /*If it's not a SIMPLEBLOB we don't know what to do with it.*/
- if(SIMPLEBLOB != pskh->blobHeader.bType)
- {
- TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
- SetLastError(NTE_BAD_TYPE);
- return FALSE;
- }
- /*We only know how to deal with RSA keys.*/
- if(CALG_RSA_KEYX != pskh->algid)
- {
- TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
- SetLastError(NTE_BAD_TYPE);
- return FALSE;
- }
- BOOL bRet = FALSE;
- //Wrapped blob size.
- DWORD wEncryptedDataLength = (DWORD)(dwDataLen - sizeof(SessionKeyHeader));
- BYTE* pKeySource = pbData + sizeof(SessionKeyHeader);
- BYTE* pbyDecryptedData = new BYTE[wEncryptedDataLength];
- DWORD wDecryptedDataLength = wEncryptedDataLength;
- if(!pbyDecryptedData)
- {
- TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
- SetLastError(NTE_FAIL);
- if(pbyDecryptedData)
- delete [] pbyDecryptedData;
- return FALSE;
- }
- /*reversal of the block pKeySource */
- for (i=wEncryptedDataLength-1, j=0; i > j; --i, ++j)
- {
- BYTE bTmp = pKeySource[i];
- pKeySource[i] = pKeySource[j];
- pKeySource[j] = bTmp;
- }
- if(!Pkcs::Decrypt(hPubKey, pKeySource, wEncryptedDataLength, pbyDecryptedData, &wDecryptedDataLength))
- {
- TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
- SetLastError(NTE_BAD_ALGID);
- if(pbyDecryptedData)
- delete [] pbyDecryptedData;
- return FALSE;
- }
- LPTSTR MicroProvider;
- // Try to create new container
- if(pskh->blobHeader.aiKeyAlg==CALG_RC2 && wDecryptedDataLength==5)
- MicroProvider="Microsoft Base Cryptographic Provider v1.0";
- else
- MicroProvider="Microsoft Enhanced Cryptographic Provider v1.0";
- fResult =CreatePrivateExponentOneKey(MicroProvider, PROV_RSA_FULL,
- "importKey", AT_KEYEXCHANGE,
- &hProv_m, &hPubPrivKey);
- if(!fResult)
- {
- TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
- SetLastError(NTE_FAIL);
- if(pbyDecryptedData)
- delete [] pbyDecryptedData;
- return FALSE;
- }
- // Import this key and get an HCRYPTKEY handle
- if (!ImportPlainSessionBlob(hProv_m, hPubPrivKey,pskh->blobHeader.aiKeyAlg , pbyDecryptedData, wDecryptedDataLength, phKey))
- {
- TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
- SetLastError(NTE_FAIL);
- if(pbyDecryptedData)
- delete [] pbyDecryptedData;
- return FALSE;
- }
- bRet = TRUE;
- if(pbyDecryptedData)
- delete [] pbyDecryptedData;
- TRACE(__LINE__,"HandleContainer::ImportKey TRUE ",NULL);
- return bRet;
- }
- /*
- %--------------------------------------------------------------------------
- % GetKeyParam
- %
- % GetKeyParam seeks the data which govern the operations of a key: manage by Provider Microsoft
- %
- % Parameters of entry :
- % IN hKey - Handle on the key
- % IN ulParametre - value of parameter
- % IN pulDataLen - length of the parameter pucData
- % IN ulFlags - values of the flag
- %
- % Parameters of exit :
- % OUT pucData - Address to which the function copies the data corresponding to the ulFlags
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::GetKeyParam(HCRYPTKEY hKey, DWORD dwParam, BYTE* pbData, DWORD* pdwDataLen, DWORD dwFlags)
- {
- TRACE(__LINE__,"HandleContainer::GetKeyParam",NULL);
- return CryptGetKeyParam(hKey, dwParam, pbData, pdwDataLen, dwFlags);
- }
- /*
- %--------------------------------------------------------------------------
- % SetKeyParam
- %
- % SetKeyParam adapt the operations to the customer requirements of a key:
- % manage by Provider Microsoft
- %
- % Parameters of entry :
- % IN hKey - Handle on a key
- % IN ulParametre - value of the parameter
- % IN pucData - Pointer containing the data which correspond to the value
- % of parameter dwParam
- % IN ulFlags - Values of the flag (not used)
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::SetKeyParam(HCRYPTKEY hKey, DWORD dwParam,CONST BYTE*pbData, DWORD dwFlags)
- {
- TRACE(__LINE__,"HandleContainer::SetKeyParam",NULL);
- return CryptSetKeyParam(hKey, dwParam, pbData, dwFlags);
- }
- /*
- %--------------------------------------------------------------------------
- % GetUserKey
- %
- % GetUserKey is used to return a handle on the pair of key of the user
- %
- % Parameters of entry :
- % IN dwKeySpec - desired type of key (AT_KEYEXCHANGEAT_SIGNATURE)
- % OUT phUserKey - address to which is copied the handle desired key
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::GetUserKey(DWORD dwKeySpec, HCRYPTKEY* phUserKey)
- {
- TRACE(__LINE__,"HandleContainer::GetUserKey BEGIN",NULL);
- if(!(currentPContainer->GetUserKey(dwKeySpec,phUserKey)))
- {
- TRACE(__LINE__,"HandleContainer::GetUserKey FALSE",NULL);
- SetLastError(NTE_NO_KEY);
- return FALSE;
- }
- TRACE(__LINE__,"HandleContainer::GetUserKey TRUE",NULL);
- return TRUE;
- }
- /*
- %--------------------------------------------------------------------------
- % CreatePrivateExponentOneKey
- %
- % CreatePrivateExponentOneKey is used to create a key private which carries
- % out during coding the identity
- %
- % Parameters of entry :
- % IN szProvider Name of provider
- % IN dwProvType
- % IN szContainer Name of container
- % IN dwKeySpec type of key
- % IN hProv handle to the provider
- % IN hPrivateKey handle to the private key
- %
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::CreatePrivateExponentOneKey(LPTSTR szProvider,DWORD dwProvType,LPTSTR szContainer,DWORD dwKeySpec,HCRYPTPROV *hProv,HCRYPTKEY *hPrivateKey)
- {
- BOOL fReturn = FALSE;
- BOOL fResult;
- int n;
- LPBYTE keyblob = NULL;
- DWORD dwkeyblob;
- DWORD dwBitLen;
- BYTE *ptr;
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey BEGIN",NULL);
- __try
- {
- *hProv = 0;
- *hPrivateKey = 0;
- if ((dwKeySpec != AT_KEYEXCHANGE) && (dwKeySpec != AT_SIGNATURE)) __leave;
- // Try to create new container
- fResult = CryptAcquireContext(hProv, szContainer, szProvider,
- dwProvType, CRYPT_NEWKEYSET);
- if (!fResult)
- {
- // If the container exists, open it
- if (GetLastError() == NTE_EXISTS)
- {
- fResult = CryptAcquireContext(hProv, szContainer, szProvider, dwProvType, 0);
- if (!fResult)
- {
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
- // No good, leave
- __leave;
- }
- }
- else
- {
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
- // No good, leave
- __leave;
- }
- }
- // Generate the private key
- fResult = CryptGenKey(*hProv, dwKeySpec, CRYPT_EXPORTABLE, hPrivateKey);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
- __leave;
- }
- // Export the private key, we'll convert it to a private
- // exponent of one key
- fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwkeyblob);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
- __leave;
- }
- keyblob = (LPBYTE)LocalAlloc(LPTR, dwkeyblob);
- if (!keyblob){
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
- __leave;
- }
- fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, keyblob, &dwkeyblob);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
- __leave;
- }
- CryptDestroyKey(*hPrivateKey);
- *hPrivateKey = 0;
- // Get the bit length of the key
- memcpy(&dwBitLen, &keyblob[12], 4);
- // Modify the Exponent in Key BLOB format
- // Key BLOB format is documented in SDK
- // Convert pubexp in rsapubkey to 1
- ptr = &keyblob[16];
- for (n = 0; n < 4; n++)
- {
- if (n == 0) ptr[n] = 1;
- else ptr[n] = 0;
- }
- // Skip pubexp
- ptr += 4;
- // Skip modulus, prime1, prime2
- ptr += (dwBitLen/8);
- ptr += (dwBitLen/16);
- ptr += (dwBitLen/16);
- // Convert exponent1 to 1
- for (n = 0; n < (dwBitLen/16); n++)
- {
- if (n == 0) ptr[n] = 1;
- else ptr[n] = 0;
- }
- // Skip exponent1
- ptr += (dwBitLen/16);
- // Convert exponent2 to 1
- for (n = 0; n < (dwBitLen/16); n++)
- {
- if (n == 0) ptr[n] = 1;
- else ptr[n] = 0;
- }
- // Skip exponent2, coefficient
- ptr += (dwBitLen/16);
- ptr += (dwBitLen/16);
- // Convert privateExponent to 1
- for (n = 0; n < (dwBitLen/8); n++)
- {
- if (n == 0) ptr[n] = 1;
- else ptr[n] = 0;
- }
- // Import the exponent-of-one private key.
- if (!CryptImportKey(*hProv, keyblob, dwkeyblob, 0, 0, hPrivateKey))
- {
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
- __leave;
- }
- TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey TRUE",NULL);
- fReturn = TRUE;
- }
- __finally
- {
- if (keyblob) LocalFree(keyblob);
- if (!fReturn)
- {
- if (*hPrivateKey) CryptDestroyKey(*hPrivateKey);
- if (*hProv) CryptReleaseContext(*hProv, 0);
- }
- }
- return fReturn;
- }
- /*
- %--------------------------------------------------------------------------
- % ImportPlainSessionBlob
- %
- % ImportPlainSessionBlob is used to import a key of session in light in a provider
- % microsoft
- %
- % Parameters of entry :
- % IN hProv handle to the provider
- % IN hPrivateKey handle to the private key
- % IN dwAlgId Algo ID
- % IN pbKeyMaterial key
- % IN dwKeyMaterial length of the key
- % IN handle to the sessionKey
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::ImportPlainSessionBlob(HCRYPTPROV hProv,
- HCRYPTKEY hPrivateKey,
- ALG_ID dwAlgId,
- LPBYTE pbKeyMaterial ,
- DWORD dwKeyMaterial ,
- HCRYPTKEY *hSessionKey)
- {
- BOOL fResult;
- BOOL fReturn = FALSE;
- BOOL fFound = FALSE;
- LPBYTE pbSessionBlob = NULL;
- DWORD dwSessionBlob, dwSize, n;
- DWORD dwPublicKeySize;
- DWORD dwProvSessionKeySize;
- ALG_ID dwPrivKeyAlg;
- LPBYTE pbPtr;
- DWORD dwFlags = CRYPT_FIRST;
- PROV_ENUMALGS_EX ProvEnum;
- HCRYPTKEY hTempKey = 0;
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob BEGIN",NULL);
- __try
- {
- // Double check to see if this provider supports this algorithm
- // and key size
- do
- {
- dwSize = sizeof(ProvEnum);
- fResult = CryptGetProvParam(hProv, PP_ENUMALGS_EX, (LPBYTE)&ProvEnum,
- &dwSize, dwFlags);
- if (!fResult) break;
- dwFlags = 0;
- if (ProvEnum.aiAlgid == dwAlgId) fFound = TRUE;
- } while (!fFound);
- if (!fFound){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- // We have to get the key size(including padding)
- // from an HCRYPTKEY handle. PP_ENUMALGS_EX contains
- // the key size without the padding so we can't use it.
- if(dwAlgId==CALG_RC2 && dwKeyMaterial==5)
- {
- fResult = CryptGenKey(hProv, dwAlgId, CRYPT_NO_SALT, &hTempKey);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- }
- else
- {
- fResult = CryptGenKey(hProv, dwAlgId, 0, &hTempKey);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- }
- /*fResult = CryptGenKey(hProv, dwAlgId, 0, &hTempKey);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }*/
- dwSize = sizeof(DWORD);
- fResult = CryptGetKeyParam(hTempKey, KP_KEYLEN, (LPBYTE)&dwProvSessionKeySize,
- &dwSize, 0);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- CryptDestroyKey(hTempKey);
- hTempKey = 0;
- // Our key is too big, leave
- if ((dwKeyMaterial * 8) > dwProvSessionKeySize){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- // Get private key's algorithm
- dwSize = sizeof(ALG_ID);
- fResult = CryptGetKeyParam(hPrivateKey, KP_ALGID, (LPBYTE)&dwPrivKeyAlg, &dwSize, 0);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- // Get private key's length in bits
- dwSize = sizeof(DWORD);
- fResult = CryptGetKeyParam(hPrivateKey, KP_KEYLEN, (LPBYTE)&dwPublicKeySize, &dwSize, 0);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- // calculate Simple blob's length
- dwSessionBlob = (dwPublicKeySize/8) + sizeof(ALG_ID) + sizeof(BLOBHEADER);
- // allocate simple blob buffer
- pbSessionBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob);
- if (!pbSessionBlob) {
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- pbPtr = pbSessionBlob;
- // SIMPLEBLOB Format is documented in SDK
- // Copy header to buffer
- ((BLOBHEADER *)pbPtr)->bType = SIMPLEBLOB;
- ((BLOBHEADER *)pbPtr)->bVersion = 2;
- ((BLOBHEADER *)pbPtr)->reserved = 0;
- ((BLOBHEADER *)pbPtr)->aiKeyAlg = dwAlgId;
- pbPtr += sizeof(BLOBHEADER);
- // Copy private key algorithm to buffer
- *((DWORD *)pbPtr) = dwPrivKeyAlg;
- pbPtr += sizeof(ALG_ID);
- // Place the key material in reverse order
- for (n = 0; n < dwKeyMaterial; n++)
- {
- pbPtr[n] = pbKeyMaterial[dwKeyMaterial-n-1];
- }
- // 3 is for the first reserved byte after the key material + the 2 reserved bytes at the end.
- dwSize = dwSessionBlob - (sizeof(ALG_ID) + sizeof(BLOBHEADER) + dwKeyMaterial+ 3);
- pbPtr +=dwKeyMaterial+1;
- // Generate random data for the rest of the buffer
- // (except that last two bytes)
- fResult = CryptGenRandom(hProv, dwSize, pbPtr);
- if (!fResult){
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- for (n = 0; n < dwSize; n++)
- {
- if (pbPtr[n] == 0) pbPtr[n] = 1;
- }
- pbSessionBlob[dwSessionBlob - 2] = 2;
- if(dwAlgId==CALG_RC2 && dwKeyMaterial==5)
- {
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob CALG RC2 40 Bits",NULL);
- fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob,
- hPrivateKey, CRYPT_EXPORTABLE|CRYPT_NO_SALT, hSessionKey);
- if (!fResult) {
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- }
- else{
- fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob,
- hPrivateKey, CRYPT_EXPORTABLE, hSessionKey);
- if (!fResult) {
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }
- }
- /*fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob,
- hPrivateKey, CRYPT_EXPORTABLE, hSessionKey);
- if (!fResult) {
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
- __leave;
- }*/
- TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob TRUE",NULL);
- fReturn = TRUE;
- }
- __finally
- {
- if (hTempKey) CryptDestroyKey(hTempKey);
- if (pbSessionBlob) LocalFree(pbSessionBlob);
- }
- return fReturn;
- }
- /*
- %--------------------------------------------------------------------------
- % ExportPlainSessionBlob
- %
- % ExportPlainSessionBlob is used to export a key of session in light
- %
- % Parameters of entry :
- % IN hPublicKey handle to the public key
- % IN hSessionKey handle to the session key
- % IN pbKeyMaterial key
- % IN dwKeyMaterial length of the key
- %
- % return : TRUE if the operation occurred well, FALSE if not
- %---------------------------------------------------------------------------
- */
- BOOL HandleContainer::ExportPlainSessionBlob(HCRYPTKEY hPublicKey,
- HCRYPTKEY hSessionKey,
- LPBYTE *pbKeyMaterial ,
- DWORD *dwKeyMaterial )
- {
- BOOL fReturn = FALSE;
- BOOL fResult;
- DWORD dwSize, n;
- LPBYTE pbSessionBlob = NULL;
- DWORD dwSessionBlob;
- LPBYTE pbPtr;
- __try
- {
- *pbKeyMaterial = NULL;
- *dwKeyMaterial = 0;
- fResult = CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB,
- 0, NULL, &dwSessionBlob );
- if (!fResult) __leave;
- pbSessionBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob );
- if (!pbSessionBlob) __leave;
- fResult = CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB,
- 0, pbSessionBlob , &dwSessionBlob );
- if (!fResult) __leave;
- // Get session key size in bits
- dwSize = sizeof(DWORD);
- fResult = CryptGetKeyParam(hSessionKey, KP_KEYLEN, (LPBYTE)dwKeyMaterial, &dwSize, 0);
- if (!fResult) __leave;
- // Get the number of bytes and allocate buffer
- *dwKeyMaterial /= 8;
- *pbKeyMaterial = (LPBYTE)LocalAlloc(LPTR, *dwKeyMaterial);
- if (!*pbKeyMaterial) __leave;
- // Skip the header
- pbPtr = pbSessionBlob;
- pbPtr += sizeof(BLOBHEADER);
- pbPtr += sizeof(ALG_ID);
- // We are at the beginning of the key
- // but we need to start at the end since
- // it's reversed
- pbPtr += (*dwKeyMaterial - 1);
- // Copy the raw key into our return buffer
- for (n = 0; n < *dwKeyMaterial; n++)
- {
- (*pbKeyMaterial)[n] = *pbPtr;
- pbPtr--;
- }
- fReturn = TRUE;
- }
- __finally
- {
- if (pbSessionBlob) LocalFree(pbSessionBlob);
- if ((!fReturn) && (*pbKeyMaterial ))
- {
- LocalFree(*pbKeyMaterial );
- *pbKeyMaterial = NULL;
- *dwKeyMaterial = 0;
- }
- }
- return fReturn;
- }