SUPPORT-8592. В случае неверной подписи в ответе передается код ошибки от криптопро
This commit is contained in:
parent
2f2a6efd89
commit
f95975719f
3 changed files with 71 additions and 14 deletions
|
|
@ -11,6 +11,12 @@
|
|||
#define VERIFY_CONF_KEY_LOCATION "location"
|
||||
#define VERIFY_CONF_KEY_THUMBPRINT "esia_cert_thumbprint"
|
||||
|
||||
#define FCGI_401_BAD_SIGNATURE_RESPONSE_FORMAT \
|
||||
"Status: 401 Unauthorized" CRLF\
|
||||
"Content-type: text/plain" CRLF\
|
||||
CRLF\
|
||||
"%s" CRLF
|
||||
|
||||
static const str_t VERIFY_CONF_DEFAULT_LOCATION = str_t_const("/verify");
|
||||
|
||||
static const int CLIENT_MAX_BODY_SIZE = 8192;
|
||||
|
|
@ -29,12 +35,14 @@ typedef struct fcgi_verify_request_s {
|
|||
char *content;
|
||||
int content_length;
|
||||
|
||||
char *verify_error;
|
||||
|
||||
} fcgi_verify_request_t;
|
||||
|
||||
|
||||
static fcgi_request_handler_pt fcgi_request_finalize_handler(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(const fcgi_verify_request_t* req_info,
|
||||
static fcgi_handler_status_t verify_jwt_sign(fcgi_verify_request_t* req_info,
|
||||
const verify_service_t *ctx);
|
||||
|
||||
|
||||
|
|
@ -156,7 +164,7 @@ fcgi_verify_handler(FCGX_Request* request, void* ctx)
|
|||
status = verify_jwt_sign(&req_info, ctx);
|
||||
|
||||
exit:
|
||||
status = fcgi_request_finalize_handler(status)(request, ctx);
|
||||
status = fcgi_request_finalize_handler(status)(request, &req_info);
|
||||
|
||||
fcgi_verify_request_clear(&req_info);
|
||||
|
||||
|
|
@ -164,6 +172,27 @@ exit:
|
|||
return status;
|
||||
}
|
||||
|
||||
static fcgi_handler_status_t
|
||||
fcgi_401_bad_signature_handler(const FCGX_Request* request, void *ctx)
|
||||
{
|
||||
LOG_TRACE("fcgi_401_bad_signature_handler");
|
||||
|
||||
const fcgi_verify_request_t *req_info = (fcgi_verify_request_t*) ctx;
|
||||
|
||||
assert(req_info->verify_error != NULL);
|
||||
|
||||
LOG_DEBUG("response status: " FCGI_401_BAD_SIGNATURE_RESPONSE_FORMAT,
|
||||
req_info->verify_error);
|
||||
|
||||
if (FCGX_FPrintF(request->out, FCGI_401_BAD_SIGNATURE_RESPONSE_FORMAT,
|
||||
req_info->verify_error) < 0) {
|
||||
LOG_ERROR("FCGX_FPrintF() failed");
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
return HANDLER_SUCCESS;
|
||||
}
|
||||
|
||||
static fcgi_request_handler_pt
|
||||
fcgi_request_finalize_handler(fcgi_handler_status_t status)
|
||||
{
|
||||
|
|
@ -180,7 +209,7 @@ fcgi_request_finalize_handler(fcgi_handler_status_t status)
|
|||
break;
|
||||
|
||||
case HANDLER_HTTP_UNAUTHORIZED:
|
||||
handler = fcgi_401_unauthorized_handler;
|
||||
handler = fcgi_401_bad_signature_handler;
|
||||
break;
|
||||
|
||||
case HANDLER_HTTP_NOT_ACCEPTABLE:
|
||||
|
|
@ -206,6 +235,7 @@ fcgi_verify_request_clear(fcgi_verify_request_t *req_info)
|
|||
LOG_TRACE("fcgi_verify_request_clear");
|
||||
|
||||
free(req_info->content);
|
||||
free(req_info->verify_error);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -276,7 +306,7 @@ error:
|
|||
}
|
||||
|
||||
static fcgi_handler_status_t
|
||||
verify_jwt_sign(const 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)
|
||||
{
|
||||
LOG_TRACE("verify_jwt_sign enter");
|
||||
|
||||
|
|
@ -318,7 +348,7 @@ verify_jwt_sign(const fcgi_verify_request_t* req_info, const verify_service_t *c
|
|||
}
|
||||
|
||||
if (cryptopro_verify(&ctx->conf->esia_cert_thumbprint, &alg, &header_payload, &sign,
|
||||
&is_verified)) {
|
||||
&is_verified, &req_info->verify_error)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -355,28 +355,51 @@ alg_id_from_str(const str_t* alg, /*out*/ ALG_ID* alg_id)
|
|||
}
|
||||
|
||||
static void
|
||||
log_verify_error()
|
||||
get_verify_error(char** verify_error)
|
||||
{
|
||||
LOG_TRACE("get_verify_error enter");
|
||||
|
||||
DWORD err = cp_function_list.GetLastError();
|
||||
|
||||
const char* err_string;
|
||||
|
||||
switch (err) {
|
||||
case NTE_BAD_SIGNATURE:
|
||||
LOG_WARN("sign is invalid: bad signature (0x%08x)", err);
|
||||
err_string = "sign is invalid: bad signature (0x%08x)";
|
||||
break;
|
||||
|
||||
case NTE_BAD_ALGID:
|
||||
LOG_WARN("sign is invalid: bad alg id (0x%08x)", err);
|
||||
err_string = "sign is invalid: bad alg id (0x%08x)";
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_WARN("sign is invalid. Last error code: 0x%08x", err);
|
||||
err_string = "sign is invalid. Last error code: 0x%08x";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t size = strlen(err_string) + 4 /*error code*/ + 1 /*terminating null*/;
|
||||
|
||||
*verify_error = malloc(size);
|
||||
if (*verify_error == NULL) {
|
||||
LOG_ERROR("get_verify_error failed. Could not allocate memory for error string "
|
||||
"(%zd bytes)", size);
|
||||
return;
|
||||
}
|
||||
|
||||
int n = snprintf(*verify_error, size, err_string, err);
|
||||
|
||||
if (n < 0 || (size_t)n >= size) {
|
||||
LOG_ERROR("get_verify_error failed. Error occurred in concatenation err_string");
|
||||
free(*verify_error);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_TRACE("get_verify_error exit");
|
||||
}
|
||||
|
||||
int
|
||||
cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t *data,
|
||||
const str_t *sign, bool* is_verified)
|
||||
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 rc = -1;
|
||||
HCERTSTORE hStoreHandle = NULL;
|
||||
|
|
@ -441,7 +464,11 @@ cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t *da
|
|||
LOG_DEBUG("sign is valid");
|
||||
*is_verified = true;
|
||||
} else {
|
||||
log_verify_error();
|
||||
get_verify_error(verify_error);
|
||||
if (*verify_error == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
LOG_WARN("%s", *verify_error);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ bool cryptopro_init(const char* cp_file);
|
|||
int cryptopro_sign(const cryptopro_context_t *ctx, const str_t *data, /*out*/ str_t *sign);
|
||||
|
||||
int cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t *data,
|
||||
const str_t *sign, bool* is_verified);
|
||||
const str_t *sign, bool* is_verified, char** verify_error);
|
||||
|
||||
#endif // CRYPTOPRO_H_INCLUDED
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue