From f9f0d56bab25d3cf24aac608c62192fa8ae5ad9d 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: Mon, 17 Feb 2025 10:16:42 +0300 Subject: [PATCH] # Conflicts: # CMakeLists.txt # conf/nginx.conf # src/utils/cryptopro.c --- conf/nginx.conf | 2 +- src/modules/service_sign.c | 6 +++ src/utils/cryptopro.c | 95 +++++++++++++++++++++++++------------- src/utils/cryptopro.h | 9 ++++ 4 files changed, 80 insertions(+), 32 deletions(-) diff --git a/conf/nginx.conf b/conf/nginx.conf index 0d5cd44..a91ef19 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -16,7 +16,7 @@ include /etc/nginx/conf-enabled.d/*.conf; http { log_format req_time '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for" $request_time'; + '"$http_user_agent" "$http_x_forwarded_for" $request_time "$upstream_addr"'; access_log /var/log/nginx/access.log req_time; proxy_temp_path /var/spool/nginx/tmp/proxy; fastcgi_temp_path /var/spool/nginx/tmp/fastcgi; 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,