SUPPORT-8890. Открытие сертификата для подписи вынесено в инициализацию

(cherry picked from commit 3807bc745778c423bf107ccf818bd55807824ef5)
This commit is contained in:
Наиля Алашкова 2025-02-07 12:19:45 +03:00
parent 40746f2bd2
commit 57297d574f
3 changed files with 79 additions and 31 deletions

View file

@ -134,6 +134,10 @@ sign_service_create(const sign_conf_t *conf)
&conf->sign_cert_thumbprint, &conf->sign_cert_thumbprint,
&conf->sign_cert_password); &conf->sign_cert_password);
if (open_signer_cert(&hsign->cryptopro_ctx)) {
goto error;
}
LOG_TRACE("sign_service_create exit"); LOG_TRACE("sign_service_create exit");
return (HSign)hsign; return (HSign)hsign;
@ -150,6 +154,8 @@ sign_service_free(HSign hsign)
if (ctx == NULL) return; if (ctx == NULL) return;
close_signer_cert(&ctx->cryptopro_ctx);
free(ctx); free(ctx);
} }

View file

@ -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 int reverse_sign(const str_t *sign, /*out*/ str_t *sign_reversed);
static HCERTSTORE cert_open_store(); 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); 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 static int
sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign) sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign)
{ {
int rc = -1; int rc = -1;
HCERTSTORE hStoreHandle;
PCCERT_CONTEXT pSignerCert = NULL;
BOOL bReleaseContext = FALSE; BOOL bReleaseContext = FALSE;
HCRYPTPROV hCryptProv; HCRYPTPROV hCryptProv;
HCRYPTHASH hash = 0; HCRYPTHASH hash = 0;
BYTE *pbSignedMessageBlob; BYTE *pbSignedMessageBlob;
DWORD cbSignedMessageBlob; DWORD cbSignedMessageBlob;
hStoreHandle = cert_open_store(); if (!verify_cert_chain(ctx->signer_cert)) {
if (hStoreHandle == NULL) {
goto exit;
}
pSignerCert = get_signer_cert(ctx, hStoreHandle);
if (pSignerCert == NULL) {
goto exit;
}
if (!verify_cert_chain(pSignerCert)) {
goto exit; goto exit;
} }
if (!cp_function_list.CryptAcquireCertificatePrivateKey( if (!cp_function_list.CryptAcquireCertificatePrivateKey(
pSignerCert, ctx->signer_cert,
CRYPT_ACQUIRE_SILENT_FLAG, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_CACHE_FLAG,
NULL, NULL,
&hCryptProv, &hCryptProv,
NULL, NULL,
@ -301,15 +332,6 @@ exit:
cp_function_list.CryptReleaseContext(hCryptProv, 0); 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) { if (rc) {
log_sign_hash_data_last_error(); log_sign_hash_data_last_error();
@ -348,7 +370,7 @@ cert_open_store()
hStoreHandle = cp_function_list.CertOpenStore(CERT_STORE_PROV_SYSTEM, hStoreHandle = cp_function_list.CertOpenStore(CERT_STORE_PROV_SYSTEM,
0, 0,
0, 0,
CERT_SYSTEM_STORE_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG,
L"MY"); L"MY");
if (hStoreHandle == NULL) { if (hStoreHandle == NULL) {
@ -357,10 +379,25 @@ cert_open_store()
} }
LOG_DEBUG("The MY store is open"); LOG_DEBUG("The MY store is open");
LOG_TRACE("cert_open_store exit");
return hStoreHandle; 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 static PCCERT_CONTEXT
get_cert_by_thumbprint(HCERTSTORE hStoreHandle, const str_t* thumbprint) get_cert_by_thumbprint(HCERTSTORE hStoreHandle, const str_t* thumbprint)
{ {
@ -681,11 +718,7 @@ exit:
cp_function_list.CertFreeCertificateContext(certificate); cp_function_list.CertFreeCertificateContext(certificate);
} }
if (hStoreHandle) { cert_close_store(hStoreHandle);
if (!cp_function_list.CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG)) {
LOG_ERROR("CertCloseStore() failed");
}
}
if (rc == 0) { if (rc == 0) {
LOG_TRACE("cryptopro_verify exit"); LOG_TRACE("cryptopro_verify exit");

View file

@ -6,10 +6,16 @@
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include "capi.h"
typedef struct cryptopro_context_s { typedef struct cryptopro_context_s {
const str_t *cert_thumbprint; const str_t *cert_thumbprint;
const str_t *password; const str_t *password;
HCERTSTORE cert_store;
PCCERT_CONTEXT signer_cert;
} cryptopro_context_t; } 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); 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_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, int cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t *data,