Exemple #1
0
/**
 * Verifies if a signature + public key matches a hash context.
 *
 * @param hash      The hash context that the signature should match.
 * @param pubKey    The public key to use on the signature.
 * @param signature The signature to check.
 * @param signatureLen The length of the signature.
 * @return CryptoX_Success on success, CryptoX_Error on error.
*/
CryptoX_Result
CyprtoAPI_VerifySignature(HCRYPTHASH *hash,
                          HCRYPTKEY *pubKey,
                          const BYTE *signature,
                          DWORD signatureLen)
{
  DWORD i;
  BOOL result;
/* Windows APIs expect the bytes in the signature to be in little-endian
 * order, but we write the signature in big-endian order.  Other APIs like
 * NSS and OpenSSL expect big-endian order.
 */
  BYTE *signatureReversed;
  if (!hash || !pubKey || !signature || signatureLen < 1) {
    return CryptoX_Error;
  }

  signatureReversed = malloc(signatureLen);
  if (!signatureReversed) {
    return CryptoX_Error;
  }

  for (i = 0; i < signatureLen; i++) {
    signatureReversed[i] = signature[signatureLen - 1 - i];
  }
  result = CryptVerifySignature(*hash, signatureReversed,
                                signatureLen, *pubKey, NULL, 0);
  free(signatureReversed);
  return result ? CryptoX_Success : CryptoX_Error;
}
bool VerifySHA1Signature(const void *data, size_t dataLen, const char *hexSignature, const void *pubkey, size_t pubkeyLen)
{
    HCRYPTPROV hProv = 0;
    HCRYPTKEY hPubKey = 0;
    HCRYPTHASH hHash = 0;
    BOOL ok = false;
    ScopedMem<BYTE> signature;
    size_t signatureLen;

#define Check(val) if ((ok = (val)) == FALSE) goto CleanUp
    Check(ExtractSignature(hexSignature, data, dataLen, signature, signatureLen));
    Check(CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
    Check(CryptImportKey(hProv, (const BYTE *)pubkey, (DWORD)pubkeyLen, 0, 0, &hPubKey));
    Check(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash));
#ifdef _WIN64
    for (; dataLen > DWORD_MAX; data = (const BYTE *)data + DWORD_MAX, dataLen -= DWORD_MAX) {
        Check(CryptHashData(hHash, (const BYTE *)data, DWORD_MAX, 0));
    }
#endif
    Check(dataLen <= DWORD_MAX && pubkeyLen <= DWORD_MAX && signatureLen <= DWORD_MAX);
    Check(CryptHashData(hHash, (const BYTE *)data, (DWORD)dataLen, 0));
    Check(CryptVerifySignature(hHash, signature, (DWORD)signatureLen, hPubKey, NULL, 0));
#undef Check

CleanUp:
    if (hHash)
        CryptDestroyHash(hHash);
    if (hProv)
        CryptReleaseContext(hProv, 0);
    return ok;
}
bool testVerifyHash(bool bVerbose){

	BYTE bSignature[64];
	strtobyte( "41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC049301456C64BA4642A1653C235A98A60249BCD6D3F746B631DF928014F6C5BF9C40" , bSignature );
	DWORD dwSigLen = 64;
	HCRYPTHASH hHash;
	HCRYPTKEY hPub;
	
	BYTE bHashVal[32+1] = "\x2D\xFB\xC1\xB3\x72\xD8\x9A\x11\x88\xC0\x9C\x52\xE0\xEE\xC6\x1F\xCE\x52\x03\x2A\xB1\x02\x2E\x8E\x67\xEC\xE6\x67\x2B\x04\x3E\xE5";
	if ( bVerbose )
		std::cout << "Supplied hash value is: \n" <<  bHashVal << std::endl;

	if (!(CryptCreateHash(hProv,
					  CALG_GOST_HASH,
					  0,
					  0,
					  &hHash)))
	{   
		if ( bVerbose )
			printf("CryptCreateHash Failed\n");
		return false;
	} 

	if ( !CryptSetHashParam(
		hHash,
		HP_HASHVAL,
		bHashVal,
		0))
	{
		if ( bVerbose )
			printf("CryptSetHashParam Failed\n");
		return false;
	}


	if ( !CryptGetUserKey( 
		hProv,
		AT_SIGNATURE,
		&hPub ))
	{
		if ( bVerbose )
			printf("CryptGetUserKey Failed\n");
		return false;
	}
	if (!CryptVerifySignature(hHash,
					       bSignature,
					       dwSigLen,
					       hPub,
					       NULL,
					       0))
	{
		if ( bVerbose )
			printf("Test Failed\n");
		return false;
	}

	return true;
}
Exemple #4
0
int main(int argc, char *argv[])
{
  HANDLE signf = 0;
  HANDLE signmmf = 0;
  PBYTE signdata = NULL;
  LARGE_INTEGER signsz = {.QuadPart = 0};
  void *keyblob = NULL;
  unsigned char err = 1;

  HCRYPTPROV prov;
  HCRYPTKEY key;
  HCRYPTHASH hash = 0;

  if (argc != 3) {
    fputs("Usage: lab2sign <input file> <output file>", stderr);
    return -1;
  }

  crash_if(!CryptAcquireContext(&prov, "lab2", MS_ENHANCED_PROV, PROV_RSA_FULL, 0),
           "Can't acquire crypt context.");

  hash = GetFileHash(prov, argv[1]);

  signf = CreateFileA(argv[2], GENERIC_READ, 0, NULL, OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL, NULL);
  signmmf = CreateFileMappingA(signf, NULL, PAGE_READONLY, 0, 0, NULL);
  crash_if(!signmmf, "Can't open memory mapped file.");
  GetFileSizeEx(signf, &signsz);
  signdata = MapViewOfFile(signmmf, FILE_MAP_READ, 0, 0, 0);
  crash_if(!signdata, "Can't map view of file.");

  crash_if(!CryptGetUserKey(prov, AT_SIGNATURE, &key),
           "Can't acquire signature key.");

  if (CryptVerifySignature(hash, signdata, signsz.LowPart, key, NULL, 0)) {
    printf("Signature matches.\n");
    err = 0;
  } else {
    printf("Signature mismatch.\n");
  }

err:
  apply_not_null(signdata, UnmapViewOfFile);
  apply_not_null(signmmf, CloseHandle);
  apply_not_null(signf, CloseHandle);

  apply_not_null(keyblob, free);

  apply_not_null(hash, CryptDestroyHash)

  if (err)
    return -1;
  return 0;
}
Exemple #5
0
/**
 * Hashes a block of data and verifies it against an RSA signature.
 */
int verify_RSA_sig(RSA_key_t rsa, int hashtype,
                   const unsigned char *mes, unsigned int meslen,
                   unsigned char *sig, unsigned int siglen)
{
    HCRYPTHASH hash;
    ALG_ID alg;
    unsigned hashlen, i;
    int rval;
    unsigned char *insig;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);

    if (!CryptCreateHash(base_prov, alg, 0, 0, &hash)) {
        mserror("CryptCreateHash failed");
        return 0;
    }
    if (!CryptHashData(hash, mes, meslen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end;
    }
    insig = calloc(siglen, 1);
    if (insig == NULL) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }
    // CryptoAPI expects signatures in little endian, so reverse the bytes
    for (i = 0; i < siglen; i++) {
        insig[i] = sig[siglen - i - 1];
    }
    if (!CryptVerifySignature(hash, insig, siglen, rsa, NULL, 0)) {
        mserror("CryptVerifySignature failed");
        free(insig);
        rval = 0;
        goto end;
    }
    free(insig);

    rval = 1;

end:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
    return rval;
}
Exemple #6
0
void checkSig(unsigned char *tucHashBuf,
			  unsigned char *tucSignature, DWORD dwSignatureLen,
			  unsigned char *tucPubKeyBlob, DWORD dwPubKeyBlobLen)
{
	HCRYPTPROV hProv;
	HCRYPTKEY hPubKey;
	HCRYPTHASH hHash;
	DWORD err;
	int errors = 0;

	if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))
		ERR_LOG_RET("CryptAcquireContext()");

	if (!CryptImportKey(hProv, tucPubKeyBlob, dwPubKeyBlobLen, 0, 0, &hPubKey))
		ERR_LOG_RET("CryptImportKey()");

	if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
		ERR_LOG_RET("CryptCreateHash(CALG_MD5)");

	if (!CryptSetHashParam(hHash, HP_HASHVAL, tucHashBuf, 0))
		ERR_LOG_RET("CryptSetHashParam(HP_HASHVAL)");

	if (!CryptVerifySignature(hHash, tucSignature, dwSignatureLen, hPubKey, NULL, 0))
	{
		err = GetLastError();
		printf("ERR (line %d): CryptVerifySignature() returned %s (0x%0x)\n", __LINE__, e2str(err), err);
		errors++;
	}

	if (!CryptDestroyHash(hHash))
		ERR_LOG_RET("CryptDestroyHash()");

	if (!CryptDestroyKey(hPubKey))
		ERR_LOG_RET("CryptDestroyKey()");

	CryptReleaseContext(hProv, 0);

done:
	return;
}
// verify a signature using public key
BOOL verify(void)
{
    BOOL bStatus = FALSE;

    // initialize crypto API
    if (open_crypt()) {
        // import public key
        if (open_key(DSA_PUBLIC_BIN)) {
            // hash the input
            if (open_hash()) {
                // convert signature to binary
                sig2bin();

                if (pbSignature != NULL) {
                    // verify signature
                    bStatus = CryptVerifySignature(hHash, pbSignature,
                                                   dwSigLen, hKey, NULL, 0);
                    printf("  [ signature is %s\n",
                           bStatus ? "valid" : "invalid");
                    xfree(pbSignature);
                }

                close_hash();
            } else {
                printf("open_hash()");
            }

            close_key();
        } else {
            printf("open_key()");
        }

        close_crypt();
    } else {
        printf("open_crypt()");
    }

    return bStatus;
}
/**
 *
 *         verify a signature using public key
 *
 * sfile : file with signature encoded in PEM format
 * ifile : file with data to verify signature for
 * rsa   : RSA object with public key
 *
 */
int rsa_verify(
    RSA* rsa,
    const char* ifile,
    const char* sfile)
{
    DWORD  sigLen;
    LPVOID sig;
    BOOL   ok = FALSE;
    // convert PEM data to binary
    sig = rsa_read_pem(sfile, &sigLen);

    if (sig != NULL) {
        // calculate sha256 hash of file
        if (rsa_hash(rsa, ifile)) {
            // verify signature using public key
            ok = CryptVerifySignature(rsa->hash, sig,
                                      sigLen, rsa->pubkey, NULL, 0);
        }
    }

    return ok;
}
bool vmsSecurity::VerifySign(LPCTSTR ptszFile, LPCTSTR ptszPubKey)
{
	HCRYPTPROV hProv = NULL;
	BOOL bOK = CryptAcquireContext (&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);	
	if (!bOK)
		return false;
	
	BYTE abKey [1000];
	DWORD dwKeySize;
	
	HANDLE h = CreateFile (ptszPubKey, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (h == INVALID_HANDLE_VALUE)
		return false;
	ReadFile (h, abKey, sizeof (abKey), &dwKeySize, NULL);
	CloseHandle (h);
	
	HCRYPTKEY hKey;
	if (FALSE == CryptImportKey (hProv, abKey, dwKeySize, NULL, 0, &hKey))
		return false;
	
	LPBYTE pbData;
	DWORD dwDataSize;
	
	h = CreateFile (ptszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (h == INVALID_HANDLE_VALUE)
		return FALSE;
	dwDataSize = GetFileSize (h, NULL);
	if (dwDataSize < strlen (FdmCryptSignatureMarker))
	{
		CloseHandle (h);
		return false;
	}
	pbData = new BYTE [dwDataSize];
	DWORD dw;
	ReadFile (h, pbData, dwDataSize, &dw, NULL);
	CloseHandle (h);
	
	int nSigLen = strlen (FdmCryptSignatureMarker);
	LPBYTE pbSig = pbData + dwDataSize - nSigLen;
	while (pbSig != pbData && strncmp ((char*)pbSig, FdmCryptSignatureMarker, nSigLen) != 0)
		pbSig--;
	if (pbData == pbSig)
	{
		delete [] pbData;
		return false;
	}
	
	HCRYPTHASH hHash;
	if (FALSE == CryptCreateHash (hProv, CALG_MD5, 0, 0, &hHash))
		return false;
	
	if (FALSE == CryptHashData (hHash, pbData, pbSig - pbData, 0))
		return false;
	
	BOOL bResult = CryptVerifySignature (hHash, pbSig + nSigLen,
		pbData + dwDataSize - pbSig - nSigLen, hKey, NULL, 0);
		
	CryptDestroyHash (hHash);
	
	delete [] pbData;
	
	CryptDestroyKey (hKey);
	
	CryptReleaseContext (hProv, 0);
	
	return bResult != FALSE;
}
Exemple #10
0
bool CCommonUtils::VerifyFile(LPCTSTR lpFileName, LPVOID lpKeyData, DWORD dwKeySize, LPCTSTR lpBase64)
{
    LPVOID lpFileData = NULL;
    DWORD  dwFileSize = 0;
    bool bRet = false;
    HCRYPTPROV hProv = NULL;
    HCRYPTKEY  hKey = NULL;
    HCRYPTHASH hHash = NULL;
    LPVOID lpSignature = NULL;
    DWORD  dwSigSize = 0;

    try
    {
        lpFileData = ReadFileData(lpFileName, dwFileSize);
        if(!lpFileData)
        {
            throw _com_error(E_FAIL);
        }

        if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) 
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptImportKey(hProv, (LPBYTE)lpKeyData, dwKeySize, NULL, 0, &hKey))
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) 
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptHashData(hHash, (LPBYTE)lpFileData, dwFileSize, 0)) 
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptStringToBinary(lpBase64, 0, CRYPT_STRING_BASE64, NULL, &dwSigSize, NULL, NULL))
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        lpSignature = malloc(dwSigSize);
        if(!CryptStringToBinary(lpBase64, 0, CRYPT_STRING_BASE64, (LPBYTE)lpSignature, &dwSigSize, NULL, NULL))
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptVerifySignature(hHash, (LPBYTE)lpSignature, dwSigSize, hKey, NULL, 0))
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        bRet = true;
    }
    catch(_com_error& err)
    {
        DEBUG_PRINTF(L"Error in verifying file 0x%08X\n", err.Error());
    }

    if(hHash)
    {
        CryptDestroyHash(hHash);
    }

    if(hProv)
    {
        CryptReleaseContext(hProv, 0);
    }

    if(lpSignature)
    {
        free(lpSignature);
    }

    if(lpFileData)
    {
        free(lpFileData);
    }

    if(lpKeyData)
    {
        free(lpKeyData);
    }

    return bRet;
}
int KSI_PKITruststore_verifyRawSignature(KSI_CTX *ctx, const unsigned char *data, unsigned data_len, const char *algoOid, const unsigned char *signature, unsigned signature_len, const KSI_PKICertificate *certificate) {
	int res = KSI_UNKNOWN_ERROR;
	ALG_ID algorithm=0;
	HCRYPTPROV hCryptProv = 0;
    PCCERT_CONTEXT subjectCert = NULL;
	HCRYPTKEY publicKey = 0;
	DWORD i=0;
	BYTE *little_endian_pkcs1= NULL;
	DWORD pkcs1_len = 0;
	HCRYPTHASH hash = 0;
	char buf[1024];

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || data == NULL || signature == NULL ||
		signature_len >= UINT_MAX || algoOid == NULL || certificate == NULL){
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}


	algorithm = algIdFromOID(algoOid);
	if (algorithm == 0) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, NULL);
		goto cleanup;
	}

	// Get the CSP context
	if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get cryptographic provider.");
		goto cleanup;
	}

	// Get the public key from the issuer certificate
	subjectCert = certificate->x509;
	if (!CryptImportPublicKeyInfo(hCryptProv, X509_ASN_ENCODING,&subjectCert->pCertInfo->SubjectPublicKeyInfo,&publicKey)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Failed to read PKI public key.");
		goto cleanup;
	}

	/*Convert big-endian to little-endian PKCS#1 signature*/
	pkcs1_len = signature_len;
	little_endian_pkcs1 = (BYTE*)KSI_malloc(pkcs1_len);

	if (little_endian_pkcs1 == NULL){
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	for (i=0; i<pkcs1_len; i++){
		little_endian_pkcs1[pkcs1_len-1-i] = signature[i];
	}

	// Create the hash object and hash input data.
	if (!CryptCreateHash(hCryptProv, algorithm, 0, 0, &hash)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to create hasher.");
		goto cleanup;
	}

	if (!CryptHashData(hash, (BYTE*)data, data_len,0)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to hash data.");
		goto cleanup;
	}

	/*Verify the signature. The format MUST be PKCS#1*/
	if (!CryptVerifySignature(hash, (BYTE*)little_endian_pkcs1, pkcs1_len, publicKey, NULL, 0)){
		DWORD error = GetLastError();
		const char *errmsg = getMSError(GetLastError(), buf, sizeof(buf));
		KSI_LOG_debug(ctx, "%s", errmsg);

		if (error == NTE_BAD_SIGNATURE)
			KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Invalid PKI signature.");
		else if (error == NTE_NO_MEMORY)
			KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, "Unable to verify PKI signature. CSP out of memory.");
		else
			KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, errmsg);

		goto cleanup;
	}

	KSI_LOG_debug(certificate->ctx, "CryptoAPI: PKI signature verified successfully.");

	res = KSI_OK;

cleanup:

	KSI_free(little_endian_pkcs1);
	if (hCryptProv) CryptReleaseContext(hCryptProv, 0);
	if (hash) CryptDestroyHash(hash);

	return res;
}
int VerifyDataSignWithHashAlg(const char * userData,  const char * hashAlg, const char * certDataB64, const char * signatureDataB64)
{
	int rv = -1;
	int ulHashAlg = 0;
	HCRYPTHASH hHash = NULL;
	char * pbCert = NULL;
	char * pbSignature = NULL;
	unsigned int ulCert = 0;
	unsigned int ulSignature = 0;
	PCCERT_CONTEXT pCertContext = NULL;  
	HCRYPTPROV hProv = NULL;  
	HCRYPTKEY hPubKey = NULL;  

	{
		ulCert = modp_b64_decode_len(strlen(certDataB64));
		ulSignature = modp_b64_decode_len(strlen(signatureDataB64));

		pbCert = (char *)malloc(ulCert);
		pbSignature =  (char *) malloc(ulSignature);

		if (NULL == pbCert || NULL == pbSignature)
		{
			sprintf(m_errMsg, "%s","memroy less.\n" );
			goto err;
		}

		ulCert = modp_b64_decode(pbCert, certDataB64,strlen(certDataB64));
		ulSignature = modp_b64_decode(pbSignature, signatureDataB64,strlen(signatureDataB64));
	}

	if (0 == strcmp(hashAlg, "MD5"))
	{
		ulHashAlg = CALG_MD5;
	}
	else if (0 == strcmp(hashAlg, "SHA"))
	{
		ulHashAlg = CALG_SHA;
	}
	else if (0 == strcmp(hashAlg, "SHA1"))
	{
		ulHashAlg = CALG_SHA1;
	}
	else if (0 == strcmp(hashAlg, "SHA_256"))
	{
		ulHashAlg = CALG_SHA_256;
	}
	else if (0 == strcmp(hashAlg, "SHA_384"))
	{
		ulHashAlg = CALG_SHA_384;
	}

	pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE *)pbCert,ulCert);
	if (!pCertContext)
	{
		sprintf(m_errMsg, "%s","Select Certificate UI failed.\n" );
		goto err;
	}


	//Ò»¡¢»ñµÃÒ»¸öCSP¾ä±ú  
	if(!CryptAcquireContext(  
		&hProv,  
		NULL,           //ÃÜÔ¿ÈÝÆ÷Ãû£¬NULL±íʾʹÓÃĬÈÏÈÝÆ÷  
		NULL,           //CSP_NAME  
		PROV_RSA_FULL,  
		0  
		)) 
	{  
		if(!CryptAcquireContext(  
			&hProv,  
			NULL,           //ÃÜÔ¿ÈÝÆ÷Ãû£¬NULL±íʾʹÓÃĬÈÏÈÝÆ÷  
			NULL,           //CSP_NAME  
			PROV_RSA_FULL,  
			CRYPT_NEWKEYSET //´´½¨ÃÜÔ¿ÈÝÆ÷  
			))
		{
			sprintf(m_errMsg, "%s","CryptAcquireContext fail.\n");
			goto err;
		}
	}  


	if(CryptImportPublicKeyInfo(
		hProv,
		X509_ASN_ENCODING,
		&(pCertContext->pCertInfo->SubjectPublicKeyInfo),
		&hPubKey
		))
	{
		sprintf(m_errMsg,"CryptImportPublicKeyInfo OK. \n");
	}
	else
	{
		sprintf(m_errMsg,"Error CryptImportPublicKeyInfo.\n");
		goto err;
	}

	//if(CryptImportKey(hProv,pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData, NULL, 0, &hPubKey))
	//{
	//	sprintf(m_errMsg,"CryptImportKey OK. \n");
	//}
	//else
	//{
	//	sprintf(m_errMsg,"Error CryptImportKey.\n");
	//	goto err;
	//}

	if(CryptCreateHash(
		hProv, 
		ulHashAlg, 
		0, 
		0, 
		&hHash)) 
	{
		sprintf(m_errMsg, "%s","An empty hash object has been created. \n");
	}
	else
	{
		sprintf(m_errMsg, "%s","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, 
		(unsigned char *)userData, 
		strlen(userData), 
		0)) 
	{
		sprintf(m_errMsg, "%s","The data buffer has been added to the hash.\n");
	}
	else
	{
		sprintf(m_errMsg, "%s","Error during CryptHashData.\n");
		goto err;
	}

	if(CryptVerifySignature(hHash, (const BYTE *)pbSignature, ulSignature,hPubKey,NULL,0))
	{
		sprintf(m_errMsg,"verify OK.\n");
	}
	else
	{
		sprintf(m_errMsg,"Error during CryptVerifySignature.\n");
		goto err;
	}

	rv = 0;

err:
	if(hHash) 
	{
		CryptDestroyHash(hHash);
	}

	if (pbSignature)
	{
		free(pbSignature);
	}

	if (pbCert)
	{
		free(pbCert);
	}

	if (pCertContext)
	{
		CertFreeCertificateContext(pCertContext);
	}

	if(hProv)  
	{
		CryptReleaseContext(hProv,0);  
	}


	return rv;
}
Exemple #13
0
void main(void)
{
//-------------------------------------------------------------------
// Declare and initialize variables.

HCRYPTPROV hProv;
BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed.";
DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
HCRYPTKEY hPubKey;
BYTE *pbKeyBlob;        
BYTE *pbSignature;
DWORD dwSigLen;
DWORD dwBlobLen;

//-------------------------------------------------------------------
// Acquire a cryptographic provider context handle.

if(CryptAcquireContext(
   &hProv, 
   NULL, 
   NULL, 
   PROV_RSA_FULL, 
   0)) 
{
     printf("CSP context acquired.\n");
}
else
{
     MyHandleError("Error during CryptAcquireContext.");
}
//-------------------------------------------------------------------
// Get the public at signature key. This is the public key
// that will be used by the receiver of the hash to verify
// the signature. In situations where the receiver could obtain the
// sender's public key from a certificate, this step would not be
// needed.

if(CryptGetUserKey(   
   hProv,    
   AT_SIGNATURE,    
   &hKey)) 
{
    printf("The signature key has been acquired. \n");
}
else
{
    MyHandleError("Error during CryptGetUserKey for signkey.");
}
//-------------------------------------------------------------------
// Export the public key. Here the public key is exported to a 
// PUBLICKEYBOLB so that the receiver of the signed hash can
// verify the signature. This BLOB could be written to a file and
// sent to another user.

if(CryptExportKey(   
   hKey,    
   NULL,    
   PUBLICKEYBLOB,
   0,    
   NULL, 
   &dwBlobLen)) 
{
     printf("Size of the BLOB for the public key determined. \n");
}
else
{
     MyHandleError("Error computing BLOB length.");
}
//-------------------------------------------------------------------
// Allocate memory for the pbKeyBlob.

if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) 
{
    printf("Memory has been allocated for the BLOB. \n");
}
else
{
    MyHandleError("Out of memory. \n");
}
//-------------------------------------------------------------------
// Do the actual exporting into the key BLOB.

if(CryptExportKey(   
   hKey, 
   NULL,    
   PUBLICKEYBLOB,    
   0,    
   pbKeyBlob,    
   &dwBlobLen))
{
     printf("Contents have been written to the BLOB. \n");
}
else
{
    MyHandleError("Error during CryptExportKey.");
}
//-------------------------------------------------------------------
// Create the hash object.

if(CryptCreateHash(
   hProv, 
   CALG_MD5, 
   0, 
   0, 
   &hHash)) 
{
     printf("Hash object created. \n");
}
else
{
    MyHandleError("Error during CryptCreateHash.");
}
//-------------------------------------------------------------------
// Compute the cryptographic hash of the buffer.

if(CryptHashData(
   hHash, 
   pbBuffer, 
   dwBufferLen, 
   0)) 
{
     printf("The data buffer has been hashed.\n");
}
else
{
     MyHandleError("Error during CryptHashData.");
}
//-------------------------------------------------------------------
// Determine the size of the signature and allocate memory.

dwSigLen= 0;
if(CryptSignHash(
   hHash, 
   AT_SIGNATURE, 
   NULL, 
   0, 
   NULL, 
   &dwSigLen)) 
{
     printf("Signature length %d found.\n",dwSigLen);
}
else
{
     MyHandleError("Error during CryptSignHash.");
}
//-------------------------------------------------------------------
// Allocate memory for the signature buffer.

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

if(CryptSignHash(
   hHash, 
   AT_SIGNATURE, 
   NULL, 
   0, 
   pbSignature, 
   &dwSigLen)) 
{
     printf("pbSignature is the hash signature.\n");
}
else
{
     MyHandleError("Error during CryptSignHash.");
}
//-------------------------------------------------------------------
// Destroy the hash object.

if(hHash) 
  CryptDestroyHash(hHash);

printf("The hash object has been destroyed.\n");
printf("The signing phase of this program is completed.\n\n");

//-------------------------------------------------------------------
// In the second phase, the hash signature is verified.
// This would most often be done by a different user in a
// separate program. The hash, signature, and the PUBLICKEYBLOB
// would be read from a file, an email message, 
// or some other source.

// Here, the original pbBuffer, pbSignature, szDescription. 
// pbKeyBlob, and their lengths are used.

// The contents of the pbBuffer must be the same data 
// that was originally signed.

//-------------------------------------------------------------------
// Get the public key of the user who created the digital signature 
// and import it into the CSP by using CryptImportKey. This returns
// a handle to the public key in hPubKey.

if(CryptImportKey(
   hProv,
   pbKeyBlob,
   dwBlobLen,
   0,
   0,
   &hPubKey))
{
     printf("The key has been imported.\n");
}
else
{
     MyHandleError("Public key import failed.");
}
//-------------------------------------------------------------------
// Create a new hash object.

if(CryptCreateHash(
   hProv, 
   CALG_MD5, 
   0, 
   0, 
   &hHash)) 
{
     printf("The hash object has been recreated. \n");
}
else
{
     MyHandleError("Error during CryptCreateHash.");
}
//-------------------------------------------------------------------
// Compute the cryptographic hash of the buffer.

if(CryptHashData(
   hHash, 
   pbBuffer, 
   dwBufferLen, 
   0)) 
{
     printf("The new hash has been created.\n");
}
else
{
     MyHandleError("Error during CryptHashData.");
}
//-------------------------------------------------------------------
// Validate the digital signature.

if(CryptVerifySignature(
   hHash, 
   pbSignature, 
   dwSigLen, 
   hPubKey,
   NULL, 
   0)) 
{
     printf("The signature has been verified.\n");
}
else
{
     printf("Signature not validated!\n");
}
//-------------------------------------------------------------------
// Free memory to be used to store signature.

if(pbSignature)
  free(pbSignature);

//-------------------------------------------------------------------
// Destroy the hash object.

if(hHash) 
  CryptDestroyHash(hHash);

//-------------------------------------------------------------------
// Release the provider handle.

if(hProv) 
   CryptReleaseContext(hProv, 0);
} //  End of main
BOOL SignVerifyFile(HCRYPTPROV hProv,
                    HCRYPTKEY hPubKey,
                    DWORD dwKeySpec,
                    ALG_ID HashAlgId,
                    LPTSTR szFileToSign,
                    LPTSTR szSigFile,
                    BOOL fSign)
{
   HCRYPTHASH hHash = NULL;
   HANDLE hDataFile = INVALID_HANDLE_VALUE;
   HANDLE hSigFile = INVALID_HANDLE_VALUE;   
   LPBYTE pbSignature = NULL;
   DWORD dwSignature;         
   BYTE pbBuffer[BUFFER_SIZE];
   DWORD dwBytesRead, dwBytesWritten;
   BOOL fResult;
   BOOL fFinished = FALSE; 
   BOOL fReturn = FALSE;

   __try
   {  
      // Open Data file
      hDataFile = CreateFile(szFileToSign, 
                             GENERIC_READ, 
                             0, 
                             NULL, 
                             OPEN_EXISTING, 
                             FILE_ATTRIBUTE_NORMAL, 
                             NULL);
      if (hDataFile == INVALID_HANDLE_VALUE)
      {
         MyPrintf(_T("CreateFile failed with %d\n"), GetLastError());
         __leave;
      }

      // Open/Create signature file
      hSigFile = CreateFile(szSigFile, 
                            GENERIC_READ|GENERIC_WRITE, 
                            0, 
                            NULL, 
                            OPEN_ALWAYS, 
                            FILE_ATTRIBUTE_NORMAL, 
                            NULL);
      if (hSigFile == INVALID_HANDLE_VALUE)
      {
         MyPrintf(_T("CreateFile failed with %d\n"), GetLastError());
         __leave;
      }

      // Create Hash
      fResult = CryptCreateHash(hProv, HashAlgId, 0, 0, &hHash);
      if (!fResult)
      {
         MyPrintf(_T("CryptCreateHash failed with %x\n"), GetLastError());
         __leave;
      }

      // Loop through file and hash file contents
      do
      {
         dwBytesRead = 0;

         fResult = ReadFile(hDataFile, pbBuffer, BUFFER_SIZE, &dwBytesRead, NULL);

         if (dwBytesRead == 0) break;

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

         fFinished = (dwBytesRead < BUFFER_SIZE);

         fResult = CryptHashData(hHash, pbBuffer, dwBytesRead, 0);
         if (!fResult)
         {
            MyPrintf(_T("CryptHashData failed with %x\n"), GetLastError());
            __leave;
         }

      } while (fFinished == FALSE);

      if (fSign)
      {
         // Get Signature size
         fResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &dwSignature);
         if (!fResult)
         {
            MyPrintf(_T("CryptSignHash failed with %x\n"), GetLastError());
            __leave;
         }

         // Allocate signature bytes
         pbSignature = (LPBYTE)LocalAlloc(LPTR, dwSignature);
         if (!pbSignature)
         {
            MyPrintf(_T("LocalAlloc failed with %d\n"), GetLastError());
            __leave;
         }

         // Sign and get back signature
         fResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, pbSignature, &dwSignature);
         if (!fResult)
         {
            MyPrintf(_T("CryptSignHash failed with %x\n"), GetLastError());
            __leave;
         }

         // Write signature to file
         fResult = WriteFile(hSigFile, pbSignature, dwSignature, &dwBytesWritten, NULL);
         if (!fResult)
         {
            MyPrintf(_T("WriteFile failed with %d\n"), GetLastError());
            __leave;
         }
      }
      else
      {
         // Get size of signature file
         dwSignature = GetFileSize(hSigFile, NULL);
         if (dwSignature == INVALID_FILE_SIZE)
         {
            MyPrintf(_T("GetFileSize failed with %d\n"), GetLastError());
            __leave;
         }

         // Allocate signature bytes
         pbSignature = (LPBYTE)LocalAlloc(LPTR, dwSignature);
         if (!pbSignature)
         {
            MyPrintf(_T("LocalAlloc failed with %d\n"), GetLastError());
            __leave;
         }

         // Read Signature
         fResult = ReadFile(hSigFile, pbSignature, dwSignature, &dwBytesRead, NULL);
         if (!fResult)
         {
            MyPrintf(_T("ReadFile failed with %d\n"), GetLastError());
            __leave;
         }

         // Verify Signature
         fResult = CryptVerifySignature(hHash, pbSignature, dwSignature, hPubKey, NULL, 0);
         if (!fResult)
         {
            MyPrintf(_T("CryptVerifySignature failed with %x\n"), GetLastError());
            __leave;
         }
      }

      fReturn = TRUE;
   }
   __finally
   {
      // Clean up
      if (hHash != NULL) CryptDestroyHash(hHash);      
      if (hDataFile != INVALID_HANDLE_VALUE) CloseHandle(hDataFile);
      if (hSigFile != INVALID_HANDLE_VALUE) CloseHandle(hSigFile);
      CheckAndLocalFree(pbSignature);
   }

   return fReturn;
}
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;
}