From 5a4ee2cb69abaa4ae39178bf8c68351510c3d0b4 Mon Sep 17 00:00:00 2001 From: alashkova Date: Tue, 22 Oct 2024 15:22:21 +0300 Subject: [PATCH] =?UTF-8?q?SUPPORT-8592.=20=D0=9D=D0=B0=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=B9=D0=BA=D0=B0=20sign::signer=5Fsubject=20=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=20sign::sign=5Fcert=5Fthumbprint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- conf/ervu-sign-module.conf.example | 2 +- src/modules/service_sign.c | 22 ++++---- src/modules/service_sign.h | 2 +- src/utils/cryptopro.c | 84 ++++++++++++++---------------- src/utils/cryptopro.h | 6 +-- Инструкция по установке.md | 6 +-- 7 files changed, 61 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 29b24ba..8b6e752 100644 --- a/README.md +++ b/README.md @@ -90,9 +90,9 @@ fcgi_thread_pool_size = 1 *\# значение по умолчанию: 1* - В секции **\[sign\]** задать настройки модуля подписания: location = /sign *\# значение по умолчанию: /sign, должно совпадать со значением в nginx.conf* -signer_subject = signer@example.ru *\# email, ИНН, СНИЛС или любая другая строка из свойства контейнера «Субъект»* +sign_cert_thumbprint = sha1_thumbprint_of_signer_cert *\# SHA1 отпечаток сертификата, которым ИС подписывает секрет* sign_cert_password = \*\*\*\* *\# пароль от контейнера* - В секции **\[verify\]** задать настройки проверки подписи маркера доступа: location = /verify *\# значение по умолчанию: /verify, должно совпадать со значением в nginx.conf* -esia_cert_thumbprint = sha1thumbprint *\# SHA1 отпечаток сертификата ЕСИА* +esia_cert_thumbprint = sha1_thumbprint_of_esia_cert *\# SHA1 отпечаток сертификата ЕСИА* diff --git a/conf/ervu-sign-module.conf.example b/conf/ervu-sign-module.conf.example index 50da565..5d32295 100644 --- a/conf/ervu-sign-module.conf.example +++ b/conf/ervu-sign-module.conf.example @@ -9,7 +9,7 @@ fcgi_listen_host = 127.0.0.1 [sign] #location = /sign -signer_subject = signer@example.ru +sign_cert_thumbprint = sign_cert_password = **** [verify] diff --git a/src/modules/service_sign.c b/src/modules/service_sign.c index d0cc461..af94665 100644 --- a/src/modules/service_sign.c +++ b/src/modules/service_sign.c @@ -4,10 +4,10 @@ #include "utils/cryptopro.h" -#define SIGN_CONF_SECTION "sign" -#define SIGN_CONF_KEY_LOCATION "location" -#define SIGN_CONF_KEY_SIGNER "signer_subject" -#define SIGN_CONF_KEY_PASSWORD "sign_cert_password" +#define SIGN_CONF_SECTION "sign" +#define SIGN_CONF_KEY_LOCATION "location" +#define SIGN_CONF_KEY_SIGN_CERT_THUMBPRINT "sign_cert_thumbprint" +#define SIGN_CONF_KEY_SIGN_CERT_PASSWORD "sign_cert_password" #define FCGI_OK_RESPONSE_FORMAT \ "Content-type: text/plain" CRLF\ @@ -58,15 +58,15 @@ sign_conf_load(sign_conf_t *conf, const conf_file_context_t conf_file) }, { SIGN_CONF_SECTION, - SIGN_CONF_KEY_SIGNER, - &(conf->signer), - CONF_FILE_VALUE_STRING, + SIGN_CONF_KEY_SIGN_CERT_THUMBPRINT, + &(conf->sign_cert_thumbprint), + CONF_FILE_VALUE_STRT, CONF_FILE_VALUE_NONE, NULL }, { SIGN_CONF_SECTION, - SIGN_CONF_KEY_PASSWORD, + SIGN_CONF_KEY_SIGN_CERT_PASSWORD, &(conf->sign_cert_password), CONF_FILE_VALUE_STRT, CONF_FILE_VALUE_PSWD, @@ -100,7 +100,7 @@ sign_conf_clear(sign_conf_t *conf) str_t_clear(&conf->sign_cert_password); str_t_clear(&conf->location); - free(conf->signer); + str_t_clear(&conf->sign_cert_thumbprint); memset(conf, 0, sizeof(sign_conf_t)); } @@ -118,7 +118,9 @@ sign_service_create(const sign_conf_t *conf) hsign->conf = conf; - cryptopro_context_set(&hsign->cryptopro_ctx, conf->signer, &conf->sign_cert_password); + cryptopro_context_set(&hsign->cryptopro_ctx, + &conf->sign_cert_thumbprint, + &conf->sign_cert_password); LOG_TRACE("sign_service_create exit"); return (HSign)hsign; diff --git a/src/modules/service_sign.h b/src/modules/service_sign.h index 5bc4546..3bbd02c 100644 --- a/src/modules/service_sign.h +++ b/src/modules/service_sign.h @@ -11,7 +11,7 @@ typedef struct sign_service_t* HSign; typedef struct sign_conf_s { str_t location; - char *signer; /* субъект контейнера */ + str_t sign_cert_thumbprint; /* SHA1 отпечаток сертификата ИС */ str_t sign_cert_password; /* пароль от контейнера */ } sign_conf_t; diff --git a/src/utils/cryptopro.c b/src/utils/cryptopro.c index fc35ca2..b93b91f 100644 --- a/src/utils/cryptopro.c +++ b/src/utils/cryptopro.c @@ -44,7 +44,7 @@ cryptopro_sign(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t LOG_TRACE("cryptopro_sign enter"); assert(ctx != NULL); - assert(ctx->signer != NULL); + assert(!str_t_is_null(*ctx->cert_thumbprint)); assert(ctx->password != NULL); assert(data != NULL && !str_t_is_null(*data)); assert(sign != NULL); @@ -209,19 +209,52 @@ cert_open_store() } static PCCERT_CONTEXT -get_signer_cert(const cryptopro_context_t *ctx, HCERTSTORE hStoreHandle) +get_cert_by_thumbprint(HCERTSTORE hStoreHandle, const str_t* thumbprint) { - PCCERT_CONTEXT cert_ctx = cp_function_list.CertFindCertificateInStore(hStoreHandle, + str_t thumbprint_bin = str_t_null; + + LOG_TRACE("get_cert_by_thumbprint enter"); + + if (hex_to_bin(thumbprint, &thumbprint_bin)) { + goto error; + } + + CRYPT_HASH_BLOB hash = { + .pbData = (BYTE*)thumbprint_bin.data, + .cbData = thumbprint_bin.len + }; + + PCCERT_CONTEXT cert = cp_function_list.CertFindCertificateInStore(hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, - CERT_FIND_SUBJECT_STR, - ctx->signer, + CERT_FIND_HASH, + &hash, NULL); - if (cert_ctx == NULL) { + if (cert == NULL) { LOG_ERROR("Could not find certificate in store"); goto error; } + str_t_clear(&thumbprint_bin); + + LOG_TRACE("get_cert_by_thumbprint exit"); + + return cert; + +error: + str_t_clear(&thumbprint_bin); + LOG_ERROR("get_cert_by_thumbprint exit with error"); + return NULL; +} + +static PCCERT_CONTEXT +get_signer_cert(const cryptopro_context_t *ctx, HCERTSTORE hStoreHandle) +{ + PCCERT_CONTEXT cert_ctx = get_cert_by_thumbprint(hStoreHandle, ctx->cert_thumbprint); + if (cert_ctx == NULL) { + goto error; + } + if (set_password(cert_ctx, ctx->password)) { goto error; } @@ -292,45 +325,6 @@ error: return -1; } -static PCCERT_CONTEXT -get_cert_by_thumbprint(HCERTSTORE hStoreHandle, const str_t* thumbprint) -{ - str_t thumbprint_bin = str_t_null; - - LOG_TRACE("get_cert_by_thumbprint enter"); - - if (hex_to_bin(thumbprint, &thumbprint_bin)) { - goto error; - } - - CRYPT_HASH_BLOB hash = { - .pbData = (BYTE*)thumbprint_bin.data, - .cbData = thumbprint_bin.len - }; - - PCCERT_CONTEXT cert = cp_function_list.CertFindCertificateInStore(hStoreHandle, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - 0, - CERT_FIND_HASH, - &hash, - NULL); - if (cert == NULL) { - LOG_ERROR("Could not find certificate in store"); - goto error; - } - - str_t_clear(&thumbprint_bin); - - LOG_TRACE("get_cert_by_thumbprint exit"); - - return cert; - -error: - str_t_clear(&thumbprint_bin); - LOG_ERROR("get_cert_by_thumbprint exit with error"); - return NULL; -} - static int alg_id_from_str(const str_t* alg, /*out*/ ALG_ID* alg_id) { diff --git a/src/utils/cryptopro.h b/src/utils/cryptopro.h index 1f30c85..cd3e1d8 100644 --- a/src/utils/cryptopro.h +++ b/src/utils/cryptopro.h @@ -8,17 +8,17 @@ typedef struct cryptopro_context_s { - const char *signer; + const str_t *cert_thumbprint; const str_t *password; } cryptopro_context_t; static inline void -cryptopro_context_set(cryptopro_context_t *ctx, const char *signer, const str_t *password) +cryptopro_context_set(cryptopro_context_t *ctx, const str_t *cert_thumbprint, const str_t *password) { assert(ctx != NULL); - ctx->signer = signer; + ctx->cert_thumbprint = cert_thumbprint; ctx->password = password; } diff --git a/Инструкция по установке.md b/Инструкция по установке.md index 160acf0..be379e9 100644 --- a/Инструкция по установке.md +++ b/Инструкция по установке.md @@ -46,13 +46,13 @@ chown -R ervu:ervu /var/opt/cprocsp/keys/ervu/key_cont.000/ ``` Получить следующие значения: -- Поле "Субъект": любая подстрока из этого поля является signer_subject (нужно будет указать в конфигурационном файле модуля подписания) +- Поле "SHA1 отпечаток": это значение нужно будет указать в конфигурационном файле модуля подписания в качестве настройки \ - Поле "Ссылка на ключ": убедиться, что значение равно "Есть" (иначе необходимо проверить выполнение предыдущих шагов) -4. (опционально) Сделать тестовую подпись с помощью установленного контейнера и полученных значений \ и \: +4. (опционально) Сделать тестовую подпись с помощью установленного контейнера и полученных значений \ и \: ``` bash touch test.txt -/opt/cprocsp/bin/amd64/cryptcp -signf -dn ./test.txt +/opt/cprocsp/bin/amd64/cryptcp -signf -thumbprint ./test.txt rm -f test.txt test.txt.sgn ```