diff options
Diffstat (limited to 'crypto/cmp/cmp_server.c')
-rw-r--r-- | crypto/cmp/cmp_server.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/crypto/cmp/cmp_server.c b/crypto/cmp/cmp_server.c index 946c32c45ebf..96f977636ca2 100644 --- a/crypto/cmp/cmp_server.c +++ b/crypto/cmp/cmp_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -22,8 +22,9 @@ /* the context for the generic CMP server */ struct ossl_cmp_srv_ctx_st { - OSSL_CMP_CTX *ctx; /* Client CMP context, partly reused for srv */ - void *custom_ctx; /* pointer to specific server context */ + void *custom_ctx; /* pointer to application-specific server context */ + OSSL_CMP_CTX *ctx; /* Client CMP context, reusing transactionID etc. */ + int certReqId; /* id of last ir/cr/kur, OSSL_CMP_CERTREQID_NONE for p10cr */ OSSL_CMP_SRV_cert_request_cb_t process_cert_request; OSSL_CMP_SRV_rr_cb_t process_rr; @@ -57,6 +58,7 @@ OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL) goto err; + ctx->certReqId = OSSL_CMP_CERTREQID_INVALID; /* all other elements are initialized to 0 or NULL, respectively */ return ctx; @@ -184,7 +186,7 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, } if (OSSL_CMP_MSG_get_bodytype(req) == OSSL_CMP_PKIBODY_P10CR) { - certReqId = OSSL_CMP_CERTREQID; + certReqId = OSSL_CMP_CERTREQID_NONE; /* p10cr does not include an Id */ p10cr = req->body->value.p10cr; } else { OSSL_CRMF_MSGS *reqs = req->body->value.ir; /* same for cr and kur */ @@ -199,7 +201,12 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, return NULL; } certReqId = OSSL_CRMF_MSG_get_certReqId(crm); + if (certReqId != OSSL_CMP_CERTREQID) { + ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); + return 0; + } } + srv_ctx->certReqId = certReqId; if (!ossl_cmp_verify_popo(srv_ctx->ctx, req, srv_ctx->acceptRAVerified)) { /* Proof of possession could not be verified */ @@ -356,6 +363,10 @@ static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx, ASN1_OCTET_STRING *certHash = status->certHash; OSSL_CMP_PKISI *si = status->statusInfo; + if (certReqId != srv_ctx->certReqId) { + ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); + return NULL; + } if (!srv_ctx->process_certConf(srv_ctx, req, certReqId, certHash, si)) return NULL; /* reason code may be: CMP_R_CERTHASH_UNMATCHED */ @@ -394,8 +405,12 @@ static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx, return NULL; } - pr = sk_OSSL_CMP_POLLREQ_value(prc, 0); + pr = sk_OSSL_CMP_POLLREQ_value(prc, OSSL_CMP_CERTREQID); certReqId = ossl_cmp_asn1_get_int(pr->certReqId); + if (certReqId != srv_ctx->certReqId) { + ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); + return NULL; + } if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId, &certReq, &check_after)) return NULL; @@ -446,7 +461,7 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, ASN1_OCTET_STRING *backup_secret; OSSL_CMP_PKIHEADER *hdr; int req_type, rsp_type; - int res; + int req_verified = 0; OSSL_CMP_MSG *rsp = NULL; if (srv_ctx == NULL || srv_ctx->ctx == NULL @@ -506,12 +521,12 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, } } - res = ossl_cmp_msg_check_update(ctx, req, unprotected_exception, - srv_ctx->acceptUnprotected); + req_verified = ossl_cmp_msg_check_update(ctx, req, unprotected_exception, + srv_ctx->acceptUnprotected); if (ctx->secretValue != NULL && ctx->pkey != NULL && ossl_cmp_hdr_get_protection_nid(hdr) != NID_id_PasswordBasedMAC) ctx->secretValue = NULL; /* use MSG_SIG_ALG when protecting rsp */ - if (!res) + if (!req_verified) goto err; switch (req_type) { @@ -568,9 +583,15 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, int fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badRequest; OSSL_CMP_PKISI *si = NULL; - if (ctx->transactionID == NULL) { - /* ignore any (extra) error in next two function calls: */ - (void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID); + if (!req_verified) { + /* + * Above ossl_cmp_msg_check_update() was not successfully executed, + * which normally would set ctx->transactionID and ctx->recipNonce. + * So anyway try to provide the right transactionID and recipNonce, + * while ignoring any (extra) error in next two function calls. + */ + if (ctx->transactionID == NULL) + (void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID); (void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce); } |