From 2418203fee214264dd34e7d7fb678d876d162193 Mon Sep 17 00:00:00 2001 From: Rajeev Ranjan Date: Fri, 23 Feb 2024 10:18:26 +0100 Subject: [PATCH] add option -rsp_crl for Mock server --- apps/cmp.c | 35 +++++++++++-- apps/include/cmp_mock_srv.h | 1 + apps/lib/cmp_mock_srv.c | 49 +++++++++++++++++++ crypto/cmp/cmp_asn.c | 11 ----- doc/man3/OSSL_CMP_ITAV_new_caCerts.pod | 12 ++--- include/openssl/cmp.h.in | 2 - .../80-test_cmp_http_data/Mock/crl.pem | 12 +++++ .../80-test_cmp_http_data/Mock/server.cnf | 1 + util/libcrypto.num | 2 +- 9 files changed, 100 insertions(+), 25 deletions(-) create mode 100644 test/recipes/80-test_cmp_http_data/Mock/crl.pem 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/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c index 9f1a98afe40f00..d46fb2df5498ef 100644 --- a/crypto/cmp/cmp_asn.c +++ b/crypto/cmp/cmp_asn.c @@ -574,17 +574,6 @@ OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_crls(const X509_CRL *crl) return NULL; } -OSSL_CMP_ITAV *OSSL_CMP_ITAV_new0_crls(STACK_OF(X509_CRL) *crls) -{ - OSSL_CMP_ITAV *itav; - - if ((itav = OSSL_CMP_ITAV_new()) == NULL) - return NULL; - itav->infoType = OBJ_nid2obj(NID_id_it_crls); - itav->infoValue.crls = crls; - return itav; -} - int OSSL_CMP_ITAV_get0_crls(const OSSL_CMP_ITAV *itav, STACK_OF(X509_CRL) **out) { if (itav == NULL || out == NULL) { diff --git a/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod b/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod index dd2be78b47963a..54c09972a75b4b 100644 --- a/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod +++ b/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod @@ -15,7 +15,7 @@ OSSL_CMP_CRLSTATUS_create, OSSL_CMP_CRLSTATUS_get0, OSSL_CMP_ITAV_new0_crlStatusList, OSSL_CMP_ITAV_get0_crlStatusList, -OSSL_CMP_ITAV_new0_crls, +OSSL_CMP_ITAV_new_crls, OSSL_CMP_ITAV_get0_crls - CMP utility functions for handling specific genm and genp messages @@ -46,8 +46,7 @@ OSSL_CMP_ITAV_get0_crls *OSSL_CMP_ITAV_new0_crlStatusList(STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList); int OSSL_CMP_ITAV_get0_crlStatusList(const OSSL_CMP_ITAV *itav, STACK_OF(OSSL_CMP_CRLSTATUS) **out); - OSSL_CMP_ITAV - *OSSL_CMP_ITAV_new0_crls(STACK_OF(X509_CRL) *crls); + OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_crls(const X509_CRL *crl); int OSSL_CMP_ITAV_get0_crls(const OSSL_CMP_ITAV *itav, STACK_OF(X509_CRL) **out); =head1 DESCRIPTION @@ -132,8 +131,9 @@ pointer to the list of CRL status data in the infoValue field of I. The pointer may be NULL if no CRL status data is included. It is an error if the infoType of I is not B. -OSSL_CMP_ITAV_new0_crls() creates a new B structure -of type B that includes the optionally given list of CRLs. +OSSL_CMP_ITAV_new_crls() creates a new B structure +of type B and fills it with a copy of the provided CRL. +The I argument may be NULL. OSSL_CMP_ITAV_get0_crls() on success assigns to I<*out> an internal pointer to the list of CRLs contained in the infoValue field of I. @@ -149,7 +149,7 @@ CMP is defined in RFC 4210. OSSL_CMP_ITAV_new_caCerts(), OSSL_CMP_ITAV_new_rootCaCert(), OSSL_CMP_ITAV_new_rootCaKeyUpdate(), OSSL_CMP_CRLSTATUS_new1(), OSSL_CMP_CRLSTATUS_create(), OSSL_CMP_ITAV_new0_crlStatusList() -and OSSL_CMP_ITAV_new0_crls() +and OSSL_CMP_ITAV_new_crls() return a pointer to the new ITAV structure on success, or NULL on error. OSSL_CMP_ITAV_get0_caCerts(), OSSL_CMP_ITAV_get0_rootCaCert(), diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in index cafd24f084e69b..7ac67bd018d5e2 100644 --- a/include/openssl/cmp.h.in +++ b/include/openssl/cmp.h.in @@ -347,8 +347,6 @@ OSSL_CMP_ITAV int OSSL_CMP_ITAV_get0_crlStatusList(const OSSL_CMP_ITAV *itav, STACK_OF(OSSL_CMP_CRLSTATUS) **out); OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_crls(const X509_CRL *crls); -OSSL_CMP_ITAV -*OSSL_CMP_ITAV_new0_crls(STACK_OF(X509_CRL) *crls); int OSSL_CMP_ITAV_get0_crls(const OSSL_CMP_ITAV *it, STACK_OF(X509_CRL) **out); void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg); 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 diff --git a/util/libcrypto.num b/util/libcrypto.num index dc646a32877338..ce3cd0faa83ae4 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5553,6 +5553,6 @@ OSSL_CMP_CRLSTATUS_get0 ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_CRLSTATUS_free ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_ITAV_new0_crlStatusList ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_ITAV_get0_crlStatusList ? 3_3_0 EXIST::FUNCTION:CMP -OSSL_CMP_ITAV_new0_crls ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_ITAV_get0_crls ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_get1_crlUpdate ? 3_3_0 EXIST::FUNCTION:CMP +OSSL_CMP_ITAV_new_crls ? 3_3_0 EXIST::FUNCTION:CMP