Beispiel #1
0
static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY * key)
{
    unsigned char *pubkey = NULL;
    DWORD len;
    BLOBHEADER *bh;
    RSA *rkey = NULL;
    DSA *dkey = NULL;
    EVP_PKEY *ret = NULL;
    if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) {
        CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR);
        capi_addlasterror();
        return NULL;
    }

    pubkey = OPENSSL_malloc(len);

    if (!pubkey)
        goto memerr;

    if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) {
        CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR);
        capi_addlasterror();
        goto err;
    }

    bh = (BLOBHEADER *) pubkey;
    if (bh->bType != PUBLICKEYBLOB) {
        CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB);
        goto err;
    }
    if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) {
        RSAPUBKEY *rp;
        DWORD rsa_modlen;
        unsigned char *rsa_modulus;
        rp = (RSAPUBKEY *) (bh + 1);
        if (rp->magic != 0x31415352) {
            char magstr[10];
            BIO_snprintf(magstr, 10, "%lx", rp->magic);
            CAPIerr(CAPI_F_CAPI_GET_PKEY,
                    CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
            ERR_add_error_data(2, "magic=0x", magstr);
            goto err;
        }
        rsa_modulus = (unsigned char *)(rp + 1);
        rkey = RSA_new_method(eng);
        if (!rkey)
            goto memerr;

        rkey->e = BN_new();
        rkey->n = BN_new();

        if (!rkey->e || !rkey->n)
            goto memerr;

        if (!BN_set_word(rkey->e, rp->pubexp))
            goto memerr;

        rsa_modlen = rp->bitlen / 8;
        if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen))
            goto memerr;

        RSA_set_ex_data(rkey, rsa_capi_idx, key);

        if (!(ret = EVP_PKEY_new()))
            goto memerr;

        EVP_PKEY_assign_RSA(ret, rkey);
        rkey = NULL;

    } else if (bh->aiKeyAlg == CALG_DSS_SIGN) {
        DSSPUBKEY *dp;
        DWORD dsa_plen;
        unsigned char *btmp;
        dp = (DSSPUBKEY *) (bh + 1);
        if (dp->magic != 0x31535344) {
            char magstr[10];
            BIO_snprintf(magstr, 10, "%lx", dp->magic);
            CAPIerr(CAPI_F_CAPI_GET_PKEY,
                    CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
            ERR_add_error_data(2, "magic=0x", magstr);
            goto err;
        }
        dsa_plen = dp->bitlen / 8;
        btmp = (unsigned char *)(dp + 1);
        dkey = DSA_new_method(eng);
        if (!dkey)
            goto memerr;
        dkey->p = BN_new();
        dkey->q = BN_new();
        dkey->g = BN_new();
        dkey->pub_key = BN_new();
        if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key)
            goto memerr;
        if (!lend_tobn(dkey->p, btmp, dsa_plen))
            goto memerr;
        btmp += dsa_plen;
        if (!lend_tobn(dkey->q, btmp, 20))
            goto memerr;
        btmp += 20;
        if (!lend_tobn(dkey->g, btmp, dsa_plen))
            goto memerr;
        btmp += dsa_plen;
        if (!lend_tobn(dkey->pub_key, btmp, dsa_plen))
            goto memerr;
        btmp += dsa_plen;

        DSA_set_ex_data(dkey, dsa_capi_idx, key);

        if (!(ret = EVP_PKEY_new()))
            goto memerr;

        EVP_PKEY_assign_DSA(ret, dkey);
        dkey = NULL;
    } else {
        char algstr[10];
        BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg);
        CAPIerr(CAPI_F_CAPI_GET_PKEY,
                CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM);
        ERR_add_error_data(2, "aiKeyAlg=0x", algstr);
        goto err;
    }

 err:
    if (pubkey)
        OPENSSL_free(pubkey);
    if (!ret) {
        if (rkey)
            RSA_free(rkey);
        if (dkey)
            DSA_free(dkey);
    }

    return ret;

 memerr:
    CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE);
    goto err;

}
Beispiel #2
0
 INT ProtectDataCAPI(const char* szKeyName, const void* pData, size_t nData, void** ppData, size_t* pnData)
 {
     USES_CONVERSION;
     ;
     HCRYPTPROV hProv=NULL;
     BOOL bResult = FALSE;
     ;
     HCRYPTKEY hExchangeKey = NULL;
     HCRYPTKEY hSessionKey = NULL;
     void*   pTempBuffer = NULL;
     DWORD   dwTempBuffer = 0;
     void*   pSessionKeyBlob = NULL;
     DWORD   dwSessionKeyBlob = 0;
     void*   pResultBuffer = NULL;
     size_t  nResultBuffer = 0;
     {
         if(!(bResult = CryptAcquireContext(
                                 &hProv,
                                 A2CT(szKeyName),
                                 MS_DEF_PROV,
                                 PROV_RSA_FULL,
                                 CRYPT_MACHINE_KEYSET)))
         {
             DWORD dwError = GetLastError();
             if(dwError == NTE_BAD_KEYSET || dwError == NTE_KEYSET_NOT_DEF)
             {
                 bResult = CreateContainer(A2CT(szKeyName), &hProv);
                 if(!bResult)
                     goto onCleanup;
             }
             else
                 goto onCleanup;
         };
         ;
         if(!(bResult = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hExchangeKey)))
         {
             DWORD dwError = GetLastError();
             if(dwError == NTE_NO_KEY)
             {
                 bResult = CreateExchangeKeyPair(hProv, &hExchangeKey);
                 if(!bResult)
                     goto onCleanup;
             }
             else
                 goto onCleanup;
         };
         ;   
         bResult = CryptGenKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hSessionKey);
         if(!bResult)
             goto onCleanup;
         ;
         //determining size of output buffer is redundant because RC4 is a stream cipher but as general it's required
         DWORD dwTempBufferSize = nData;
         bResult = CryptEncrypt(hSessionKey, NULL, TRUE, 0, NULL, &dwTempBufferSize, dwTempBufferSize);
         if(!bResult)
             goto onCleanup;
         pTempBuffer = malloc(dwTempBufferSize);
         dwTempBuffer = nData;
         memcpy(pTempBuffer, pData, nData);
         bResult = CryptEncrypt(hSessionKey, NULL, TRUE, 0, (PBYTE)pTempBuffer, &dwTempBuffer, dwTempBufferSize);
         if(!bResult)
             goto onCleanup;
         ;
         bResult = CryptExportKey(hSessionKey, hExchangeKey, SIMPLEBLOB, 0, NULL, &dwSessionKeyBlob);
         if(!bResult)
             goto onCleanup;
         pSessionKeyBlob = malloc(dwSessionKeyBlob);
         bResult = CryptExportKey(hSessionKey, hExchangeKey, SIMPLEBLOB, 0, (PBYTE)pSessionKeyBlob, &dwSessionKeyBlob);
         if(!bResult)
             goto onCleanup;
         ;
         nResultBuffer = dwTempBuffer + dwSessionKeyBlob + sizeof(dwSessionKeyBlob) + sizeof(dwTempBuffer);
         pResultBuffer = malloc(nResultBuffer);
         PBYTE p = (PBYTE)pResultBuffer;
         memcpy(p, &dwSessionKeyBlob, sizeof(dwSessionKeyBlob));
         p += sizeof(dwSessionKeyBlob);
         memcpy(p, pSessionKeyBlob, dwSessionKeyBlob);
         p += dwSessionKeyBlob;
         memcpy(p, &dwTempBuffer, sizeof(dwTempBuffer));
         p += sizeof(dwTempBuffer);
         memcpy(p, pTempBuffer, dwTempBuffer);
         p += dwTempBuffer;
         _ASSERTE(p  == nResultBuffer + PBYTE(pResultBuffer));
         *ppData = pResultBuffer;
         *pnData = nResultBuffer;
         pResultBuffer = NULL;
     };
 onCleanup:
     DWORD dwError = bResult ? 0 : GetLastError();
     if(hSessionKey)
         CryptDestroyKey(hSessionKey);
     if(hExchangeKey)
         CryptDestroyKey(hExchangeKey);
     if(hProv)
         CryptReleaseContext(hProv, 0);
     Free(pTempBuffer, dwTempBuffer);
     Free(pSessionKeyBlob, dwSessionKeyBlob);
     Free(pResultBuffer, nResultBuffer);
     return (int)dwError;
 };
Beispiel #3
0
/******************************************************************************
 *
 * Utils
 *
 * Low level helper routines for importing plain text keys in MS HKEY handle,
 * since MSCrypto API does not support import of plain text (session) keys
 * just like that. These functions are based upon MS kb article #228786
 * and "Base Provider Key BLOBs" article for priv key blob format.
 *
 ******************************************************************************/
BOOL
xmlSecMSCryptoCreatePrivateExponentOneKey(HCRYPTPROV hProv, HCRYPTKEY *hPrivateKey)
{
    HCRYPTKEY hKey = 0;
    LPBYTE keyBlob = NULL;
    DWORD keyBlobLen;
    PUBLICKEYSTRUC* pubKeyStruc;
    RSAPUBKEY* rsaPubKey;
    DWORD bitLen;
    BYTE *ptr;
    int n;
    BOOL res = FALSE;

    xmlSecAssert2(hProv != 0, FALSE);
    xmlSecAssert2(hPrivateKey != NULL, FALSE);

    /* just in case */
    *hPrivateKey = 0;

    /* Generate the private key */
    if(!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey)) {
        xmlSecMSCryptoError("CryptGenKey", NULL);
        goto done;
    }

    /* Export the private key, we'll convert it to a private exponent of one key */
    if(!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, NULL, &keyBlobLen)) {
        xmlSecMSCryptoError("CryptExportKey", NULL);
        goto done;
    }

    keyBlob = (LPBYTE)xmlMalloc(sizeof(BYTE) * keyBlobLen);
    if(keyBlob == NULL) {
        xmlSecMallocError(sizeof(BYTE) * keyBlobLen, NULL);
        goto done;
    }

    if(!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, keyBlob, &keyBlobLen)) {
        xmlSecMSCryptoError("CryptExportKey", NULL);
        goto done;
    }
    CryptDestroyKey(hKey);
    hKey = 0;

    /* Get the bit length of the key */
    if(keyBlobLen < sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY)) {
        xmlSecMSCryptoError2("CryptExportKey", NULL,
                             "len=%ld",
                             (long int)keyBlobLen);
        goto done;
    }
    pubKeyStruc = (PUBLICKEYSTRUC*)keyBlob;
    if(pubKeyStruc->bVersion != 0x02) {
        xmlSecMSCryptoError2("CryptExportKey", NULL,
                             "pubKeyStruc->bVersion=%ld",
                             (long int)pubKeyStruc->bVersion);
        goto done;
    }
    if(pubKeyStruc->bType != PRIVATEKEYBLOB) {
        xmlSecMSCryptoError2("CryptExportKey", NULL,
                             "pubKeyStruc->bType=%ld",
                             (long int)pubKeyStruc->bType);
        goto done;
    }

    /* aleksey: don't ask me why it is RSAPUBKEY, just don't ask */
    rsaPubKey = (RSAPUBKEY*)(keyBlob + sizeof(PUBLICKEYSTRUC));

    /* check that we have RSA private key */
    if(rsaPubKey->magic != 0x32415352) {
        xmlSecMSCryptoError2("CryptExportKey", NULL,
                             "rsaPubKey->magic=0x%08lx",
                             (long int)rsaPubKey->magic);
        goto done;
    }
    bitLen = rsaPubKey->bitlen;

    /*  Modify the Exponent in Key BLOB format Key BLOB format is documented in SDK */
    rsaPubKey->pubexp = 1;

    /* Private-key BLOBs, type PRIVATEKEYBLOB, are used to store private keys outside a CSP.
     * Base provider private-key BLOBs have the following format:
     *
     * PUBLICKEYSTRUC  publickeystruc ;
     * RSAPUBKEY rsapubkey;
     * BYTE modulus[rsapubkey.bitlen/8];                1/8
     * BYTE prime1[rsapubkey.bitlen/16];                1/16
     * BYTE prime2[rsapubkey.bitlen/16];                1/16
     * BYTE exponent1[rsapubkey.bitlen/16];             1/16
     * BYTE exponent2[rsapubkey.bitlen/16];             1/16
     * BYTE coefficient[rsapubkey.bitlen/16];           1/16
     * BYTE privateExponent[rsapubkey.bitlen/8];        1/8
     */
    if(keyBlobLen < sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + bitLen / 2 + bitLen / 16) {
        xmlSecMSCryptoError2("CryptExportKey", NULL,
                             "keBlobLen=%ld", keyBlobLen);
        goto done;
    }
    ptr = (BYTE*)(keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));

    /* Skip modulus, prime1, prime2 */
    ptr += bitLen / 8;
    ptr += bitLen / 16;
    ptr += bitLen / 16;

    /* Convert exponent1 to 1 */
    for (n = 0; n < (bitLen / 16); n++) {
        if (n == 0) ptr[n] = 1;
        else ptr[n] = 0;
    }
    ptr += bitLen / 16;

    /* Convert exponent2 to 1 */
    for (n = 0; n < (bitLen / 16); n++) {
        if (n == 0) ptr[n] = 1;
        else ptr[n] = 0;
    }
    ptr += bitLen / 16;

    /* Skip coefficient */
    ptr += bitLen / 16;

    /* Convert privateExponent to 1 */
    for (n = 0; n < (bitLen / 16); n++) {
        if (n == 0) ptr[n] = 1;
        else ptr[n] = 0;
    }

    /* Import the exponent-of-one private key. */
    if (!CryptImportKey(hProv, keyBlob, keyBlobLen, 0, 0, &hKey)) {
        xmlSecMSCryptoError("CryptImportKey", NULL);
        goto done;
    }
    (*hPrivateKey) = hKey;
    hKey = 0;
    res = TRUE;

done:
    if(keyBlob != NULL) {
        xmlFree(keyBlob);
    }
    if (hKey != 0) {
        CryptDestroyKey(hKey);
    }

    return res;
}
BOOL EncryptDecryptFile(LPTSTR lpszCertificateName,
                        LPTSTR lpszCertificateStoreName,
                        DWORD  dwCertStoreOpenFlags,
                        LPTSTR lpszInputFileName,
                        LPTSTR lpszOutputFileName,
                        BOOL fEncrypt)
{
   BOOL fResult = FALSE;
   HCRYPTPROV hProv = NULL;
   HCRYPTKEY hRSAKey = NULL;
   HCRYPTKEY hSessionKey = NULL;
   HANDLE hInFile = INVALID_HANDLE_VALUE;
   HANDLE hOutFile = INVALID_HANDLE_VALUE;
   BOOL finished = FALSE;
   BYTE pbBuffer[OUT_BUFFER_SIZE];
   DWORD dwByteCount = 0;
   DWORD dwBytesRead = 0;
   DWORD dwBytesWritten = 0;
   LPBYTE pbSessionKeyBlob = NULL;
   DWORD dwSessionKeyBlob = 0;
   BOOL fCallerFreeProv = FALSE;
   PCCERT_CONTEXT pCertContext = NULL;
   BOOL fSuccess = FALSE;

   __try
   {
      pCertContext = GetCertificateContextFromName(lpszCertificateName,
                        lpszCertificateStoreName,
                        dwCertStoreOpenFlags);
      if (pCertContext == NULL)
      {
         __leave;
      }

      fResult = AcquireAndGetRSAKey(pCertContext,
                        &hProv,
                        &hRSAKey,
                        fEncrypt,
                        &fCallerFreeProv);
      if (fResult == FALSE)
      {
         __leave;
      }

      // Open the input file to be encrypted or decrypted
      hInFile = CreateFile(lpszInputFileName,
                  GENERIC_READ,
                  0,
                  NULL,
                  OPEN_EXISTING, 
                  FILE_ATTRIBUTE_NORMAL,
                  NULL);
      if (hInFile == INVALID_HANDLE_VALUE)
      {
         MyPrintf(_T("CreateFile failed with %d\n"), GetLastError());
         __leave;
      }

      // Open the output file to write the encrypted or decrypted data
      hOutFile = CreateFile(lpszOutputFileName,
                  GENERIC_WRITE,
                  0,
                  NULL,
                  CREATE_ALWAYS, 
                  FILE_ATTRIBUTE_NORMAL,
                  NULL);
      if (hOutFile == INVALID_HANDLE_VALUE)
      {
         MyPrintf(_T("CreateFile failed with %d\n"), GetLastError());
         __leave;
      } 
  
      if (fEncrypt)
      {
         fResult = CryptGenKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hSessionKey);
         if (!fResult)
         {
            MyPrintf(_T("CryptGenKey failed with %X\n"), GetLastError());
            __leave;
         }

         // The first call to ExportKey with NULL gets the key size.
         dwSessionKeyBlob = 0;
         fResult = CryptExportKey(hSessionKey, hRSAKey, SIMPLEBLOB, 0,
                     NULL, &dwSessionKeyBlob);
         if (!fResult)
         {
            MyPrintf(_T("CryptExportKey failed with %X\n"), GetLastError());
            __leave;
         }
      
         // Allocate memory for Encrypted Session key blob
         pbSessionKeyBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionKeyBlob);
         if (!pbSessionKeyBlob)
         {
            MyPrintf(_T("LocalAlloc failed with %d\n"), GetLastError());
            __leave;
         }

         fResult = CryptExportKey(hSessionKey, hRSAKey, SIMPLEBLOB, 0,
                     pbSessionKeyBlob, &dwSessionKeyBlob);
         if (!fResult)
         {
            MyPrintf(_T("CryptExportKey failed with %X\n"), GetLastError());
            __leave;
         }

         // Write the size of key blob, then the key blob itself, to output file.
         fResult = WriteFile(hOutFile, &dwSessionKeyBlob,
                     sizeof(dwSessionKeyBlob),
                     &dwBytesWritten, NULL);
         if (!fResult)
         {
            MyPrintf(_T("WriteFile failed with %d\n"), GetLastError());
            __leave;
         }
         fResult = WriteFile(hOutFile, pbSessionKeyBlob,
                     dwSessionKeyBlob,
                     &dwBytesWritten, NULL);
         if (!fResult)
         {
            MyPrintf(_T("WriteFile failed with %d\n"), GetLastError());
            __leave;
         }
      }
      else
      {
         // Read in key block size, then key blob itself from input file.
         fResult = ReadFile(hInFile, &dwByteCount, sizeof(dwByteCount), 
               &dwBytesRead, NULL);
         if (!fResult)
         {
            MyPrintf(_T("ReadFile failed with %d\n"), GetLastError());
            __leave;
         }

         fResult = ReadFile(hInFile, pbBuffer, dwByteCount, &dwBytesRead, NULL);
         if (!fResult)
         {
            MyPrintf(_T("ReadFile failed with %d\n"), GetLastError());
            __leave;
         }

         // import key blob into "CSP"
         fResult = CryptImportKey(hProv, pbBuffer, dwByteCount, hRSAKey, 0, &hSessionKey);
         if (!fResult)
         {
            MyPrintf(_T("CryptImportKey failed with %X\n"), GetLastError());
            __leave;
         }
      }

      do
      {
         dwByteCount = 0;

         // Now read data from the input file 64K bytes at a time.
         fResult = ReadFile(hInFile, pbBuffer, IN_BUFFER_SIZE, &dwByteCount, NULL);

         // If the file size is exact multiple of 64K, dwByteCount will be zero after
         // all the data has been read from the input file. In this case, simply break
         // from the while loop. The check to do this is below
         if (dwByteCount == 0)
            break;

         if (!fResult)
         {
            MyPrintf(_T("ReadFile failed with %d\n"), GetLastError());
            __leave;
         }

         finished = (dwByteCount < IN_BUFFER_SIZE);

         // Encrypt/Decrypt depending on the required action.
         if (fEncrypt)
         {
            fResult = CryptEncrypt(hSessionKey, 0, finished, 0, pbBuffer, &dwByteCount,
                           OUT_BUFFER_SIZE);
            if (!fResult)
            {
               MyPrintf(_T("CryptEncrypt failed with %X\n"), GetLastError());
               __leave;
            }
         }
         else
         {
            fResult = CryptDecrypt(hSessionKey, 0, finished, 0, pbBuffer, &dwByteCount);
            if (!fResult)
            {
               MyPrintf(_T("CryptDecrypt failed with %X\n"), GetLastError());
               __leave;
            }
         }

         // Write the encrypted/decrypted data to the output file.
         fResult = WriteFile(hOutFile, pbBuffer, dwByteCount,
            &dwBytesWritten, NULL);
         if (!fResult)
         {
            MyPrintf(_T("WriteFile failed with %d\n"), GetLastError());
            __leave;
         }

      } while (!finished);

      if (fEncrypt)
         MyPrintf(_T("File %s is encrypted successfully!\n"), lpszInputFileName);
      else
         MyPrintf(_T("File %s is decrypted successfully!\n"), lpszInputFileName);

      fSuccess = TRUE;
   }
   __finally
   {
      /* Cleanup */
      CheckAndLocalFree(pbSessionKeyBlob);
      if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);
      if (hRSAKey != NULL) CryptDestroyKey(hRSAKey);
      if (hSessionKey != NULL) CryptDestroyKey(hSessionKey);
      if (fCallerFreeProv && hProv != NULL) CryptReleaseContext(hProv, 0);
      if (hInFile != INVALID_HANDLE_VALUE) CloseHandle(hInFile);
      if (hOutFile != INVALID_HANDLE_VALUE) CloseHandle(hOutFile);
   }

   return fSuccess;
}
Beispiel #5
0
int  main (int argc, char *argv[])
{


    DWORD dwProvType = 75;   
    DWORD data_len = 0;			    
    BYTE *oid = NULL;			    
    DWORD dwBlobLen = 0;		    
    DWORD cAlg = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 31);

	LPCSTR SourceName = NULL;
	LPCSTR Psdw = NULL;

	HANDLE hCurrProc = GetCurrentProcess();
	char patch[] = {0x80,0xbd,0x1c,0x00,0x00,0x00,0x98,0x75,0x07,0xc6,0x85,0x1c,0x00,0x00,0x00,0x9c,0x90,0x90,0x90,0x90,0x90,0x90}; ///!!!
	int patchLen = sizeof(patch);
	DWORD previous = 0;

	DWORD writeAddr = 0x11BC2;// INITIALIZED with offset!!!  //0x611E1BC2;


	/// PARSE COMMAND PARAMETERS HERE
	for (int n = 1;n < argc;n++) {
		if (n+1 >= argc)
			break;
		if (strcmp(argv[n],"-p") == 0) {
			Psdw = argv[++n];
		}
		if (strcmp(argv[n],"-s") == 0) {
			SourceName = argv[++n];
		}
	}
	if (!Psdw || !SourceName) {
		printf("[!] Dude, u specified incorrect parameters :/\n\tUsage: %s -s <source container name> -p <container password>",argv[0]);
		exit(1);
	}


    if(!CryptAcquireContextA(
	&hProvResponder, 
	"\\\\.\\Registry\\DestCopy", //Hardcoded name for container we create!!!
	NULL,
	dwProvType,
	CRYPT_NEWKEYSET | CRYPT_SILENT))
    {
		HandleError("Error during CryptAcquireContext");
    }


    if(!CryptAcquireContextA(
	&hProvSender, 
	SourceName, 
	NULL, 
	dwProvType, 
	0)) 
    {
		HandleError("Error during CryptAcquireContext");
    }

	/// FIND ADDRESS TO PATCH
	HMODULE hModules[1024];
	DWORD needed;
	if (EnumProcessModules(hCurrProc,hModules,1024,&needed)) {
		for (int i = 0; i < (needed / sizeof(HMODULE)); i++ )
        {
            char szModName[1024];

            if ( GetModuleFileNameA( hModules[i], szModName, sizeof(szModName)))
            {
				if (StrStrA(szModName, "cpcspi.dll")) {
					writeAddr += (DWORD)hModules[i];
					printf("[+] Address in memory for patching is '%08X'.\n",writeAddr);
					break;
				}
            }
        }
	}

	
	/// !!!
	printf("[+] Now we patch process memory, patch size is '%i' bytes...",patchLen);
	VirtualProtectEx(hCurrProc, (void*)writeAddr, 2, PAGE_EXECUTE_READWRITE, &previous);
	WriteProcessMemory(hCurrProc, (void*)writeAddr, &patch, patchLen, NULL);
	printf("Ok\n");

	printf("[+] Now we export container '%s'...\n",SourceName);

	if(!CryptGetProvParam( 
	hProvSender, 
	92, 
	NULL, 
	&data_len, 
	0))
    {
		HandleError("Error computing buffer length");
    }

    oid = (BYTE *)malloc( data_len );
    if( !oid )
		HandleError("Out of memory.");


    if(!CryptGetProvParam( 
	hProvSender, 
	92, 
	oid, 
	&data_len, 
	0))
    {
		HandleError("Error during CryptGetProvParam");
    }


    if(!CryptSetProvParam(
	hProvResponder, 
	92, 
	oid, 
	0 ))
    {
		free( oid );
		HandleError("Error during CryptSetProvParam");
    }

    free( oid );

    data_len = 0;


    if(!CryptGetProvParam( 
	hProvSender, 
	93, 
	NULL, 
	&data_len, 
	0))
    {
		HandleError("Error computing buffer length");
    }

	/// SPECIFY PASSWORD FOR CONTAINER HERE
	if(!CryptSetProvParam( hProvSender,PP_SIGNATURE_PIN,(LPBYTE)Psdw,0))
	{
	    HandleError("Error during CryptSetProvParam");
	}

    oid = (BYTE *)malloc( data_len );
    if( !oid )
		HandleError("Out of memory");

    if(!CryptGetProvParam( 
	hProvSender, 
	93, 
	oid, 
	&data_len, 
	0))
    {
		free( oid );
		HandleError("Error during CryptGetProvParam");
    }

    if(!CryptSetProvParam(
	hProvResponder, 
	93, 
	oid, 
	0 ))
    {
		free( oid );
		HandleError("Error during CryptSetProvParam");
    }
    free( oid );


    if(!CryptGetUserKey( 
	hProvSender, 
	AT_KEYEXCHANGE, 
	&hSenderKey )) 
    {
		HandleError("Error during CryptGetUserKey private key");
    }		

	
    if(!CryptGenKey(
	hProvSender, 
	(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | 37), 
	CRYPT_EXPORTABLE, 
	&hSenderEphemKey)) 
    {
		HandleError("ERROR -- CryptGenKey");
    }
	
	
    if(!CryptGenKey(
	hProvResponder, 
	(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | 37), 
	CRYPT_EXPORTABLE | CRYPT_PREGEN,
	&hResponderEphemKey))
    {
		HandleError("ERROR -- CryptGenKey");
    }
	
	
    if(!CryptGetKeyParam( 
	hSenderEphemKey, 
	106, 
	NULL, 
	&dwBlobLen, 
	0))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob)
		HandleError("Out of memory");


    if(!CryptGetKeyParam( 
	hSenderEphemKey, 
	106, 
	pbKeyBlob, 
	&dwBlobLen, 
	0))
    {
		HandleError("Error during CryptGetProvParam");
    }

    if(!CryptSetKeyParam(
	hResponderEphemKey, 
	106, 
	pbKeyBlob, 
	0))
    {
		HandleError("Error during CryptSetProvParam");
    }

    free(pbKeyBlob);
    pbKeyBlob = NULL; 
    dwBlobLen = 0;


    if(!CryptSetKeyParam(
	hResponderEphemKey, 
	KP_X, 
	NULL, 
	0))
    {
		HandleError("Error during CryptSetKeyParam");
    }

    if(!CryptExportKey(
	hSenderEphemKey,
	0, 
	PUBLICKEYBLOB,
	0, 
	NULL,
	&dwBlobLen ))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob) 
		HandleError("Out of memory");

    if(!CryptExportKey(
	hSenderEphemKey,
	0, 
	PUBLICKEYBLOB,
	0, 
	pbKeyBlob,
	&dwBlobLen ))
    {
		HandleError("Error during CryptExportKey");
    }


    if(!CryptImportKey(
	hProvResponder, 
	pbKeyBlob, 
	dwBlobLen, 
	hResponderEphemKey, 
	0, 
	&hResponderAgreeKey))
    {
		HandleError("Error during CryptImportKey ephemeral key");
    }


    free(pbKeyBlob);
    pbKeyBlob = NULL; 
    dwBlobLen = 0;


    if(!CryptExportKey(
	hResponderEphemKey,
	0, 
	PUBLICKEYBLOB,
	0, 
	NULL,
	&dwBlobLen ))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob) 
		HandleError("Out of memory");

    if(!CryptExportKey(
	hResponderEphemKey,
	0, 
	PUBLICKEYBLOB,
	0, 
	pbKeyBlob,
	&dwBlobLen ))
    {
		HandleError("Error during CryptExportKey");
    }

 

    if(!CryptImportKey(
	hProvSender, 
	pbKeyBlob, 
	dwBlobLen, 
	hSenderEphemKey, 
	0, 
	&hSenderAgreeKey))
    {
		HandleError("Error during CryptImportKey ephemeral key");
    }


    free(pbKeyBlob);
    pbKeyBlob = NULL; 
    dwBlobLen = 0;


    if(!CryptSetKeyParam(
	hSenderAgreeKey,
	KP_ALGID, 
	(BYTE*)&cAlg,
	0 ))
    {
		HandleError("Error during CryptSetKeyParam agree key");
    }


    if(!CryptSetKeyParam(
	hResponderAgreeKey,
	KP_ALGID, 
	(BYTE*)&cAlg,
	0 ))
    {
		HandleError("Error during CryptSetKeyParam agree key");
    }
	

    if(!CryptExportKey(
	hSenderKey,
	hSenderAgreeKey, 
	PRIVATEKEYBLOB,
	0, 
	NULL,
	&dwBlobLen ))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob) 
		HandleError("Out of memory");

    if(!CryptExportKey(
	hSenderKey,
	hSenderAgreeKey, 
	PRIVATEKEYBLOB,
	0, 
	pbKeyBlob,
	&dwBlobLen ))
    {
		HandleError("Error during CryptExportKey");
    }



    if(!CryptImportKey(
	hProvResponder, 
	pbKeyBlob, 
	dwBlobLen, 
	hResponderAgreeKey, 
	0,
	&hResponderKey))
    {
		HandleError("Error during CryptImportKey private key");
    }


    free(pbKeyBlob);
    pbKeyBlob = NULL; 
    dwBlobLen = 0;



    if(!CryptGetKeyParam( 
	hSenderKey, 
	KP_CERTIFICATE, 
	NULL, 
	&dwBlobLen, 
	0))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);

    if(!pbKeyBlob)
    {
		HandleError("Out of memory");
    }


    if(!CryptGetKeyParam( 
	hSenderKey, 
	KP_CERTIFICATE, 
	pbKeyBlob, 
	&dwBlobLen, 
	0))
    {
		HandleError("Error during CryptGetProvParam");
    }

    if(!CryptSetKeyParam(
	hResponderKey, 
	KP_CERTIFICATE, 
	pbKeyBlob, 
	0))
    {
		HandleError("Error during CryptSetProvParam");
    }

	printf("[+] D0n3!!!\n");

    CleanUp();
    return 0;
}
STDMETHODIMP FileEncrypter::EncryptFile(BSTR szInFN,BSTR szOutFN,BSTR szPwd){
	if (!szInFN || _tcslen(szInFN)==0) {
		InfoMsgBox(_T("对不起,您必须提供待加密的文件名!"));
		return S_OK;
	}
	if (!szOutFN || _tcslen(szOutFN)==0) {
		InfoMsgBox(_T("对不起,您必须提供加密后的文件名!"));
		return S_OK;
	}
	FILE *hSource=0; 
	FILE *hDestination=0; 

	HCRYPTPROV hCryptProv; 
	HCRYPTKEY hKey; 
	HCRYPTKEY hXchgKey; 
	HCRYPTHASH hHash; 
	
	PBYTE pbKeyBlob; 
	DWORD dwKeyBlobLen; 
	
	PBYTE pbBuffer; 
	DWORD dwBlockLen; 
	DWORD dwBufferLen; 
	DWORD dwCount; 

	char* utf8Pwd=NULL;

	TCHAR msgTip[STRLEN_DEFAULT]={0};
	_tfopen_s(&hSource,szInFN,_T("rb"));
	if(!hSource){
		_stprintf_s(msgTip,_T("对不起,无法打开文件“%s”!"),szInFN);
		InfoMsgBox(msgTip);
		goto clean;
	}
	_tfopen_s(&hDestination,szOutFN,_T("wb"));
	if(!hDestination){
		_stprintf_s(msgTip,_T("对不起,无法打开文件“%s”!"),szOutFN);
		InfoMsgBox(msgTip);
		goto clean;
	}

	TCHAR szContainerName[]=_T("f0d74c20-4a68-47d2-a1d2-7c622399ad48");	//TODO:容器名称为“test”?
	//初始化CSP上下文
	if(CryptAcquireContext(&hCryptProv,szContainerName,PROVIDER_NAME,PROV_RSA_FULL,0))
	{
		//正确初始化CSP
	}
	else
	{
		if(!CryptAcquireContext(&hCryptProv,szContainerName,PROVIDER_NAME,PROV_RSA_FULL,CRYPT_NEWKEYSET)){
			InfoMsgBox(_T("对不起,无法初始化CSP上下文,请确认UKey是否插入电脑且工作正常,并安装了正确的驱动程序!"));
			goto clean;
		}
	}
	//如果没有提供密码
	if(!szPwd || _tcslen(szPwd)==0){
		if(!CryptGenKey(hCryptProv,ENCRYPT_ALGORITHM,CRYPT_EXPORTABLE, /*KEYLENGTH | CRYPT_EXPORTABLE, */&hKey))
		{
			InfoMsgBox(_T("对不起,无法生成密钥,请确认UKey是否插入电脑且工作正常,并安装了正确的驱动程序!"));
			goto clean;
		}
		if(CryptGetUserKey(hCryptProv,AT_KEYEXCHANGE,&hXchgKey)){
			//公钥被成功获取
		}
		else{
			CryptGenKey(hCryptProv,AT_KEYEXCHANGE,0,&hXchgKey);
		}
		if(!CryptExportKey(hKey,hXchgKey,SIMPLEBLOB, 0,NULL, &dwKeyBlobLen)){
			InfoMsgBox(_T("对不起,无法获取密钥块,请确认UKey是否插入电脑且工作正常,并安装了正确的驱动程序!"));
			goto clean;
		}
		if(!(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen)))
		{ 
			InfoMsgBox(_T("对不起,无法为密钥块分配内存!"));
			goto clean;
		}
		if(!CryptExportKey(hKey,hXchgKey,SIMPLEBLOB,0, pbKeyBlob, &dwKeyBlobLen)){
			InfoMsgBox(_T("对不起,无法为导出密钥!"));
			goto clean;
		}
		CryptDestroyKey(hXchgKey); 
		hXchgKey = 0;
		fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination); 
		if(ferror(hDestination))
		{
			InfoMsgBox(_T("无法写入输出文件!"));
			goto clean;
		}
		fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination); 
		if(ferror(hDestination))
		{ 
			InfoMsgBox(_T("无法写入输出文件!"));
			goto clean;
		}
	}
	else{	//提供了密码
		if(!CryptCreateHash(hCryptProv,CALG_MD5, 0,0,&hHash))
		{
			InfoMsgBox(_T("无法创建哈希!"));
			goto clean;
		}
		int keyLen=FromUTF16(szPwd,NULL,0);
		if (keyLen>0) keyLen+=1;
		utf8Pwd=new char[keyLen];
		FromUTF16(szPwd,utf8Pwd,keyLen);
		if(!CryptHashData( hHash, (BYTE *)utf8Pwd, keyLen-1, 0))
		{
			InfoMsgBox(_T("无法创建密码哈希值!"));
			goto clean;
		}
		if(!CryptDeriveKey( hCryptProv,ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey))
		{
			InfoMsgBox(_T("无法从哈希值创建密钥!"));
			goto clean;
		}
		CryptDestroyHash(hHash); 
		hHash = 0; 
	}
	dwBlockLen = 1024 - 1024 % ENCRYPT_BLOCK_SIZE; 
	if(ENCRYPT_BLOCK_SIZE > 1) 
		dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; 
	else 
		dwBufferLen = dwBlockLen; 

	if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
	{
		InfoMsgBox(_T("对不起,无法为缓冲区分配内存!"));
		goto clean;
	}
	//循环读取源文件的数据然后加密数据并把结果写入目标文件
	do
	{ 
		dwCount = fread(pbBuffer, 1, dwBlockLen, hSource); 
		if(ferror(hSource))
		{ 
			InfoMsgBox(_T("对不起,无法读取待加密文件数据!"));
			goto clean;
		}
		
		if(!CryptEncrypt(hKey,0,feof(hSource),0,pbBuffer,&dwCount,dwBufferLen))
		{ 
			InfoMsgBox(_T("加密过程出现错误!"));
			goto clean;
		} 
		
		fwrite(pbBuffer, 1, dwCount, hDestination); 
		if(ferror(hDestination))
		{ 
			InfoMsgBox(_T("对不起,无法写入加密后的数据到目标文件!"));
			goto clean;
		}
	} 
	while(!feof(hSource)); 
	InfoMsgBox(_T("加密成功!"));
	//资源释放
clean:
	if(utf8Pwd) delete[] utf8Pwd;
	if(hSource) fclose(hSource); 
	if(hDestination) fclose(hDestination);
	if(pbBuffer) free(pbBuffer); 

	if(hKey) CryptDestroyKey(hKey); 

	if(hXchgKey) CryptDestroyKey(hXchgKey); 

	if(hHash) CryptDestroyHash(hHash); 

	if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
	return S_OK;
}
Beispiel #7
0
static BOOL
decodeSK( BOOL aes256, DWORD keylen, BYTE *keybuf )
{
    BYTE	buffer[ 1024 ];
    DWORD	i, size, length;

    struct skb
    {
	PUBLICKEYSTRUC	hdr;
	ALG_ID		algId;
	BYTE		key[1];
    }		*expKey = (struct skb *)buffer;

    struct ptkb
    {
	PUBLICKEYSTRUC	hdr;
	DWORD		keysize;
	BYTE		key[1];
    }		*txtKey = (struct ptkb *)buffer;

    length = (expKey->key - buffer) + keylen;

    if ( length > sizeof( buffer ) )
    {
	fprintf( stderr, "CryptImportKey() requires %d bytes\n", length );
	return( FALSE );
    }

    expKey->hdr.bType = SIMPLEBLOB;
    expKey->hdr.bVersion = CUR_BLOB_VERSION;
    expKey->hdr.reserved = 0;
    expKey->hdr.aiKeyAlg = aes256 ? SessKey256 : SessKey128;
    expKey->algId = XchgKeyType;

    /*
    ** NOTE: it appears that the encoded key is byte swapped compared
    ** to external standards.  There is a cryptic reference to a
    ** ReverseMemCopy() function in the RSA/SChannel server master
    ** key creation example.  Also, the internal RSA modulus is
    ** byte swapped compared to the X509 encoding.  This swap is
    ** required to interoperate with JavaSSE.
    */
    for( i = 0; i < keylen; i++ )
	expKey->key[i] = keybuf[ keylen - i - 1 ];

    if ( ! CryptImportKey( provider, (BYTE *)expKey, length, xchgKey, CRYPT_EXPORTABLE, &sessKey ) )
    {
	fprintf( stderr, "CryptImportKey() failed: 0x%x\n", GetLastError() );
	return( FALSE );
    }

    if ( ! CryptSetKeyParam( sessKey, KP_MODE, (BYTE *)&sessKeyMode, 0 ) )
    {
	fprintf( stderr, "CryptSetKeyParam() MODE failed: 0x%x\n", GetLastError() );
	return( 0 );
    }

    if ( ! CryptSetKeyParam( sessKey, KP_PADDING, (BYTE *)&sessKeyPadding, 0 ) )
    {
	fprintf( stderr, "CryptSetKeyParam() PADDING failed: 0x%x\n", GetLastError() );
	return( 0 );
    }

    if ( sessKeyMode == CRYPT_MODE_CBC )
    {
	size = sizeof( length );

	if ( ! CryptGetKeyParam( sessKey, KP_BLOCKLEN, (BYTE *)&length, &size, 0 ) )
	{
	    fprintf( stderr, "CryptGetKeyParam() BLOCKLEN failed: 0x%x\n", GetLastError() );
	    exit( 1 );
        }

	length /= 8;	/* Bits -> bytes */
	for( i = 0; i < length; i++ )  buffer[i] = 0;
	
	if ( ! CryptSetKeyParam( sessKey, KP_IV, buffer, 0 ) )
	{
	    fprintf( stderr, "CryptSetKeyParam() PADDING failed: 0x%x\n", GetLastError() );
	    return( 0 );
	}
    }

    if ( verbose )
    {
	if ( ! CryptExportKey( sessKey, 0, PLAINTEXTKEYBLOB, 0, NULL, &size ) )
	{
	    fprintf( stderr, "CryptExportKey() [1] failed: 0x%x\n", GetLastError() );
	    return( FALSE );
	}

	if ( size > sizeof( buffer ) )
	{
	    fprintf( stderr, "CryptExportKey() requires %d bytes\n", size );
	    return( FALSE );
	}

	length = sizeof( buffer );

	if ( ! CryptExportKey( sessKey, 0, PLAINTEXTKEYBLOB, 0, (BYTE *)txtKey, &length ) )
	{
	    fprintf( stderr, "CryptExportKey() [2] failed: 0x%x\n", GetLastError() );
	    return( FALSE );
	}

	printf( "Sess Key: \n" );
	hexDump( txtKey->keysize, txtKey->key );
	keyInfo( sessKey );
    }

    return( TRUE );
}
Beispiel #8
0
BOOL EncryptData(char *buffer, char **encrData,DWORD *dwBufferSize) {
	HCRYPTPROV hProv = 0;
	HCRYPTKEY hKey = 0;
	HCRYPTKEY hXchgKey = 0;
	BYTE *pbBuffer;
	DWORD dwCount;
	DWORD dwBlobLen;
	BOOL res;
	DWORD srcIndex=0,destIndex,actSize;
	DWORD error;
	// Get a handle to the default provider.
    //if(!(res=CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))) {
	if(FALSE == (res=CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))) {
		if((GetLastError()==NTE_KEYSET_NOT_DEF)||(GetLastError()==NTE_BAD_KEYSET))
			res=CreateKeyset(&hProv);
	}

    if(!res) {
		goto done;
	}

	res=FALSE;
    
    // Get a handle to key exchange key.
	if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey)) {

	//Si
		DWORD errcode = GetLastError();
		if ( errcode == NTE_NO_KEY)
		{
			//create key exchange key pair
			if (! CryptGenKey(hProv,AT_KEYEXCHANGE,0,&hXchgKey))
			{
				goto done;
			}
		}
		else
		{
			SetLastError(errcode);
			goto done;
		}

	}


	// Create a random block cipher session key.
	if(!CryptGenKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKey)) {
		goto done;
	}
	
	// Determine the size of the key blob and allocate memory.
	CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, NULL, &dwBlobLen);
		
	
	actSize=dwBlobLen+sizeof(DWORD)+*dwBufferSize+64;
	if((pbBuffer = (PBYTE)malloc(actSize)) == NULL) goto done;
	
	*(DWORD*)pbBuffer=dwBlobLen;
	// Export the key into a simple key blob.
	if(!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, pbBuffer+sizeof(DWORD),&dwBlobLen)) {
		free(pbBuffer);
		goto done;
	}
	
	
	destIndex=dwBlobLen+sizeof(DWORD);
	while(srcIndex<*dwBufferSize) {    
		dwCount = min(BLOCK_SIZE,*dwBufferSize-srcIndex);	
		memcpy(pbBuffer+destIndex,buffer+srcIndex,dwCount);
		srcIndex+=dwCount;
		if(actSize<destIndex) {
			pbBuffer=(PBYTE)realloc(pbBuffer,2*destIndex);
			actSize=2*destIndex;
		}
		
		if(!CryptEncrypt(hKey, 0, srcIndex>=*dwBufferSize, 0, pbBuffer+destIndex, &dwCount, actSize-destIndex))    {
			free(pbBuffer);
			*dwBufferSize=0;
            *encrData = 0;
			goto done;    
		}    
		destIndex+=dwCount;
	}
	res=TRUE;
	*dwBufferSize=destIndex;
	*encrData=(char*)pbBuffer;


done:
	error=GetLastError();
	// Destroy the session key.
	if(hKey != 0) CryptDestroyKey(hKey);
	// Destroy the key exchange key.
	if(hXchgKey != 0) CryptDestroyKey(hXchgKey);
	// Release the provider handle.
	if(hProv != 0) CryptReleaseContext(hProv, 0);
	//if(pbBuffer) free(pbBuffer);
	SetLastError(error);
	return res;
}
Beispiel #9
0
static BOOL
initCrypt()
{
    BYTE	buffer[ 1024 ];
    DWORD	size, flags;

    if ( ! CryptAcquireContext( &provider, NULL, NULL, ProvType, CRYPT_VERIFYCONTEXT ) )
    {
	fprintf( stderr, "CryptAcquireContext() failed: 0x%x\n", GetLastError() );
	return( FALSE );
    }

    if ( ! CryptGenKey( provider, XchgKeyType, XchgKeyFlags, &xchgKey ) )
    {
	fprintf( stderr, "CryptGenKey() failed: 0x%x\n", GetLastError() );
	return( FALSE );
    }

    for( flags = CRYPT_FIRST; ; flags = CRYPT_NEXT )
    {
	PROV_ENUMALGS_EX *info = (PROV_ENUMALGS_EX *)buffer;

	size = sizeof( buffer );

	if ( ! CryptGetProvParam( provider, PP_ENUMALGS_EX, buffer, &size, flags ) )
	{
	    DWORD status = GetLastError();

	    if ( status == ERROR_NO_MORE_ITEMS )  break;
	    fprintf( stderr, "CryptGetProvParam() failed: 0x%x\n", GetLastError() );
	    return( FALSE );
	}

	switch( info->aiAlgid )
	{
	case CALG_RSA_KEYX :	rsaMaxKey = max( rsaMaxKey, info->dwMaxLen );	break;
	case CALG_AES_128 :
	case CALG_AES_192 :
	case CALG_AES_256 :	aesMaxKey = max( aesMaxKey, info->dwMaxLen );	break;
	}
    }

    if ( verbose )
    {
	struct pkb
	{
	    PUBLICKEYSTRUC	hdr;
	    RSAPUBKEY		rsa;
	    BYTE		mod[1];
	}	*rsaKey= (struct pkb *)buffer;

	printf( "RSA Max Key Length: %d\n", rsaMaxKey );
	printf( "AES Max Key Length: %d\n", aesMaxKey );

	if ( ! CryptExportKey( xchgKey, 0, PUBLICKEYBLOB, 0, NULL, &size ) )
	{
	     fprintf( stderr, "CryptExportKey() [1] failed: 0x%x\n", GetLastError() );
	     return( FALSE );
	}

	if ( size > sizeof( buffer ) )
	{
	    fprintf( stderr, "CryptExportKey() requires %d bytes\n", size );
	    return( FALSE );
	}

	size = sizeof( buffer );

	if ( ! CryptExportKey( xchgKey, 0, PUBLICKEYBLOB, 0, (BYTE *)rsaKey, &size ) )
	{
	     fprintf( stderr, "CryptExportKey() [2] failed: 0x%x\n", GetLastError() );
	     return( FALSE );
	}

	printf( "Xchg Exp: %d\n", rsaKey->rsa.pubexp );
	printf( "Xchg Mod: \n" );
	hexDump( rsaKey->rsa.bitlen / 8, rsaKey->mod );
    }

    if ( rsaMaxKey < 1024  ||  aesMaxKey < 128 )
    {
	fprintf( stderr, "Invalid minimum key length\n" );
	return( FALSE );
    }

    return( TRUE );
}
static BOOL CAPIEncryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword)
{
    FILE *hSource      = NULL;
    FILE *hDestination = NULL;
	errno_t err;
    INT eof = 0;

    HCRYPTPROV hProv   = 0;
    HCRYPTKEY hKey     = 0;
    HCRYPTKEY hXchgKey = 0;
    HCRYPTHASH hHash   = 0;

    PBYTE pbKeyBlob = NULL;
    DWORD dwKeyBlobLen;

    PBYTE pbBuffer = NULL;
    DWORD dwBlockLen;
    DWORD dwBufferLen;
    DWORD dwCount;

    BOOL status = FALSE;

    // Open source file.
	err=fopen_s(&hSource,szSource,"rb");
    if(err !=0) {
        printf("Error opening Plaintext file!\n");
        goto done;
    }

    // Open destination file.
	err=fopen_s(&hDestination,szDestination,"wb");
	if(err != 0){
        printf("Error opening Ciphertext file!\n");
        goto done;
    }

    // Get handle to the CSP. In order to be used with different OSs 
	// with different default provides, the CSP is explicitly set. 
	// If the Microsoft Enhanced Provider is not installed, set parameter
	// three to MS_DEF_PROV 
    
	if(!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0)) {
        printf("Error %x during CryptAcquireContext!\n", GetLastError());
        goto done;
    }

    if(szPassword == NULL) {
        // Encrypt the file with a random session key.

        // Create a random session key.
        if(!CryptGenKey(hProv, ENCRYPT_ALGORITHM, KEYLENGTH | CRYPT_EXPORTABLE, &hKey)) {
            printf("Error %x during CryptGenKey!\n", GetLastError());
            goto done;
        }

        // Get handle to key exchange public key.
        if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey)) {
            printf("Error %x during CryptGetUserKey!\n", GetLastError());
            goto done;
        }

        // Determine size of the key blob and allocate memory.
        if(!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, NULL, &dwKeyBlobLen)) {
            printf("Error %x computing blob length!\n", GetLastError());
            goto done;
        }
        if((pbKeyBlob = (unsigned char *) malloc(dwKeyBlobLen)) == NULL) {
            printf("Out of memory!\n");
            goto done;
        }

        // Export session key into a simple key blob.
        if(!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, pbKeyBlob, &dwKeyBlobLen)) {
            printf("Error %x during CryptExportKey!\n", GetLastError());
            goto done;
        }

        // Release key exchange key handle.
        CryptDestroyKey(hXchgKey);
        hXchgKey = 0;

        // Write size of key blob to destination file.
        fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);
        if(ferror(hDestination)) {
            printf("Error writing header!\n");
            goto done;
        }

        // Write key blob to destination file.
        fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);
        if(ferror(hDestination)) {
            printf("Error writing header!\n");
            goto done;
        }

    } else {
        // Encrypt the file with a session key derived from a password.

        // Create a hash object.
        if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
            printf("Error %x during CryptCreateHash!\n", GetLastError());
            goto done;
        }

        // Hash in the password data.
        if(!CryptHashData(hHash, (const unsigned char *)szPassword, (DWORD)strlen(szPassword), 0)) {
            printf("Error %x during CryptHashData!\n", GetLastError());
            goto done;
        }

        // Derive a session key from the hash object.
        if(!CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey)) {
            printf("Error %x during CryptDeriveKey!\n", GetLastError());
            goto done;
        }

        // Destroy the hash object.
        CryptDestroyHash(hHash);
        hHash = 0;
    }

    // Determine number of bytes to encrypt at a time. This must be a multiple
    // of ENCRYPT_BLOCK_SIZE.
    dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;

    // Determine the block size. If a block cipher is used this must have
    // room for an extra block.
#ifdef USE_BLOCK_CIPHER
        dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
#else
        dwBufferLen = dwBlockLen;
#endif

    // Allocate memory.
    if((pbBuffer = (unsigned char *) malloc(dwBufferLen)) == NULL) {
        printf("Out of memory!\n");
        goto done;
    }

    // Encrypt source file and write to Source file.
    do {
        // Read up to 'dwBlockLen' bytes from source file.
        dwCount = (DWORD)fread(pbBuffer, 1, dwBlockLen, hSource);
        if(ferror(hSource)) {
            printf("Error reading Plaintext!\n");
            goto done;
        }
        eof = feof(hSource);

        // Encrypt data
        if(!CryptEncrypt(hKey, 0, eof, 0, pbBuffer, &dwCount, dwBufferLen)) {
            printf("bytes required:%d\n",dwCount);
            printf("Error %x during CryptEncrypt!\n", GetLastError());
            goto done;
        }

        // Write data to destination file.
        fwrite(pbBuffer, 1, dwCount, hDestination);
        if(ferror(hDestination)) {
            printf("Error writing Ciphertext!\n");
            goto done;
        }
    } while(!feof(hSource));

    status = TRUE;

    printf("OK\n");

    done:

    // Close files.
    if(hSource) fclose(hSource);
    if(hDestination) fclose(hDestination);

    // Free memory.
    if(pbKeyBlob) free(pbKeyBlob);
    if(pbBuffer) free(pbBuffer);

    // Destroy session key.
    if(hKey) CryptDestroyKey(hKey);

    // Release key exchange key handle.
    if(hXchgKey) CryptDestroyKey(hXchgKey);

    // Destroy hash object.
    if(hHash) CryptDestroyHash(hHash);

    // Release provider handle.
    if(hProv) CryptReleaseContext(hProv, 0);

    return(status);
}
Beispiel #11
0
BOOL 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;

   __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)
            {
               // No good, leave
               __leave;
            }
         }
         else
         {
            // No good, leave
            __leave;
         }
      }

      // Generate the private key
      fResult = CryptGenKey(*hProv, dwKeySpec, CRYPT_EXPORTABLE, hPrivateKey);
      if (!fResult) __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) __leave;      

      keyblob = (LPBYTE)LocalAlloc(LPTR, dwkeyblob);
      if (!keyblob) __leave;

      fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, keyblob, &dwkeyblob);
      if (!fResult) __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))
      {                 
         __leave;
      }

      fReturn = TRUE;
   }
   __finally
   {
      if (keyblob) LocalFree(keyblob);

      if (!fReturn)
      {
         if (*hPrivateKey) CryptDestroyKey(*hPrivateKey);
         if (*hProv) CryptReleaseContext(*hProv, 0);
      }
   }

   return fReturn;
}
Beispiel #12
0
HRESULT CPkcs10::put_PublicKey(HCRYPTPROV hprov, DWORD dwKeySpec)
// Store the indicated public key in the subjectPublicKeyInfo field
// of the CertificationRequest. From PKCS #10:
//
//		subjectPublicKeyInfo contains information about the public 
//		key being certified. The information identifies the entity's 
//		public-key algorithm (and any associated parameters); examples 
//		of public-key algorithms include X.509's rsa and PKCS #1's 
//		rsaEncryption. 
//
//		The information also includes a bit-string representation of 
//		the entity's public key. For both public-key algorithms just 
//		mentioned, the bit string contains the BER encoding of a 
//		value of X.509/PKCS #1 type RSAPublicKey
//	
	{
	HRESULT hr = m_pworld->HprovToSubjectPublicKeyInfo(
					hprov, 
                    dwKeySpec,
					m_preq->certificationRequestInfo.subjectPublicKeyInfo
					);
	#if defined(_DEBUG) 
    // Check to to make sure we can read what we wrote
    if (hr==S_OK)
		{
		HCRYPTKEY hkeyuser;
		VERIFY(CryptGetUserKey(hprov, dwKeySpec, &hkeyuser));
		BYTE rgb1[1024];	DWORD cb1 = 1024;
//		BYTE rgb2[1024];	DWORD cb2 = 1024;
		VERIFY(CryptExportKey(hkeyuser, 0, PUBLICKEYBLOB, 0, rgb1, &cb1));
//		VERIFY(CryptExportKey(hkeypub,  0, PUBLICKEYBLOB, 0, rgb2, &cb2));
//			Would like to do the above, but CAPI won't let us export an imported key
//			(*(&(*##$^*&. So, having verified we can successfully fully import, we just
//			go get the raw bits again.
		BLOB b;	m_pworld->Init(b);
		
        HCRYPTKEY hkeypub;
		if (get_PublicKey(hprov, &hkeypub) == S_OK)
            {
		    VERIFY(CryptDestroyKey(hkeypub));
            }
        else
            OutputDebugString("DigSig: Public key retrieval failed\n");

		VERIFY(m_pworld->PublicKeyBlobFromBitString(m_preq->certificationRequestInfo.subjectPublicKeyInfo, dwKeySpec, &b) == S_OK);
		DWORD cb2 = b.cbSize; BYTE* rgb2 = b.pBlobData;
		VERIFY(cb1 == cb2);
		if (cb1 != cb2)
            {
            cb1 = min(cb1,cb2);
            cb2 = cb1;
            }
        ((PUBLICKEYSTRUC*)rgb1)->reserved = 0;
		((PUBLICKEYSTRUC*)rgb2)->reserved = 0;
		VERIFY(memcmp(rgb1, rgb2, cb1) == 0);
		VERIFY(CryptDestroyKey(hkeyuser));

		m_pworld->Free(b);
		}
	#endif

	MakeDirty();
	return hr;
	}
int _tmain(int argc, _TCHAR* argv[])
{
	//--------------------------------------------------------------------
	// Declare and initialize variables.
	HCERTSTORE       hCertStore = NULL;        
	PCCERT_CONTEXT   pCertContext = NULL;      
	TCHAR * pszStoreName = TEXT("MY");
	HCRYPTKEY hKey = NULL;
	HCRYPTPROV hProv = NULL;
	DWORD dwKeySpec = 0;
	BOOL bCallerFreeProv = FALSE;
	HCRYPTHASH hHash;
	DWORD dwSigLen= 0;
	BYTE * pbSignature = NULL;

	//-------------------------------------------------------------
	// Declare and initialize variables.
	BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed.";
	DWORD dwBufferLen = strlen((char *)pbBuffer)+1;

	//--------------------------------------------------------------------
	//   Open a certificate store.
	if ( hCertStore = CertOpenSystemStore(
		NULL,
		pszStoreName))
	{
		fprintf(stderr,"The store has been opened.\n");
	}
	else
	{
		printf("Unable to open store.\n");
		goto err;
	}
	//--------------------------------------------------------------------
	//  Display a list of the certificates in the store and 
	//  allow the user to select a certificate. 
	if(!(pCertContext = CryptUIDlgSelectCertificateFromStore(
		hCertStore,      // Open the store that contains the certificates to
		// display
		NULL,
		NULL,
		NULL,
		CRYPTUI_SELECT_LOCATION_COLUMN,
		0,
		NULL)))
	{
		printf("Select Certificate UI failed.\n" );
		goto err;
	}

#if 1
	//获取CSP句柄
	if (!CryptAcquireCertificatePrivateKey(pCertContext, 0, NULL, &hProv, &dwKeySpec, &bCallerFreeProv))
	{
		printf("CryptAcquireCertificatePrivateKey failed.\n" );
		goto err;
	}

	//获取密钥句柄
	if(!CryptGetUserKey(hProv, dwKeySpec, &hKey))
	{
		printf("CryptGetUserKey failed.\n" );
		goto err;
	}

	
	
	//--------------------------------------------------------------------
	// Acquire a hash object handle.
	if(CryptCreateHash(
		hProv, 
		CALG_MD5, 
		0, 
		0, 
		&hHash)) 
	{
		printf("An empty hash object has been created. \n");
	}
	else
	{
		printf("Error during CryptBeginHash!\n");
		goto err;
	}


	//--------------------------------------------------------------------
	//  This code assumes that the handle of a cryptographic context 
	//  has been acquired and that a hash object has been created 
	//  and its handle (hHash) is available.
	if(CryptHashData(
		hHash, 
		pbBuffer, 
		dwBufferLen, 
		0)) 
	{
		printf("The data buffer has been added to the hash.\n");
	}
	else
	{
		printf("Error during CryptHashData.\n");
		goto err;
	}


	//--------------------------------------------------------------------
	// Determine the size of the signature and allocate memory.
	dwSigLen= 0;
	if(CryptSignHash(
		hHash, 
		dwKeySpec, 
		NULL, 
		0, 
		NULL, 
		&dwSigLen)) 
	{
		printf("Signature length %d found.\n",dwSigLen);
	}
	else
	{
		printf("Error during CryptSignHash\n");
		goto err;
	}
	//--------------------------------------------------------------------
	// Allocate memory for the signature buffer.

	if(pbSignature = (BYTE *)malloc(dwSigLen))
	{
		printf("Memory allocated for the signature.\n");
	}
	else
	{
		printf("Out of memory\n");
		goto err;
	}
	//--------------------------------------------------------------------
	// Sign the hash object.

	if(CryptSignHash(
		hHash, 
		dwKeySpec, 
		NULL, 
		0, 
		pbSignature, 
		&dwSigLen)) 
	{
		printf("pbSignature is the hash signature.\n");
	}
	else
	{
		printf("Error during CryptSignHash.\n");
		goto err;
	}


	{
		DWORD dwBlobLen = 0;
		BYTE * pbKeyBlob = 0;
		HCRYPTKEY hPubKey = 0; 

		if(CryptExportKey(  
			hKey, 
			NULL, 
			PUBLICKEYBLOB,       //导出公钥
			0,   
			NULL,
			&dwBlobLen))         //返回密钥数据长度
		{
			printf("Size of the BLOB for the public key determined. \n");
		}
		else
		{
			printf("Error computing BLOB length.\n");
			goto err;
		}

		if(pbKeyBlob = (BYTE*)malloc(dwBlobLen))
		{
			printf("Memory has been allocated for the BLOB. \n");
		}
		else
		{
			printf("Out of memory. \n");
			goto err;
		}
		if(CryptExportKey(  
			hKey,
			NULL, 
			PUBLICKEYBLOB,   
			0,   
			pbKeyBlob,       //返回密钥数据
			&dwBlobLen)) //导出的密钥数据的长度
		{
			printf("Contents have been written to the BLOB. \n");
		}
		else
		{
			printf("Error exporting key.\n");
			goto err;
		}

		if(CryptImportKey(hProv,pbKeyBlob, dwBlobLen, NULL, 0, &hPubKey))
		{
			printf("CryptImportKey OK. \n");
		}
		else
		{
			printf("Error CryptImportKey.\n");
			goto err;
		}

		if(CryptVerifySignature(hHash, pbSignature, dwSigLen,hPubKey,NULL,0))
		{
			printf("verify OK.\n");
		}
		else
		{
			printf("Error during CryptVerifySignature.\n");
			goto err;
		}

	}

	if(CryptVerifySignature(hHash, pbSignature, dwSigLen,hKey,NULL,0))
	{
		printf("verify OK.\n");
	}
	else
	{
		printf("Error during CryptVerifySignature.\n");
		goto err;
	}

#endif

	BYTE* pbMessage =  

		(BYTE*)"CryptoAPI is a good way to handle security";  
	DWORD cbMessage = strlen((char*) pbMessage)+1;  
	//证书的上下文  

	CRYPT_SIGN_MESSAGE_PARA SigParams;  

	DWORD cbSignedMessageBlob;  

	BYTE *pbSignedMessageBlob;  

	DWORD cbDecodedMessageBlob;  

	BYTE *pbDecodedMessageBlob;  

	CRYPT_VERIFY_MESSAGE_PARA VerifyParams;  

	const BYTE* MessageArray[] = {pbMessage};  

	DWORD MessageSizeArray[1];  

	MessageSizeArray[0] = cbMessage;  

	printf("Begin processing. \n");  
	printf(" The message to be signed is\n-> %s.\n",pbMessage);  

	//--------------------------------------------------------------------  
	//初始化签名结构  
	SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);  

	SigParams.dwMsgEncodingType = (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING);  

	SigParams.pSigningCert = pCertContext;  

	SigParams.HashAlgorithm.pszObjId = szOID_RSA_MD5;  

	SigParams.HashAlgorithm.Parameters.cbData = NULL;  

	SigParams.cMsgCert = 1;  

	SigParams.rgpMsgCert = &pCertContext;  

	SigParams.cAuthAttr = 0;  

	SigParams.dwInnerContentType = 0;  

	SigParams.cMsgCrl = 0;  

	SigParams.cUnauthAttr = 0;  

	SigParams.dwFlags = 0;  

	SigParams.pvHashAuxInfo = NULL;  

	SigParams.rgAuthAttr = NULL;  

	//首先得到BLOB的大小  
	if(CryptSignMessage(  
		&SigParams, // Signature parameters  
		FALSE, // Not detached  
		1, // Number of messages  
		MessageArray, // Messages to be signed  
		MessageSizeArray, // Size of messages  
		NULL, // Buffer for signed message  
		&cbSignedMessageBlob)) // Size of buffer  
	{
		printf("The size of the BLOB is %d.\n",cbSignedMessageBlob);  
	} 
	else  
	{
		printf("Getting signed BLOB size failed");  
	}  

	//--------------------------------------------------------------------  
	//分配BLOB的内存.  

	if(!(pbSignedMessageBlob =  
		(BYTE*)malloc(cbSignedMessageBlob)))  
	{ 
		printf("Memory allocation error while signing.");  
	}  

	if(CryptSignMessage(  
		&SigParams, //  
		FALSE, //  
		1, //消息数量  
		MessageArray, //待签名的消息  
		MessageSizeArray, //消息大小  
		pbSignedMessageBlob, //缓冲区 
		&cbSignedMessageBlob)) //缓冲区大小  
	{  
		printf("The message was signed successfully. \n");  
	} 
	else  
	{  
		printf("Error getting signed BLOB");  
	}  

	//--------------------------------------------------------------------
	//验证签名信息  
	//--------------------------------------------------------------------
	//初始化VerifyParams结构.  

	VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);  

	VerifyParams.dwMsgAndCertEncodingType =  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING); 

	VerifyParams.hCryptProv = 0;  

	VerifyParams.pfnGetSignerCertificate = NULL;  

	VerifyParams.pvGetArg = NULL;  

	if(CryptVerifyMessageSignature(  
		&VerifyParams, //.  
		0, //  
		pbSignedMessageBlob, //.  
		cbSignedMessageBlob, //  
		NULL, //  
		&cbDecodedMessageBlob, //
		NULL)) // Pointer to signer certificate.  
	{  
		printf("%d bytes need for the buffer.\n",cbDecodedMessageBlob);  
	}  
	else  
	{  
		printf("Verification message failed. \n");  
	}  

	//为缓冲区分配内存.  
	if(!(pbDecodedMessageBlob =  
		(BYTE*)malloc(cbDecodedMessageBlob)))  
	{  
		printf("Memory allocation error allocating decode BLOB.");  
	}  

	//得到缓冲区的大小  
	if(CryptVerifyMessageSignature(  
		&VerifyParams, // Verify parameters.  
		0, // Signer index.  
		pbSignedMessageBlob, // Pointer to signed BLOB.  
		cbSignedMessageBlob, // Size of signed BLOB.  
		pbDecodedMessageBlob, // Buffer for decoded message.  
		&cbDecodedMessageBlob, // Size of buffer.  
		NULL)) // Pointer to signer certificate.  

	{  
		printf("The verified message is \n-> %s \n",pbDecodedMessageBlob);  
	}  
	else  
	{  
		printf("Verification message failed. \n"); 
	}  

err:
	WTF_PrintErrorMsg();

	if(pbSignedMessageBlob)  
	{
		free(pbSignedMessageBlob);  
	}

	if(pbDecodedMessageBlob)  
	{
		free(pbDecodedMessageBlob);  
	}

	if (pbSignature)
	{
		free(pbSignature);
	}

	if(hHash) 
	{
		CryptDestroyHash(hHash);
	}
	if (hKey)
	{
		CryptDestroyKey(hKey);
	}

	if (hProv)
	{
		CryptReleaseContext(hProv, 0);
	}
	if (pCertContext)
	{
		CertFreeCertificateContext(pCertContext);
	}
	
	if (hCertStore)
	{
		CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
	}
	
	return 0;
}