diff --git a/apps/cmp.c b/apps/cmp.c index 676dcc9f4c3f0c..3b10a6941e0c74 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -187,6 +187,7 @@ static char *opt_srv_trusted = NULL; static char *opt_srv_untrusted = NULL; static char *opt_ref_cert = NULL; static char *opt_rsp_cert = NULL; +static char *opt_rsp_crl = NULL; static char *opt_rsp_extracerts = NULL; static char *opt_rsp_capubs = NULL; static char *opt_rsp_newwithnew = NULL; @@ -267,9 +268,9 @@ typedef enum OPTION_choice { OPT_SRV_REF, OPT_SRV_SECRET, 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_REF_CERT, OPT_RSP_CERT, OPT_RSP_CRL, 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, OPT_FAILUREBITS, OPT_STATUSSTRING, @@ -546,6 +547,8 @@ const OPTIONS cmp_options[] = { "Certificate to be expected for rr and any oldCertID in kur messages"}, {"rsp_cert", OPT_RSP_CERT, 's', "Certificate to be returned as mock enrollment result"}, + {"rsp_crl", OPT_RSP_CRL, 's', + "CRL to be returned in genp of type crls"}, {"rsp_extracerts", OPT_RSP_EXTRACERTS, 's', "Extra certificates to be included in mock certification responses"}, {"rsp_capubs", OPT_RSP_CAPUBS, 's', @@ -655,8 +658,9 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {&opt_srv_ref}, {&opt_srv_secret}, {&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_ref_cert}, {&opt_rsp_cert}, {&opt_rsp_crl}, {&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}, @@ -1005,6 +1009,21 @@ static int setup_certs(char *files, const char *desc, void *ctx, return ok; } +typedef int (*add_X509_CRL_fn_t)(void *ctx, const X509_CRL *crl); +static int setup_crl(void *ctx, const char *file, const char *desc, + add_X509_CRL_fn_t set1_fn) +{ + X509_CRL *crl; + int ok; + + if (file == NULL) + return 1; + if ((crl = load_crl(file, FORMAT_UNDEF, 0, desc)) == NULL) + return 0; + ok = (*set1_fn)(ctx, crl); + X509_CRL_free(crl); + return ok; +} /* * parse and transform some options, checking their syntax. * Returns 1 on success, 0 on error @@ -1147,6 +1166,9 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) (add_X509_fn_t)ossl_cmp_mock_srv_set1_certOut)) goto err; } + if (!setup_crl(srv_ctx, opt_rsp_crl, "CRL the mock server returns", + (add_X509_CRL_fn_t)ossl_cmp_mock_srv_set1_crlOut)) + goto err; if (!setup_certs(opt_rsp_extracerts, "CMP extra certificates for mock server", srv_ctx, (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_chainOut)) @@ -2909,6 +2931,9 @@ static int get_opts(int argc, char **argv) case OPT_RSP_CERT: opt_rsp_cert = opt_str(); break; + case OPT_RSP_CRL: + opt_rsp_crl = opt_str(); + break; case OPT_RSP_EXTRACERTS: opt_rsp_extracerts = opt_str(); break; diff --git a/apps/include/cmp_mock_srv.h b/apps/include/cmp_mock_srv.h index fcc1ef7bb4f0b3..6b4290460aa6cc 100644 --- a/apps/include/cmp_mock_srv.h +++ b/apps/include/cmp_mock_srv.h @@ -22,6 +22,7 @@ void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx); int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); +int ossl_cmp_mock_srv_set1_crlOut(OSSL_CMP_SRV_CTX *srv_ctx, X509_CRL *crl); 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, diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c index 5fed3a9fd07a19..5116d5ae528f74 100644 --- a/apps/lib/cmp_mock_srv.c +++ b/apps/lib/cmp_mock_srv.c @@ -20,6 +20,7 @@ typedef struct { X509 *refCert; /* cert to expect for oldCertID in kur/rr msg */ X509 *certOut; /* certificate to be returned in cp/ip/kup msg */ + X509_CRL *crlOut; /* CRL to be returned in genp for crls */ 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 */ @@ -87,6 +88,22 @@ static mock_srv_ctx *mock_srv_ctx_new(void) DEFINE_OSSL_SET1_CERT(refCert) DEFINE_OSSL_SET1_CERT(certOut) +int ossl_cmp_mock_srv_set1_crlOut(OSSL_CMP_SRV_CTX *srv_ctx, + X509_CRL *crl) +{ + 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 (crl != NULL && !X509_CRL_up_ref(crl)) + return 0; + X509_CRL_free(ctx->crlOut); + ctx->crlOut = crl; + return 1; +} + int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) *chain) { @@ -391,6 +408,27 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, return OSSL_CMP_PKISI_dup(ctx->statusOut); } +static int check_client_crl(const STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList, + const X509_CRL *crl) +{ + OSSL_CMP_CRLSTATUS *crlstatus; + DIST_POINT_NAME *distpoint; + GENERAL_NAMES *gen; + ASN1_TIME *thisupd; + + if (crlStatusList == NULL || crl == NULL) + return 0; + if (sk_OSSL_CMP_CRLSTATUS_num(crlStatusList) != 1) + return 0; + crlstatus = sk_OSSL_CMP_CRLSTATUS_value(crlStatusList, 0); + if (!OSSL_CMP_CRLSTATUS_get0(crlstatus, &distpoint, &gen, &thisupd)) + return 0; + if (ASN1_TIME_compare(thisupd, X509_CRL_get0_lastUpdate(crl)) >= 0) + return 0; + + return 1; +} + static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid, const OSSL_CMP_ITAV *req) { @@ -405,6 +443,17 @@ static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid, ctx->newWithOld, ctx->oldWithNew); break; + case NID_id_it_crlStatusList: + { + STACK_OF(OSSL_CMP_CRLSTATUS) *crlstatuslist; + + rsp = OSSL_CMP_ITAV_get0_crlStatusList(req, &crlstatuslist) + ? check_client_crl(crlstatuslist, ctx->crlOut) + ? OSSL_CMP_ITAV_new_crls(ctx->crlOut) + : OSSL_CMP_ITAV_new_crls(NULL) + : OSSL_CMP_ITAV_new_crls(NULL); + } + break; default: rsp = OSSL_CMP_ITAV_dup(req); } diff --git a/test/recipes/80-test_cmp_http_data/Mock/crl.pem b/test/recipes/80-test_cmp_http_data/Mock/crl.pem new file mode 100644 index 00000000000000..2645c087c2e961 --- /dev/null +++ b/test/recipes/80-test_cmp_http_data/Mock/crl.pem @@ -0,0 +1,12 @@ +-----BEGIN X509 CRL----- +MIIBvDCBpQIBATANBgkqhkiG9w0BAQsFADBBMQswCQYDVQQGEwJERTEKMAgGA1UE +CgwBVDEMMAoGA1UECwwDQ1NUMRgwFgYDVQQDDA9JbnRlcm1lZGlhdGUtQ0EXDTI0 +MDIyMTEzMzI1M1oXDTI0MDMyMjEzMzI1M1qgMDAuMB8GA1UdIwQYMBaAFBDZZKAn +y+b1L603J/y1BOJ02UqAMAsGA1UdFAQEAgIQADANBgkqhkiG9w0BAQsFAAOCAQEA +Jll0byISsqxLXZEIKUhzP+li/iuwERTP/8YpAI99aKOZdlFALlIrSeEPV1cf00we +FGtFdkRYLIomnv5pMln+54SvA3QZ0dIUHflkFGcBnpCvQT9cFo6LyH9cYhzWBEG9 +bSswnPYjA12wNQGg5ZthAlxq7RdxAWtILm1sfxQGKxZ0xkMV+kFA4+DykwXZ28DH +XD/lR9XmlZiQFDdVtQ5X4wresOoai3ISjLriq9CjtJPjNlXwNtz++olMFficyDgM +Qhz9j+2ybXITf1EQeccO5u1oBxo3neFV/IqWHOUXPUUFffEX3LAc4wm6hovJzQuj +C8Tq5E61cKTCpXRfptp7gg== +-----END X509 CRL----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/server.cnf b/test/recipes/80-test_cmp_http_data/Mock/server.cnf index 5e330789c946ff..e35277c54fc156 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/server.cnf +++ b/test/recipes/80-test_cmp_http_data/Mock/server.cnf @@ -12,6 +12,7 @@ no_cache_extracerts = 1 ref_cert = signer_only.crt rsp_cert = signer_only.crt +rsp_crl = crl.pem rsp_capubs = trusted.crt rsp_extracerts = signer_issuing.crt