From 1c99d4016c70e06a6970db807605af6e7976ca18 Mon Sep 17 00:00:00 2001 From: alashkova Date: Fri, 18 Oct 2024 16:27:41 +0300 Subject: [PATCH] =?UTF-8?q?SUPPORT-8592.=20=D0=A0=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=20=D1=81=20jwt-=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=D0=BC=D0=B8=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=B2=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D1=84=D0=B0=D0=B9=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 1 + src/modules/service_verify.c | 75 ++---------------------------------- src/utils/jwt.c | 75 ++++++++++++++++++++++++++++++++++++ src/utils/jwt.h | 13 +++++++ 4 files changed, 92 insertions(+), 72 deletions(-) create mode 100644 src/utils/jwt.c create mode 100644 src/utils/jwt.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c9fecbb..50d447c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,6 +112,7 @@ ADD_EXECUTABLE (${PROJECT_NAME} ${UTILS_DIR}/gconf_file.c ${UTILS_DIR}/glib_utils.c ${UTILS_DIR}/json_parser.c + ${UTILS_DIR}/jwt.c ${UTILS_DIR}/library.c ${UTILS_DIR}/logger.c ${UTILS_DIR}/str_t.c diff --git a/src/modules/service_verify.c b/src/modules/service_verify.c index b6d7a6b..fd82789 100644 --- a/src/modules/service_verify.c +++ b/src/modules/service_verify.c @@ -4,7 +4,7 @@ #include "utils/base64.h" #include "utils/cryptopro.h" -#include "utils/json_parser.h" +#include "utils/jwt.h" #define VERIFY_CONF_SECTION "verify" @@ -22,8 +22,6 @@ static const str_t VERIFY_CONF_DEFAULT_LOCATION = str_t_const("/verify"); static const int CLIENT_MAX_BODY_SIZE = 8192; static const char* ACCEPTABLE_CONTENT_TYPE = "text/plain"; -static const char* JWT_ALG_FIELD_NAME = "alg"; - typedef struct verify_service_s { const verify_conf_t *conf; @@ -240,73 +238,6 @@ fcgi_verify_request_clear(fcgi_verify_request_t *req_info) memset(req_info, 0, sizeof(fcgi_verify_request_t)); } -static int -get_jwt_header_payload_and_sign(const str_t *jwt, - /*out*/ str_t *header, - /*out*/ str_t *header_payload, - /*out*/ str_t *sign) -{ - LOG_TRACE("get_jwt_header_payload_and_sign enter"); - - size_t p_start = 0, p_end = 0; - - for (size_t i = 0; i < jwt->len; i++) { - if (jwt->data[i] == '.') { - if (p_start == 0) { - p_start = i + 1; - } else { - p_end = i; - break; - } - } - } - - if (p_start == 0 || p_end == 0) { - LOG_ERROR("Could not parse jwt. p_start = %zd, p_end = %zd", p_start, p_end); - return -1; - } - - header->data = (char*)jwt->data; - header->len = p_start - 1; - - header_payload->data = (char*)jwt->data; - header_payload->len = p_end; - - sign->data = (char*)jwt->data + p_end + 1; - sign->len = jwt->len - p_end - 1; - - LOG_DEBUG("header: %.*s", (int) header->len, header->data); - LOG_DEBUG("header_payload: %.*s", (int) header_payload->len, header_payload->data); - LOG_DEBUG("sign: %.*s", (int) sign->len, sign->data); - - LOG_TRACE("get_jwt_header_payload_and_sign exit"); - - return 0; -} - -static int -get_alg_from_header(const str_t *header, /*out*/ str_t *alg) -{ - LOG_TRACE("get_alg_from_header"); - - Hjson_parser parser = json_parser_create(header->data, header->len); - if (parser == NULL) { - goto error; - } - - if (json_get_string_member(parser, JWT_ALG_FIELD_NAME, alg)) { - goto error; - } - - json_parser_free(parser); - return 0; - -error: - json_parser_free(parser); - LOG_ERROR("get_alg_from_header exit with error"); - return -1; -} - static fcgi_handler_status_t verify_jwt_sign(fcgi_verify_request_t* req_info, const verify_service_t *ctx) { @@ -325,7 +256,7 @@ verify_jwt_sign(fcgi_verify_request_t* req_info, const verify_service_t *ctx) str_t header_payload = str_t_null; str_t alg = str_t_null; - if (get_jwt_header_payload_and_sign(&jwt, &header_base64, &header_payload, &sign_base64)) { + if (jwt_get_header_payload_and_sign(&jwt, &header_base64, &header_payload, &sign_base64)) { goto error; } @@ -351,7 +282,7 @@ verify_jwt_sign(fcgi_verify_request_t* req_info, const verify_service_t *ctx) goto error; } - if (get_alg_from_header(&header, &alg)) { + if (jwt_get_alg_from_header(&header, &alg)) { goto error; } diff --git a/src/utils/jwt.c b/src/utils/jwt.c new file mode 100644 index 0000000..91ae4b7 --- /dev/null +++ b/src/utils/jwt.c @@ -0,0 +1,75 @@ +#include "jwt.h" + +#include "json_parser.h" +#include "logger.h" + +#define JWT_ALG_FIELD_NAME "alg" + +int +jwt_get_header_payload_and_sign(const str_t *jwt, + /*out*/ str_t *header, + /*out*/ str_t *header_payload, + /*out*/ str_t *sign) +{ + LOG_TRACE("jwt_get_header_payload_and_sign enter"); + + size_t p_start = 0, p_end = 0; + + for (size_t i = 0; i < jwt->len; i++) { + if (jwt->data[i] == '.') { + if (p_start == 0) { + p_start = i + 1; + } else { + p_end = i; + break; + } + } + } + + if (p_start == 0 || p_end == 0) { + LOG_ERROR("Could not parse jwt. p_start = %zd, p_end = %zd", p_start, p_end); + return -1; + } + + header->data = (char*)jwt->data; + header->len = p_start - 1; + + header_payload->data = (char*)jwt->data; + header_payload->len = p_end; + + sign->data = (char*)jwt->data + p_end + 1; + sign->len = jwt->len - p_end - 1; + + LOG_DEBUG("header: %.*s", (int) header->len, header->data); + LOG_DEBUG("header_payload: %.*s", (int) header_payload->len, header_payload->data); + LOG_DEBUG("sign: %.*s", (int) sign->len, sign->data); + + LOG_TRACE("jwt_get_header_payload_and_sign exit"); + + return 0; +} + +int +jwt_get_alg_from_header(const str_t *header, /*out*/ str_t *alg) +{ + LOG_TRACE("jwt_get_alg_from_header enter"); + + Hjson_parser parser = json_parser_create(header->data, header->len); + if (parser == NULL) { + goto error; + } + + if (json_get_string_member(parser, JWT_ALG_FIELD_NAME, alg)) { + goto error; + } + + json_parser_free(parser); + + LOG_TRACE("jwt_get_alg_from_header exit"); + return 0; + +error: + json_parser_free(parser); + LOG_ERROR("jwt_get_alg_from_header exit with error"); + return -1; +} diff --git a/src/utils/jwt.h b/src/utils/jwt.h new file mode 100644 index 0000000..f268849 --- /dev/null +++ b/src/utils/jwt.h @@ -0,0 +1,13 @@ +#ifndef JWT_H_INCLUDED +#define JWT_H_INCLUDED + +#include "str_t.h" + +int jwt_get_header_payload_and_sign(const str_t *jwt, + /*out*/ str_t *header, + /*out*/ str_t *header_payload, + /*out*/ str_t *sign); + +int jwt_get_alg_from_header(const str_t *header, /*out*/ str_t *alg); + +#endif // JWT_H_INCLUDED \ No newline at end of file