From 57297d574f00ce06bfec678067d539cba68818a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B0=D0=B8=D0=BB=D1=8F=20=D0=90=D0=BB=D0=B0=D1=88?= =?UTF-8?q?=D0=BA=D0=BE=D0=B2=D0=B0?= Date: Fri, 7 Feb 2025 12:19:45 +0300 Subject: [PATCH] =?UTF-8?q?SUPPORT-8890.=20=D0=9E=D1=82=D0=BA=D1=80=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D0=B5=20=D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=D1=82=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D0=BF=D0=B8=D1=81=D0=B8=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=B2=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8?= =?UTF-8?q?=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 3807bc745778c423bf107ccf818bd55807824ef5) --- src/modules/service_sign.c | 6 +++ src/utils/cryptopro.c | 95 +++++++++++++++++++++++++------------- src/utils/cryptopro.h | 9 ++++ 3 files changed, 79 insertions(+), 31 deletions(-) diff --git a/src/modules/service_sign.c b/src/modules/service_sign.c index a9f75c8..dd886e7 100644 --- a/src/modules/service_sign.c +++ b/src/modules/service_sign.c @@ -134,6 +134,10 @@ sign_service_create(const sign_conf_t *conf) &conf->sign_cert_thumbprint, &conf->sign_cert_password); + if (open_signer_cert(&hsign->cryptopro_ctx)) { + goto error; + } + LOG_TRACE("sign_service_create exit"); return (HSign)hsign; @@ -150,6 +154,8 @@ sign_service_free(HSign hsign) if (ctx == NULL) return; + close_signer_cert(&ctx->cryptopro_ctx); + free(ctx); } diff --git a/src/utils/cryptopro.c b/src/utils/cryptopro.c index 1187c3b..71b3f63 100644 --- a/src/utils/cryptopro.c +++ b/src/utils/cryptopro.c @@ -14,6 +14,7 @@ static int sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*o static int reverse_sign(const str_t *sign, /*out*/ str_t *sign_reversed); static HCERTSTORE cert_open_store(); +static void cert_close_store(HCERTSTORE hStoreHandle); static PCCERT_CONTEXT get_signer_cert(const cryptopro_context_t *ctx, HCERTSTORE hStoreHandle); @@ -227,35 +228,65 @@ log_sign_hash_data_last_error() } } +int +open_signer_cert(cryptopro_context_t *ctx) +{ + LOG_TRACE("open_signer_cert enter"); + + ctx->cert_store = cert_open_store(); + if (ctx->cert_store == NULL) { + goto error; + } + + ctx->signer_cert = get_signer_cert(ctx, ctx->cert_store); + if (ctx->signer_cert == NULL) { + goto error; + } + + LOG_TRACE("open_signer_cert exit"); + + return 0; + +error: + LOG_ERROR("open_signer_cert exit with error. Last error code: 0x%08x", + cp_function_list.GetLastError()); + close_signer_cert(ctx); + return -1; +} + +void +close_signer_cert(cryptopro_context_t *ctx) +{ + LOG_TRACE("close_signer_cert enter"); + + if (ctx->signer_cert) { + cp_function_list.CertFreeCertificateContext(ctx->signer_cert); + ctx->signer_cert = NULL; + } + + cert_close_store(ctx->cert_store); + ctx->cert_store = NULL; + + LOG_TRACE("close_signer_cert exit"); +} + static int sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign) { int rc = -1; - HCERTSTORE hStoreHandle; - PCCERT_CONTEXT pSignerCert = NULL; BOOL bReleaseContext = FALSE; HCRYPTPROV hCryptProv; HCRYPTHASH hash = 0; BYTE *pbSignedMessageBlob; DWORD cbSignedMessageBlob; - hStoreHandle = cert_open_store(); - if (hStoreHandle == NULL) { - goto exit; - } - - pSignerCert = get_signer_cert(ctx, hStoreHandle); - if (pSignerCert == NULL) { - goto exit; - } - - if (!verify_cert_chain(pSignerCert)) { + if (!verify_cert_chain(ctx->signer_cert)) { goto exit; } if (!cp_function_list.CryptAcquireCertificatePrivateKey( - pSignerCert, - CRYPT_ACQUIRE_SILENT_FLAG, + ctx->signer_cert, + CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_CACHE_FLAG, NULL, &hCryptProv, NULL, @@ -301,15 +332,6 @@ exit: cp_function_list.CryptReleaseContext(hCryptProv, 0); } - if (pSignerCert) { - cp_function_list.CertFreeCertificateContext(pSignerCert); - } - - if (hStoreHandle) { - if (!cp_function_list.CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG)) { - LOG_ERROR("CertCloseStore() failed"); - } - } if (rc) { log_sign_hash_data_last_error(); @@ -348,7 +370,7 @@ cert_open_store() hStoreHandle = cp_function_list.CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, - CERT_SYSTEM_STORE_CURRENT_USER, + CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); if (hStoreHandle == NULL) { @@ -357,10 +379,25 @@ cert_open_store() } LOG_DEBUG("The MY store is open"); - + LOG_TRACE("cert_open_store exit"); return hStoreHandle; } + +static void +cert_close_store(HCERTSTORE hStoreHandle) +{ + LOG_TRACE("cert_close_store enter"); + + if (hStoreHandle) { + if (!cp_function_list.CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG)) { + LOG_ERROR("CertCloseStore() failed"); + } + } + + LOG_TRACE("cert_close_store exit"); +} + static PCCERT_CONTEXT get_cert_by_thumbprint(HCERTSTORE hStoreHandle, const str_t* thumbprint) { @@ -681,11 +718,7 @@ exit: cp_function_list.CertFreeCertificateContext(certificate); } - if (hStoreHandle) { - if (!cp_function_list.CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG)) { - LOG_ERROR("CertCloseStore() failed"); - } - } + cert_close_store(hStoreHandle); if (rc == 0) { LOG_TRACE("cryptopro_verify exit"); diff --git a/src/utils/cryptopro.h b/src/utils/cryptopro.h index 6aed9b0..6391017 100644 --- a/src/utils/cryptopro.h +++ b/src/utils/cryptopro.h @@ -6,10 +6,16 @@ #include #include +#include "capi.h" + typedef struct cryptopro_context_s { const str_t *cert_thumbprint; const str_t *password; + + HCERTSTORE cert_store; + PCCERT_CONTEXT signer_cert; + } cryptopro_context_t; @@ -24,6 +30,9 @@ cryptopro_context_set(cryptopro_context_t *ctx, const str_t *cert_thumbprint, co bool cryptopro_init(const char* cp_file); +int open_signer_cert(cryptopro_context_t *ctx); +void close_signer_cert(cryptopro_context_t *ctx); + int cryptopro_sign(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign); int cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t *data,