Esempio n. 1
0
///////////////////////////////////////////////////////////////////////////////////////
// Function: GetRSAKeyFromCert
// Description: RSA key fetching from the cert
///////////////////////////////////////////////////////////////////////////////////////
BOOL GetRSAKeyFromCert(
///////////////////////////////////////////////////////////////////////////////////////
    PCCERT_CONTEXT pCertContext,
    HCRYPTPROV *hProv,
    HCRYPTKEY *hPubKey,
    DWORD *dwKeySpec,
    BOOL *fFreeProv)
{
    BOOL fResult;
    BOOL fReturn = FALSE;

    __try
    {
        if (hProv == NULL || hPubKey == NULL ||
                dwKeySpec == NULL || fFreeProv == NULL)
        {
            __leave;

        }

        *hProv = NULL;
        *hPubKey = NULL;
        *fFreeProv = FALSE;

        fResult = CryptAcquireCertificatePrivateKey(pCertContext,
                  NULL,
                  NULL,
                  hProv,
                  dwKeySpec,
                  fFreeProv);
        if (!fResult)
        {
            __leave;
        }


        fReturn = TRUE;
    }
    __finally
    {
        if (!fReturn)
        {
            if (*hPubKey != NULL)
            {
                CryptDestroyKey(*hPubKey);
                *hPubKey = NULL;
            }

            if ((*fFreeProv == TRUE) && (*hProv != NULL))
            {
                CryptReleaseContext(*hProv, 0);
                *hProv = NULL;
                *fFreeProv = FALSE;
            }
        }
    }

    return fReturn;
}
BOOL isCardInReader(PCCERT_CONTEXT certContext) {
#ifndef WIN_XP
	DWORD flags = CRYPT_ACQUIRE_CACHE_FLAG|CRYPT_ACQUIRE_COMPARE_KEY_FLAG|CRYPT_ACQUIRE_SILENT_FLAG;
	NCRYPT_KEY_HANDLE key = 0;
	DWORD spec = 0;
	BOOL ncrypt = FALSE;
	CryptAcquireCertificatePrivateKey(certContext, flags, 0, &key, &spec, &ncrypt);
	if(!key) {
		return FALSE;
	}
	if(ncrypt) {
		NCryptFreeObject(key);
	}
#endif
	return TRUE;
}
/*****************************************************************************
 HrGetSignerKeyAndChain

  This function retrieves a signing certificate from the local user’s 
  certificate store, builds certificates chain and returns key handle 
  for the signing key.”

  NOTE:
  The phCryptProvOrNCryptKey is cached and must not be released by the caller.

*****************************************************************************/
static
HRESULT
HrGetSignerKeyAndChain(
    LPCWSTR                 wszSubject,
    PCCERT_CHAIN_CONTEXT    *ppChainContext,
    HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey,    
    DWORD                   *pdwKeySpec
    )
{
    HRESULT         hr = S_FALSE;
    HCERTSTORE      hStore = NULL;
    PCCERT_CONTEXT  pCert = NULL;
    BOOL            fCallerFreeProvOrNCryptKey = FALSE;

    CERT_CHAIN_PARA  ChainPara         = {0};
    ChainPara.cbSize = sizeof(ChainPara);

    *ppChainContext = NULL;
    *phCryptProvOrNCryptKey = NULL;
    *pdwKeySpec = 0;

    //
    // Open the local user store to search for certificates
    //

    hStore = CertOpenStore(
                            CERT_STORE_PROV_SYSTEM_W,
                            X509_ASN_ENCODING,
                            NULL,
                            CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
                            L"MY"
                            );
    
    if( NULL == hStore )
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        goto CleanUp;
    }

    if( NULL != wszSubject && 0 != *wszSubject )
    {
        //
        // Search by Name
        //

        while( NULL != ( pCert = CertFindCertificateInStore(
                            hStore,
                            X509_ASN_ENCODING,
                            0,
                            CERT_FIND_SUBJECT_STR,
                            wszSubject,
                            pCert
                            )))
        {
            if( CryptAcquireCertificatePrivateKey(
                            pCert,
                            CRYPT_ACQUIRE_CACHE_FLAG,
                            NULL,
                            phCryptProvOrNCryptKey,
                            pdwKeySpec,
                            &fCallerFreeProvOrNCryptKey
                            ))
            {
                break;
            }
        }
    }
    else
    {
        //
        // Get the first available certificate in the store
        //

        while( NULL != ( pCert = CertEnumCertificatesInStore(
                            hStore,
                            pCert
                            )))
        {
            if( CryptAcquireCertificatePrivateKey(
                            pCert,
                            CRYPT_ACQUIRE_CACHE_FLAG,
                            NULL,
                            phCryptProvOrNCryptKey,
                            pdwKeySpec,
                            &fCallerFreeProvOrNCryptKey
                            ))
            {
                break;
            }
        }
    }

    if( NULL == pCert )
    {
        hr = CRYPT_XML_E_SIGNER;
        goto CleanUp;
    }

    //
    // Build the certificate chain without revocation check.
    //

    if( !CertGetCertificateChain(
                                NULL,                   // use the default chain engine
                                pCert,                  // pointer to the end certificate
                                NULL,                   // use the default time
                                NULL,                   // search no additional stores
                                &ChainPara,            
                                0,                      // no revocation check
                                NULL,                   // currently reserved
                                ppChainContext ))       // return a pointer to the chain created
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        goto CleanUp;
    }

CleanUp:

    if( FAILED(hr) )
    {
        *phCryptProvOrNCryptKey = NULL;
        *pdwKeySpec = 0;
    }

    if( NULL != pCert )
    {
        CertFreeCertificateContext( pCert );
    }

    if( NULL != hStore )
    {
        CertCloseStore( hStore, 0 );
    }

    return hr;
}
DWORD do_low_sign (const char *infile, const char *outfile)
{
	char OID[64] = szOID_CP_GOST_R3411;
    int include = 1;
    HCRYPTPROV hCryptProv = 0;               // CSP handle
    PCCERT_CONTEXT pUserCert = NULL;		// User certificate to be used
	
    DWORD keytype = 0;
    CSP_BOOL should_release_ctx = FALSE;
    DWORD ret = 1;
    FILE *tbs = NULL;
    BYTE *mem_tbs = NULL;
    DWORD mem_len = 0;
    
    HCRYPTMSG hMsg = 0;
    
    DWORD			HashAlgSize;
	DWORD			dwSize;
    CRYPT_ALGORITHM_IDENTIFIER	HashAlgorithm;
    CMSG_SIGNER_ENCODE_INFO	SignerEncodeInfo;
    CERT_BLOB			SignerCertBlob;
    CERT_BLOB			SignerCertBlobArray[1];
    DWORD			cbEncodedBlob;
    BYTE			*pbEncodedBlob = NULL;
    CMSG_SIGNER_ENCODE_INFO	SignerEncodeInfoArray[1];
    CMSG_SIGNED_ENCODE_INFO	SignedMsgEncodeInfo;
	CSP_BOOL bResult = FALSE;
	CRYPT_KEY_PROV_INFO *pProvInfo = NULL;
	
	HCERTSTORE hCertStore = 0;
	
	hCertStore = CertOpenSystemStore(0, "My");
	if(!hCertStore){
		ret = CSP_GetLastError();
		fprintf (stderr, "CertOpenSystemStore failed.");
		goto err;
	}
	
	while( !bResult){
		pUserCert= CertEnumCertificatesInStore(hCertStore, pUserCert);
		if(!pUserCert){
			break;
		}
		bResult = CertGetCertificateContextProperty(
													pUserCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSize);
		if (bResult) {
			
			free(pProvInfo);
			pProvInfo = (CRYPT_KEY_PROV_INFO *)malloc(dwSize);
			if (pProvInfo) {
				bResult = CertGetCertificateContextProperty(
															pUserCert, CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, &dwSize);
			}
			
		}
	}
	if(!bResult){
		fprintf (stderr, "No certificates with private key link.");
		goto err;
	}
	
    if (! infile) {
		fprintf (stderr, "No input file was specified\n");
		goto err;
    }
	
    if (CryptAcquireCertificatePrivateKey(
										  pUserCert,        
										  0,		//DWORD dwFlags,               
										  NULL,            
										  &hCryptProv,     
										  &keytype,           // returned key type AT_SIGNATURE ! AT_KEYEXCAHGE
										  &should_release_ctx  // if FALSE DO NOT Release CTX
										  )) {
		printf("A CSP has been acquired. \n");
    }
    else {
		ret = CSP_GetLastError();
		fprintf (stderr, "Cryptographic context could not be acquired.");
		goto err;
    }
	
	
    tbs = fopen (infile, "rb");
    if (!tbs) {
		fprintf (stderr, "Cannot open input file\n");
		goto err;
    }
	
    
    mem_len = 0;
    while (!feof(tbs)) {
		int r = 0;
		BYTE tmp[1024];
		r = fread (tmp, 1, 1024, tbs);
		mem_tbs = (BYTE *)realloc(mem_tbs, mem_len+r);
		memcpy (&mem_tbs[mem_len], tmp, r);
		mem_len += r;
    }
    fclose (tbs);
    tbs = NULL;
	
	
	//--------------------------------------------------------------------
	// Initialize the algorithm identifier structure.
    
    HashAlgSize = sizeof(HashAlgorithm);
    memset(&HashAlgorithm, 0, HashAlgSize); // Init. to zero.
    HashAlgorithm.pszObjId = OID;	    // Initialize the necessary member.
    
    //--------------------------------------------------------------------
    // Initialize the CMSG_SIGNER_ENCODE_INFO structure.
    
    memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
    SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
    SignerEncodeInfo.pCertInfo = pUserCert->pCertInfo;
    SignerEncodeInfo.hCryptProv = hCryptProv;
    SignerEncodeInfo.dwKeySpec = keytype;
    SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
    SignerEncodeInfo.pvHashAuxInfo = NULL;
    
    //--------------------------------------------------------------------
    // Create an array of one. Note: Currently, there can be only one
    // signer.
    
    SignerEncodeInfoArray[0] = SignerEncodeInfo;
    
    //--------------------------------------------------------------------
    // Initialize the CMSG_SIGNED_ENCODE_INFO structure.
    
    SignerCertBlob.cbData = pUserCert->cbCertEncoded;
    SignerCertBlob.pbData = pUserCert->pbCertEncoded;
    
    //--------------------------------------------------------------------
    // Initialize the array of one CertBlob.
    
    SignerCertBlobArray[0] = SignerCertBlob;
    memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
    SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
    SignedMsgEncodeInfo.cSigners = 1;
    SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
    SignedMsgEncodeInfo.cCertEncoded = include;
    if (include)
		SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
    else
		SignedMsgEncodeInfo.rgCertEncoded = NULL;
    SignedMsgEncodeInfo.rgCrlEncoded = NULL;
    
    //--------------------------------------------------------------------
    // Get the size of the encoded message blob.
    
    if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
													  TYPE_DER,       // Message encoding type
													  0,                      // Flags
													  CMSG_SIGNED,            // Message type
													  &SignedMsgEncodeInfo,   // Pointer to structure
													  NULL,                   // Inner content object ID
													  mem_len))		// Size of content */
	{
		printf("The length of the data has been calculated. \n");
    }
    else
    {
		ret = CSP_GetLastError();
		fprintf (stderr, "Getting cbEncodedBlob length failed");
		goto err;		
    }
    //--------------------------------------------------------------------
    // Allocate memory for the encoded blob.
    
    pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob);
    if (!pbEncodedBlob){
		ret = CSP_GetLastError();
		fprintf (stderr, "Memory allocation failed");
		goto err;
	}
    //--------------------------------------------------------------------
    // Open a message to encode.
    
    if(hMsg = CryptMsgOpenToEncode(
								   TYPE_DER,        // Encoding type
								   0,                       // Flags
								   CMSG_SIGNED,             // Message type
								   &SignedMsgEncodeInfo,    // Pointer to structure
								   NULL,                    // Inner content object ID
								   NULL))                   // Stream information (not used)
    {
		printf("The message to be encoded has been opened. \n");
    }
    else
    {
		ret = CSP_GetLastError();
		fprintf (stderr, "OpenToEncode failed");
		goto err;
    }
    //--------------------------------------------------------------------
    // Update the message with the data.
    
    if(CryptMsgUpdate(
					  hMsg,		// Handle to the message
					  mem_tbs,		// Pointer to the content
					  mem_len,	// Size of the content
					  TRUE))		// Last call
    {
		printf("Content has been added to the encoded message. \n");
    }
    else
    {
		ret = CSP_GetLastError();
		fprintf (stderr, "MsgUpdate failed");
		goto err;
    }
    //--------------------------------------------------------------------
    // Get the resulting message.
    
    if(CryptMsgGetParam(
						hMsg,                      // Handle to the message
						CMSG_CONTENT_PARAM,        // Parameter type
						0,                         // Index
						pbEncodedBlob,             // Pointer to the blob
						&cbEncodedBlob))           // Size of the blob
    {
		printf("Message encoded successfully. \n");
    }
    else
    {
		ret = CSP_GetLastError();
		fprintf (stderr, "MsgGetParam failed");
		goto err;
    }
    //--------------------------------------------------------------------
    // pbEncodedBlob now points to the encoded, signed content.
    //--------------------------------------------------------------------
    if (outfile) {
		FILE *out = NULL;
		out = fopen (outfile, "wb");
		if (out) {
			fwrite (pbEncodedBlob, cbEncodedBlob, 1, out);
			fclose (out);
			printf ("Output file (%s) has been saved\n", outfile);
			
		}
		else
			perror ("Cannot open out file\n");
	}
    
	ret = 0;
    //--------------------------------------------------------------------
    // Clean up.
err:
    if(pbEncodedBlob)
		free(pbEncodedBlob);
    if(hMsg)
		CryptMsgClose(hMsg);
    if(hCryptProv) 
		CryptReleaseContext(hCryptProv,0);
	if(hCertStore)
		CertCloseStore(hCertStore, 0);
	
    return ret;
} 
Esempio n. 5
0
static int HCSP_setContext(void)
{
   int result = TRUE;

   LPSTR a = NULL;
   LPSTR b = NULL;
   LPSTR c = "My";

#ifdef DEBUG
   BIO_printf(err, "Call HCSP_setContext()\n");
#endif

#ifdef FILE_CONFIG
   readFileConfig(); /* get specified context provider, etc...  */

   if (pCryptProvider[0]     && strcasecmp(pCryptProvider,     "default")) a = pCryptProvider;
   if (pCryptContainer[0]    && strcasecmp(pCryptContainer,    "default")) b = pCryptContainer;
   if (pSubsystemProtocol[0] && strcasecmp(pSubsystemProtocol, "default")) c = pSubsystemProtocol;
#endif

#ifdef DEBUG
   strcpy(pSubsystemProtocol, c);

   BIO_printf(err, "Call HCSP_setContext()\n");
   BIO_printf(err, "pCryptProvider: \"%s\"\n", a);
   BIO_printf(err, "dwProviderType: %d\n", dwProviderType);
   BIO_printf(err, "pCryptContainer: \"%s\"\n", b);
   BIO_printf(err, "pSubsystemProtocol: \"%s\"\n", c);
   BIO_printf(err, "pFindPara: \"%s\"\n", pFindPara);
#endif

   /*
    * Set hCryptProvider to NULL to use the default CSP. If hCryptProvider is not NULL,
    * it must be a CSP handle created by using the CryptAcquireContext function.
    */

   if (!(hCertStore = CertOpenSystemStore(hCryptProvider, c)))
      {
#  ifdef DEBUG
      routine = "CertOpenSystemStore";
#  endif

      goto error;
      }

#ifdef DEBUG
   enumCertificate();
#endif

   if (!(pCertContext = CertFindCertificateInStore(
        hCertStore,
        (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
        0,
        CERT_FIND_SUBJECT_STR_A,
        pFindPara,
        NULL)))
      {
#  ifdef DEBUG
      routine = "CertFindCertificateInStore";
#  endif

      goto error;
      }

   if (!CryptAcquireCertificatePrivateKey(
      pCertContext,
      0,
      NULL,
      &hCryptProvider,
      &dwKeySpec,
      NULL))
      {
#  ifdef DEBUG
      routine = "CryptAcquireCertificatePrivateKey";
#  endif

      goto error;
      }

#ifdef DEBUG
   printInfo();
   enumKeyContainers();
   enumAlgorithms();

   printCertificate(pCertContext);
#endif

   bInitialized = TRUE;    /* set initialization flag */

   goto end;

error:

   result = FALSE;

end:

#ifdef DEBUG
   BIO_printf(err, "Return HCSP_setContext(%d)\n", result);
#endif

   return result;
}
Esempio n. 6
0
void CEstEIDIEPluginBHO::signWithCNG(BSTR id, BSTR hash, BSTR *signature) {
	LOG_LOCATION;
#ifdef WIN_XP
	EstEID_log("WARNING: CNG is not supported for windows XP");
#else
	int methodResult = true;


	#define NT_SUCCESS(Status)          (((NTSTATUS)(Status)) >= 0)
	SECURITY_STATUS secStatus = ERROR_SUCCESS;
	NCRYPT_KEY_HANDLE hKey = NULL;
	DWORD cbSignature = 0;
	NTSTATUS status = ((NTSTATUS)0xC0000001L);
	PBYTE pbSignature = NULL;
	PCCERT_CONTEXT certContext = NULL;
	HCERTSTORE cert_store;
	BOOL must_release_provider;		
		
	int hashHexLength = _bstr_t(hash).length()/2;

	BCRYPT_PKCS1_PADDING_INFO padInfo;
	padInfo.pszAlgId = 0;
	switch(hashHexLength) {
		case BINARY_SHA1_LENGTH:
			padInfo.pszAlgId = NCRYPT_SHA1_ALGORITHM;break; 
		case BINARY_SHA224_LENGTH:
			padInfo.pszAlgId = L"SHA224"; break;
		case BINARY_SHA256_LENGTH :
			padInfo.pszAlgId = NCRYPT_SHA256_ALGORITHM; break;
		case BINARY_SHA512_LENGTH:
			padInfo.pszAlgId = NCRYPT_SHA512_ALGORITHM; break;
		default:
			break; 
	}
	
	try {
		if(!id || !strlen(CW2A(id))) {
			throw CryptoException(ESTEID_CERT_NOT_FOUND_ERROR);
		}
		EstEID_log("signing started, selected certificate id = %s", CW2A(id));	

		if(padInfo.pszAlgId == 0) {
			throw CryptoException(ESTEID_INVALID_HASH_ERROR);
		}


		cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, L"MY");
		if(!cert_store) throw CryptoException();

		while(certContext = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext)) {
			if(certificateMatchesId(certContext, id)) {
				if (!CryptAcquireCertificatePrivateKey(certContext, CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG|CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &hKey,
					NULL, &must_release_provider)) {
					throw CryptoException(ESTEID_CRYPTO_API_ERROR);
				}

				BYTE hashBytes[65];
				CryptStringToBinary(hash, hashHexLength*2, CRYPT_STRING_HEX, hashBytes, (DWORD*)&hashHexLength, 0, 0);
				EstEID_log("Number of bytes stored in hashBytes buffer = %u", hashHexLength);
		
				EstEID_log("signing with %s", CW2A(padInfo.pszAlgId));
				if(FAILED(secStatus = NCryptSignHash(hKey, &padInfo, (PBYTE)hashBytes, hashHexLength, NULL, 0, &cbSignature, 0))) {
					throw CryptoException(secStatus);
				}

				pbSignature = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbSignature);
				if(NULL == pbSignature){
					throw CryptoException(ESTEID_CRYPTO_API_ERROR);
				}
				
				if(FAILED(secStatus = NCryptSignHash(hKey, &padInfo, (PBYTE)hashBytes, hashHexLength, pbSignature, cbSignature, &cbSignature, BCRYPT_PAD_PKCS1))) {
					throw CryptoException(secStatus);
				}

				std::stringstream ss;
				for (DWORD i = 0; i < cbSignature; i++) {
					ss << std::hex << std::setfill('0') << std::setw(2) << (short)pbSignature[i];
				}
				*signature = _bstr_t(ss.str().c_str()).Detach();
			}
		}
	}
	catch(CryptoException e) {
		*signature = _bstr_t("").Detach();
		if(pbSignature) HeapFree(GetProcessHeap(), 0, pbSignature);
		if(hKey) NCryptFreeObject(hKey);
		if(certContext) CertFreeCertificateContext(certContext);
		if(must_release_provider && cert_store) CertCloseStore(cert_store, 0);

		throw CryptoException(e.windowsErrorCode);
	}
	CertFreeCertificateContext(certContext);
	if(must_release_provider) CertCloseStore(cert_store, 0);
#endif

}
Esempio n. 7
0
void CEstEIDIEPluginBHO::signWithCSP(BSTR id, BSTR hash, BSTR *signature) {
	LOG_LOCATION;

	HCRYPTPROV cryptoProvider = NULL;
	HCRYPTHASH _hash = NULL ;
	PCCERT_CONTEXT certContext = NULL;
	HCERTSTORE cert_store;
	BOOL must_release_provider;		

	try{
		if(!id || !strlen(CW2A(id))) {
			throw CryptoException(ESTEID_CERT_NOT_FOUND_ERROR);
		}
		EstEID_log("signing started, selected certificate id = %s", CW2A(id));	

#define VALID_HASH_LENGTH 40
		if (_bstr_t(hash).length() != VALID_HASH_LENGTH) {
			throw CryptoException("invalid hash");
		}

		cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, L"MY");
		if(!cert_store) throw CryptoException();
		
		while(certContext = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext)) {
			if(certificateMatchesId(certContext, id)) {
				DWORD key_type = 0;
				if (CryptAcquireCertificatePrivateKey(certContext, CRYPT_ACQUIRE_CACHE_FLAG, 
					NULL, &cryptoProvider, &key_type, &must_release_provider)) {
						BYTE hashBytes[21];
						DWORD hashBytesLength = 20;
						
						CryptStringToBinary(hash, VALID_HASH_LENGTH, CRYPT_STRING_HEX, hashBytes, &hashBytesLength, 0, 0);
						hashBytes[hashBytesLength] = '\0';
						EstEID_log("Number of bytes stored in hashBytes buffer = %u", hashBytesLength);

						CryptoErrorHandler(CryptCreateHash(cryptoProvider, CALG_SHA1, 0, 0, &_hash));
						EstEID_log("CryptCreateHash() set hash object pointer to %p", _hash);  

						CryptoErrorHandler(CryptSetHashParam(_hash, HP_HASHVAL, hashBytes, 0));

						#define SIGNATURE_LENGTH 1024 
						BYTE _signature[SIGNATURE_LENGTH];
						DWORD signatureLength = SIGNATURE_LENGTH;
						INT retCode = CryptSignHash(_hash, AT_SIGNATURE, NULL, 0, _signature, &signatureLength);
						DWORD lastError = GetLastError();
						EstEID_log("CryptSignHash() return code: %u (%s) %x", retCode, retCode ? "SUCCESS" : "FAILURE", lastError);
						if(!retCode) throw CryptoException(lastError);

						CryptDestroyHash(_hash);
						CryptReleaseContext(cryptoProvider, 0);	
						CertFreeCertificateContext(certContext);
						if(must_release_provider) CertCloseStore(cert_store, 0);

						std::stringstream ss;
						for (DWORD i = 0; i < signatureLength; i++) {
							ss << std::hex << std::setfill('0') << std::setw(2) << (short)_signature[signatureLength - i - 1];
						}

						*signature = _bstr_t(ss.str().c_str()).Detach();
				}
				else {
					INT lastError = GetLastError();
					EstEID_log("ERROR: CryptAcquireCertificatePrivateKey() failed, error code = %lXh", GetLastError());
					switch(lastError) {
					case NTE_BAD_PUBLIC_KEY:
						EstEID_log("       error code %lXh: NTE_BAD_PUBLIC_KEY", lastError);
						break;
					case NTE_SILENT_CONTEXT:
						EstEID_log("       error code %lXh: NTE_SILENT_CONTEXT", lastError);
					}
				}				
				break;
			}
		}	
	}
	catch(CryptoException e) {
		*signature = _bstr_t("").Detach();
		if(_hash) CryptDestroyHash(_hash);
		if(cryptoProvider) CryptReleaseContext(cryptoProvider, 0);
		if(certContext) CertFreeCertificateContext(certContext);
		if(must_release_provider && cert_store) CertCloseStore(cert_store, 0);

		throw(CryptoException(e.windowsErrorCode));
	}
}
BOOL AcquireAndGetRSAKey(PCCERT_CONTEXT pCertContext,
                         HCRYPTPROV *phProv,
                         HCRYPTKEY *phRSAKey,
                         BOOL fEncrypt,
                         BOOL *pfCallerFreeProv)
{
    BOOL fSuccess = FALSE;
    DWORD dwKeySpec = 0;

    __try
    {
        *phProv = NULL;
        *phRSAKey = NULL;
        *pfCallerFreeProv = FALSE;

        if (fEncrypt)
        {
            // Acquire context for RSA key
            fSuccess = CryptAcquireContext(phProv,
                                           NULL,
                                           MS_DEF_PROV,
                                           PROV_RSA_FULL,
                                           CRYPT_VERIFYCONTEXT);
            if (!fSuccess)
            {
                MyPrintf(_T("CryptAcquireContext failed with %X\n"), GetLastError());
                __leave;
            }

            // Import the RSA public key from the certificate context
            fSuccess = CryptImportPublicKeyInfo(*phProv,
                                                MY_ENCODING,
                                                &(pCertContext->pCertInfo->SubjectPublicKeyInfo),
                                                phRSAKey);
            if (!fSuccess)
            {
                MyPrintf(_T("CryptImportPublicKeyInfo failed with %X\n"), GetLastError());
                __leave;
            }

            *pfCallerFreeProv = TRUE;
        }
        else
        {
            // Acquire the RSA private key
            fSuccess = CryptAcquireCertificatePrivateKey(pCertContext,
                       CRYPT_ACQUIRE_USE_PROV_INFO_FLAG|CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
                       NULL, phProv, &dwKeySpec, pfCallerFreeProv);
            if (!fSuccess)
            {
                MyPrintf(_T("CryptAcquireCertificatePrivateKey failed with %X\n"), GetLastError());
                __leave;
            }

            // Get the RSA key handle
            fSuccess = CryptGetUserKey(*phProv, dwKeySpec, phRSAKey);
            if (!fSuccess)
            {
                MyPrintf(_T("CryptGetUserKey failed with %X\n"), GetLastError());
                __leave;
            }
        }
    }
    __finally
    {
        if (fSuccess == FALSE)
        {
            if (phProv && *phProv != NULL)
            {
                CryptReleaseContext(*phProv, 0);
                *phProv = NULL;
            }
            if (phRSAKey && *phRSAKey != NULL)
            {
                CryptDestroyKey(*phRSAKey);
                *phRSAKey = NULL;
            }
        }
    }

    return fSuccess;
}
Esempio n. 9
0
BYTE* SignAndEncrypt(
	wchar_t const*const signer_name,
	const BYTE *pbToBeSignedAndEncrypted,
	DWORD cbToBeSignedAndEncrypted,
	DWORD *pcbSignedAndEncryptedBlob)
{
	//---------------------------------------------------------------
	// Declare and initialize local variables.

	FILE *hToSave;
	HCERTSTORE hCertStore;

	//---------------------------------------------------------------
	// pSignerCertContext will be the certificate of 
	// the message signer.

	PCCERT_CONTEXT pSignerCertContext ;

	//---------------------------------------------------------------
	// pReceiverCertContext will be the certificate of the 
	// message receiver.

	PCCERT_CONTEXT pReceiverCertContext;

	TCHAR pszNameString[256];
	CRYPT_SIGN_MESSAGE_PARA SignPara;
	CRYPT_ENCRYPT_MESSAGE_PARA EncryptPara;
	DWORD cRecipientCert;
	PCCERT_CONTEXT rgpRecipientCert[5];
	BYTE *pbSignedAndEncryptedBlob = NULL;
	//CERT_NAME_BLOB Subject_Blob;
	BYTE *pbDataIn;
	DWORD dwKeySpec;
	NCRYPT_KEY_HANDLE hCryptProv;

	//---------------------------------------------------------------
	// Open the MY certificate store. 
	// For more information, see the CertOpenStore function 
	// PSDK reference page. 
	// Note: Case is not significant in certificate store names.

	if ( !( hCertStore = CertOpenStore(
		CERT_STORE_PROV_SYSTEM,
		0,
		NULL,
		CERT_SYSTEM_STORE_CURRENT_USER,
		L"my")))
	{
		MyHandleError(TEXT("The MY store could not be opened."));
	}

	//---------------------------------------------------------------
	// Get the certificate for the signer.

	if(!(pSignerCertContext = CertFindCertificateInStore(
		hCertStore,
		MY_ENCODING_TYPE,
		0,
		CERT_FIND_SUBJECT_STR,
		signer_name,
		NULL)))
	{
		MyHandleError(TEXT("Cert not found.\n"));
	}

	//---------------------------------------------------------------
	// Get and print the name of the message signer.
	// The following two calls to CertGetNameString with different
	// values for the second parameter get two different forms of 
	// the certificate subject's name.

	if(CertGetNameString(
		pSignerCertContext ,
		CERT_NAME_SIMPLE_DISPLAY_TYPE,
		0,
		NULL,
		pszNameString,
		MAX_NAME) > 1)
	{
		_tprintf(
			TEXT("The SIMPLE_DISPLAY_TYPE message signer's name is ")
			TEXT("%s \n"),
			pszNameString);
	}
	else
	{
		MyHandleError(
			TEXT("Getting the name of the signer failed.\n"));
	}

	if(CertGetNameString(
		pSignerCertContext,
		CERT_NAME_RDN_TYPE,
		0,
		NULL,
		pszNameString,
		MAX_NAME) > 1)
	{
		_tprintf(
			TEXT("The RDM_TYPE message signer's name is %s \n"),
			pszNameString);
	}
	else
	{
		MyHandleError(
			TEXT("Getting the name of the signer failed.\n"));
	}

	if(!( CryptAcquireCertificatePrivateKey(
		pSignerCertContext,
		CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG,
		NULL,
		&hCryptProv,
		&dwKeySpec,
		NULL)))
	{
		DWORD const errcode = GetLastError();
		std::wcerr << format_sys_message<TCHAR>(errcode) << TEXT("\n"); 

		MyHandleError(TEXT("CryptAcquireCertificatePrivateKey.\n"));
	}



	pReceiverCertContext = pSignerCertContext; // send to self
	//---------------------------------------------------------------
	// Get and print the subject name from the receiver's
	// certificate.

	if(CertGetNameString(
		pReceiverCertContext ,
		CERT_NAME_SIMPLE_DISPLAY_TYPE,
		0,
		NULL,
		pszNameString,
		MAX_NAME) > 1)
	{
		_tprintf(TEXT("The message receiver is  %s \n"), 
			pszNameString);
	}
	else
	{
		MyHandleError(
			TEXT("Getting the name of the receiver failed.\n"));
	}

	//---------------------------------------------------------------
	// Initialize variables and data structures
	// for the call to CryptSignAndEncryptMessage.

	SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
	SignPara.dwMsgEncodingType = MY_ENCODING_TYPE;
	SignPara.pSigningCert = pSignerCertContext ;
	SignPara.HashAlgorithm.pszObjId = OID_HASH_G34311;
	SignPara.HashAlgorithm.Parameters.cbData = 0;
	SignPara.pvHashAuxInfo = NULL;
	SignPara.cMsgCert = 1;
	SignPara.rgpMsgCert = &pSignerCertContext ;
	SignPara.cMsgCrl = 0;
	SignPara.rgpMsgCrl = NULL;
	SignPara.cAuthAttr = 0;
	SignPara.rgAuthAttr = NULL;
	SignPara.cUnauthAttr = 0;
	SignPara.rgUnauthAttr = NULL;
	SignPara.dwFlags = 0;
	SignPara.dwInnerContentType = 0;

	EncryptPara.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
	EncryptPara.dwMsgEncodingType = MY_ENCODING_TYPE;
	EncryptPara.hCryptProv = 0;
	EncryptPara.ContentEncryptionAlgorithm.pszObjId = OID_G28147_89_GAMMA_CBC; //szOID_RSA_RC4;
	EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0;
	EncryptPara.pvEncryptionAuxInfo = NULL;
	EncryptPara.dwFlags = 0;
	EncryptPara.dwInnerContentType = 0;

	cRecipientCert = 1;
	rgpRecipientCert[0] = pReceiverCertContext;
	*pcbSignedAndEncryptedBlob = 0;
	pbSignedAndEncryptedBlob = NULL;

	if( CryptSignAndEncryptMessage(
		&SignPara,
		&EncryptPara,
		cRecipientCert,
		rgpRecipientCert,
		pbToBeSignedAndEncrypted,
		cbToBeSignedAndEncrypted,
		NULL, // the pbSignedAndEncryptedBlob
		pcbSignedAndEncryptedBlob))
	{
		_tprintf(TEXT("%d bytes for the buffer .\n"),
			*pcbSignedAndEncryptedBlob);
	}
	else
	{

		DWORD const errcode = GetLastError();
		std::wcerr << format_sys_message<TCHAR>(errcode) << TEXT("\n"); 

		MyHandleError(TEXT("Getting the buffer length failed."));
	}

	//---------------------------------------------------------------
	// Allocate memory for the buffer.

	if(!(pbSignedAndEncryptedBlob = 
		(unsigned char *)malloc(*pcbSignedAndEncryptedBlob)))
	{
		MyHandleError(TEXT("Memory allocation failed."));
	}

	//---------------------------------------------------------------
	// Call the function a second time to copy the signed and 
	// encrypted message into the buffer.

	if( CryptSignAndEncryptMessage(
		&SignPara,
		&EncryptPara,
		cRecipientCert,
		rgpRecipientCert,
		pbToBeSignedAndEncrypted,
		cbToBeSignedAndEncrypted,
		pbSignedAndEncryptedBlob,
		pcbSignedAndEncryptedBlob))
	{
		_tprintf(TEXT("The message is signed and encrypted.\n"));
	}
	else
	{
		MyHandleError(
			TEXT("The message failed to sign and encrypt."));
	}

	//---------------------------------------------------------------
	// Clean up.

	if(pSignerCertContext )
	{
		CertFreeCertificateContext(pSignerCertContext);
	}

	// send to self so the same cert is used
// 	if(pReceiverCertContext )
// 	{
// 		CertFreeCertificateContext(pReceiverCertContext);
// 	}

	CertCloseStore(hCertStore, 0);

	//---------------------------------------------------------------
	// Return the signed and encrypted message.

	return pbSignedAndEncryptedBlob;

}  // End SignAndEncrypt.
Esempio n. 10
0
NTSTATUS kuhl_m_crypto_l_certificates(int argc, wchar_t * argv[])
{
	HCERTSTORE hCertificateStore;
	PCCERT_CONTEXT pCertContext;
	DWORD i, j, dwSizeNeeded, keySpec;
	wchar_t *certName;
	PCRYPT_KEY_PROV_INFO pBuffer;
	HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv;
	HCRYPTKEY maCle;
	BOOL keyToFree;

	PCWCHAR szSystemStore, szStore;
	DWORD dwSystemStore = 0;

	BOOL export = kull_m_string_args_byName(argc, argv, L"export", NULL, NULL);

	kull_m_string_args_byName(argc, argv, L"systemstore", &szSystemStore, kuhl_m_crypto_system_stores[0].name);
	dwSystemStore = kuhl_m_crypto_system_store_to_dword(szSystemStore);
	kull_m_string_args_byName(argc, argv, L"store", &szStore, L"My");

	kprintf(L" * System Store  : \'%s\' (0x%08x)\n"
			L" * Store         : \'%s\'\n\n",
			szSystemStore, dwSystemStore,
			szStore);

	if(hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, dwSystemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, szStore))
	{
		for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++)
		{
			for(j = 0; j < ARRAYSIZE(nameSrc); j++)
			{
				dwSizeNeeded = CertGetNameString(pCertContext, nameSrc[j], 0, NULL, NULL, 0);
				if(dwSizeNeeded > 0)
				{
					if(certName = (wchar_t *) LocalAlloc(LPTR, dwSizeNeeded * sizeof(wchar_t)))
					{
						if(CertGetNameString(pCertContext, nameSrc[j], 0, NULL, certName, dwSizeNeeded) == dwSizeNeeded)
						{
							kprintf(L"%2u. %s\n", i, certName);

							dwSizeNeeded = 0;
							if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSizeNeeded))
							{
								if(pBuffer = (PCRYPT_KEY_PROV_INFO) LocalAlloc(LPTR, dwSizeNeeded))
								{
									if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pBuffer, &dwSizeNeeded))
									{
										kprintf(
											L"\tKey Container  : %s\n"
											L"\tProvider       : %s\n",
											(pBuffer->pwszContainerName ? pBuffer->pwszContainerName : L"(null)"),
											(pBuffer->pwszProvName ? pBuffer->pwszProvName : L"(null)"));
										
										if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &keyToFree))
										{
											kprintf(L"\tType           : %s (0x%08x)\n", kuhl_m_crypto_keytype_to_str(keySpec), keySpec);

											if(keySpec != CERT_NCRYPT_KEY_SPEC)
											{
												if(CryptGetUserKey(monProv, keySpec, &maCle))
												{
													kuhl_m_crypto_printKeyInfos(0, maCle);
													CryptDestroyKey(maCle);
												}
												else PRINT_ERROR_AUTO(L"CryptGetUserKey");

												if(keyToFree)
													CryptReleaseContext(monProv, 0);
											}
											else if(kuhl_m_crypto_hNCrypt)
											{
												kuhl_m_crypto_printKeyInfos(monProv, 0);
												if(keyToFree)
													K_NCryptFreeObject(monProv);
											}
											else PRINT_ERROR(L"keySpec == CERT_NCRYPT_KEY_SPEC without CNG Handle ?\n");

										} else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey");
									} else PRINT_ERROR_AUTO(L"CertGetCertificateContextProperty");
								}
								LocalFree(pBuffer);
								if(!export)
									kprintf(L"\n");
							}

							if(export)
								kuhl_m_crypto_exportCert(pCertContext, (BOOL) dwSizeNeeded, szSystemStore, szStore, i, certName);

						} else PRINT_ERROR_AUTO(L"CertGetNameString");
						LocalFree(certName);
					}
					break;
				} else PRINT_ERROR_AUTO(L"CertGetNameString (for len)");	
			}
Esempio n. 11
0
int SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop)
{
    HCERTSTORE cs;
    X509 *cert = NULL;
    RSA *rsa = NULL, *pub_rsa;
    CAPI_DATA *cd = calloc(1, sizeof(*cd));
    RSA_METHOD *my_rsa_method = calloc(1, sizeof(*my_rsa_method));

    if (cd == NULL || my_rsa_method == NULL) {
	SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
	goto err;
    }
    /* search CURRENT_USER first, then LOCAL_MACHINE */
    cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER |
		       CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY");
    if (cs == NULL) {
	CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE);
	goto err;
    }
    cd->cert_context = find_certificate_in_store(cert_prop, cs);
    CertCloseStore(cs, 0);
    if (!cd->cert_context) {
	cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE |
			   CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY");
	if (cs == NULL) {
	    CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE);
	    goto err;
	}
	cd->cert_context = find_certificate_in_store(cert_prop, cs);
	CertCloseStore(cs, 0);
	if (cd->cert_context == NULL) {
	    CRYPTOAPIerr(CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE);
	    goto err;
	}
    }

    /* cert_context->pbCertEncoded is the cert X509 DER encoded. */
    cert = d2i_X509(NULL, (unsigned char **) &cd->cert_context->pbCertEncoded,
		    cd->cert_context->cbCertEncoded);
    if (cert == NULL) {
	SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_ASN1_LIB);
	goto err;
    }

    /* set up stuff to use the private key */
#ifdef __MINGW32_VERSION
    /* MinGW w32api is incomplete when it comes to CryptoAPI, as per version 3.1
     * anyway. This is a hack around that problem. */
    if (crypt32dll == NULL) {
	crypt32dll = LoadLibrary("crypt32");
	if (crypt32dll == NULL) {
	    CRYPTOAPIerr(CRYPTOAPI_F_LOAD_LIBRARY);
	    goto err;
	}
    }
    if (CryptAcquireCertificatePrivateKey == NULL) {
	CryptAcquireCertificatePrivateKey = GetProcAddress(crypt32dll,
		"CryptAcquireCertificatePrivateKey");
	if (CryptAcquireCertificatePrivateKey == NULL) {
	    CRYPTOAPIerr(CRYPTOAPI_F_GET_PROC_ADDRESS);
	    goto err;
	}
    }
#endif
    if (!CryptAcquireCertificatePrivateKey(cd->cert_context, CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
	    NULL, &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov)) {
	/* if we don't have a smart card reader here, and we try to access a
	 * smart card certificate, we get:
	 * "Error 1223: The operation was canceled by the user." */
	CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY);
	goto err;
    }
    /* here we don't need to do CryptGetUserKey() or anything; all necessary key
     * info is in cd->cert_context, and then, in cd->crypt_prov.  */

    my_rsa_method->name = "Microsoft CryptoAPI RSA Method";
    my_rsa_method->rsa_pub_enc = rsa_pub_enc;
    my_rsa_method->rsa_pub_dec = rsa_pub_dec;
    my_rsa_method->rsa_priv_enc = rsa_priv_enc;
    my_rsa_method->rsa_priv_dec = rsa_priv_dec;
    /* my_rsa_method->init = init; */
    my_rsa_method->finish = finish;
    my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK;
    my_rsa_method->app_data = (char *) cd;

    rsa = RSA_new();
    if (rsa == NULL) {
	SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
	goto err;
    }

    /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(),
     * so we do it here then...  */
    if (!SSL_CTX_use_certificate(ssl_ctx, cert))
	goto err;
    /* the public key */
    pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
    /* SSL_CTX_use_certificate() increased the reference count in 'cert', so
     * we decrease it here with X509_free(), or it will never be cleaned up. */
    X509_free(cert);
    cert = NULL;

    /* I'm not sure about what we have to fill in in the RSA, trying out stuff... */
    /* rsa->n indicates the key size */
    rsa->n = BN_dup(pub_rsa->n);
    rsa->flags |= RSA_FLAG_EXT_PKEY;
    if (!RSA_set_method(rsa, my_rsa_method))
	goto err;

    if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa))
	goto err;
    /* SSL_CTX_use_RSAPrivateKey() increased the reference count in 'rsa', so
     * we decrease it here with RSA_free(), or it will never be cleaned up. */
    RSA_free(rsa);
    return 1;

  err:
    if (cert)
	X509_free(cert);
    if (rsa)
	RSA_free(rsa);
    else {
	if (my_rsa_method)
	    free(my_rsa_method);
	if (cd) {
	    if (cd->free_crypt_prov && cd->crypt_prov)
		CryptReleaseContext(cd->crypt_prov, 0);
	    if (cd->cert_context)
		CertFreeCertificateContext(cd->cert_context);
	    free(cd);
	}
    }
    return 0;
}
Esempio n. 12
0
BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,
 BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[],
 DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob)
{
    HCRYPTPROV hCryptProv;
    BOOL ret, freeProv = FALSE;
    DWORD i, keySpec;
    PCERT_BLOB certBlob = NULL;
    PCRL_BLOB crlBlob = NULL;
    CMSG_SIGNED_ENCODE_INFO signInfo;
    CMSG_SIGNER_ENCODE_INFO signer;
    HCRYPTMSG msg = 0;

    TRACE("(%p, %d, %d, %p, %p, %p, %p)\n", pSignPara, fDetachedSignature,
     cToBeSigned, rgpbToBeSigned, rgcbToBeSigned, pbSignedBlob, pcbSignedBlob);

    if (pSignPara->cbSize != sizeof(CRYPT_SIGN_MESSAGE_PARA) ||
     GET_CMSG_ENCODING_TYPE(pSignPara->dwMsgEncodingType) !=
     PKCS_7_ASN_ENCODING)
    {
        *pcbSignedBlob = 0;
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (!pSignPara->pSigningCert)
        return TRUE;

    ret = CryptAcquireCertificatePrivateKey(pSignPara->pSigningCert,
     CRYPT_ACQUIRE_CACHE_FLAG, NULL, &hCryptProv, &keySpec, &freeProv);
    if (!ret)
        return FALSE;

    memset(&signer, 0, sizeof(signer));
    signer.cbSize = sizeof(signer);
    signer.pCertInfo = pSignPara->pSigningCert->pCertInfo;
    signer.hCryptProv = hCryptProv;
    signer.dwKeySpec = keySpec;
    signer.HashAlgorithm = pSignPara->HashAlgorithm;
    signer.pvHashAuxInfo = pSignPara->pvHashAuxInfo;
    signer.cAuthAttr = pSignPara->cAuthAttr;
    signer.rgAuthAttr = pSignPara->rgAuthAttr;
    signer.cUnauthAttr = pSignPara->cUnauthAttr;
    signer.rgUnauthAttr = pSignPara->rgUnauthAttr;

    memset(&signInfo, 0, sizeof(signInfo));
    signInfo.cbSize = sizeof(signInfo);
    signInfo.cSigners = 1;
    signInfo.rgSigners = &signer;

    if (pSignPara->cMsgCert)
    {
        certBlob = CryptMemAlloc(sizeof(CERT_BLOB) * pSignPara->cMsgCert);
        if (certBlob)
        {
            for (i = 0; i < pSignPara->cMsgCert; ++i)
            {
                certBlob[i].cbData = pSignPara->rgpMsgCert[i]->cbCertEncoded;
                certBlob[i].pbData = pSignPara->rgpMsgCert[i]->pbCertEncoded;
            }
            signInfo.cCertEncoded = pSignPara->cMsgCert;
            signInfo.rgCertEncoded = certBlob;
        }
        else
            ret = FALSE;
    }
    if (pSignPara->cMsgCrl)
    {
        crlBlob = CryptMemAlloc(sizeof(CRL_BLOB) * pSignPara->cMsgCrl);
        if (crlBlob)
        {
            for (i = 0; i < pSignPara->cMsgCrl; ++i)
            {
                crlBlob[i].cbData = pSignPara->rgpMsgCrl[i]->cbCrlEncoded;
                crlBlob[i].pbData = pSignPara->rgpMsgCrl[i]->pbCrlEncoded;
            }
            signInfo.cCrlEncoded = pSignPara->cMsgCrl;
            signInfo.rgCrlEncoded = crlBlob;
        }
        else
            ret = FALSE;
    }
    if (pSignPara->dwFlags || pSignPara->dwInnerContentType)
        FIXME("unimplemented feature\n");

    if (ret)
        msg = CryptMsgOpenToEncode(pSignPara->dwMsgEncodingType,
         fDetachedSignature ? CMSG_DETACHED_FLAG : 0, CMSG_SIGNED, &signInfo,
         NULL, NULL);
    if (msg)
    {
        if (cToBeSigned)
        {
            for (i = 0; ret && i < cToBeSigned; ++i)
            {
                ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i],
                 i == cToBeSigned - 1);
            }
        }
        else
            ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
        if (ret)
            ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbSignedBlob,
             pcbSignedBlob);
        CryptMsgClose(msg);
    }
    else
        ret = FALSE;

    CryptMemFree(crlBlob);
    CryptMemFree(certBlob);
    if (freeProv)
        CryptReleaseContext(hCryptProv, 0);
    return ret;
}
Esempio n. 13
0
    void PfxCertificate::init(
        ByteBuffer pfxBlob, 
        const tstring & password,
        const tstring & certName)
    {
        CRYPT_DATA_BLOB blob = {0};
        blob.cbData   = static_cast<DWORD>(pfxBlob.getLength());
        blob.pbData   = (BYTE*) pfxBlob.getPtr();

        BOOL recognizedPFX = PFXIsPFXBlob(&blob);
        DWORD dwErr = GetLastError();


        RCF_VERIFY(
            recognizedPFX, 
            Exception(_RcfError_ApiError("PFXIsPFXBlob()"), dwErr));

        std::wstring wPassword = RCF::toWstring(password);

        // For Windows 98, the flag CRYPT_MACHINE_KEYSET is not valid.
        mPfxStore = PFXImportCertStore(
            &blob, 
            wPassword.c_str(),
            CRYPT_MACHINE_KEYSET | CRYPT_EXPORTABLE);

        dwErr = GetLastError();

        RCF_VERIFY(
            mPfxStore, 
            Exception(_RcfError_ApiError("PFXImportCertStore()"), dwErr));

        PCCERT_CONTEXT pCertStore = NULL;

        // Tempting to use CERT_FIND_ANY for the case where there is just a single
        // certificate in the PFX file. However, doing so appears to not load the
        // private key information. So we use CERT_FIND_SUBJECT_STR instead, and
        // require the certificate name to be passed in.
        
        DWORD dwFindType = CERT_FIND_SUBJECT_STR;
        std::wstring wCertName = RCF::toWstring(certName);
        const void * pvFindPara = wCertName.c_str();

        pCertStore = CertFindCertificateInStore(
            mPfxStore, 
            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
            0,
            dwFindType,
            pvFindPara,
            pCertStore);

        dwErr = GetLastError();

        RCF_VERIFY(
            pCertStore, 
            Exception(_RcfError_ApiError("CertFindCertificateInStore()"), dwErr));

        BOOL bFreeHandle;
        HCRYPTPROV hProv;
        DWORD dwKeySpec;

        BOOL bResult = CryptAcquireCertificatePrivateKey(
            pCertStore, 
            0, 
            NULL, 
            &hProv, 
            &dwKeySpec, 
            &bFreeHandle);

        dwErr = GetLastError();

        RCF_VERIFY(
            bResult, 
            Exception(_RcfError_ApiError("CryptAcquireCertificatePrivateKey()"), dwErr));

        mpCert = pCertStore; 
    }
BOOL GetRSAKeyFromCert(PCCERT_CONTEXT pCertContext,
                       BOOL fSign,
                       HCRYPTPROV *hProv,
                       HCRYPTKEY *hPubKey,
                       DWORD *dwKeySpec,
                       BOOL *fFreeProv)
{   
   BOOL fResult;
   BOOL fReturn = FALSE;
   
   __try
   {  
      if (hProv == NULL || hPubKey == NULL || 
          dwKeySpec == NULL || fFreeProv == NULL)
      {
         __leave;
      }

      *hProv = 0;
      *hPubKey = 0;
      *fFreeProv = FALSE;
    
      if (fSign)
      {
         // Acquire the certificate's private key
         fResult = CryptAcquireCertificatePrivateKey(pCertContext,
                                                     CRYPT_ACQUIRE_USE_PROV_INFO_FLAG|
                                                     CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
                                                     NULL,
                                                     hProv,
                                                     dwKeySpec,
                                                     fFreeProv);
         if (!fResult)
         {
            MyPrintf(_T("CryptAcquireCertificatePrivateKey failed with %x\n"), GetLastError());
            __leave;
         }
      }
      else
      {
         fResult = CryptAcquireContext(hProv, 
                                       NULL, 
                                       MS_DEF_PROV,
                                       PROV_RSA_FULL, 
                                       CRYPT_VERIFYCONTEXT);
         if (!fResult)
         {
            MyPrintf(_T("CryptAcquireContext failed with %x\n"), GetLastError());
            __leave;
         }

         *fFreeProv = TRUE;

         // Import the public key from the certificate so we can verify
         fResult = CryptImportPublicKeyInfo(*hProv,
                                            ENCODING,
                                            &(pCertContext->pCertInfo->SubjectPublicKeyInfo),
                                            hPubKey);
         if (!fResult)
         {
            MyPrintf(_T("CryptImportPublicKeyInfo failed with %x\n"), GetLastError());
            __leave;
         }         
      }

      fReturn = TRUE;
   }
   __finally
   {
      if (!fReturn)
      {
         if (*hPubKey != NULL) 
         {
            CryptDestroyKey(*hPubKey);
            *hPubKey = NULL;
         }

         if ((*fFreeProv == TRUE) && (*hProv != NULL)) 
         {
            CryptReleaseContext(*hProv, 0);
            *hProv = NULL;
            *fFreeProv = FALSE;
         }
      }
   }

   return fReturn;
}
void mod_mimikatz_crypto::listAndOrExportCertificates(vector<wstring> * arguments, bool exportCert)
{
	wstring monEmplacement = L"CERT_SYSTEM_STORE_CURRENT_USER";
	wstring monStore = L"My";

	if(arguments->size() == 1)
	{
		monEmplacement = arguments->front();
	}
	else if(arguments->size() == 2)
	{
		monEmplacement = arguments->front();
		monStore = arguments->back();
	}
	
	(*outputStream) << L"Emplacement : \'" << monEmplacement << L'\'';

	DWORD systemStore;
	if(mod_crypto::getSystemStoreFromString(monEmplacement, &systemStore))
	{
		(*outputStream) << L"\\" << monStore << endl;
		if(HCERTSTORE hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, NULL, NULL, systemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, monStore.c_str()))
		{
			DWORD i;
			PCCERT_CONTEXT pCertContext;
			for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++)
			{
				wstring * certName = new wstring();
				bool reussite = false;

				if(!mod_crypto::getCertNameFromCertCTX(pCertContext, certName))
					certName->assign(L"[empty]");

				(*outputStream) << L"\t - " << *certName << endl;;
				sanitizeFileName(certName);

				wstringstream monBuff;
				monBuff << monEmplacement << L'_' << monStore << L'_' << i << L'_' << *certName << L'.';
										
				mod_crypto::KIWI_KEY_PROV_INFO keyProvInfo;
				if(mod_crypto::getKiwiKeyProvInfo(pCertContext, &keyProvInfo))
				{
					(*outputStream) << L"\t\tContainer Clé : " << keyProvInfo.pwszContainerName << endl;
					(*outputStream) << L"\t\tProvider      : " << keyProvInfo.pwszProvName << endl;
						
					HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv = NULL;
					DWORD keySpec = 0;
					BOOL aFermer = false;
						
					if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &aFermer))
					{
						(*outputStream) << L"\t\tType          : " << mod_crypto::KeyTypeToString(keySpec) << endl;
							
						DWORD size = 0;
						bool exportable = false;

						if(keySpec == CERT_NCRYPT_KEY_SPEC)
						{
							if(mod_cryptong::isNcrypt)
							{
								reussite = mod_cryptong::getKeySize(&monProv, &size);
								reussite &=mod_cryptong::isKeyExportable(&monProv, &exportable);

								if(aFermer)
								{
									mod_cryptong::NCryptFreeObject(monProv);
								}
							}
							else (*outputStream) << L"\t\t\tErreur : Clé de type nCrypt, sans nCrypt ?" << endl;
						}
						else
						{
							DWORD tailleEcrite = 0;
							DWORD exportability;

							HCRYPTKEY maCle = NULL;
							if(reussite = (CryptGetUserKey(monProv, keySpec, &maCle) != 0))
							{
								tailleEcrite = sizeof(DWORD);
								reussite = (CryptGetKeyParam(maCle, KP_KEYLEN, reinterpret_cast<BYTE *>(&size), &tailleEcrite, NULL) != 0);
								tailleEcrite = sizeof(DWORD);
								reussite &= (CryptGetKeyParam(maCle, KP_PERMISSIONS, reinterpret_cast<BYTE *>(&exportability), &tailleEcrite, NULL) != 0);
								exportable = (exportability & CRYPT_EXPORT) != 0;
							}

							if(aFermer)
							{
								CryptReleaseContext(monProv, 0);
							}
						}
						if(reussite)
						{
							(*outputStream) << L"\t\tExportabilité : " << (exportable ? L"OUI" : L"NON") << endl;
							(*outputStream) << L"\t\tTaille clé    : " << size << endl;
						}

						if(exportCert)
						{
							wstring PFXFile = monBuff.str();
							PFXFile.append(L"pfx");

							reussite = mod_crypto::CertCTXtoPFX(pCertContext, PFXFile, L"mimikatz");

							(*outputStream) << L"\t\tExport privé dans  \'" << PFXFile << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
							if(!reussite)
							{
								(*outputStream) << L"\t\t\t" << mod_system::getWinError() << endl;
							}
						}
					}
					else (*outputStream) << L"CryptAcquireCertificatePrivateKey : " << mod_system::getWinError() << endl;
				}

				if(exportCert)
				{
					wstring DERFile = monBuff.str();
					DERFile.append(L"der");
						
					reussite = mod_crypto::CertCTXtoDER(pCertContext, DERFile);
						
					(*outputStream) << L"\t\tExport public dans \'" << DERFile << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
					if(!reussite)
					{
						(*outputStream) << L"\t\t\t" << mod_system::getWinError() << endl;
					}
				}
				delete certName;
			}
			CertCloseStore(hCertificateStore, CERT_CLOSE_STORE_FORCE_FLAG);
		}
		else (*outputStream) << L"CertOpenStore : " << mod_system::getWinError() << endl;
	}
	else (*outputStream) << L" introuvable !" << endl;
}
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;
}