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_LOCATION "location"
|
||||||
#define VERIFY_CONF_KEY_THUMBPRINT "esia_cert_thumbprint"
|
#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 str_t VERIFY_CONF_DEFAULT_LOCATION = str_t_const("/verify");
|
||||||
|
|
||||||
static const int CLIENT_MAX_BODY_SIZE = 8192;
|
static const int CLIENT_MAX_BODY_SIZE = 8192;
|
||||||
|
|
@ -29,12 +35,14 @@ typedef struct fcgi_verify_request_s {
|
||||||
char *content;
|
char *content;
|
||||||
int content_length;
|
int content_length;
|
||||||
|
|
||||||
|
char *verify_error;
|
||||||
|
|
||||||
} fcgi_verify_request_t;
|
} fcgi_verify_request_t;
|
||||||
|
|
||||||
|
|
||||||
static fcgi_request_handler_pt fcgi_request_finalize_handler(fcgi_handler_status_t status);
|
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 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);
|
const verify_service_t *ctx);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -156,7 +164,7 @@ fcgi_verify_handler(FCGX_Request* request, void* ctx)
|
||||||
status = verify_jwt_sign(&req_info, ctx);
|
status = verify_jwt_sign(&req_info, ctx);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
status = fcgi_request_finalize_handler(status)(request, ctx);
|
status = fcgi_request_finalize_handler(status)(request, &req_info);
|
||||||
|
|
||||||
fcgi_verify_request_clear(&req_info);
|
fcgi_verify_request_clear(&req_info);
|
||||||
|
|
||||||
|
|
@ -164,6 +172,27 @@ exit:
|
||||||
return status;
|
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
|
static fcgi_request_handler_pt
|
||||||
fcgi_request_finalize_handler(fcgi_handler_status_t status)
|
fcgi_request_finalize_handler(fcgi_handler_status_t status)
|
||||||
{
|
{
|
||||||
|
|
@ -180,7 +209,7 @@ fcgi_request_finalize_handler(fcgi_handler_status_t status)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HANDLER_HTTP_UNAUTHORIZED:
|
case HANDLER_HTTP_UNAUTHORIZED:
|
||||||
handler = fcgi_401_unauthorized_handler;
|
handler = fcgi_401_bad_signature_handler;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HANDLER_HTTP_NOT_ACCEPTABLE:
|
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");
|
LOG_TRACE("fcgi_verify_request_clear");
|
||||||
|
|
||||||
free(req_info->content);
|
free(req_info->content);
|
||||||
|
free(req_info->verify_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -276,7 +306,7 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static fcgi_handler_status_t
|
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");
|
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,
|
if (cryptopro_verify(&ctx->conf->esia_cert_thumbprint, &alg, &header_payload, &sign,
|
||||||
&is_verified)) {
|
&is_verified, &req_info->verify_error)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -355,28 +355,51 @@ alg_id_from_str(const str_t* alg, /*out*/ ALG_ID* alg_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
log_verify_error()
|
get_verify_error(char** verify_error)
|
||||||
{
|
{
|
||||||
|
LOG_TRACE("get_verify_error enter");
|
||||||
|
|
||||||
DWORD err = cp_function_list.GetLastError();
|
DWORD err = cp_function_list.GetLastError();
|
||||||
|
|
||||||
|
const char* err_string;
|
||||||
|
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case NTE_BAD_SIGNATURE:
|
case NTE_BAD_SIGNATURE:
|
||||||
LOG_WARN("sign is invalid: bad signature (0x%08x)", err);
|
err_string = "sign is invalid: bad signature (0x%08x)";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NTE_BAD_ALGID:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_WARN("sign is invalid. Last error code: 0x%08x", err);
|
err_string = "sign is invalid. Last error code: 0x%08x";
|
||||||
break;
|
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
|
int
|
||||||
cryptopro_verify(const str_t* cert_thumbprint, const str_t* alg, const str_t *data,
|
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)
|
||||||
{
|
{
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
HCERTSTORE hStoreHandle = NULL;
|
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");
|
LOG_DEBUG("sign is valid");
|
||||||
*is_verified = true;
|
*is_verified = true;
|
||||||
} else {
|
} else {
|
||||||
log_verify_error();
|
get_verify_error(verify_error);
|
||||||
|
if (*verify_error == NULL) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
LOG_WARN("%s", *verify_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = 0;
|
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_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,
|
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
|
#endif // CRYPTOPRO_H_INCLUDED
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue