diff --git a/CMakeLists.txt b/CMakeLists.txt index d598d3c..0d58f77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,6 +125,7 @@ ADD_EXECUTABLE (${PROJECT_NAME} ${UTILS_DIR}/jwt.c ${UTILS_DIR}/library.c ${UTILS_DIR}/logger.c + ${UTILS_DIR}/response_builder.c ${UTILS_DIR}/str_t.c ${UTILS_DIR}/timer.c ${UTILS_DIR}/uuid.c diff --git a/README.md b/README.md index 7b5c8a7..1d303c7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ - подпись данных - проверка подписи маркера доступа -### Подпись данных +## Подпись данных Приложение принимает POST-запрос по протоколу FastCGI (Content-Type: text/plain). C помощью ДСЧ генерирует state - набор случайных символов, генерируется по стандарту UUID. @@ -36,14 +36,14 @@ $ /opt/cprocsp/bin/amd64/curl -v http://127.0.0.1/sign -H "Content-Type: text/pl } ``` -### Проверка подписи маркера доступа +## Проверка подписи маркера доступа Приложение принимает POST-запрос по протоколу FastCGI (Content-Type: text/plain). Проверяет подпись маркера доступа, полученного в теле запроса. В ответе возвращает один из следующих статус-кодов: -- 200 OK - подпись валидна -- 401 Unauthorized - подпись невалидна (в теле ответа возвращается код ошибки от криптопровайдера) -- 500 Internal Server Error - внутренняя ошибка сервера +- `200 OK`- подпись валидна +- `401 Unauthorized` - подпись невалидна (в теле ответа возвращается код ошибки от криптопровайдера) +- `500 Internal Server Error` - внутренняя ошибка сервера (подробнее см. в `Обработка ошибок`) Пример выполнения запроса: ``` @@ -65,6 +65,24 @@ $ /opt/cprocsp/bin/amd64/curl -v http://127.0.0.1/verify -H "Content-Type: text/ < ``` +## Обработка ошибок + +В случае ошибки сервер возвращает ответ со статус-кодом `500 Internal Server Error` и телом в формате JSON, содержащим поле `error_code`. +Пример ответа: +```json +{ + "error_code": "CERT_TRUST_REVOCATION_STATUS_UNKNOWN" +} +``` + +### Возможные коды ошибок (`error_code`) + +| Код | Описание | +|-----------------------------------------|----------| +| `CERT_TRUST_REVOCATION_STATUS_UNKNOWN` | Неизвестен статус отзыва сертификата или одного из сертификатов в цепочке (проблема с CRL) | +| `CERT_TRUST_IS_UNTRUSTED_ROOT` | Сертификат или цепочка сертификатов основана на ненадежном корневом сертификате | +| `CERT_TRUST_IS_NOT_TIME_VALID` | Этот сертификат или один из сертификатов в цепочке сертификатов является недопустимым по времени | + ## Сборка из исходников Инструкции по сборке из исходников см. "Инструкция по сборке.md" @@ -116,5 +134,3 @@ export SIGN_LOG_TIME=on ``` unset SIGN_LOG_TIME ``` - - diff --git a/src/fcgisrv/fcgi_utils.c b/src/fcgisrv/fcgi_utils.c index 64ab5b3..95a1654 100644 --- a/src/fcgisrv/fcgi_utils.c +++ b/src/fcgisrv/fcgi_utils.c @@ -1,9 +1,11 @@ #include "fcgi_server_internal.h" #include "utils/logger.h" +#include "utils/response_builder.h" #include + int fcgi_get_content_length(const FCGX_Request* request) { @@ -161,3 +163,31 @@ fcgi_printf_header(const FCGX_Request* request, const char* name, const char* va return HANDLER_SUCCESS; } + +fcgi_handler_status_t +fcgi_500_internal_server_error_handler(const FCGX_Request* request, const char *error_code) +{ + LOG_TRACE("fcgi_500_internal_server_error_handler"); + + char *response = build_response_from_error_code(error_code); + if (response == NULL) { + goto error; + } + + LOG_DEBUG("response status: " FCGI_500_RESPONSE_FORMAT, response); + + if (FCGX_FPrintF(request->out, FCGI_500_RESPONSE_FORMAT, response) < 0) { + LOG_ERROR("FCGX_FPrintF() failed"); + goto error; + } + + fcgi_print_log(request, "500 Internal Server Error"); + + free(response); + return HANDLER_SUCCESS; + +error: + free(response); + LOG_ERROR("fcgi_500_internal_server_error_handler exit with error"); + return HANDLER_ERROR; +} diff --git a/src/fcgisrv/fcgi_utils.h b/src/fcgisrv/fcgi_utils.h index 080531b..a7e195f 100644 --- a/src/fcgisrv/fcgi_utils.h +++ b/src/fcgisrv/fcgi_utils.h @@ -131,9 +131,9 @@ fcgi_printf_header(const FCGX_Request* request, const char* name, const char* va #define FCGI_500_RESPONSE_FORMAT \ "Status: 500 Internal Server Error" CRLF\ - "Content-type: text/plain" CRLF\ + "Content-type: application/json" CRLF\ CRLF\ - "500 Internal Server Error" CRLF + "%s" CRLF @@ -213,12 +213,8 @@ fcgi_413_request_entity_too_large_handler(const FCGX_Request* request, void* ctx } -static inline fcgi_handler_status_t -fcgi_500_internal_server_error_handler(const FCGX_Request* request, void* ctx __attribute__((unused))) -{ - fcgi_print_log(request, "500 Internal Server Error"); - return FCGI_CHECK_PRINTF_STATUS(request, FCGI_500_RESPONSE_FORMAT, 500); -} +fcgi_handler_status_t +fcgi_500_internal_server_error_handler(const FCGX_Request* request, const char *error_code); /******************************************************************************/ diff --git a/src/modules/service_sign.c b/src/modules/service_sign.c index e887d4c..32e8ea9 100644 --- a/src/modules/service_sign.c +++ b/src/modules/service_sign.c @@ -3,9 +3,9 @@ #include "fcgisrv/fcgi_utils.h" #include "utils/cryptopro.h" -#include "utils/json_writer.h" #include "utils/timer.h" #include "utils/uuid.h" +#include "utils/response_builder.h" #define SIGN_CONF_SECTION "sign" #define SIGN_CONF_KEY_LOCATION "location" @@ -17,6 +17,7 @@ CRLF\ "%s" CRLF + static const str_t SIGN_CONF_DEFAULT_LOCATION = str_t_const("/sign"); static const int CLIENT_MAX_BODY_SIZE = 4096; @@ -36,12 +37,15 @@ typedef struct fcgi_sign_request_s { int content_length; char *response; + const char *error_code; } fcgi_sign_request_t; 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 fcgi_handler_status_t fcgi_request_finalize(const FCGX_Request* request, + fcgi_sign_request_t *req_info, + fcgi_handler_status_t status); static int sign_content_with_state(const sign_service_t *hsign, fcgi_sign_request_t *req_info); @@ -212,7 +216,7 @@ fcgi_sign_handler(FCGX_Request* request, void* ctx) // status = HANDLER_SUCCESS; exit: - status = fcgi_request_finalize_handler(status)(request, &req_info); + status = fcgi_request_finalize(request, &req_info, status); fcgi_sign_request_clear(&req_info); @@ -235,12 +239,10 @@ fcgi_sign_request_clear(fcgi_sign_request_t *req_info) } static fcgi_handler_status_t -fcgi_ok_handler(const FCGX_Request* request, void *ctx) +fcgi_ok_handler(const FCGX_Request* request, const fcgi_sign_request_t *req_info) { LOG_TRACE("fcgi_ok_handler"); - const fcgi_sign_request_t *req_info = (fcgi_sign_request_t*) ctx; - LOG_DEBUG("response status: " FCGI_OK_RESPONSE_FORMAT, req_info->response); if (FCGX_FPrintF(request->out, FCGI_OK_RESPONSE_FORMAT, req_info->response) < 0) { @@ -251,39 +253,32 @@ fcgi_ok_handler(const FCGX_Request* request, void *ctx) return HANDLER_SUCCESS; } -static fcgi_request_handler_pt -fcgi_request_finalize_handler(fcgi_handler_status_t status) +static fcgi_handler_status_t +fcgi_request_finalize(const FCGX_Request* request, fcgi_sign_request_t *req_info, + fcgi_handler_status_t status) { - fcgi_request_handler_pt handler; - switch (status) { case HANDLER_SUCCESS: - handler = fcgi_ok_handler; - break; + return fcgi_ok_handler(request, req_info); case HANDLER_HTTP_OK: - handler = fcgi_200_ok_handler; - break; + return fcgi_200_ok_handler(request, req_info); case HANDLER_HTTP_BAD_REQUEST: - handler = fcgi_400_bad_request_handler; - break; + return fcgi_400_bad_request_handler(request, req_info); case HANDLER_HTTP_NOT_ACCEPTABLE: - handler = fcgi_406_not_acceptable_handler; - break; + return fcgi_406_not_acceptable_handler(request, req_info); case HANDLER_HTTP_REQUEST_ENTITY_TOO_LARGE: - handler = fcgi_413_request_entity_too_large_handler; - break; + return fcgi_413_request_entity_too_large_handler(request, req_info); case HANDLER_ERROR: default: - handler = fcgi_500_internal_server_error_handler; break; } - return handler; + return fcgi_500_internal_server_error_handler(request, req_info->error_code); } static int @@ -318,52 +313,7 @@ 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_content_with_state(const sign_service_t *hsign, fcgi_sign_request_t *req_info) @@ -383,13 +333,14 @@ sign_content_with_state(const sign_service_t *hsign, fcgi_sign_request_t *req_in goto error; } - if (cryptopro_sign(&hsign->cryptopro_ctx, &content_state, &signature)) { + if (cryptopro_sign(&hsign->cryptopro_ctx, &content_state, &signature, &req_info->error_code)) { goto error; } assert(str_t_is_null_terminated(signature)); + assert(req_info->error_code == NULL); - req_info->response = generate_response(signature.data, state); + req_info->response = build_response_from_signature(signature.data, state); if (req_info->response == NULL) { goto error; diff --git a/src/modules/service_verify.c b/src/modules/service_verify.c index 3316dc1..1e242f4 100644 --- a/src/modules/service_verify.c +++ b/src/modules/service_verify.c @@ -37,12 +37,15 @@ typedef struct fcgi_verify_request_s { char *content; int content_length; - char *verify_error; + char *verify_error; // клиентская ошибка (подпись невалидна) - статус 401 + const char *error_code; // серверная ошибка - статус 500 } fcgi_verify_request_t; -static fcgi_request_handler_pt fcgi_request_finalize_handler(fcgi_handler_status_t status); +static fcgi_handler_status_t fcgi_request_finalize(const FCGX_Request* request, + fcgi_verify_request_t *req_info, + fcgi_handler_status_t status); static void fcgi_verify_request_clear(fcgi_verify_request_t *req_info); static fcgi_handler_status_t verify_jwt_sign(fcgi_verify_request_t* req_info, verify_service_t *ctx); @@ -180,7 +183,7 @@ fcgi_verify_handler(FCGX_Request* request, void* ctx) status = verify_jwt_sign(&req_info, ctx); exit: - status = fcgi_request_finalize_handler(status)(request, &req_info); + status = fcgi_request_finalize(request, &req_info, status); fcgi_verify_request_clear(&req_info); @@ -211,40 +214,33 @@ fcgi_401_bad_signature_handler(const FCGX_Request* request, void *ctx) return HANDLER_SUCCESS; } -static fcgi_request_handler_pt -fcgi_request_finalize_handler(fcgi_handler_status_t status) +static fcgi_handler_status_t +fcgi_request_finalize(const FCGX_Request* request, fcgi_verify_request_t *req_info, + fcgi_handler_status_t status) { - fcgi_request_handler_pt handler; - switch (status) { case HANDLER_SUCCESS: case HANDLER_HTTP_OK: - handler = fcgi_200_ok_handler; - break; + return fcgi_200_ok_handler(request, req_info); case HANDLER_HTTP_BAD_REQUEST: - handler = fcgi_400_bad_request_handler; - break; + return fcgi_400_bad_request_handler(request, req_info); case HANDLER_HTTP_UNAUTHORIZED: - handler = fcgi_401_bad_signature_handler; - break; + return fcgi_401_bad_signature_handler(request, req_info); case HANDLER_HTTP_NOT_ACCEPTABLE: - handler = fcgi_406_not_acceptable_handler; - break; + return fcgi_406_not_acceptable_handler(request, req_info); case HANDLER_HTTP_REQUEST_ENTITY_TOO_LARGE: - handler = fcgi_413_request_entity_too_large_handler; - break; + return fcgi_413_request_entity_too_large_handler(request, req_info); case HANDLER_ERROR: default: - handler = fcgi_500_internal_server_error_handler; break; } - return handler; + return fcgi_500_internal_server_error_handler(request, req_info->error_code); } static void @@ -259,9 +255,10 @@ fcgi_verify_request_clear(fcgi_verify_request_t *req_info) } static int -verify_sign_using_thumbprint_list(cryptopro_context_t *ctx, const string_list_t* thumbprint_list, +verify_sign_using_thumbprint_list(cryptopro_context_t* ctx, 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) + const str_t* sign, bool* is_verified, char** verify_error, + const char** error_code) { int rc = -1; @@ -278,7 +275,7 @@ verify_sign_using_thumbprint_list(cryptopro_context_t *ctx, const string_list_t* ctx->cert_thumbprint = &thumbprint; - rc = cryptopro_verify(ctx, alg, header_payload, sign, is_verified, verify_error); + rc = cryptopro_verify(ctx, alg, header_payload, sign, is_verified, verify_error, error_code); if (rc) { LOG_ERROR("cryptopro_verify() failed for cert with thumbprint '%s'", cert_thumbprint); } @@ -347,7 +344,7 @@ verify_jwt_sign(fcgi_verify_request_t* req_info, verify_service_t *ctx) if (verify_sign_using_thumbprint_list(&ctx->cryptopro_ctx, &ctx->conf->esia_cert_thumbprint_list, &alg, &header_payload, &sign, &is_verified, - &req_info->verify_error)) { + &req_info->verify_error, &req_info->error_code)) { goto error; } diff --git a/src/utils/cryptopro.c b/src/utils/cryptopro.c index 5d183fd..cfbba5d 100644 --- a/src/utils/cryptopro.c +++ b/src/utils/cryptopro.c @@ -5,11 +5,15 @@ #include "library.h" #include "logger.h" +static const char* CERT_TRUST_IS_UNTRUSTED_ROOT_ERR_CODE = "CERT_TRUST_IS_UNTRUSTED_ROOT"; +static const char* CERT_TRUST_REVOCATION_STATUS_UNKNOWN_ERR_CODE = "CERT_TRUST_REVOCATION_STATUS_UNKNOWN"; +static const char* CERT_TRUST_IS_NOT_TIME_VALID_ERR_CODE = "CERT_TRUST_IS_NOT_TIME_VALID"; static capi_function_list_t cp_function_list; static library_t libcapi; -static int sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign); +static int sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, + /*out*/ str_t *sign, /*out*/ const char **error_code); static int reverse_sign(const str_t *sign, /*out*/ str_t *sign_reversed); @@ -38,7 +42,8 @@ cryptopro_init(const char* cp_file) } int -cryptopro_sign(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign) +cryptopro_sign(const cryptopro_context_t *ctx, const str_t *data, + /*out*/ str_t *sign, /*out*/ const char **error_code) { str_t signed_data = str_t_null; str_t sign_reversed = str_t_null; @@ -51,7 +56,7 @@ cryptopro_sign(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t assert(data != NULL && !str_t_is_null(*data)); assert(sign != NULL); - if (sign_hash_data(ctx, data, &signed_data)) { + if (sign_hash_data(ctx, data, &signed_data, error_code)) { goto error; } @@ -94,8 +99,38 @@ free_cert_chain(PCCERT_CHAIN_CONTEXT chain_ctx) LOG_TRACE("free_cert_chain exit"); } +static void +process_trust_status_error(DWORD status, /*out*/ const char **error_code) +{ + LOG_TRACE("process_trust_status_error enter"); + + switch (status) { + case CERT_TRUST_REVOCATION_STATUS_UNKNOWN: + *error_code = CERT_TRUST_REVOCATION_STATUS_UNKNOWN_ERR_CODE; + break; + case CERT_TRUST_IS_UNTRUSTED_ROOT: + *error_code = CERT_TRUST_IS_UNTRUSTED_ROOT_ERR_CODE; + break; + case CERT_TRUST_IS_NOT_TIME_VALID: + *error_code = CERT_TRUST_IS_NOT_TIME_VALID_ERR_CODE; + break; + default: + *error_code = NULL; + break; + } + + if (*error_code) { + LOG_WARN("The certificate is not trusted. CERT_TRUST_STATUS: '0x%08x' (%s)", + status, *error_code); + } else { + LOG_WARN("The certificate is not trusted. CERT_TRUST_STATUS: '0x%08x'", status); + } + + LOG_TRACE("process_trust_status_error exit"); +} + static PCCERT_CHAIN_CONTEXT -get_cert_chain(PCCERT_CONTEXT certificate) +get_cert_chain(PCCERT_CONTEXT certificate, /*out*/ const char **error_code) { LOG_TRACE("get_cert_chain enter"); @@ -118,8 +153,7 @@ get_cert_chain(PCCERT_CONTEXT certificate) } if (chain_ctx->TrustStatus.dwErrorStatus) { - LOG_WARN("The certificate is not trusted. CERT_TRUST_STATUS: '0x%08x'", - chain_ctx->TrustStatus.dwErrorStatus); + process_trust_status_error(chain_ctx->TrustStatus.dwErrorStatus, error_code); goto error; } @@ -180,7 +214,7 @@ exit: } static bool -verify_cert_chain(PCCERT_CONTEXT certificate, timer_context_t *timer_ctx) +verify_cert_chain(PCCERT_CONTEXT certificate, timer_context_t *timer_ctx, /*out*/ const char **error_code) { bool is_verified = false; @@ -188,7 +222,7 @@ verify_cert_chain(PCCERT_CONTEXT certificate, timer_context_t *timer_ctx) timer_on_get_cert_chain_enter(timer_ctx); - PCCERT_CHAIN_CONTEXT chain_ctx = get_cert_chain(certificate); + PCCERT_CHAIN_CONTEXT chain_ctx = get_cert_chain(certificate, error_code); if (chain_ctx == NULL) { goto exit; } @@ -310,7 +344,7 @@ log_sign_hash_data_last_error() } static int -sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign) +sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign, /*out*/ const char **error_code) { int rc = -1; BOOL bReleaseContext = FALSE; @@ -321,7 +355,7 @@ sign_hash_data(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t timer_on_verify_cert_chain_enter(ctx->timer_ctx); - if (!verify_cert_chain(ctx->signer_cert, ctx->timer_ctx)) { + if (!verify_cert_chain(ctx->signer_cert, ctx->timer_ctx, error_code)) { goto exit; } @@ -673,8 +707,8 @@ get_verify_error(char** verify_error) } int -cryptopro_verify(cryptopro_context_t *ctx, const str_t* alg, const str_t* data, - const str_t* sign, bool* is_verified, char** verify_error) +cryptopro_verify(cryptopro_context_t* ctx, const str_t* alg, const str_t* data, + const str_t* sign, bool* is_verified, char** verify_error, const char** error_code) { int rc = -1; HCERTSTORE hStoreHandle = NULL; @@ -711,7 +745,7 @@ cryptopro_verify(cryptopro_context_t *ctx, const str_t* alg, const str_t* data, timer_on_verify_cert_chain_enter(ctx->timer_ctx); - if (!verify_cert_chain(certificate, ctx->timer_ctx)) { + if (!verify_cert_chain(certificate, ctx->timer_ctx, error_code)) { goto exit; } diff --git a/src/utils/cryptopro.h b/src/utils/cryptopro.h index 6a318c4..2921f54 100644 --- a/src/utils/cryptopro.h +++ b/src/utils/cryptopro.h @@ -41,10 +41,12 @@ 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_sign(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign, + /*out*/ const char **error_code); -int cryptopro_verify(cryptopro_context_t *сtx, const str_t* alg, const str_t *data, - const str_t *sign, bool* is_verified, char** verify_error); +int cryptopro_verify(cryptopro_context_t* ctx, const str_t* alg, const str_t* data, + const str_t* sign, bool* is_verified, char** verify_error, + const char** error_code); int cryptopro_gen_random(const cryptopro_context_t *ctx, unsigned char* data, size_t len); diff --git a/src/utils/response_builder.c b/src/utils/response_builder.c new file mode 100644 index 0000000..1a932b9 --- /dev/null +++ b/src/utils/response_builder.c @@ -0,0 +1,100 @@ +#include "response_builder.h" + +#include "utils/json_writer.h" +#include "utils/logger.h" + +static const char* DEFAULT_ERROR_CODE = "INTERNAL_ERROR"; + +char * +build_response_from_error_code(const char *error_code) +{ + JsonBuilder *jbuilder; + char *response; + + LOG_TRACE("build_response_from_error_code enter"); + + if (error_code == NULL) { + error_code = DEFAULT_ERROR_CODE; + } + + jbuilder = json_builder_new(); + if (jbuilder == NULL) { + LOG_ERROR("build_response_from_error_code. json_builder_new failed"); + goto error; + } + + if (json_builder_begin_object(jbuilder) == NULL) { + LOG_ERROR("build_response_from_error_code. json_builder_begin_object failed"); + goto error; + } + + if (json_write_member_string(jbuilder, "error_code", error_code)) { + goto error; + } + + if (json_builder_end_object(jbuilder) == NULL) { + LOG_ERROR("build_response_from_error_code. json_builder_end_object failed"); + goto error; + } + + response = json_write_to_str(jbuilder); + + g_object_unref(jbuilder); + + LOG_TRACE("build_response_from_error_code exit"); + return response; + +error: + if (jbuilder != NULL) { + g_object_unref(jbuilder); + } + LOG_ERROR("build_response_from_error_code exit with error"); + return NULL; +} + +char * +build_response_from_signature(const char *signature, const char *state) +{ + JsonBuilder *jbuilder; + char *response; + + LOG_TRACE("build_response_from_signature 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("build_response_from_signature exit"); + return response; + +error: + if (jbuilder != NULL) { + g_object_unref(jbuilder); + } + LOG_ERROR("build_response_from_signature exit with error"); + return NULL; +} diff --git a/src/utils/response_builder.h b/src/utils/response_builder.h new file mode 100644 index 0000000..1dd8dc1 --- /dev/null +++ b/src/utils/response_builder.h @@ -0,0 +1,14 @@ +#ifndef RESPONSE_BUILDER_H_INCLUDED +#define RESPONSE_BUILDER_H_INCLUDED + + +/* common functions */ + +char * build_response_from_error_code(const char *error_code); + +/* functions for sign service */ + +char * build_response_from_signature(const char *signature, const char *state); + + +#endif // RESPONSE_BUILDER_H_INCLUDED diff --git a/src/utils/timer.c b/src/utils/timer.c index c2fb2bc..667d785 100644 --- a/src/utils/timer.c +++ b/src/utils/timer.c @@ -11,10 +11,10 @@ init_timers(timer_context_t *ctx) { const char* slt = getenv(ENV_SIGN_LOG_TIME); if (slt != NULL) { - LOG_INFO("environment variable '" ENV_SIGN_LOG_TIME "'='%s' -> timings logging: ON", slt); + LOG_DEBUG("environment variable '" ENV_SIGN_LOG_TIME "'='%s' -> timings logging: ON", slt); ctx->is_timer_on = true; } else { - LOG_INFO("environment variable '" ENV_SIGN_LOG_TIME "' does not exist " + LOG_DEBUG("environment variable '" ENV_SIGN_LOG_TIME "' does not exist " "-> timings logging: OFF"); ctx->is_timer_on = false; }