From 857094ef3120ababc55b197439e189af9410de36 Mon Sep 17 00:00:00 2001 From: alashkova Date: Thu, 26 Dec 2024 14:43:18 +0300 Subject: [PATCH 1/6] =?UTF-8?q?SUPPORT-8821.=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B0=D0=BD=D0=B4=D0=BE=D0=BC=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D1=87=D0=B8=D1=81=D0=BB=D0=B0=20=D1=81=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=D1=81=D1=82=D0=B2=D0=B0=D0=BC=D0=B8=20=D0=9A=D1=80=D0=B8?= =?UTF-8?q?=D0=BF=D1=82=D0=BE=D0=9F=D1=80=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/capi.c | 1 + src/utils/capi.h | 8 ++++++++ src/utils/cryptopro.c | 35 ++++++++++++++++++++++++++++++++++- src/utils/cryptopro.h | 2 ++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/utils/capi.c b/src/utils/capi.c index c6458e7..5cc5f8a 100644 --- a/src/utils/capi.c +++ b/src/utils/capi.c @@ -31,6 +31,7 @@ capi_function_list_init(library_t *lib, capi_function_list_t *fl) LIBRARY_RESOLVE(fl->CertGetCertificateChain, lib, "CertGetCertificateChain"); LIBRARY_RESOLVE(fl->CertVerifyCertificateChainPolicy, lib, "CertVerifyCertificateChainPolicy"); LIBRARY_RESOLVE(fl->CertFreeCertificateChain, lib, "CertFreeCertificateChain"); + LIBRARY_RESOLVE(fl->CryptGenRandom, lib, "CryptGenRandom"); #ifdef UNICODE LIBRARY_RESOLVE(fl->CryptSignHash, lib, "CryptSignHashW"); diff --git a/src/utils/capi.h b/src/utils/capi.h index 71fe5c4..ba5ed09 100644 --- a/src/utils/capi.h +++ b/src/utils/capi.h @@ -200,6 +200,13 @@ DECLARE_FN(WINADVAPI, CERT_FREE_CERTIFICATE_CHAIN, (PCCERT_CHAIN_CONTEXT pChainContext)); +DECLARE_FN(WINADVAPI, + BOOL, + CRYPT_GEN_RANDOM, + (HCRYPTPROV hProv, + DWORD dwLen, + BYTE *pbBuffer)); + #ifdef UNICODE #define CRYPT_SIGN_HASH_FN CRYPT_SIGN_HASH_W_FN #define CRYPT_VERIFY_SIGNATURE_FN CRYPT_VERIFY_SIGNATURE_W_FN @@ -233,6 +240,7 @@ typedef struct { CERT_GET_CERTIFICATE_CHAIN_FN CertGetCertificateChain; CERT_VERIFY_CERTIFICATE_CHAIN_POLICY_FN CertVerifyCertificateChainPolicy; CERT_FREE_CERTIFICATE_CHAIN_FN CertFreeCertificateChain; + CRYPT_GEN_RANDOM_FN CryptGenRandom; } capi_function_list_t; diff --git a/src/utils/cryptopro.c b/src/utils/cryptopro.c index acaa949..ba533cd 100644 --- a/src/utils/cryptopro.c +++ b/src/utils/cryptopro.c @@ -253,7 +253,7 @@ sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t } if (!cp_function_list.CryptAcquireCertificatePrivateKey( - pSignerCert, + pSignerCert, CRYPT_ACQUIRE_SILENT_FLAG, NULL, &hCryptProv, @@ -663,3 +663,36 @@ exit: return rc; } + +int +cryptopro_gen_random(unsigned char* data, size_t len) +{ + HCRYPTPROV hCryptProv = 0; + + LOG_TRACE("cryptopro_gen_random enter"); + + if (!cp_function_list.CryptAcquireContext(&hCryptProv, NULL, CP_KC1_GR3410_2001_PROV, + PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT)) { + LOG_ERROR("CryptAcquireContext() failed"); + goto error; + } + + if (!cp_function_list.CryptGenRandom(hCryptProv, len, data)) { + LOG_ERROR("CryptGenRandom() failed"); + goto error; + } + + cp_function_list.CryptReleaseContext(hCryptProv, 0); + + LOG_TRACE("cryptopro_gen_random exit"); + return 0; + +error: + if (hCryptProv) { + cp_function_list.CryptReleaseContext(hCryptProv, 0); + } + + LOG_ERROR("cryptopro_gen_random exit with error. Last error code: 0x%08x", + cp_function_list.GetLastError()); + return -1; +} \ No newline at end of file diff --git a/src/utils/cryptopro.h b/src/utils/cryptopro.h index cd3e1d8..6aed9b0 100644 --- a/src/utils/cryptopro.h +++ b/src/utils/cryptopro.h @@ -29,4 +29,6 @@ int cryptopro_sign(const cryptopro_context_t *ctx, const str_t *data, /*out*/ st int cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t *data, const str_t *sign, bool* is_verified, char** verify_error); +int cryptopro_gen_random(unsigned char* data, size_t len); + #endif // CRYPTOPRO_H_INCLUDED From eabc54da1276fe4ebcfae2d6bdadf21478471878 Mon Sep 17 00:00:00 2001 From: alashkova Date: Thu, 26 Dec 2024 16:41:00 +0300 Subject: [PATCH 2/6] =?UTF-8?q?SUPPORT-8821.=20=D0=93=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20uuid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 + src/utils/uuid.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++ src/utils/uuid.h | 7 +++ 3 files changed, 125 insertions(+) create mode 100644 src/utils/uuid.c create mode 100644 src/utils/uuid.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ad9918..56bfb6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ SET (DEP_LIBS -ldl -ljson-glib-1.0 -lgobject-2.0 + -luuid ) # JSON-GLIB @@ -124,6 +125,7 @@ ADD_EXECUTABLE (${PROJECT_NAME} ${UTILS_DIR}/library.c ${UTILS_DIR}/logger.c ${UTILS_DIR}/str_t.c + ${UTILS_DIR}/uuid.c ${FCGISRV_DIR}/fcgi_map.c ${FCGISRV_DIR}/fcgi_server.c ${FCGISRV_DIR}/fcgi_thread.c diff --git a/src/utils/uuid.c b/src/utils/uuid.c new file mode 100644 index 0000000..21149c9 --- /dev/null +++ b/src/utils/uuid.c @@ -0,0 +1,116 @@ +#include "uuid.h" + +#include "cryptopro.h" +#include "logger.h" + +#include +#include +#include + +struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint16_t clock_seq; + uint8_t node[6]; +}; + +static void +uuid_unpack(const uuid_t in, struct uuid *uu) +{ + const uint8_t *ptr = in; + uint32_t tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_low = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_mid = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_hi_and_version = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->clock_seq = tmp; + + memcpy(uu->node, ptr, 6); +} + +static void +uuid_pack(const struct uuid *uu, uuid_t ptr) +{ + uint32_t tmp; + unsigned char *out = ptr; + + tmp = uu->time_low; + out[3] = (unsigned char) tmp; + tmp >>= 8; + out[2] = (unsigned char) tmp; + tmp >>= 8; + out[1] = (unsigned char) tmp; + tmp >>= 8; + out[0] = (unsigned char) tmp; + + tmp = uu->time_mid; + out[5] = (unsigned char) tmp; + tmp >>= 8; + out[4] = (unsigned char) tmp; + + tmp = uu->time_hi_and_version; + out[7] = (unsigned char) tmp; + tmp >>= 8; + out[6] = (unsigned char) tmp; + + tmp = uu->clock_seq; + out[9] = (unsigned char) tmp; + tmp >>= 8; + out[8] = (unsigned char) tmp; + + memcpy(out+10, uu->node, 6); +} + +char* +generate_uuid4() +{ + char *uuid; + uuid_t buf; + uuid_t out; + struct uuid uu; + + LOG_TRACE("generate_uuid enter"); + + uuid = malloc(UUID_STR_LEN); + if (uuid == NULL) { + LOG_ERROR("Could not allocate memory fot uuid (%d bytes)", UUID_STR_LEN); + goto error; + } + + if (cryptopro_gen_random(buf, sizeof(buf))) { + goto error; + } + + uuid_unpack(buf, &uu); + + uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000; + uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000; + + uuid_pack(&uu, out); + + LOG_DEBUG("uuid_type: %d, uuid_variant: %d", uuid_type(out), uuid_variant(out)); + + uuid_unparse(out, uuid); + + LOG_TRACE("generate_uuid exit"); + return uuid; + +error: + free(uuid); + LOG_ERROR("generate_uuid exit with error"); + return NULL; +} diff --git a/src/utils/uuid.h b/src/utils/uuid.h new file mode 100644 index 0000000..290aa43 --- /dev/null +++ b/src/utils/uuid.h @@ -0,0 +1,7 @@ +#ifndef UUID_H_INCLUDED +#define UUID_H_INCLUDED + +// generates uuid version 4 +char* generate_uuid4(); + +#endif // UUID_H_INCLUDED \ No newline at end of file From 919fd8cd7a0a4daaa07fc0fbbe692bf8c231c9f9 Mon Sep 17 00:00:00 2001 From: alashkova Date: Thu, 9 Jan 2025 11:00:39 +0300 Subject: [PATCH 3/6] =?UTF-8?q?SUPPORT-8821.=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20json=5Fwriter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 1 + src/utils/json_writer.c | 48 +++++++++++++++++++++++++++++++++++++++++ src/utils/json_writer.h | 13 +++++++++++ 3 files changed, 62 insertions(+) create mode 100644 src/utils/json_writer.c create mode 100644 src/utils/json_writer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 56bfb6c..3a7e087 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,7 @@ ADD_EXECUTABLE (${PROJECT_NAME} ${UTILS_DIR}/gconf_file.c ${UTILS_DIR}/glib_utils.c ${UTILS_DIR}/json_parser.c + ${UTILS_DIR}/json_writer.c ${UTILS_DIR}/jwt.c ${UTILS_DIR}/library.c ${UTILS_DIR}/logger.c diff --git a/src/utils/json_writer.c b/src/utils/json_writer.c new file mode 100644 index 0000000..e7581d0 --- /dev/null +++ b/src/utils/json_writer.c @@ -0,0 +1,48 @@ +#include "json_writer.h" + +#include "logger.h" + +char * +json_write_to_str(JsonBuilder *builder) +{ + char *out; + + LOG_TRACE("json_write_to_str enter"); + + JsonNode *jnode = json_builder_get_root(builder); + if (jnode == NULL) { + LOG_ERROR("json_builder_get_root failed"); + LOG_ERROR("json_write_to_str exit with error"); + return NULL; + } + + out = json_to_string(jnode, FALSE); + + json_node_unref(jnode); + + LOG_TRACE("json_write_to_str exit"); + return out; +} + +int +json_write_member_string(JsonBuilder *builder, const char *member_name, const char *value) +{ + LOG_TRACE("json_write_member_string enter"); + + if (json_builder_set_member_name(builder, member_name) == NULL) { + LOG_ERROR("json_builder_set_member_name failed"); + goto error; + } + + if (json_builder_add_string_value(builder, value) == NULL) { + LOG_ERROR("json_builder_add_string_value failed"); + goto error; + } + + LOG_TRACE("json_write_member_string exit"); + return 0; + +error: + LOG_ERROR("json_write_member_string exit with error"); + return -1; +} \ No newline at end of file diff --git a/src/utils/json_writer.h b/src/utils/json_writer.h new file mode 100644 index 0000000..29b7b4a --- /dev/null +++ b/src/utils/json_writer.h @@ -0,0 +1,13 @@ +#ifndef JSON_WRITER_H_INCLUDED +#define JSON_WRITER_H_INCLUDED + + +#include + + +char* json_write_to_str(JsonBuilder *builder); + +int json_write_member_string(JsonBuilder *builder, const char *member_name, const char *value); + + +#endif // JSON_WRITER_H_INCLUDED \ No newline at end of file From de5afea941d7b55d216e1f0a07f915e39cd2e879 Mon Sep 17 00:00:00 2001 From: alashkova Date: Thu, 9 Jan 2025 16:32:40 +0300 Subject: [PATCH 4/6] =?UTF-8?q?SUPPORT-8821.=20=D0=93=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20client=5Fsecret,=20=D0=B2=20?= =?UTF-8?q?=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D0=B5=20=D0=B2=D0=BE=D0=B7=D0=B2?= =?UTF-8?q?=D1=80=D0=B0=D1=89=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D0=BF=D0=B8=D1=81=D1=8C=20=D0=B8=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/service_sign.c | 152 ++++++++++++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 21 deletions(-) diff --git a/src/modules/service_sign.c b/src/modules/service_sign.c index 78bf9f7..828c4bb 100644 --- a/src/modules/service_sign.c +++ b/src/modules/service_sign.c @@ -3,6 +3,8 @@ #include "fcgisrv/fcgi_utils.h" #include "utils/cryptopro.h" +#include "utils/json_writer.h" +#include "utils/uuid.h" #define SIGN_CONF_SECTION "sign" #define SIGN_CONF_KEY_LOCATION "location" @@ -10,9 +12,9 @@ #define SIGN_CONF_KEY_SIGN_CERT_PASSWORD "sign_cert_password" #define FCGI_OK_RESPONSE_FORMAT \ - "Content-type: text/plain" CRLF\ + "Content-type: application/json" CRLF\ CRLF\ - "%.*s" CRLF + "%s" CRLF static const str_t SIGN_CONF_DEFAULT_LOCATION = str_t_const("/sign"); @@ -30,7 +32,7 @@ typedef struct fcgi_sign_request_s { char *content; int content_length; - str_t signed_content; + char *response; } fcgi_sign_request_t; @@ -38,7 +40,7 @@ static void fcgi_sign_request_clear(fcgi_sign_request_t *req_info); static fcgi_request_handler_pt fcgi_request_finalize_handler(fcgi_handler_status_t status); -static int sign_content(const sign_service_t *hsign, fcgi_sign_request_t *req_info); +static int sign_client_secret(const sign_service_t *hsign, fcgi_sign_request_t *req_info); int sign_conf_load(sign_conf_t *conf, const conf_file_context_t conf_file) @@ -182,7 +184,7 @@ fcgi_sign_handler(FCGX_Request* request, void* ctx) goto exit; } - if (sign_content(hsign, &req_info)) { + if (sign_client_secret(hsign, &req_info)) { status = HANDLER_ERROR; goto exit; } @@ -204,7 +206,9 @@ fcgi_sign_request_clear(fcgi_sign_request_t *req_info) LOG_TRACE("fcgi_sign_request_clear"); free(req_info->content); - str_t_clear(&(req_info->signed_content)); + free(req_info->response); + + memset(req_info, 0, sizeof(fcgi_sign_request_t)); } static fcgi_handler_status_t @@ -214,11 +218,9 @@ fcgi_ok_handler(const FCGX_Request* request, void *ctx) const fcgi_sign_request_t *req_info = (fcgi_sign_request_t*) ctx; - LOG_DEBUG("response status: " FCGI_OK_RESPONSE_FORMAT, - (int) req_info->signed_content.len, req_info->signed_content.data); - - if (FCGX_FPrintF(request->out, FCGI_OK_RESPONSE_FORMAT, - (int) req_info->signed_content.len, req_info->signed_content.data) < 0) { + LOG_DEBUG("response status: " FCGI_OK_RESPONSE_FORMAT, req_info->response); + + if (FCGX_FPrintF(request->out, FCGI_OK_RESPONSE_FORMAT, req_info->response) < 0) { LOG_ERROR("FCGX_FPrintF() failed"); return HANDLER_ERROR; } @@ -233,10 +235,13 @@ fcgi_request_finalize_handler(fcgi_handler_status_t status) switch (status) { case HANDLER_SUCCESS: - case HANDLER_HTTP_OK: handler = fcgi_ok_handler; break; + case HANDLER_HTTP_OK: + handler = fcgi_200_ok_handler; + break; + case HANDLER_HTTP_BAD_REQUEST: handler = fcgi_400_bad_request_handler; break; @@ -259,23 +264,128 @@ fcgi_request_finalize_handler(fcgi_handler_status_t status) } static int -sign_content(const sign_service_t *hsign, fcgi_sign_request_t *req_info) +generate_client_secret(const fcgi_sign_request_t *req_info, const char *state, + /*out*/ str_t *secret) { - LOG_TRACE("sign_content enter"); + LOG_TRACE("generate_client_secret enter"); - str_t content = { - .data = req_info->content, - .len = req_info->content_length - }; + size_t secret_size = req_info->content_length + strlen(state); - if (cryptopro_sign(&hsign->cryptopro_ctx, &content, &req_info->signed_content)) { + secret->data = malloc(secret_size); + if (secret->data == NULL) { + LOG_ERROR("Could not allocate memory for client_secret (%zd bytes)", secret_size); goto error; } - LOG_TRACE("sign_content exit"); + int len = snprintf(secret->data, secret_size, req_info->content, state); + if (len < 0 || (size_t)len >= secret_size) { + LOG_ERROR("Could not concatenate client_secret"); + goto error; + } + + secret->len = len; + + LOG_TRACE("generate_client_secret exit"); return 0; error: - LOG_ERROR("sign_content exit with error"); + str_t_clear(secret); + LOG_ERROR("generate_client_secret exit with error"); + return -1; +} + +static char * +generate_response(const char *signature, const char *state) +{ + JsonBuilder *jbuilder; + char *response; + + LOG_TRACE("generate_response enter"); + + jbuilder = json_builder_new(); + if (jbuilder == NULL) { + LOG_ERROR("json_builder_new failed"); + goto error; + } + + if (json_builder_begin_object(jbuilder) == NULL) { + LOG_ERROR("json_builder_begin_object failed"); + goto error; + } + + if (json_write_member_string(jbuilder, "signature", signature)) { + goto error; + } + + if (json_write_member_string(jbuilder, "state", state)) { + goto error; + } + + if (json_builder_end_object(jbuilder) == NULL) { + LOG_ERROR("json_builder_end_object failed"); + goto error; + } + + response = json_write_to_str(jbuilder); + + g_object_unref(jbuilder); + + LOG_TRACE("generate_response exit"); + return response; + +error: + if (jbuilder != NULL) { + g_object_unref(jbuilder); + } + LOG_ERROR("generate_response exit with error"); + return NULL; +} + +static int +sign_client_secret(const sign_service_t *hsign, fcgi_sign_request_t *req_info) +{ + str_t secret = str_t_null; + char *state = NULL; + str_t signature = str_t_null; + + LOG_TRACE("sign_client_secret enter"); + + state = generate_uuid4(); + if (state == NULL) { + goto error; + } + + if (generate_client_secret(req_info, state, &secret)) { + goto error; + } + + if (cryptopro_sign(&hsign->cryptopro_ctx, &secret, &signature)) { + goto error; + } + + assert(str_t_is_null_terminated(signature)); + + req_info->response = generate_response(signature.data, state); + + if (req_info->response == NULL) { + goto error; + } + + LOG_DEBUG("state: '%s'", state); + LOG_DEBUG("client secret: '%.*s'", (int) secret.len, secret.data); + LOG_DEBUG("response: '%s'", req_info->response); + + str_t_clear(&secret); + free(state); + str_t_clear(&signature); + + LOG_TRACE("sign_client_secret exit"); + return 0; + +error: + str_t_clear(&secret); + free(state); + str_t_clear(&signature); + LOG_ERROR("sign_client_secret exit with error"); return -1; } \ No newline at end of file From 1ea0ea63295df6ca8e65d90c631b379d77427c64 Mon Sep 17 00:00:00 2001 From: alashkova Date: Fri, 10 Jan 2025 14:45:04 +0300 Subject: [PATCH 5/6] =?UTF-8?q?SUPPORT-8821.=20=D0=9E=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=B4=D0=BE=D0=BA=D0=B5=D1=80=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile.micord | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile.micord b/Dockerfile.micord index 06ebcb9..019607a 100644 --- a/Dockerfile.micord +++ b/Dockerfile.micord @@ -14,7 +14,8 @@ RUN apt-get update \ make \ gcc \ gcc10 \ - libjson-glib libjson-glib-devel + libjson-glib libjson-glib-devel \ + libuuid libuuid-devel WORKDIR /build COPY src src @@ -33,7 +34,7 @@ ENV TZ=Europe/Moscow COPY entrypoint.sh /entrypoint.sh RUN apt-get update \ - && apt-get -y install glib2 libfcgi libjson-glib \ + && apt-get -y install glib2 libfcgi libjson-glib libuuid \ && apt-get clean \ && rm -f /var/cache/apt/*.bin \ && rm -f /var/lib/apt/lists/update* \ From af1b87348e7d34c10ff698f022c9a8c1a7ca866c Mon Sep 17 00:00:00 2001 From: alashkova Date: Fri, 10 Jan 2025 15:30:09 +0300 Subject: [PATCH 6/6] =?UTF-8?q?SUPPORT-8821.=20=D0=9E=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20Readme,=20=D0=98=D0=BD=D1=81?= =?UTF-8?q?=D1=82=D1=80=D1=83=D0=BA=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=20?= =?UTF-8?q?=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B5=20=D0=B8=20=D0=98=D0=BD?= =?UTF-8?q?=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 ++++++++++------ Инструкция по сборке.md | 2 +- Инструкция по установке.md | 9 ++++++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1a7a620..b53ac00 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,9 @@ ### Подпись данных Приложение принимает POST-запрос по протоколу FastCGI (Content-Type: text/plain). -Подписывает строку, полученную в теле запроса. -В ответе возвращает подпись в формате urlSafeBase64 (Content-Type: text/plain). +C помощью аппаратного ДСЧ генерирует state - набор случайных символов, генерируется по стандарту UUID. +В строку, полученную в теле запроса, добавляет state. +В ответе возвращает подпись полученной строки в формате urlSafeBase64 (параметр "signature") и сгенерированный state (параметр "state") (Content-Type: application/json). Пример выполнения запроса: ``` @@ -24,12 +25,15 @@ $ curl -v http://127.0.0.1:8080/sign -H "Content-Type: text/plain" -d "test" > < HTTP/1.1 200 OK < Server: nginx/1.24.0 -< Date: Fri, 16 Aug 2024 07:33:13 GMT -< Content-Type: text/plain +< Date: Tue, 20 Aug 2024 12:00:25 GMT +< Content-Type: application/json < Transfer-Encoding: chunked < Connection: keep-alive -< -urlSafeBase64_of_signed_string_test +< +{ + "signature": "urlSafeBase64_of_signed_string_test_with_state", + "state": "7c327cb7-7916-4255-bc46-85fbc5ad7d5f" +} ``` ### Проверка подписи маркера доступа diff --git a/Инструкция по сборке.md b/Инструкция по сборке.md index 5b320af..591924f 100644 --- a/Инструкция по сборке.md +++ b/Инструкция по сборке.md @@ -18,7 +18,7 @@ cd - 1. Установить зависимости для сборки приложения: ``` bash apt-get install cmake gcc gcc10 -apt-get install glib2-devel libfcgi-devel libjson-glib libjson-glib-devel +apt-get install glib2-devel libfcgi-devel libjson-glib libjson-glib-devel libuuid libuuid-devel ``` 2. Собрать приложение из исходников: diff --git a/Инструкция по установке.md b/Инструкция по установке.md index 8e3390c..96e93d8 100644 --- a/Инструкция по установке.md +++ b/Инструкция по установке.md @@ -157,7 +157,7 @@ systemctl start nginx 1. Установить зависимости для запуска приложения: ``` bash -apt-get install glib2 libfcgi libjson-glib +apt-get install glib2 libfcgi libjson-glib libuuid ``` 2. Скопировать исполняемый файл: @@ -207,11 +207,14 @@ curl -v http://127.0.0.1/sign -H "Content-Type: text/plain" -d "test" < HTTP/1.1 200 OK < Server: nginx/1.24.0 < Date: Tue, 20 Aug 2024 12:00:25 GMT -< Content-Type: text/plain +< Content-Type: application/json < Transfer-Encoding: chunked < Connection: keep-alive < -REFlyzGQrCjX9DvA7hWwN9vf5kPqBxcG4TLYnXUHnAS9_G-sLAFvaJei2OhxpaWNraHbOv_mMsM_bcDsXWiC0Q +{ + "signature": "urlSafeBase64_of_signed_string_test_with_state", + "state": "7c327cb7-7916-4255-bc46-85fbc5ad7d5f" +} * Connection #0 to host 127.0.0.1 left intact ```