⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 handlecontainer.cpp

📁 PKCS#11的微软CSP实现源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
   {
      *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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -