crypto/cmp/,apps/lib/cmp_mock_srv.c: various improvements on delayed delivery

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/20727)
This commit is contained in:
Dr. David von Oheimb 2023-04-28 13:45:21 +02:00 committed by Dr. David von Oheimb
parent 192bfec487
commit bedffe1731
16 changed files with 163 additions and 134 deletions

View File

@ -43,6 +43,7 @@ OpenSSL 3.3
* Added several new features of CMPv3 defined in RFC 9480 and RFC 9483: * Added several new features of CMPv3 defined in RFC 9480 and RFC 9483:
- `certProfile` request message header and respective `-profile` CLI option - `certProfile` request message header and respective `-profile` CLI option
- support for delayed delivery of all types of response messages
*David von Oheimb* *David von Oheimb*

View File

@ -183,15 +183,15 @@ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
return 1; return 1;
} }
static int delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx, /* determine whether to delay response to (non-polling) request */
const OSSL_CMP_MSG *req) static int delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req)
{ {
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
int req_type = OSSL_CMP_MSG_get_bodytype(req); int req_type = OSSL_CMP_MSG_get_bodytype(req);
if (ctx == NULL || req == NULL) { if (ctx == NULL || req == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0; return -1;
} }
/* /*
@ -211,11 +211,10 @@ static int delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx,
if (ctx->req != NULL) { /* TODO: move this check to cmp_server.c */ if (ctx->req != NULL) { /* TODO: move this check to cmp_server.c */
/* already in polling mode */ /* already in polling mode */
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
return 0; return -1;
} }
if ((ctx->req = OSSL_CMP_MSG_dup(req)) == NULL) if ((ctx->req = OSSL_CMP_MSG_dup(req)) == NULL)
return -1; return -1;
return 1; return 1;
} }
return 0; return 0;
@ -236,17 +235,17 @@ static int refcert_cmp(const X509 *refcert,
&& (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0); && (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0);
} }
/* Reset dynamic variable in case of incomplete tansaction */ /* reset the state that belongs to a transaction */
static int reset_transaction(OSSL_CMP_SRV_CTX *srv_ctx) static int clean_transaction(OSSL_CMP_SRV_CTX *srv_ctx,
ossl_unused const ASN1_OCTET_STRING *id)
{ {
mock_srv_ctx *ctx = NULL; mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
if (srv_ctx == NULL) { if (ctx == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0; return 0;
} }
ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
ctx->curr_pollCount = 0; ctx->curr_pollCount = 0;
OSSL_CMP_MSG_free(ctx->req); OSSL_CMP_MSG_free(ctx->req);
ctx->req = NULL; ctx->req = NULL;
@ -533,6 +532,7 @@ static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
return 1; return 1;
} }
/* return 0 on failure, 1 on success, setting *req or otherwise *check_after */
static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx, static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *pollReq, const OSSL_CMP_MSG *pollReq,
ossl_unused int certReqId, ossl_unused int certReqId,
@ -540,21 +540,21 @@ static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
{ {
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
if (req != NULL)
*req = NULL;
if (ctx == NULL || pollReq == NULL if (ctx == NULL || pollReq == NULL
|| req == NULL || check_after == NULL) { || req == NULL || check_after == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0; return 0;
} }
if (ctx->sendError == 1 if (ctx->sendError == 1
|| ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) { || ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) {
*req = NULL;
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return 0; return 0;
} }
if (ctx->req == NULL) { /* TODO: move this check to cmp_server.c */ if (ctx->req == NULL) { /* not currently in polling mode */
/* not currently in polling mode */ ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_POLLREQ);
*req = NULL;
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
return 0; return 0;
} }
@ -564,7 +564,6 @@ static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
ctx->req = NULL; ctx->req = NULL;
*check_after = 0; *check_after = 0;
} else { } else {
*req = NULL;
*check_after = ctx->checkAfterTime; *check_after = ctx->checkAfterTime;
} }
return 1; return 1;
@ -579,8 +578,8 @@ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq)
&& OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request, && OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request,
process_rr, process_genm, process_error, process_rr, process_genm, process_error,
process_certConf, process_pollReq) process_certConf, process_pollReq)
&& OSSL_CMP_SRV_CTX_setup_polling(srv_ctx, reset_transaction, && OSSL_CMP_SRV_CTX_init_trans(srv_ctx,
delayed_delivery)) delayed_delivery, clean_transaction))
return srv_ctx; return srv_ctx;
mock_srv_ctx_free(ctx); mock_srv_ctx_free(ctx);

View File

@ -113,7 +113,7 @@ static int save_statusInfo(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si)
return 1; return 1;
} }
static int is_crep_with_waiting(OSSL_CMP_MSG *resp, int rid) static int is_crep_with_waiting(const OSSL_CMP_MSG *resp, int rid)
{ {
OSSL_CMP_CERTREPMESSAGE *crepmsg; OSSL_CMP_CERTREPMESSAGE *crepmsg;
OSSL_CMP_CERTRESPONSE *crep; OSSL_CMP_CERTRESPONSE *crep;
@ -210,11 +210,11 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
return 0; return 0;
/* /*
* 'rep' can have the expected response type, which during polling is * rep can have the expected response type, which during polling is pollRep.
* pollRep. When polling, also any other non-error response (the final * When polling, also any other non-error response (the final response)
* response) is fine here. When not yet polling, delayed delivery may * is fine here. When not yet polling, delayed delivery may be initiated
* be started by an error with 'waiting' status (while it may also be * by the server returning an error message with 'waiting' status (or a
* started by an expected response type ip/cp/kup). * response message of expected type ip/cp/kup with 'waiting' status).
*/ */
if (bt == expected_type if (bt == expected_type
|| (expected_type == OSSL_CMP_PKIBODY_POLLREP || (expected_type == OSSL_CMP_PKIBODY_POLLREP
@ -272,8 +272,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
* Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value. * Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value.
* Returns 1 on success and provides the received PKIMESSAGE in *rep. * Returns 1 on success and provides the received PKIMESSAGE in *rep.
* In this case the caller is responsible for freeing *rep. * In this case the caller is responsible for freeing *rep.
* Returns 0 on error (which includes the case that timeout has been reached or * Returns 0 on error (which includes the cases that timeout has been reached
* received response with waiting status). * or a response with 'waiting' status has been received).
*/ */
static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
OSSL_CMP_MSG **rep, int *checkAfter) OSSL_CMP_MSG **rep, int *checkAfter)
@ -364,7 +364,7 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
} }
} else if (is_crep_with_waiting(prep, rid) } else if (is_crep_with_waiting(prep, rid)
|| ossl_cmp_is_error_with_waiting(prep)) { || ossl_cmp_is_error_with_waiting(prep)) {
/* status cannot be 'waiting' at this point */ /* received status must not be 'waiting' */
(void)ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection, (void)ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection,
OSSL_CMP_CTX_FAILINFO_badRequest, OSSL_CMP_CTX_FAILINFO_badRequest,
"polling already started", "polling already started",
@ -393,12 +393,12 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
} }
static int save_senderNonce_if_waiting(OSSL_CMP_CTX *ctx, static int save_senderNonce_if_waiting(OSSL_CMP_CTX *ctx,
OSSL_CMP_MSG *rep, int rid) const OSSL_CMP_MSG *rep, int rid)
{ {
/* /*
* LWCMP section 4.4 states: the senderNonce of the preceding request * Lightweight CMP Profile section 4.4 states: the senderNonce of the
* message because this value will be needed for checking the recipNonce * preceding request message because this value will be needed for checking
* of the final response to be received after polling. * the recipNonce of the final response to be received after polling.
*/ */
if ((is_crep_with_waiting(rep, rid) if ((is_crep_with_waiting(rep, rid)
|| ossl_cmp_is_error_with_waiting(rep)) || ossl_cmp_is_error_with_waiting(rep))
@ -409,8 +409,8 @@ static int save_senderNonce_if_waiting(OSSL_CMP_CTX *ctx,
} }
/* /*
* send request and get response possibly with polling initiated by error msg. * Send request and get response possibly with polling initiated by error msg.
* Polling for ip/cp/kup/ with 'waiting' status is handled elsewhere. * Polling for ip/cp/kup/ with 'waiting' status is handled by cert_response().
*/ */
static int send_receive_also_delayed(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, static int send_receive_also_delayed(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
OSSL_CMP_MSG **rep, int expected_type) OSSL_CMP_MSG **rep, int expected_type)
@ -420,12 +420,9 @@ static int send_receive_also_delayed(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
return 0; return 0;
if (ossl_cmp_is_error_with_waiting(*rep)) { if (ossl_cmp_is_error_with_waiting(*rep)) {
if (!save_senderNonce_if_waiting(ctx, *rep, -1 /* rid */)) if (!save_senderNonce_if_waiting(ctx, *rep, OSSL_CMP_CERTREQID_NONE))
return 0; return 0;
/* /* not modifying ctx->status during certConf and error exchanges */
* not modifying ctx->status during the certConf & error exchange,
* because these additional exchanges should not change the status.
*/
if (expected_type != OSSL_CMP_PKIBODY_PKICONF if (expected_type != OSSL_CMP_PKIBODY_PKICONF
&& !save_statusInfo(ctx, (*rep)->body->value.error->pKIStatusInfo)) && !save_statusInfo(ctx, (*rep)->body->value.error->pKIStatusInfo))
return 0; return 0;
@ -433,7 +430,7 @@ static int send_receive_also_delayed(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
OSSL_CMP_MSG_free(*rep); OSSL_CMP_MSG_free(*rep);
*rep = NULL; *rep = NULL;
if (poll_for_response(ctx, 1 /* can sleep */, -1 /* rid */, if (poll_for_response(ctx, 1 /* can sleep */, OSSL_CMP_CERTREQID_NONE,
rep, NULL /* checkAfter */) <= 0) { rep, NULL /* checkAfter */) <= 0) {
ERR_raise(ERR_LIB_CMP, CMP_R_POLLING_FAILED); ERR_raise(ERR_LIB_CMP, CMP_R_POLLING_FAILED);
return 0; return 0;
@ -462,8 +459,8 @@ int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int certReqId,
if (certConf == NULL) if (certConf == NULL)
goto err; goto err;
res = send_receive_also_delayed(ctx, certConf, res = send_receive_also_delayed(ctx, certConf, &PKIconf,
&PKIconf, OSSL_CMP_PKIBODY_PKICONF); OSSL_CMP_PKIBODY_PKICONF);
err: err:
OSSL_CMP_MSG_free(certConf); OSSL_CMP_MSG_free(certConf);
@ -683,10 +680,10 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
return 0; return 0;
si = crep->status; si = crep->status;
if (rid == OSSL_CMP_CERTREQID_NONE) { if (rid == OSSL_CMP_CERTREQID_NONE) {
/* for OSSL_CMP_PKIBODY_P10CR learn CertReqId from response */ /* for OSSL_CMP_PKIBODY_P10CR learn CertReqId from response */
rid = ossl_cmp_asn1_get_int(crep->certReqId); rid = ossl_cmp_asn1_get_int(crep->certReqId);
if (rid == OSSL_CMP_CERTREQID_NONE) { if (rid != OSSL_CMP_CERTREQID_NONE) {
ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
return 0; return 0;
} }
@ -702,7 +699,11 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
return 0; return 0;
if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_waiting) { if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_waiting) {
/* here we allow different flavor of ip/cp/kup & error with waiting */ /*
* Here we allow both and error message with waiting indication
* as well as a certificate response with waiting indication, where
* its flavor (ip, cp, or kup) may not strictly match ir/cr/p10cr/kur.
*/
OSSL_CMP_MSG_free(*resp); OSSL_CMP_MSG_free(*resp);
*resp = NULL; *resp = NULL;
if ((ret = poll_for_response(ctx, sleep, rid, resp, checkAfter)) != 0) { if ((ret = poll_for_response(ctx, sleep, rid, resp, checkAfter)) != 0) {
@ -715,12 +716,12 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
} }
} }
/* at this point, ip/cp/kup or error without waiting */ /* at this point, we have received ip/cp/kup/error without waiting */
if (rcvd_type == OSSL_CMP_PKIBODY_ERROR) { if (rcvd_type == OSSL_CMP_PKIBODY_ERROR) {
ERR_raise(ERR_LIB_CMP, CMP_R_RECEIVED_ERROR); ERR_raise(ERR_LIB_CMP, CMP_R_RECEIVED_ERROR);
return 0; return 0;
} }
/* here we are strict on the flavor of ip/cp/kup */ /* here we are strict on the flavor of ip/cp/kup: must match request */
if (rcvd_type != expected_type) { if (rcvd_type != expected_type) {
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
return 0; return 0;
@ -738,8 +739,7 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
* if the CMP server returned certificates in the caPubs field, copy them * if the CMP server returned certificates in the caPubs field, copy them
* to the context so that they can be retrieved if necessary * to the context so that they can be retrieved if necessary
*/ */
if (crepmsg != NULL if (crepmsg != NULL && crepmsg->caPubs != NULL
&& crepmsg->caPubs != NULL
&& !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs)) && !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs))
return 0; return 0;

View File

@ -76,6 +76,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
"error validating protection"}, "error validating protection"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE), {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE),
"error validating signature"}, "error validating signature"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_EXPECTED_POLLREQ), "expected pollreq"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN), {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN),
"failed building own chain"}, "failed building own chain"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY), {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
@ -149,6 +150,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS), {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS),
"unexpected pkistatus"}, "unexpected pkistatus"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_POLLREQ), "unexpected pollreq"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID), {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
"unknown algorithm id"}, "unknown algorithm id"},
@ -158,6 +160,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
"unsupported algorithm"}, "unsupported algorithm"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE), {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE),
"unsupported key type"}, "unsupported key type"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PKIBODY),
"unsupported pkibody"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC), {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC),
"unsupported protection alg dhbasedmac"}, "unsupported protection alg dhbasedmac"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_LARGE), "value too large"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_LARGE), "value too large"},

View File

@ -984,8 +984,7 @@ static int suitable_rid(const ASN1_INTEGER *certReqId, int rid)
return 1; return 1;
trid = ossl_cmp_asn1_get_int(certReqId); trid = ossl_cmp_asn1_get_int(certReqId);
if (trid < OSSL_CMP_CERTREQID_NONE) {
if (trid == OSSL_CMP_CERTREQID_NONE) {
ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
return 0; return 0;
} }

View File

@ -22,9 +22,9 @@
/* the context for the generic CMP server */ /* the context for the generic CMP server */
struct ossl_cmp_srv_ctx_st struct ossl_cmp_srv_ctx_st
{ {
void *custom_ctx; /* pointer to application-specific server context */ OSSL_CMP_CTX *ctx; /* CMP client context reused for transactionID etc. */
OSSL_CMP_CTX *ctx; /* Client CMP context, reusing transactionID etc. */ void *custom_ctx; /* application-specific server context */
int certReqId; /* id of last ir/cr/kur, OSSL_CMP_CERTREQID_NONE for p10cr */ int certReqId; /* of ir/cr/kur, OSSL_CMP_CERTREQID_NONE for p10cr */
OSSL_CMP_SRV_cert_request_cb_t process_cert_request; OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
OSSL_CMP_SRV_rr_cb_t process_rr; OSSL_CMP_SRV_rr_cb_t process_rr;
@ -32,8 +32,8 @@ struct ossl_cmp_srv_ctx_st
OSSL_CMP_SRV_error_cb_t process_error; OSSL_CMP_SRV_error_cb_t process_error;
OSSL_CMP_SRV_certConf_cb_t process_certConf; OSSL_CMP_SRV_certConf_cb_t process_certConf;
OSSL_CMP_SRV_pollReq_cb_t process_pollReq; OSSL_CMP_SRV_pollReq_cb_t process_pollReq;
OSSL_CMP_SRV_reset_transaction_cb_t reset_transaction;
OSSL_CMP_SRV_delayed_delivery_cb_t delayed_delivery; OSSL_CMP_SRV_delayed_delivery_cb_t delayed_delivery;
OSSL_CMP_SRV_clean_transaction_cb_t clean_transaction;
int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */ int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
int acceptUnprotected; /* Accept requests with no/invalid prot. */ int acceptUnprotected; /* Accept requests with no/invalid prot. */
@ -91,16 +91,16 @@ int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
return 1; return 1;
} }
int OSSL_CMP_SRV_CTX_setup_polling(OSSL_CMP_SRV_CTX *srv_ctx, int OSSL_CMP_SRV_CTX_init_trans(OSSL_CMP_SRV_CTX *srv_ctx,
OSSL_CMP_SRV_reset_transaction_cb_t reset_transaction, OSSL_CMP_SRV_delayed_delivery_cb_t delay,
OSSL_CMP_SRV_delayed_delivery_cb_t delayed_delivery) OSSL_CMP_SRV_clean_transaction_cb_t clean)
{ {
if (srv_ctx == NULL) { if (srv_ctx == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0; return 0;
} }
srv_ctx->reset_transaction = reset_transaction; srv_ctx->delayed_delivery = delay;
srv_ctx->delayed_delivery = delayed_delivery; srv_ctx->clean_transaction = clean;
return 1; return 1;
} }
@ -164,13 +164,13 @@ int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
return 1; return 1;
} }
/* Return error msg with waiting status if polling is initiated, else NULL. */ /* return error msg with waiting status if polling is initiated, else NULL */
static OSSL_CMP_MSG *delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx, static OSSL_CMP_MSG *delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *req) const OSSL_CMP_MSG *req)
{ {
OSSL_CMP_MSG *msg = NULL;
OSSL_CMP_PKISI *si = NULL;
int ret; int ret;
OSSL_CMP_PKISI *si;
OSSL_CMP_MSG *msg;
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL
&& srv_ctx->delayed_delivery != NULL)) && srv_ctx->delayed_delivery != NULL))
@ -180,8 +180,8 @@ static OSSL_CMP_MSG *delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx,
if (ret == 0 || !ossl_assert(ret != -1)) if (ret == 0 || !ossl_assert(ret != -1))
return NULL; return NULL;
if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL)) si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL);
== NULL) if (si == NULL)
return NULL; return NULL;
msg = ossl_cmp_error_new(srv_ctx->ctx, si, 0, msg = ossl_cmp_error_new(srv_ctx->ctx, si, 0,
@ -236,15 +236,14 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED); ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
return NULL; return NULL;
} }
if ((crm = sk_OSSL_CRMF_MSG_value(reqs, 0)) == NULL) {
if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND); ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND);
return NULL; return NULL;
} }
certReqId = OSSL_CRMF_MSG_get_certReqId(crm); certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
if (certReqId != OSSL_CMP_CERTREQID) { if (certReqId != OSSL_CMP_CERTREQID) { /* so far, only possible value */
ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID);
return 0; return NULL;
} }
} }
srv_ctx->certReqId = certReqId; srv_ctx->certReqId = certReqId;
@ -306,9 +305,8 @@ static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED); ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
return NULL; return NULL;
} }
details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr, 0);
if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr, if (details == NULL) {
OSSL_CMP_REVREQSID)) == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return NULL; return NULL;
} }
@ -397,7 +395,7 @@ static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
} else { } else {
if (num > 1) if (num > 1)
ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored"); ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored");
status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID); status = sk_OSSL_CMP_CERTSTATUS_value(ccc, 0);
} }
if (status != NULL) { if (status != NULL) {
@ -428,7 +426,7 @@ static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
return msg; return msg;
} }
/* pollreq should be handled separately, to avoid recursive call */ /* pollReq is handled separately, to avoid recursive call */
static OSSL_CMP_MSG *process_non_polling_request(OSSL_CMP_SRV_CTX *srv_ctx, static OSSL_CMP_MSG *process_non_polling_request(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *req) const OSSL_CMP_MSG *req)
{ {
@ -444,38 +442,41 @@ static OSSL_CMP_MSG *process_non_polling_request(OSSL_CMP_SRV_CTX *srv_ctx,
case OSSL_CMP_PKIBODY_P10CR: case OSSL_CMP_PKIBODY_P10CR:
case OSSL_CMP_PKIBODY_KUR: case OSSL_CMP_PKIBODY_KUR:
if (srv_ctx->process_cert_request == NULL) if (srv_ctx->process_cert_request == NULL)
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
else else
rsp = process_cert_request(srv_ctx, req); rsp = process_cert_request(srv_ctx, req);
break; break;
case OSSL_CMP_PKIBODY_RR: case OSSL_CMP_PKIBODY_RR:
if (srv_ctx->process_rr == NULL) if (srv_ctx->process_rr == NULL)
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
else else
rsp = process_rr(srv_ctx, req); rsp = process_rr(srv_ctx, req);
break; break;
case OSSL_CMP_PKIBODY_GENM: case OSSL_CMP_PKIBODY_GENM:
if (srv_ctx->process_genm == NULL) if (srv_ctx->process_genm == NULL)
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
else else
rsp = process_genm(srv_ctx, req); rsp = process_genm(srv_ctx, req);
break; break;
case OSSL_CMP_PKIBODY_ERROR: case OSSL_CMP_PKIBODY_ERROR:
if (srv_ctx->process_error == NULL) if (srv_ctx->process_error == NULL)
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
else else
rsp = process_error(srv_ctx, req); rsp = process_error(srv_ctx, req);
break; break;
case OSSL_CMP_PKIBODY_CERTCONF: case OSSL_CMP_PKIBODY_CERTCONF:
if (srv_ctx->process_certConf == NULL) if (srv_ctx->process_certConf == NULL)
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
else else
rsp = process_certConf(srv_ctx, req); rsp = process_certConf(srv_ctx, req);
break; break;
default:
/* Other request message types are not supported */ case OSSL_CMP_PKIBODY_POLLREQ:
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
break; break;
default:
ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
break;
} }
return rsp; return rsp;
@ -500,12 +501,8 @@ static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
return NULL; return NULL;
} }
pr = sk_OSSL_CMP_POLLREQ_value(prc, OSSL_CMP_CERTREQID); pr = sk_OSSL_CMP_POLLREQ_value(prc, 0);
certReqId = ossl_cmp_asn1_get_int(pr->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, if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId,
&orig_req, &check_after)) &orig_req, &check_after))
return NULL; return NULL;
@ -604,8 +601,11 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|| !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)) || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL))
goto err; goto err;
if (srv_ctx->reset_transaction != NULL) if (srv_ctx->clean_transaction != NULL
(void)srv_ctx->reset_transaction(srv_ctx); && !srv_ctx->clean_transaction(srv_ctx, NULL)) {
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
goto err;
}
break; break;
default: default:
@ -628,7 +628,7 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
if (req_type == OSSL_CMP_PKIBODY_POLLREQ) { if (req_type == OSSL_CMP_PKIBODY_POLLREQ) {
if (srv_ctx->process_pollReq == NULL) if (srv_ctx->process_pollReq == NULL)
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PKIBODY);
else else
rsp = process_pollReq(srv_ctx, req); rsp = process_pollReq(srv_ctx, req);
} else { } else {
@ -693,8 +693,7 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
/* fall through */ /* fall through */
case OSSL_CMP_PKIBODY_ERROR: case OSSL_CMP_PKIBODY_ERROR:
if (rsp != NULL if (rsp != NULL && ossl_cmp_is_error_with_waiting(rsp))
&& ossl_cmp_is_error_with_waiting(rsp))
break; break;
/* fall through */ /* fall through */
@ -702,12 +701,13 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
case OSSL_CMP_PKIBODY_PKICONF: case OSSL_CMP_PKIBODY_PKICONF:
case OSSL_CMP_PKIBODY_GENP: case OSSL_CMP_PKIBODY_GENP:
/* Other terminating response message types are not supported */ /* Other terminating response message types are not supported */
srv_ctx->certReqId = OSSL_CMP_CERTREQID_INVALID;
/* Prepare for next transaction, ignoring any errors here: */ /* Prepare for next transaction, ignoring any errors here: */
if (srv_ctx->clean_transaction != NULL)
(void)srv_ctx->clean_transaction(srv_ctx, ctx->transactionID);
(void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL);
(void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL); (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL);
ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */ ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */
if (srv_ctx->reset_transaction != NULL)
(void)srv_ctx->reset_transaction(srv_ctx);
default: /* not closing transaction in other cases */ default: /* not closing transaction in other cases */
break; break;

View File

@ -787,8 +787,8 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
return 0; return 0;
/* /*
* enable clearing irrelevant errors in attempts to validate recipient nonce * enable clearing irrelevant errors
* in case of delayed delivery. * in attempts to validate recipient nonce in case of delayed delivery.
*/ */
(void)ERR_set_mark(); (void)ERR_set_mark();
/* compare received nonce with the one we sent */ /* compare received nonce with the one we sent */
@ -805,7 +805,6 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
return 0; return 0;
} }
} }
/* discard any intermediate error while trying to check recipient nonce */
(void)ERR_pop_to_mark(); (void)ERR_pop_to_mark();
/* if not yet present, learn transactionID */ /* if not yet present, learn transactionID */

View File

@ -227,6 +227,7 @@ CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf
CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature
CMP_R_EXPECTED_POLLREQ:104:expected pollreq
CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain
CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
@ -275,12 +276,14 @@ CMP_R_UNCLEAN_CTX:191:unclean ctx
CMP_R_UNEXPECTED_CERTPROFILE:196:unexpected certprofile CMP_R_UNEXPECTED_CERTPROFILE:196:unexpected certprofile
CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus
CMP_R_UNEXPECTED_POLLREQ:105:unexpected pollreq
CMP_R_UNEXPECTED_PVNO:153:unexpected pvno CMP_R_UNEXPECTED_PVNO:153:unexpected pvno
CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id
CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type
CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus
CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm
CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type
CMP_R_UNSUPPORTED_PKIBODY:101:unsupported pkibody
CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\ CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\
unsupported protection alg dhbasedmac unsupported protection alg dhbasedmac
CMP_R_VALUE_TOO_LARGE:175:value too large CMP_R_VALUE_TOO_LARGE:175:value too large

View File

@ -12,10 +12,10 @@ OSSL_CMP_SRV_certConf_cb_t,
OSSL_CMP_SRV_genm_cb_t, OSSL_CMP_SRV_genm_cb_t,
OSSL_CMP_SRV_error_cb_t, OSSL_CMP_SRV_error_cb_t,
OSSL_CMP_SRV_pollReq_cb_t, OSSL_CMP_SRV_pollReq_cb_t,
OSSL_CMP_SRV_reset_transaction_cb_t,
OSSL_CMP_SRV_delayed_delivery_cb_t,
OSSL_CMP_SRV_CTX_init, OSSL_CMP_SRV_CTX_init,
OSSL_CMP_SRV_CTX_setup_polling, OSSL_CMP_SRV_delayed_delivery_cb_t,
OSSL_CMP_SRV_clean_transaction_cb_t,
OSSL_CMP_SRV_CTX_init_trans,
OSSL_CMP_SRV_CTX_get0_cmp_ctx, OSSL_CMP_SRV_CTX_get0_cmp_ctx,
OSSL_CMP_SRV_CTX_get0_custom_ctx, OSSL_CMP_SRV_CTX_get0_custom_ctx,
OSSL_CMP_SRV_CTX_set_send_unprotected_errors, OSSL_CMP_SRV_CTX_set_send_unprotected_errors,
@ -67,9 +67,6 @@ OSSL_CMP_SRV_CTX_set_grant_implicit_confirm
int certReqId, int certReqId,
OSSL_CMP_MSG **certReq, OSSL_CMP_MSG **certReq,
int64_t *check_after); int64_t *check_after);
typedef int (*OSSL_CMP_SRV_reset_transaction_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx);
typedef int (*OSSL_CMP_SRV_delayed_delivery_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *req);
int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx, int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
OSSL_CMP_SRV_cert_request_cb_t process_cert_request, OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
OSSL_CMP_SRV_rr_cb_t process_rr, OSSL_CMP_SRV_rr_cb_t process_rr,
@ -77,9 +74,13 @@ OSSL_CMP_SRV_CTX_set_grant_implicit_confirm
OSSL_CMP_SRV_error_cb_t process_error, OSSL_CMP_SRV_error_cb_t process_error,
OSSL_CMP_SRV_certConf_cb_t process_certConf, OSSL_CMP_SRV_certConf_cb_t process_certConf,
OSSL_CMP_SRV_pollReq_cb_t process_pollReq); OSSL_CMP_SRV_pollReq_cb_t process_pollReq);
int OSSL_CMP_SRV_CTX_setup_polling(OSSL_CMP_SRV_CTX *srv_ctx, typedef int (*OSSL_CMP_SRV_delayed_delivery_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
OSSL_CMP_SRV_reset_transaction_cb_t reset_transaction, const OSSL_CMP_MSG *req);
OSSL_CMP_SRV_delayed_delivery_cb_t delayed_delivery); typedef int (*OSSL_CMP_SRV_clean_transaction_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
const ASN1_OCTET_STRING *id);
int OSSL_CMP_SRV_CTX_init_trans(OSSL_CMP_SRV_CTX *srv_ctx,
OSSL_CMP_SRV_delayed_delivery_cb_t delay,
OSSL_CMP_SRV_clean_transaction_cb_t clean);
OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx); OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx); void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
@ -122,8 +123,19 @@ All arguments except I<srv_ctx> may be NULL.
If a callback for some message type is not given this means that the respective If a callback for some message type is not given this means that the respective
type of CMP message is not supported by the server. type of CMP message is not supported by the server.
OSSL_CMP_SRV_CTX_setup_polling() sets in the given I<srv_ctx> callback functions OSSL_CMP_SRV_CTX_init_trans() sets in I<srv_ctx> the optional callback
for reseting transaction and intitiating delayed delivery. functions for initiating delayed delivery and cleaning up a transaction.
If the <delay> function is NULL then delivery of responses is never delayed.
Otherwise I<delay> takes a custom server context and a request message as input.
It must return 1 if delivery of the respecive response shall be delayed,
0 if not, and -1 on error.
If the <clean> function is NULL then no specific cleanup is performed.
Otherwise I<clean> takes a custom server context and a transaction ID pointer
as input, where the pointer is NULL in case a new transaction is being started
and otherwise provides the ID of the transaction being terminated.
The <clean> function should reset the respective portions of the state
and free related memory.
It must return 1 on success and 0 on error.
OSSL_CMP_SRV_CTX_get0_cmp_ctx() returns the B<OSSL_CMP_CTX> from the I<srv_ctx>. OSSL_CMP_SRV_CTX_get0_cmp_ctx() returns the B<OSSL_CMP_CTX> from the I<srv_ctx>.
@ -168,6 +180,10 @@ All other functions return 1 on success, 0 on error.
The OpenSSL CMP support was added in OpenSSL 3.0. The OpenSSL CMP support was added in OpenSSL 3.0.
OSSL_CMP_SRV_CTX_init_trans()
supporting delayed delivery of all types of response messages
was added in OpenSSL 3.3.
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.

View File

@ -78,8 +78,8 @@ Typically I<crm> is NULL, then the template ingredients are taken from I<ctx>
and need to be filled in using L<OSSL_CMP_CTX_set1_subjectName(3)>, and need to be filled in using L<OSSL_CMP_CTX_set1_subjectName(3)>,
L<OSSL_CMP_CTX_set0_newPkey(3)>, L<OSSL_CMP_CTX_set1_oldCert(3)>, etc. L<OSSL_CMP_CTX_set0_newPkey(3)>, L<OSSL_CMP_CTX_set1_oldCert(3)>, etc.
For P10CR, L<OSSL_CMP_CTX_set1_p10CSR(3)> needs to be used instead. For P10CR, L<OSSL_CMP_CTX_set1_p10CSR(3)> needs to be used instead.
The enrollment session may be blocked by sleeping until the addressed The enrollment session may be blocked (with polling and sleeping in between)
CA (or an intermediate PKI component) can fully process and answer the request. until the server side can fully process and ultimately answer the request.
OSSL_CMP_try_certreq() is an alternative to the above functions that is OSSL_CMP_try_certreq() is an alternative to the above functions that is
more flexible regarding what to do after receiving a checkAfter value. more flexible regarding what to do after receiving a checkAfter value.
@ -118,11 +118,15 @@ We take "accepted" and "grantedWithMods" as clear success and handle
typically return them as an indication that the certificate was already revoked. typically return them as an indication that the certificate was already revoked.
"rejection" is a clear error. The values "waiting" and "keyUpdateWarning" "rejection" is a clear error. The values "waiting" and "keyUpdateWarning"
make no sense for revocation and thus are treated as an error as well. make no sense for revocation and thus are treated as an error as well.
The revocation session may be blocked (with polling and sleeping in between)
until the server can fully process and ultimately answer the request.
OSSL_CMP_exec_GENM_ses() sends a genm general message containing the sequence of OSSL_CMP_exec_GENM_ses() sends a genm general message containing the sequence of
infoType and infoValue pairs (InfoTypeAndValue; short: B<ITAV>) infoType and infoValue pairs (InfoTypeAndValue; short: B<ITAV>)
optionally provided in the I<ctx> using L<OSSL_CMP_CTX_push0_genm_ITAV(3)>. optionally provided in the I<ctx> using L<OSSL_CMP_CTX_push0_genm_ITAV(3)>.
On success it records in I<ctx> the status B<OSSL_CMP_PKISTATUS_accepted> The message exchange may be blocked (with polling and sleeping in between)
until the server can fully process and ultimately answer the request.
On success the function records in I<ctx> status B<OSSL_CMP_PKISTATUS_accepted>
and returns the list of B<ITAV>s received in a genp response message. and returns the list of B<ITAV>s received in a genp response message.
This can be used, for instance, This can be used, for instance,
with infoType C<signKeyPairTypes> to obtain the set of signature with infoType C<signKeyPairTypes> to obtain the set of signature
@ -216,6 +220,9 @@ The OpenSSL CMP support was added in OpenSSL 3.0.
OSSL_CMP_get1_caCerts() and OSSL_CMP_get1_rootCaKeyUpdate() OSSL_CMP_get1_caCerts() and OSSL_CMP_get1_rootCaKeyUpdate()
were added in OpenSSL 3.2. were added in OpenSSL 3.2.
Support for delayed delivery of all types of response messages
was added in OpenSSL 3.3.
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved.

View File

@ -155,13 +155,14 @@ static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
return 0; return 0;
} }
static int reset_transaction(OSSL_CMP_SRV_CTX *srv_ctx) static int clean_transaction(ossl_unused OSSL_CMP_SRV_CTX *srv_ctx,
ossl_unused const ASN1_OCTET_STRING *id)
{ {
return 1; return 1;
} }
static int delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx, static int delayed_delivery(ossl_unused OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *req) ossl_unused const OSSL_CMP_MSG *req)
{ {
return 0; return 0;
} }
@ -195,8 +196,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
&& OSSL_CMP_SRV_CTX_init(srv_ctx, NULL, process_cert_request, && OSSL_CMP_SRV_CTX_init(srv_ctx, NULL, process_cert_request,
process_rr, process_genm, process_error, process_rr, process_genm, process_error,
process_certConf, process_pollReq) process_certConf, process_pollReq)
&& OSSL_CMP_SRV_CTX_setup_polling(srv_ctx, reset_transaction, && OSSL_CMP_SRV_CTX_init_trans(srv_ctx, delayed_delivery,
delayed_delivery)) clean_transaction))
OSSL_CMP_MSG_free(OSSL_CMP_SRV_process_request(srv_ctx, msg)); OSSL_CMP_MSG_free(OSSL_CMP_SRV_process_request(srv_ctx, msg));
OSSL_CMP_CTX_free(client_ctx); OSSL_CMP_CTX_free(client_ctx);

View File

@ -469,9 +469,6 @@ typedef int (*OSSL_CMP_SRV_pollReq_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *req, int certReqId, const OSSL_CMP_MSG *req, int certReqId,
OSSL_CMP_MSG **certReq, OSSL_CMP_MSG **certReq,
int64_t *check_after); int64_t *check_after);
typedef int (*OSSL_CMP_SRV_reset_transaction_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx);
typedef int (*OSSL_CMP_SRV_delayed_delivery_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *req);
int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx, int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
OSSL_CMP_SRV_cert_request_cb_t process_cert_request, OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
OSSL_CMP_SRV_rr_cb_t process_rr, OSSL_CMP_SRV_rr_cb_t process_rr,
@ -479,9 +476,13 @@ int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
OSSL_CMP_SRV_error_cb_t process_error, OSSL_CMP_SRV_error_cb_t process_error,
OSSL_CMP_SRV_certConf_cb_t process_certConf, OSSL_CMP_SRV_certConf_cb_t process_certConf,
OSSL_CMP_SRV_pollReq_cb_t process_pollReq); OSSL_CMP_SRV_pollReq_cb_t process_pollReq);
int OSSL_CMP_SRV_CTX_setup_polling(OSSL_CMP_SRV_CTX *srv_ctx, typedef int (*OSSL_CMP_SRV_delayed_delivery_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
OSSL_CMP_SRV_reset_transaction_cb_t reset_transaction, const OSSL_CMP_MSG *req);
OSSL_CMP_SRV_delayed_delivery_cb_t delayed_delivery); typedef int (*OSSL_CMP_SRV_clean_transaction_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
const ASN1_OCTET_STRING *id);
int OSSL_CMP_SRV_CTX_init_trans(OSSL_CMP_SRV_CTX *srv_ctx,
OSSL_CMP_SRV_delayed_delivery_cb_t delay,
OSSL_CMP_SRV_clean_transaction_cb_t clean);
OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx); OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx); void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx, int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,

View File

@ -55,6 +55,7 @@
# define CMP_R_ERROR_UNEXPECTED_CERTCONF 160 # define CMP_R_ERROR_UNEXPECTED_CERTCONF 160
# define CMP_R_ERROR_VALIDATING_PROTECTION 140 # define CMP_R_ERROR_VALIDATING_PROTECTION 140
# define CMP_R_ERROR_VALIDATING_SIGNATURE 171 # define CMP_R_ERROR_VALIDATING_SIGNATURE 171
# define CMP_R_EXPECTED_POLLREQ 104
# define CMP_R_FAILED_BUILDING_OWN_CHAIN 164 # define CMP_R_FAILED_BUILDING_OWN_CHAIN 164
# define CMP_R_FAILED_EXTRACTING_PUBKEY 141 # define CMP_R_FAILED_EXTRACTING_PUBKEY 141
# define CMP_R_FAILURE_OBTAINING_RANDOM 110 # define CMP_R_FAILURE_OBTAINING_RANDOM 110
@ -101,12 +102,14 @@
# define CMP_R_UNEXPECTED_CERTPROFILE 196 # define CMP_R_UNEXPECTED_CERTPROFILE 196
# define CMP_R_UNEXPECTED_PKIBODY 133 # define CMP_R_UNEXPECTED_PKIBODY 133
# define CMP_R_UNEXPECTED_PKISTATUS 185 # define CMP_R_UNEXPECTED_PKISTATUS 185
# define CMP_R_UNEXPECTED_POLLREQ 105
# define CMP_R_UNEXPECTED_PVNO 153 # define CMP_R_UNEXPECTED_PVNO 153
# define CMP_R_UNKNOWN_ALGORITHM_ID 134 # define CMP_R_UNKNOWN_ALGORITHM_ID 134
# define CMP_R_UNKNOWN_CERT_TYPE 135 # define CMP_R_UNKNOWN_CERT_TYPE 135
# define CMP_R_UNKNOWN_PKISTATUS 186 # define CMP_R_UNKNOWN_PKISTATUS 186
# define CMP_R_UNSUPPORTED_ALGORITHM 136 # define CMP_R_UNSUPPORTED_ALGORITHM 136
# define CMP_R_UNSUPPORTED_KEY_TYPE 137 # define CMP_R_UNSUPPORTED_KEY_TYPE 137
# define CMP_R_UNSUPPORTED_PKIBODY 101
# define CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC 154 # define CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC 154
# define CMP_R_VALUE_TOO_LARGE 175 # define CMP_R_VALUE_TOO_LARGE 175
# define CMP_R_VALUE_TOO_SMALL 177 # define CMP_R_VALUE_TOO_SMALL 177

View File

@ -194,7 +194,7 @@ static int test_exec_IR_ses(void)
return result; return result;
} }
static int test_exec_any_ses_poll(int req_type, int check_after, static int test_exec_REQ_ses_poll(int req_type, int check_after,
int poll_count, int total_timeout, int poll_count, int total_timeout,
int expect) int expect)
{ {
@ -206,14 +206,10 @@ static int test_exec_any_ses_poll(int req_type, int check_after,
OSSL_CMP_CTX_set_option(fixture->cmp_ctx, OSSL_CMP_CTX_set_option(fixture->cmp_ctx,
OSSL_CMP_OPT_TOTAL_TIMEOUT, total_timeout); OSSL_CMP_OPT_TOTAL_TIMEOUT, total_timeout);
if (req_type == OSSL_CMP_PKIBODY_IR || req_type == OSSL_CMP_PKIBODY_CR if (req_type == OSSL_CMP_PKIBODY_IR) {
|| req_type == OSSL_CMP_PKIBODY_KUR
|| req_type == OSSL_CMP_PKIBODY_P10CR) {
EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down); EXECUTE_TEST(execute_exec_certrequest_ses_test, tear_down);
} else if (req_type == OSSL_CMP_PKIBODY_GENM) { } else if (req_type == OSSL_CMP_PKIBODY_GENM) {
EXECUTE_TEST(execute_exec_GENM_ses_test, tear_down); EXECUTE_TEST(execute_exec_GENM_ses_test, tear_down);
} else {
result = 0;
} }
return result; return result;
} }
@ -221,20 +217,20 @@ static int test_exec_any_ses_poll(int req_type, int check_after,
static int checkAfter = 1; static int checkAfter = 1;
static int test_exec_IR_ses_poll_ok(void) static int test_exec_IR_ses_poll_ok(void)
{ {
return test_exec_any_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter, 2, 0, return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter, 2, 0,
OSSL_CMP_PKISTATUS_accepted); OSSL_CMP_PKISTATUS_accepted);
} }
static int test_exec_IR_ses_poll_no_timeout(void) static int test_exec_IR_ses_poll_no_timeout(void)
{ {
return test_exec_any_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter, return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter,
2 /* pollCount */, checkAfter + 4, 2 /* pollCount */, checkAfter + 4,
OSSL_CMP_PKISTATUS_accepted); OSSL_CMP_PKISTATUS_accepted);
} }
static int test_exec_IR_ses_poll_total_timeout(void) static int test_exec_IR_ses_poll_total_timeout(void)
{ {
return !test_exec_any_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter + 1, return !test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter + 1,
3 /* pollCount */, checkAfter + 6, 3 /* pollCount */, checkAfter + 6,
OSSL_CMP_PKISTATUS_waiting); OSSL_CMP_PKISTATUS_waiting);
} }
@ -419,20 +415,20 @@ static int test_try_certreq_poll_abort(void)
static int test_exec_GENM_ses_poll_ok(void) static int test_exec_GENM_ses_poll_ok(void)
{ {
return test_exec_any_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter, 2, 0, return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter, 2, 0,
OSSL_CMP_PKISTATUS_accepted); OSSL_CMP_PKISTATUS_accepted);
} }
static int test_exec_GENM_ses_poll_no_timeout(void) static int test_exec_GENM_ses_poll_no_timeout(void)
{ {
return test_exec_any_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter, return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter,
1 /* pollCount */, checkAfter + 1, 1 /* pollCount */, checkAfter + 1,
OSSL_CMP_PKISTATUS_accepted); OSSL_CMP_PKISTATUS_accepted);
} }
static int test_exec_GENM_ses_poll_total_timeout(void) static int test_exec_GENM_ses_poll_total_timeout(void)
{ {
return test_exec_any_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter + 1, return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_GENM, checkAfter + 1,
3 /* pollCount */, checkAfter + 2, 3 /* pollCount */, checkAfter + 2,
OSSL_CMP_PKISTATUS_waiting); OSSL_CMP_PKISTATUS_waiting);
} }

View File

@ -76,7 +76,7 @@ static int execute_test_handle_request(CMP_SRV_TEST_FIXTURE *fixture)
if (!TEST_true(OSSL_CMP_SRV_CTX_init(ctx, dummy_custom_ctx, if (!TEST_true(OSSL_CMP_SRV_CTX_init(ctx, dummy_custom_ctx,
process_cert_request, NULL, NULL, process_cert_request, NULL, NULL,
NULL, NULL, NULL)) NULL, NULL, NULL))
|| !TEST_true(OSSL_CMP_SRV_CTX_setup_polling(ctx, NULL, NULL)) || !TEST_true(OSSL_CMP_SRV_CTX_init_trans(ctx, NULL, NULL))
|| !TEST_ptr(custom_ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(ctx)) || !TEST_ptr(custom_ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(ctx))
|| !TEST_int_eq(strcmp(custom_ctx, dummy_custom_ctx), 0)) || !TEST_int_eq(strcmp(custom_ctx, dummy_custom_ctx), 0))
goto end; goto end;

View File

@ -5540,6 +5540,6 @@ OSSL_CMP_CTX_get0_geninfo_ITAVs ? 3_3_0 EXIST::FUNCTION:CMP
OSSL_CMP_HDR_get0_geninfo_ITAVs ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_HDR_get0_geninfo_ITAVs ? 3_3_0 EXIST::FUNCTION:CMP
OSSL_CMP_ITAV_new0_certProfile ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_ITAV_new0_certProfile ? 3_3_0 EXIST::FUNCTION:CMP
OSSL_CMP_ITAV_get0_certProfile ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_ITAV_get0_certProfile ? 3_3_0 EXIST::FUNCTION:CMP
OSSL_CMP_SRV_CTX_setup_polling ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_SRV_CTX_init_trans ? 3_3_0 EXIST::FUNCTION:CMP
EVP_DigestSqueeze ? 3_3_0 EXIST::FUNCTION: EVP_DigestSqueeze ? 3_3_0 EXIST::FUNCTION:
ERR_pop ? 3_3_0 EXIST::FUNCTION: ERR_pop ? 3_3_0 EXIST::FUNCTION: