SUPPORT-8714. Добавлена возможность указывать несколько сертификатов ЕСИА

This commit is contained in:
alashkova 2024-11-19 17:08:58 +03:00
parent b93b8b8068
commit 19fb6499ab
4 changed files with 51 additions and 8 deletions

View file

@ -95,4 +95,4 @@ sign_cert_password = \*\*\*\* *\# пароль от контейнера*
- В секции **\[verify\]** задать настройки проверки подписи маркера доступа: - В секции **\[verify\]** задать настройки проверки подписи маркера доступа:
location = /verify *\# значение по умолчанию: /verify* location = /verify *\# значение по умолчанию: /verify*
esia_cert_thumbprint = sha1_thumbprint_of_esia_cert *\# SHA1 отпечаток сертификата ЕСИА* esia_cert_thumbprint = sha1_thumbprint_of_esia_cert0 sha1_thumbprint_of_esia_cert1 *\# список SHA1 отпечатков сертификатов ЕСИА, указанных через пробел*

View file

@ -63,8 +63,8 @@ verify_conf_load(verify_conf_t *conf, const conf_file_context_t conf_file)
{ {
VERIFY_CONF_SECTION, VERIFY_CONF_SECTION,
VERIFY_CONF_KEY_THUMBPRINT, VERIFY_CONF_KEY_THUMBPRINT,
&conf->esia_cert_thumbprint, &conf->esia_cert_thumbprint_list,
CONF_FILE_VALUE_STRT, CONF_FILE_VALUE_STRING_LIST,
CONF_FILE_VALUE_NONE, CONF_FILE_VALUE_NONE,
NULL NULL
}, },
@ -91,7 +91,7 @@ verify_conf_clear(verify_conf_t *conf)
if (conf == NULL) return; if (conf == NULL) return;
str_t_clear(&conf->location); str_t_clear(&conf->location);
str_t_clear(&conf->esia_cert_thumbprint); string_list_clear(&conf->esia_cert_thumbprint_list);
memset(conf, 0, sizeof(verify_conf_t)); memset(conf, 0, sizeof(verify_conf_t));
} }
@ -238,6 +238,42 @@ fcgi_verify_request_clear(fcgi_verify_request_t *req_info)
memset(req_info, 0, sizeof(fcgi_verify_request_t)); memset(req_info, 0, sizeof(fcgi_verify_request_t));
} }
static int
verify_sign_using_thumbprint_list(const string_list_t* thumbprint_list, const str_t* alg,
const str_t* header_payload, const str_t* sign,
bool* is_verified, char** verify_error)
{
int rc = -1;
LOG_TRACE("verify_sign_using_thumbprint_list enter");
for (size_t i = 0; i < thumbprint_list->size; i++) {
const char *cert_thumbprint = thumbprint_list->list[i];
str_t thumbprint = {
.data = (char*) cert_thumbprint,
.len = strlen(cert_thumbprint)
};
LOG_DEBUG("Try to verify jwt using cert with thumbprint '%s'...", cert_thumbprint);
rc = cryptopro_verify(&thumbprint, alg, header_payload, sign, is_verified, verify_error);
if (rc) {
LOG_ERROR("cryptopro_verify() failed for cert with thumbprint '%s'", cert_thumbprint);
}
if (*is_verified) {
LOG_DEBUG("jwt verified using cert with thumbprint '%s'", cert_thumbprint);
break;
} else {
LOG_DEBUG("Could not veify jwt using cert with thumbprint '%s'. Desc: %s",
cert_thumbprint, *verify_error);
}
}
LOG_TRACE("verify_sign_using_thumbprint_list exit");
return rc;
}
static fcgi_handler_status_t static fcgi_handler_status_t
verify_jwt_sign(fcgi_verify_request_t* req_info, const verify_service_t *ctx) verify_jwt_sign(fcgi_verify_request_t* req_info, const verify_service_t *ctx)
{ {
@ -286,8 +322,9 @@ verify_jwt_sign(fcgi_verify_request_t* req_info, const verify_service_t *ctx)
goto error; goto error;
} }
if (cryptopro_verify(&ctx->conf->esia_cert_thumbprint, &alg, &header_payload, &sign, if (verify_sign_using_thumbprint_list(&ctx->conf->esia_cert_thumbprint_list, &alg,
&is_verified, &req_info->verify_error)) { &header_payload, &sign, &is_verified,
&req_info->verify_error)) {
goto error; goto error;
} }

View file

@ -5,12 +5,13 @@
#include "utils/conf_file_context.h" #include "utils/conf_file_context.h"
#include "utils/str_t.h" #include "utils/str_t.h"
#include "utils/types.h"
typedef struct verify_service_t* HVerify; typedef struct verify_service_t* HVerify;
typedef struct verify_conf_s { typedef struct verify_conf_s {
str_t location; str_t location;
str_t esia_cert_thumbprint; string_list_t esia_cert_thumbprint_list;
} verify_conf_t; } verify_conf_t;

View file

@ -371,6 +371,10 @@ get_verify_error(char** verify_error)
size_t size = strlen(err_string) + 4 /*error code*/ + 1 /*terminating null*/; size_t size = strlen(err_string) + 4 /*error code*/ + 1 /*terminating null*/;
if (*verify_error != NULL) {
free(*verify_error); // в ответе отдаем последнюю ошибку
}
*verify_error = malloc(size); *verify_error = malloc(size);
if (*verify_error == NULL) { if (*verify_error == NULL) {
LOG_ERROR("get_verify_error failed. Could not allocate memory for error string " LOG_ERROR("get_verify_error failed. Could not allocate memory for error string "
@ -461,7 +465,8 @@ cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t* da
if (*verify_error == NULL) { if (*verify_error == NULL) {
goto exit; goto exit;
} }
LOG_WARN("%s", *verify_error); LOG_WARN("%s, cert_thumbprint: %.*s", *verify_error,
(int) cert_thumbprint->len, cert_thumbprint->data);
} }
rc = 0; rc = 0;