diff --git a/src/utils/capi.c b/src/utils/capi.c index c6458e7..5cc5f8a 100644 --- a/src/utils/capi.c +++ b/src/utils/capi.c @@ -31,6 +31,7 @@ capi_function_list_init(library_t *lib, capi_function_list_t *fl) LIBRARY_RESOLVE(fl->CertGetCertificateChain, lib, "CertGetCertificateChain"); LIBRARY_RESOLVE(fl->CertVerifyCertificateChainPolicy, lib, "CertVerifyCertificateChainPolicy"); LIBRARY_RESOLVE(fl->CertFreeCertificateChain, lib, "CertFreeCertificateChain"); + LIBRARY_RESOLVE(fl->CryptGenRandom, lib, "CryptGenRandom"); #ifdef UNICODE LIBRARY_RESOLVE(fl->CryptSignHash, lib, "CryptSignHashW"); diff --git a/src/utils/capi.h b/src/utils/capi.h index 71fe5c4..ba5ed09 100644 --- a/src/utils/capi.h +++ b/src/utils/capi.h @@ -200,6 +200,13 @@ DECLARE_FN(WINADVAPI, CERT_FREE_CERTIFICATE_CHAIN, (PCCERT_CHAIN_CONTEXT pChainContext)); +DECLARE_FN(WINADVAPI, + BOOL, + CRYPT_GEN_RANDOM, + (HCRYPTPROV hProv, + DWORD dwLen, + BYTE *pbBuffer)); + #ifdef UNICODE #define CRYPT_SIGN_HASH_FN CRYPT_SIGN_HASH_W_FN #define CRYPT_VERIFY_SIGNATURE_FN CRYPT_VERIFY_SIGNATURE_W_FN @@ -233,6 +240,7 @@ typedef struct { CERT_GET_CERTIFICATE_CHAIN_FN CertGetCertificateChain; CERT_VERIFY_CERTIFICATE_CHAIN_POLICY_FN CertVerifyCertificateChainPolicy; CERT_FREE_CERTIFICATE_CHAIN_FN CertFreeCertificateChain; + CRYPT_GEN_RANDOM_FN CryptGenRandom; } capi_function_list_t; diff --git a/src/utils/cryptopro.c b/src/utils/cryptopro.c index acaa949..ba533cd 100644 --- a/src/utils/cryptopro.c +++ b/src/utils/cryptopro.c @@ -253,7 +253,7 @@ sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t } if (!cp_function_list.CryptAcquireCertificatePrivateKey( - pSignerCert, + pSignerCert, CRYPT_ACQUIRE_SILENT_FLAG, NULL, &hCryptProv, @@ -663,3 +663,36 @@ exit: return rc; } + +int +cryptopro_gen_random(unsigned char* data, size_t len) +{ + HCRYPTPROV hCryptProv = 0; + + LOG_TRACE("cryptopro_gen_random enter"); + + if (!cp_function_list.CryptAcquireContext(&hCryptProv, NULL, CP_KC1_GR3410_2001_PROV, + PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT)) { + LOG_ERROR("CryptAcquireContext() failed"); + goto error; + } + + if (!cp_function_list.CryptGenRandom(hCryptProv, len, data)) { + LOG_ERROR("CryptGenRandom() failed"); + goto error; + } + + cp_function_list.CryptReleaseContext(hCryptProv, 0); + + LOG_TRACE("cryptopro_gen_random exit"); + return 0; + +error: + if (hCryptProv) { + cp_function_list.CryptReleaseContext(hCryptProv, 0); + } + + LOG_ERROR("cryptopro_gen_random exit with error. Last error code: 0x%08x", + cp_function_list.GetLastError()); + return -1; +} \ No newline at end of file diff --git a/src/utils/cryptopro.h b/src/utils/cryptopro.h index cd3e1d8..6aed9b0 100644 --- a/src/utils/cryptopro.h +++ b/src/utils/cryptopro.h @@ -29,4 +29,6 @@ int cryptopro_sign(const cryptopro_context_t *ctx, const str_t *data, /*out*/ st int cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t *data, const str_t *sign, bool* is_verified, char** verify_error); +int cryptopro_gen_random(unsigned char* data, size_t len); + #endif // CRYPTOPRO_H_INCLUDED