diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2022-09-17 10:56:21 +0200 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2023-07-17 00:48:36 +0200 |
commit | 01b048513153bdbee3efc82389d38d353352a7f1 (patch) | |
tree | f22d8f0a44aeb740bc8a7ab837605f82dc10d8f3 /apps | |
parent | CMP app and API doc: add note on critical server auth on receiving trust anch... (diff) | |
download | openssl-01b048513153bdbee3efc82389d38d353352a7f1.tar.xz openssl-01b048513153bdbee3efc82389d38d353352a7f1.zip |
CMP: add support for genm with rootCaCert and genp with rootCaKeyUpdate
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21129)
Diffstat (limited to 'apps')
-rw-r--r-- | apps/cmp.c | 211 | ||||
-rw-r--r-- | apps/include/cmp_mock_srv.h | 3 | ||||
-rw-r--r-- | apps/lib/cmp_mock_srv.c | 98 |
3 files changed, 213 insertions, 99 deletions
diff --git a/apps/cmp.c b/apps/cmp.c index d56a5e451c..dbc609a2e0 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -89,6 +89,10 @@ static int opt_unprotected_errors = 0; static char *opt_srvcertout = NULL; static char *opt_extracertsout = NULL; static char *opt_cacertsout = NULL; +static char *opt_oldwithold = NULL; +static char *opt_newwithnew = NULL; +static char *opt_newwithold = NULL; +static char *opt_oldwithnew = NULL; /* client authentication */ static char *opt_ref = NULL; @@ -181,6 +185,10 @@ static char *opt_ref_cert = NULL; static char *opt_rsp_cert = NULL; static char *opt_rsp_extracerts = NULL; static char *opt_rsp_capubs = NULL; +static char *opt_rsp_newwithnew = NULL; +static char *opt_rsp_newwithold = NULL; +static char *opt_rsp_oldwithnew = NULL; + static int opt_poll_count = 0; static int opt_check_after = 1; static int opt_grant_implicitconf = 0; @@ -224,6 +232,7 @@ typedef enum OPTION_choice { OPT_EXPECT_SENDER, OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT, + OPT_OLDWITHOLD, OPT_NEWWITHNEW, OPT_NEWWITHOLD, OPT_OLDWITHNEW, OPT_REF, OPT_SECRET, OPT_CERT, OPT_OWN_TRUSTED, OPT_KEY, OPT_KEYPASS, OPT_DIGEST, OPT_MAC, OPT_EXTRACERTS, @@ -254,6 +263,7 @@ typedef enum OPTION_choice { OPT_SRV_CERT, OPT_SRV_KEY, OPT_SRV_KEYPASS, OPT_SRV_TRUSTED, OPT_SRV_UNTRUSTED, OPT_REF_CERT, OPT_RSP_CERT, OPT_RSP_EXTRACERTS, OPT_RSP_CAPUBS, + OPT_RSP_NEWWITHNEW, OPT_RSP_NEWWITHOLD, OPT_RSP_OLDWITHNEW, OPT_POLL_COUNT, OPT_CHECK_AFTER, OPT_GRANT_IMPLICITCONF, OPT_PKISTATUS, OPT_FAILURE, @@ -278,7 +288,9 @@ const OPTIONS cmp_options[] = { OPT_SECTION("Generic message"), {"cmd", OPT_CMD, 's', "CMP request to send: ir/cr/kur/p10cr/rr/genm"}, {"infotype", OPT_INFOTYPE, 's', - "InfoType name for requesting specific info in genm, e.g. 'caCerts'"}, + "InfoType name for requesting specific info in genm, with specific support"}, + {OPT_MORE_STR, 0, 0, + "for 'caCerts' and 'rootCaCert'"}, {"geninfo", OPT_GENINFO, 's', "generalInfo integer values to place in request PKIHeader with given OID"}, {OPT_MORE_STR, 0, 0, @@ -399,6 +411,14 @@ const OPTIONS cmp_options[] = { "File to save extra certificates received in the extraCerts field"}, {"cacertsout", OPT_CACERTSOUT, 's', "File to save CA certs received in caPubs field or genp with id-it-caCerts"}, + { "oldwithold", OPT_OLDWITHOLD, 's', + "Root CA certificate to request update for in genm of type rootCaCert"}, + { "newwithnew", OPT_NEWWITHNEW, 's', + "File to save NewWithNew cert received in genp of type rootCaKeyUpdate"}, + { "newwithold", OPT_NEWWITHOLD, 's', + "File to save NewWithOld cert received in genp of type rootCaKeyUpdate"}, + { "oldwithnew", OPT_OLDWITHNEW, 's', + "File to save OldWithNew cert received in genp of type rootCaKeyUpdate"}, OPT_SECTION("Client authentication"), {"ref", OPT_REF, 's', @@ -517,6 +537,12 @@ const OPTIONS cmp_options[] = { "Extra certificates to be included in mock certification responses"}, {"rsp_capubs", OPT_RSP_CAPUBS, 's', "CA certificates to be included in mock ip response"}, + {"rsp_newwithnew", OPT_RSP_NEWWITHNEW, 's', + "New root CA certificate to include in genp of type rootCaKeyUpdate"}, + {"rsp_newwithold", OPT_RSP_NEWWITHOLD, 's', + "NewWithOld transition cert to include in genp of type rootCaKeyUpdate"}, + {"rsp_oldwithnew", OPT_RSP_OLDWITHNEW, 's', + "OldWithNew transition cert to include in genp of type rootCaKeyUpdate"}, {"poll_count", OPT_POLL_COUNT, 'N', "Number of times the client must poll before receiving a certificate"}, {"check_after", OPT_CHECK_AFTER, 'N', @@ -584,6 +610,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {&opt_expect_sender}, {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors}, {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout}, + {&opt_oldwithold}, {&opt_newwithnew}, {&opt_newwithold}, {&opt_oldwithnew}, {&opt_ref}, {&opt_secret}, {&opt_cert}, {&opt_own_trusted}, {&opt_key}, {&opt_keypass}, @@ -614,6 +641,8 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {&opt_srv_cert}, {&opt_srv_key}, {&opt_srv_keypass}, {&opt_srv_trusted}, {&opt_srv_untrusted}, {&opt_ref_cert}, {&opt_rsp_cert}, {&opt_rsp_extracerts}, {&opt_rsp_capubs}, + {&opt_rsp_newwithnew}, {&opt_rsp_newwithold}, {&opt_rsp_oldwithnew}, + {(char **)&opt_poll_count}, {(char **)&opt_check_after}, {(char **)&opt_grant_implicitconf}, {(char **)&opt_pkistatus}, {(char **)&opt_failure}, @@ -929,8 +958,23 @@ static X509_STORE *load_trusted(char *input, int for_new_cert, const char *desc) return NULL; } -typedef int (*add_X509_stack_fn_t)(void *ctx, const STACK_OF(X509) *certs); +typedef int (*add_X509_fn_t)(void *ctx, const X509 *cert); +static int setup_cert(void *ctx, const char *file, const char *pass, + const char *desc, add_X509_fn_t set1_fn) +{ + X509 *cert; + int ok; + + if (file == NULL) + return 1; + if ((cert = load_cert_pwd(file, pass, desc)) == NULL) + return 0; + ok = (*set1_fn)(ctx, cert); + X509_free(cert); + return ok; +} +typedef int (*add_X509_stack_fn_t)(void *ctx, const STACK_OF(X509) *certs); static int setup_certs(char *files, const char *desc, void *ctx, add_X509_stack_fn_t set1_fn) { @@ -1043,16 +1087,10 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) CMP_err("must give both -srv_cert and -srv_key options or neither"); goto err; } - if (opt_srv_cert != NULL) { - X509 *srv_cert = load_cert_pwd(opt_srv_cert, opt_srv_keypass, - "certificate of the mock server"); - - if (srv_cert == NULL || !OSSL_CMP_CTX_set1_cert(ctx, srv_cert)) { - X509_free(srv_cert); - goto err; - } - X509_free(srv_cert); - } + if (!setup_cert(ctx, opt_srv_cert, opt_srv_keypass, + "signer certificate of the mock server", + (add_X509_fn_t)OSSL_CMP_CTX_set1_cert)) + goto err; if (opt_srv_key != NULL) { EVP_PKEY *pkey = load_key_pwd(opt_srv_key, opt_keyform, opt_srv_keypass, @@ -1082,31 +1120,17 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted)) goto err; - if (opt_ref_cert != NULL) { - X509 *cert = load_cert_pwd(opt_ref_cert, opt_keypass, - "reference cert to be expected by the mock server"); - - if (cert == NULL) - goto err; - if (!ossl_cmp_mock_srv_set1_refCert(srv_ctx, cert)) { - X509_free(cert); + if (!setup_cert(srv_ctx, opt_ref_cert, opt_otherpass, + "reference cert to be expected by the mock server", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_refCert)) goto err; - } - X509_free(cert); - } if (opt_rsp_cert == NULL) { CMP_warn("no -rsp_cert given for mock server"); } else { - X509 *cert = load_cert_pwd(opt_rsp_cert, opt_keypass, - "cert to be returned by the mock server"); - - if (cert == NULL) - goto err; - if (!ossl_cmp_mock_srv_set1_certOut(srv_ctx, cert)) { - X509_free(cert); + if (!setup_cert(srv_ctx, opt_rsp_cert, opt_keypass, + "cert the mock server returns on certificate requests", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_certOut)) goto err; - } - X509_free(cert); } if (!setup_certs(opt_rsp_extracerts, "CMP extra certificates for mock server", srv_ctx, @@ -1115,6 +1139,16 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) if (!setup_certs(opt_rsp_capubs, "caPubs for mock server", srv_ctx, (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_caPubsOut)) goto err; + if (!setup_cert(srv_ctx, opt_rsp_newwithnew, opt_otherpass, + "NewWithNew cert the mock server returns in rootCaKeyUpdate", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_newWithNew) + || !setup_cert(srv_ctx, opt_rsp_newwithold, opt_otherpass, + "NewWithOld cert the mock server returns in rootCaKeyUpdate", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_newWithOld) + || !setup_cert(srv_ctx, opt_rsp_oldwithnew, opt_otherpass, + "OldWithNew cert the mock server returns in rootCaKeyUpdate", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_oldWithNew)) + goto err; (void)ossl_cmp_mock_srv_set_pollCount(srv_ctx, opt_poll_count); (void)ossl_cmp_mock_srv_set_checkAfterTime(srv_ctx, opt_check_after); if (opt_grant_implicitconf) @@ -1171,10 +1205,6 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) return 0; if (opt_srvcert != NULL || opt_trusted != NULL) { - X509 *srvcert; - X509_STORE *ts; - int ok; - if (opt_srvcert != NULL) { if (opt_trusted != NULL) { CMP_warn("-trusted option is ignored since -srvcert option is present"); @@ -1184,14 +1214,14 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) CMP_warn("-recipient option is ignored since -srvcert option is present"); opt_recipient = NULL; } - srvcert = load_cert_pwd(opt_srvcert, opt_otherpass, - "directly trusted CMP server certificate"); - ok = srvcert != NULL && OSSL_CMP_CTX_set1_srvCert(ctx, srvcert); - X509_free(srvcert); - if (!ok) + if (!setup_cert(ctx, opt_srvcert, opt_otherpass, + "directly trusted CMP server certificate", + (add_X509_fn_t)OSSL_CMP_CTX_set1_srvCert)) return 0; } if (opt_trusted != NULL) { + X509_STORE *ts; + /* * the 0 arg below clears any expected host/ip/email address; * opt_expect_sender is used instead @@ -1408,7 +1438,7 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) CMP_err("must give -ref if no -cert and no -subject given"); return 0; } - if (!opt_secret && ((opt_cert == NULL) != (opt_key == NULL))) { + if (opt_secret == NULL && ((opt_cert == NULL) != (opt_key == NULL))) { CMP_err("must give both -cert and -key options or neither"); return 0; } @@ -1786,22 +1816,13 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (opt_cmd == CMP_GENM) { CMP_warn("-oldcert option is ignored for 'genm' command"); } else { - X509 *oldcert = load_cert_pwd(opt_oldcert, opt_keypass, - opt_cmd == CMP_KUR ? - "certificate to be updated" : - opt_cmd == CMP_RR ? - "certificate to be revoked" : - "reference certificate (oldcert)"); - /* opt_keypass needed if opt_oldcert is an encrypted PKCS#12 file */ - - if (oldcert == NULL) - return 0; - if (!OSSL_CMP_CTX_set1_oldCert(ctx, oldcert)) { - X509_free(oldcert); - CMP_err("out of memory"); + if (!setup_cert(ctx, opt_oldcert, opt_keypass, + /* needed if opt_oldcert is encrypted PKCS12 file */ + opt_cmd == CMP_KUR ? "certificate to be updated" : + opt_cmd == CMP_RR ? "certificate to be revoked" : + "reference certificate (oldcert)", + (add_X509_fn_t)OSSL_CMP_CTX_set1_oldCert)) return 0; - } - X509_free(oldcert); } } cleanse(opt_keypass); @@ -1969,6 +1990,18 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) goto err; } } + if (opt_cmd != CMP_GENM || opt_infotype != NID_id_it_rootCaCert) { + const char *msg = "option is ignored unless -cmd 'genm' and -infotype rootCaCert is given"; + + if (opt_oldwithold != NULL) + CMP_warn1("-oldwithold %s", msg); + if (opt_newwithnew != NULL) + CMP_warn1("-newwithnew %s", msg); + if (opt_newwithold != NULL) + CMP_warn1("-newwithold %s", msg); + if (opt_oldwithnew != NULL) + CMP_warn1("-oldwithnew %s", msg); + } if (!setup_verification_ctx(ctx)) goto err; @@ -2549,6 +2582,18 @@ static int get_opts(int argc, char **argv) case OPT_CACERTSOUT: opt_cacertsout = opt_str(); break; + case OPT_OLDWITHOLD: + opt_oldwithold = opt_str(); + break; + case OPT_NEWWITHNEW: + opt_newwithnew = opt_str(); + break; + case OPT_NEWWITHOLD: + opt_newwithold = opt_str(); + break; + case OPT_OLDWITHNEW: + opt_oldwithnew = opt_str(); + break; case OPT_V_CASES: if (!opt_verify(o, vpm)) @@ -2727,6 +2772,15 @@ static int get_opts(int argc, char **argv) case OPT_RSP_CAPUBS: opt_rsp_capubs = opt_str(); break; + case OPT_RSP_NEWWITHNEW: + opt_rsp_newwithnew = opt_str(); + break; + case OPT_RSP_NEWWITHOLD: + opt_rsp_newwithold = opt_str(); + break; + case OPT_RSP_OLDWITHNEW: + opt_rsp_oldwithnew = opt_str(); + break; case OPT_POLL_COUNT: opt_poll_count = opt_int_arg(); break; @@ -2905,6 +2959,49 @@ static int do_genm(OSSL_CMP_CTX *ctx) return 0; } return 1; + } else if (opt_infotype == NID_id_it_rootCaCert) { + X509 *oldwithold = NULL; + X509 *newwithnew = NULL; + X509 *newwithold = NULL; + X509 *oldwithnew = NULL; + int res = 0; + + if (opt_newwithnew == NULL) { + CMP_err("Missing -newwithnew option for -infotype rootCaCert"); + return 0; + } + if (opt_oldwithold == NULL) { + CMP_warn("No -oldwithold given, will use all certs given with -trusted as trust anchors for verifying the newWithNew cert"); + } else { + oldwithold = load_cert_pwd(opt_oldwithold, opt_otherpass, + "OldWithOld cert for genm with -infotype rootCaCert"); + if (oldwithold == NULL) + goto end_upd; + } + if (!OSSL_CMP_get1_rootCaKeyUpdate(ctx, oldwithold, &newwithnew, + &newwithold, &oldwithnew)) + goto end_upd; + /* At this point might check authorization of response sender/origin */ + + if (newwithnew == NULL) + CMP_info("no root CA certificate update available"); + else if (oldwithold == NULL && oldwithnew != NULL) + CMP_warn("oldWithNew certificate received in genp for verifying oldWithOld, but oldWithOld was not provided"); + + if (save_cert_or_delete(newwithnew, opt_newwithnew, + "NewWithNew cert from genp") + && save_cert_or_delete(newwithold, opt_newwithold, + "NewWithOld cert from genp") + && save_cert_or_delete(oldwithnew, opt_oldwithnew, + "OldWithNew cert from genp")) + res = 1; + + X509_free(newwithnew); + X509_free(newwithold); + X509_free(oldwithnew); + end_upd: + X509_free(oldwithold); + return res; } else { OSSL_CMP_ITAV *req; STACK_OF(OSSL_CMP_ITAV) *itavs; diff --git a/apps/include/cmp_mock_srv.h b/apps/include/cmp_mock_srv.h index 68a8356857..6308ab93da 100644 --- a/apps/include/cmp_mock_srv.h +++ b/apps/include/cmp_mock_srv.h @@ -26,6 +26,9 @@ int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) *chain); int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) *caPubs); +int ossl_cmp_mock_srv_set1_newWithNew(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); +int ossl_cmp_mock_srv_set1_newWithOld(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); +int ossl_cmp_mock_srv_set1_oldWithNew(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, int fail_info, const char *text); int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype); diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c index e4c30e4438..f0ef2317db 100644 --- a/apps/lib/cmp_mock_srv.c +++ b/apps/lib/cmp_mock_srv.c @@ -22,6 +22,9 @@ typedef struct X509 *certOut; /* certificate to be returned in cp/ip/kup msg */ STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */ STACK_OF(X509) *caPubsOut; /* used in caPubs of ip and in caCerts of genp */ + X509 *newWithNew; /* to return in newWithNew of rootKeyUpdate */ + X509 *newWithOld; /* to return in newWithOld of rootKeyUpdate */ + X509 *oldWithNew; /* to return in oldWithNew of rootKeyUpdate */ OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */ int sendError; /* send error response on given request type */ OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */ @@ -63,37 +66,26 @@ static mock_srv_ctx *mock_srv_ctx_new(void) return NULL; } -int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert) -{ - mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); - - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - if (cert == NULL || X509_up_ref(cert)) { - X509_free(ctx->refCert); - ctx->refCert = cert; - return 1; +#define DEFINE_OSSL_SET1_CERT(FIELD) \ + int ossl_cmp_mock_srv_set1_##FIELD(OSSL_CMP_SRV_CTX *srv_ctx, \ + X509 *cert) \ + { \ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); \ + \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return 0; \ + } \ + if (cert == NULL || X509_up_ref(cert)) { \ + X509_free(ctx->FIELD); \ + ctx->FIELD = cert; \ + return 1; \ + } \ + return 0; \ } - return 0; -} -int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert) -{ - mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); - - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - if (cert == NULL || X509_up_ref(cert)) { - X509_free(ctx->certOut); - ctx->certOut = cert; - return 1; - } - return 0; -} +DEFINE_OSSL_SET1_CERT(refCert) +DEFINE_OSSL_SET1_CERT(certOut) int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) *chain) @@ -129,6 +121,10 @@ int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, return 1; } +DEFINE_OSSL_SET1_CERT(newWithNew) +DEFINE_OSSL_SET1_CERT(newWithOld) +DEFINE_OSSL_SET1_CERT(oldWithNew) + int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, int fail_info, const char *text) { @@ -212,6 +208,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) **caPubs) { mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + int bodytype; OSSL_CMP_PKISI *si = NULL; if (ctx == NULL || cert_req == NULL @@ -219,8 +216,8 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); return NULL; } - if (ctx->sendError == 1 - || ctx->sendError == OSSL_CMP_MSG_get_bodytype(cert_req)) { + bodytype = OSSL_CMP_MSG_get_bodytype(cert_req); + if (ctx->sendError == 1 || ctx->sendError == bodytype) { ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); return NULL; } @@ -245,7 +242,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, ctx->curr_pollCount = 0; /* accept cert update request only for the reference cert, if given */ - if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR + if (bodytype == OSSL_CMP_KUR && crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) { const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm); @@ -268,7 +265,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, if (ctx->chainOut != NULL && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL) goto err; - if (ctx->caPubsOut != NULL + if (ctx->caPubsOut != NULL /* OSSL_CMP_PKIBODY_IP not visible here */ && (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL) goto err; if (ctx->statusOut != NULL @@ -314,6 +311,26 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, return OSSL_CMP_PKISI_dup(ctx->statusOut); } +static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid, + const OSSL_CMP_ITAV *req) +{ + OSSL_CMP_ITAV *rsp; + + switch (req_nid) { + case NID_id_it_caCerts: + rsp = OSSL_CMP_ITAV_new_caCerts(ctx->caPubsOut); + break; + case NID_id_it_rootCaCert: + rsp = OSSL_CMP_ITAV_new_rootCaKeyUpdate(ctx->newWithNew, + ctx->newWithOld, + ctx->oldWithNew); + break; + default: + rsp = OSSL_CMP_ITAV_dup(req); + } + return rsp; +} + static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *genm, const STACK_OF(OSSL_CMP_ITAV) *in, @@ -335,16 +352,13 @@ static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx, OSSL_CMP_ITAV *req = sk_OSSL_CMP_ITAV_value(in, 0), *rsp; ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(req); - if (OBJ_obj2nid(obj) == NID_id_it_caCerts) { - if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL) - return 0; - if ((rsp = OSSL_CMP_ITAV_new_caCerts(ctx->caPubsOut)) == NULL) { - sk_OSSL_CMP_ITAV_free(*out); - return 0; - } - (void)sk_OSSL_CMP_ITAV_push(*out, rsp); + if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL) + return 0; + rsp = process_genm_itav(ctx, OBJ_obj2nid(obj), req); + if (rsp != NULL && sk_OSSL_CMP_ITAV_push(*out, rsp)) return 1; - } + sk_OSSL_CMP_ITAV_free(*out); + return 0; } *out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup, |