From d8925c82f8c9f9c2068ac826b5c071b58586ba82 Mon Sep 17 00:00:00 2001 From: "Dr. David von Oheimb" Date: Sat, 3 Dec 2022 17:49:08 +0100 Subject: [PATCH 1/6] CMP: add support for genm with crlStatusList and genp with crls --- crypto/cmp/cmp_asn.c | 250 ++++++++++++++++++++++++- crypto/cmp/cmp_err.c | 6 +- crypto/cmp/cmp_hdr.c | 7 +- crypto/cmp/cmp_local.h | 35 ++++ doc/man3/OSSL_CMP_ITAV_new_caCerts.pod | 114 +++++++++-- include/crypto/cmperr.h | 2 +- include/openssl/cmp.h.in | 80 +++++++- include/openssl/cmperr.h | 2 +- 8 files changed, 466 insertions(+), 30 deletions(-) diff --git a/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c index 3049d4f080081..2156bb96de109 100644 --- a/crypto/cmp/cmp_asn.c +++ b/crypto/cmp/cmp_asn.c @@ -120,6 +120,11 @@ ASN1_ADB(OSSL_CMP_ITAV) = { ADB_ENTRY(NID_id_it_certProfile, ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.certProfile, ASN1_UTF8STRING)), + ADB_ENTRY(NID_id_it_crlStatusList, + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.crlStatusList, + OSSL_CMP_CRLSTATUS)), + ADB_ENTRY(NID_id_it_crls, + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.crls, X509_CRL)) } ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0, &infotypeandvalue_default_tt, NULL); @@ -138,6 +143,22 @@ ASN1_SEQUENCE(OSSL_CMP_ROOTCAKEYUPDATE) = { } ASN1_SEQUENCE_END(OSSL_CMP_ROOTCAKEYUPDATE) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE) +ASN1_CHOICE(OSSL_CMP_CRLSOURCE) = { + ASN1_EXP(OSSL_CMP_CRLSOURCE, value.dpn, DIST_POINT_NAME, 0), + ASN1_EXP(OSSL_CMP_CRLSOURCE, value.issuer, GENERAL_NAMES, 1), +} ASN1_CHOICE_END(OSSL_CMP_CRLSOURCE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CRLSOURCE) +#define OSSL_CMP_CRLSOURCE_DPN 0 +#define OSSL_CMP_CRLSOURCE_ISSUER 1 + +ASN1_SEQUENCE(OSSL_CMP_CRLSTATUS) = { + ASN1_SIMPLE(OSSL_CMP_CRLSTATUS, source, OSSL_CMP_CRLSOURCE), + ASN1_OPT(OSSL_CMP_CRLSTATUS, thisUpdate, ASN1_TIME) +} ASN1_SEQUENCE_END(OSSL_CMP_CRLSTATUS) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CRLSTATUS) + +IMPLEMENT_ASN1_DUP_FUNCTION(DIST_POINT_NAME) + OSSL_CMP_ITAV *OSSL_CMP_ITAV_create(ASN1_OBJECT *type, ASN1_TYPE *value) { OSSL_CMP_ITAV *itav; @@ -303,7 +324,7 @@ OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, itav->infoValue.rootCaKeyUpdate = upd; return itav; - err: + err: OSSL_CMP_ROOTCAKEYUPDATE_free(upd); return NULL; } @@ -332,7 +353,232 @@ int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav, return 1; } -/* get ASN.1 encoded integer, return -2 on error; -1 is valid for certReqId */ +OSSL_CMP_ITAV +*OSSL_CMP_ITAV_new0_crlStatusList(STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList) +{ + OSSL_CMP_ITAV *itav; + + if ((itav = OSSL_CMP_ITAV_new()) == NULL) + return NULL; + itav->infoType = OBJ_nid2obj(NID_id_it_crlStatusList); + itav->infoValue.crlStatusList = crlStatusList; + return itav; +} + +int OSSL_CMP_ITAV_get0_crlStatusList(const OSSL_CMP_ITAV *itav, + STACK_OF(OSSL_CMP_CRLSTATUS) **out) +{ + if (itav == NULL || out == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (OBJ_obj2nid(itav->infoType) != NID_id_it_crlStatusList) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + *out = itav->infoValue.crlStatusList; + return 1; +} + +OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_new1(const DIST_POINT_NAME *dpn, + const GENERAL_NAMES *issuer, + const ASN1_TIME *thisUpdate) +{ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + return dpn == NULL && issuer == NULL && thisUpdate == NULL ? NULL : NULL; +#else + OSSL_CMP_CRLSOURCE *crlsource; + OSSL_CMP_CRLSTATUS *crlstatus; + + if (dpn == NULL && issuer == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (dpn != NULL && issuer != NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + + if ((crlstatus = OSSL_CMP_CRLSTATUS_new()) == NULL) + return NULL; + crlsource = crlstatus->source; + + if (dpn != NULL) { + crlsource->type = OSSL_CMP_CRLSOURCE_DPN; + if ((crlsource->value.dpn = DIST_POINT_NAME_dup(dpn)) == NULL) + goto err; + } else { + crlsource->type = OSSL_CMP_CRLSOURCE_ISSUER; + if ((crlsource->value.issuer = + sk_GENERAL_NAME_deep_copy(issuer, GENERAL_NAME_dup, + GENERAL_NAME_free)) == NULL) + goto err; + } + + if (thisUpdate != NULL + && (crlstatus->thisUpdate = ASN1_TIME_dup(thisUpdate)) == NULL) + goto err; + return crlstatus; + + err: + OSSL_CMP_CRLSTATUS_free(crlstatus); + return NULL; +#endif +} + +static GENERAL_NAMES *gennames_new(const X509_NAME *nm) +{ + GENERAL_NAMES *names; + GENERAL_NAME *name = NULL; + + if ((names = sk_GENERAL_NAME_new_reserve(NULL, 1)) == NULL) + return NULL; + if (!GENERAL_NAME_create(&name, nm)) { + sk_GENERAL_NAME_free(names); + return NULL; + } + (void)sk_GENERAL_NAME_push(names, name); /* cannot fail */ + return names; +} + +static int gennames_allowed(GENERAL_NAMES *names, int only_DN) +{ + if (names == NULL) + return 0; + if (!only_DN) + return 1; + return sk_GENERAL_NAME_num(names) == 1 + && sk_GENERAL_NAME_value(names, 0)->type == GEN_DIRNAME; +} + +OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_create(const X509_CRL *crl, + const X509 *cert, int only_DN) +{ + STACK_OF(DIST_POINT) *crldps = NULL; + ISSUING_DIST_POINT *idp = NULL; + DIST_POINT_NAME *dpn = NULL; + AUTHORITY_KEYID *akid = NULL; + GENERAL_NAMES *issuers = NULL; + const GENERAL_NAMES *CRLissuer = NULL; + const ASN1_TIME *last = crl == NULL ? NULL : X509_CRL_get0_lastUpdate(crl); + OSSL_CMP_CRLSTATUS *status = NULL; + int i, NID_akid = NID_authority_key_identifier; + + /* + * Note: X509{,_CRL}_get_ext_d2i(..., NID, &i, ...) return the 1st extension + * with the given NID that is available, if any. There might be more such. + */ + if (cert != NULL) { + crldps = X509_get_ext_d2i(cert, NID_crl_distribution_points, &i, NULL); + /* if available, take the first suitable element */ + for (i = 0; i < sk_DIST_POINT_num(crldps); i++) { + DIST_POINT *dp = sk_DIST_POINT_value(crldps, i); + + if (dp == NULL) + continue; + if ((dpn = dp->distpoint) != NULL) { + CRLissuer = NULL; + break; + } + if (gennames_allowed(dp->CRLissuer, only_DN) && CRLissuer == NULL) + /* don't break because any dp->distpoint in list is preferred */ + CRLissuer = dp->CRLissuer; + } + } else { + if (crl == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + idp = X509_CRL_get_ext_d2i(crl, + NID_issuing_distribution_point, &i, NULL); + if (idp != NULL && idp->distpoint != NULL) + dpn = idp->distpoint; + } + + if (dpn == NULL && CRLissuer == NULL) { + if (cert != NULL) { + akid = X509_get_ext_d2i(cert, NID_akid, &i, NULL); + if (akid != NULL && gennames_allowed(akid->issuer, only_DN)) + CRLissuer = akid->issuer; + else + CRLissuer = issuers = gennames_new(X509_get_issuer_name(cert)); + } + if (CRLissuer == NULL && crl != NULL) { + akid = X509_CRL_get_ext_d2i(crl, NID_akid, &i, NULL); + if (akid != NULL && gennames_allowed(akid->issuer, only_DN)) + CRLissuer = akid->issuer; + else + CRLissuer = issuers = gennames_new(X509_CRL_get_issuer(crl)); + } + if (CRLissuer == NULL) + goto end; + } + + status = OSSL_CMP_CRLSTATUS_new1(dpn, CRLissuer, last); + end: + sk_DIST_POINT_pop_free(crldps, DIST_POINT_free); + ISSUING_DIST_POINT_free(idp); + AUTHORITY_KEYID_free(akid); + sk_GENERAL_NAME_pop_free(issuers, GENERAL_NAME_free); + return status; +} + +int OSSL_CMP_CRLSTATUS_get0(const OSSL_CMP_CRLSTATUS *crlstatus, + DIST_POINT_NAME **dpn, GENERAL_NAMES **issuer, + ASN1_TIME **thisUpdate) +{ + OSSL_CMP_CRLSOURCE *crlsource; + + if (crlstatus == NULL || dpn == NULL || issuer == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if ((crlsource = crlstatus->source) == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (crlsource->type == OSSL_CMP_CRLSOURCE_DPN) { + *dpn = crlsource->value.dpn; + *issuer = NULL; + } else if (crlsource->type == OSSL_CMP_CRLSOURCE_ISSUER) { + *dpn = NULL; + *issuer = crlsource->value.issuer; + } else { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (thisUpdate != NULL) + *thisUpdate = crlstatus->thisUpdate; + return 1; +} + +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) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (OBJ_obj2nid(itav->infoType) != NID_id_it_crls) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + *out = itav->infoValue.crls; + return 1; +} + +/* get ASN.1 encoded integer, return -1 on error */ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a) { int64_t res; diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c index 30095aa7c52d3..808f3abbbe911 100644 --- a/crypto/cmp/cmp_err.c +++ b/crypto/cmp/cmp_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -90,7 +90,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_GENP), "invalid genp"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_OPTION), "invalid option"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ROOTCAKEYUPDATE), - "invalid rootcakeyupdate"}, + "invalid rootcakeyupdate"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CERTID), "missing certid"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION), "missing key input for creating protection"}, @@ -146,7 +146,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNCLEAN_CTX), "unclean ctx"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CERTPROFILE), - "unexpected certprofile"}, + "unexpected certprofile"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS), "unexpected pkistatus"}, diff --git a/crypto/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c index 4358b38873f35..c319beedb6fc8 100644 --- a/crypto/cmp/cmp_hdr.c +++ b/crypto/cmp/cmp_hdr.c @@ -90,7 +90,8 @@ int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name) } /* assign to *tgt a copy of src (which may be NULL to indicate an empty DN) */ -static int set1_general_name(GENERAL_NAME **tgt, const X509_NAME *src) +/* TODO move to ../x509/ and use also for OCSP, ESS, etc. */ +int GENERAL_NAME_create(GENERAL_NAME **tgt, const X509_NAME *src) { GENERAL_NAME *name; @@ -126,14 +127,14 @@ int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm) { if (!ossl_assert(hdr != NULL)) return 0; - return set1_general_name(&hdr->sender, nm); + return GENERAL_NAME_create(&hdr->sender, nm); } int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm) { if (!ossl_assert(hdr != NULL)) return 0; - return set1_general_name(&hdr->recipient, nm); + return GENERAL_NAME_create(&hdr->recipient, nm); } int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr) diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h index edec8808a78de..b6148485ff78a 100644 --- a/crypto/cmp/cmp_local.h +++ b/crypto/cmp/cmp_local.h @@ -211,6 +211,36 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT) typedef struct ossl_cmp_rootcakeyupdate_st OSSL_CMP_ROOTCAKEYUPDATE; DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE) +typedef struct ossl_cmp_certreqtemplate_st OSSL_CMP_CERTREQTEMPLATE; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTREQTEMPLATE) + +/*- + * CRLSource ::= CHOICE { + * dpn [0] DistributionPointName, + * issuer [1] GeneralNames } + */ + +typedef struct ossl_cmp_crlsource_st { + int type; + union { + DIST_POINT_NAME *dpn; + GENERAL_NAMES *issuer; + } value; +} OSSL_CMP_CRLSOURCE; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CRLSOURCE) + +/* + * CRLStatus ::= SEQUENCE { + * source CRLSource, + * thisUpdate Time OPTIONAL } + */ + +struct ossl_cmp_crlstatus_st { + OSSL_CMP_CRLSOURCE *source; + ASN1_TIME *thisUpdate; +}; /* OSSL_CMP_CRLSTATUS */ +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CRLSTATUS) + /*- * declared already here as it will be used in OSSL_CMP_MSG (nested) and * infoType and infoValue @@ -264,6 +294,11 @@ struct ossl_cmp_itav_st { X509 *rootCaCert; /* NID_id_it_rootCaKeyUpdate - Root CA Certificate Update */ OSSL_CMP_ROOTCAKEYUPDATE *rootCaKeyUpdate; + /* NID_id_it_crlStatusList - CRL Update Retrieval */ + STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList; + /* NID_id_it_crls - Certificate Status Lists */ + STACK_OF(X509_CRL) *crls; + /* this is to be used for so far undeclared objects */ ASN1_TYPE *other; } infoValue; diff --git a/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod b/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod index 66f0ac90309d2..dd2be78b47963 100644 --- a/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod +++ b/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod @@ -7,7 +7,16 @@ OSSL_CMP_ITAV_get0_caCerts, OSSL_CMP_ITAV_new_rootCaCert, OSSL_CMP_ITAV_get0_rootCaCert, OSSL_CMP_ITAV_new_rootCaKeyUpdate, -OSSL_CMP_ITAV_get0_rootCaKeyUpdate +OSSL_CMP_ITAV_get0_rootCaKeyUpdate, +OSSL_CMP_ITAV_new0_certReqTemplate, +OSSL_CMP_ITAV_get1_certReqTemplate, +OSSL_CMP_CRLSTATUS_new1, +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_get0_crls - CMP utility functions for handling specific genm and genp messages =head1 SYNOPSIS @@ -16,7 +25,6 @@ OSSL_CMP_ITAV_get0_rootCaKeyUpdate OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts); int OSSL_CMP_ITAV_get0_caCerts(const OSSL_CMP_ITAV *itav, STACK_OF(X509) **out); - OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaCert(const X509 *rootCaCert); int OSSL_CMP_ITAV_get0_rootCaCert(const OSSL_CMP_ITAV *itav, X509 **out); OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, @@ -26,6 +34,21 @@ OSSL_CMP_ITAV_get0_rootCaKeyUpdate X509 **newWithNew, X509 **newWithOld, X509 **oldWithNew); + OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_new1(const DIST_POINT_NAME *dpn, + const GENERAL_NAMES *issuer, + const ASN1_TIME *thisUpdate); + OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_create(const X509_CRL *crl, + const X509 *cert, int only_DN); + int OSSL_CMP_CRLSTATUS_get0(const OSSL_CMP_CRLSTATUS *crlstatus, + DIST_POINT_NAME **dpn, GENERAL_NAMES **issuer, + ASN1_TIME **thisUpdate); + OSSL_CMP_ITAV + *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); + int OSSL_CMP_ITAV_get0_crls(const OSSL_CMP_ITAV *itav, STACK_OF(X509_CRL) **out); =head1 DESCRIPTION @@ -50,16 +73,72 @@ OSSL_CMP_ITAV_new_rootCaKeyUpdate() creates a new B structure of type B that includes an RootCaKeyUpdateContent structure with the optional I, I, and I certificates. -OSSL_CMP_ITAV_get0_rootCaKeyUpdate() requires that I has infoType -B. -If an update of a root CA certificate is included, -it assigns to I<*newWithNew> the internal pointer -to the certificate contained in the newWithNew infoValue sub-field of I. -If I is not NULL, it assigns to I<*newWithOld> the internal pointer -to the certificate contained in the newWithOld infoValue sub-field of I. -If I is not NULL, it assigns to I<*oldWithNew> the internal pointer -to the certificate contained in the oldWithNew infoValue sub-field of I. -Each of these pointers will be NULL if the respective sub-field is not set. +OSSL_CMP_ITAV_get0_rootCaKeyUpdate() +requires that I has type B. +It assigns NULL to I<*newWithNew> if no root CA key update value is in I, +otherwise an internal pointer to the certificate contained in the newWithNew +field of the RootCaKeyUpdateContent structure. +If I is not NULL, it assigns to I<*newWithOld> an internal pointer +to the certificate contained in the newWithOld field. +If I is not NULL, it assigns to I<*oldWithNew> an internal pointer +to the certificate contained in the oldWithNew field. +Each of these two pointers will be NULL if no root CA key update value +is in I or the respective field is not present. + +OSSL_CMP_CRLSTATUS_new1() allocates a new B structure +that contains either a copy of the distribution point name I +or a copy of the certificate issuer I, while giving both is an error. +If given, a copy of the CRL issuance time I is also included. + +OSSL_CMP_CRLSTATUS_create() is a high-level variant of OSSL_CMP_CRLSTATUS_new1() +using data obtained from the I and/or I parameters. +The thisUpdate field is filled with the thisUpdate field of I if present. +The CRLSource field is filled with the first data item found in them as follows. +Any available distribution point name is preferred over issuer names. +Data from I, if present, is preferred over data from I. +If no distribution point names are available, +candidate issuer names are taken from following sources, as far as present: + +=over 4 + +=item the list of distribution points in the first cRLDistributionPoints +extension of I, + +=item the issuer field of the authority key identifier of I, + +=item the issuer DN of I, + +=item the issuer field of the authority key identifier of I, and + +=item the issuer DN of I. + +=back + +If is set, a candidate issuer name of type B is +accepted only if it contains exactly one general name of type directoryName. + +OSSL_CMP_CRLSTATUS_get0() reads the fields of I +and assigns them to I<*dpn>, I<*issuer>, and I<*thisUpdate>. +I<*thisUpdate> is assigned only if the I argument is not NULL. +Depending on the choice present, either I<*dpn> or I<*issuer> will be NULL. +I<*thisUpdate> can also be NULL if the field is not present. + +OSSL_CMP_ITAV_new0_crlStatusList() creates a new B structure of +type B that includes the optionally given list of +CRL status data, each of which is of type B. + +OSSL_CMP_ITAV_get0_crlStatusList() on success assigns to I<*out> an internal +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_get0_crls() on success assigns to I<*out> an internal pointer to +the list of CRLs contained in the infoValue field of I. +The pointer may be NULL if no CRL is included. +It is an error if the infoType of I is not B. =head1 NOTES @@ -67,12 +146,15 @@ CMP is defined in RFC 4210. =head1 RETURN VALUES -OSSL_CMP_ITAV_new_caCerts(), -OSSL_CMP_ITAV_new_rootCaCert(), and OSSL_CMP_ITAV_new_rootCaKeyUpdate() +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() return a pointer to the new ITAV structure on success, or NULL on error. -OSSL_CMP_ITAV_get0_caCerts(), -OSSL_CMP_ITAV_get0_rootCaCert(), and OSSL_CMP_ITAV_get0_rootCaKeyUpdate() +OSSL_CMP_ITAV_get0_caCerts(), OSSL_CMP_ITAV_get0_rootCaCert(), +OSSL_CMP_ITAV_get0_rootCaKeyUpdate(), OSSL_CMP_CRLSTATUS_get0(), +OSSL_CMP_ITAV_get0_crlStatusList() and OSSL_CMP_ITAV_get0_crls() return 1 on success, 0 on error. =head1 SEE ALSO diff --git a/include/crypto/cmperr.h b/include/crypto/cmperr.h index 2bd1637384661..89512baabb9de 100644 --- a/include/crypto/cmperr.h +++ b/include/crypto/cmperr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in index da82a3f41927a..f0fab5dc192a5 100644 --- a/include/openssl/cmp.h.in +++ b/include/openssl/cmp.h.in @@ -32,6 +32,9 @@ use OpenSSL::stackhash qw(generate_stack_macros); # include # include +/* TODO move to x509v3.h.in and use also for OCSP, ESS, etc. */ +int GENERAL_NAME_create(GENERAL_NAME **tgt, const X509_NAME *src); + # ifdef __cplusplus extern "C" { # endif @@ -225,9 +228,61 @@ typedef struct ossl_cmp_certstatus_st OSSL_CMP_CERTSTATUS; -} typedef struct ossl_cmp_itav_st OSSL_CMP_ITAV; DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV) -{- - generate_stack_macros("OSSL_CMP_ITAV"); --} +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_ITAV, OSSL_CMP_ITAV, OSSL_CMP_ITAV) +#define sk_OSSL_CMP_ITAV_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_value(sk, idx) ((OSSL_CMP_ITAV *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk), (idx))) +#define sk_OSSL_CMP_ITAV_new(cmp) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp))) +#define sk_OSSL_CMP_ITAV_new_null() ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CMP_ITAV_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp), (n))) +#define sk_OSSL_CMP_ITAV_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (n)) +#define sk_OSSL_CMP_ITAV_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_delete(sk, i) ((OSSL_CMP_ITAV *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (i))) +#define sk_OSSL_CMP_ITAV_delete_ptr(sk, ptr) ((OSSL_CMP_ITAV *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr))) +#define sk_OSSL_CMP_ITAV_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) +#define sk_OSSL_CMP_ITAV_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) +#define sk_OSSL_CMP_ITAV_pop(sk) ((OSSL_CMP_ITAV *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_ITAV_sk_type(sk))) +#define sk_OSSL_CMP_ITAV_shift(sk) ((OSSL_CMP_ITAV *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_ITAV_sk_type(sk))) +#define sk_OSSL_CMP_ITAV_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_ITAV_sk_type(sk),ossl_check_OSSL_CMP_ITAV_freefunc_type(freefunc)) +#define sk_OSSL_CMP_ITAV_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr), (idx)) +#define sk_OSSL_CMP_ITAV_set(sk, idx, ptr) ((OSSL_CMP_ITAV *)OPENSSL_sk_set(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (idx), ossl_check_OSSL_CMP_ITAV_type(ptr))) +#define sk_OSSL_CMP_ITAV_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) +#define sk_OSSL_CMP_ITAV_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) +#define sk_OSSL_CMP_ITAV_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr), pnum) +#define sk_OSSL_CMP_ITAV_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_dup(sk) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk))) +#define sk_OSSL_CMP_ITAV_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_ITAV_freefunc_type(freefunc))) +#define sk_OSSL_CMP_ITAV_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_ITAV_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp))) + +typedef struct ossl_cmp_crlstatus_st OSSL_CMP_CRLSTATUS; +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_CRLSTATUS, OSSL_CMP_CRLSTATUS, OSSL_CMP_CRLSTATUS) +#define sk_OSSL_CMP_CRLSTATUS_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CRLSTATUS_value(sk, idx) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk), (idx))) +#define sk_OSSL_CMP_CRLSTATUS_new(cmp) ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_CRLSTATUS_compfunc_type(cmp))) +#define sk_OSSL_CMP_CRLSTATUS_new_null() ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CMP_CRLSTATUS_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_CRLSTATUS_compfunc_type(cmp), (n))) +#define sk_OSSL_CMP_CRLSTATUS_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), (n)) +#define sk_OSSL_CMP_CRLSTATUS_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CRLSTATUS_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CRLSTATUS_delete(sk, i) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), (i))) +#define sk_OSSL_CMP_CRLSTATUS_delete_ptr(sk, ptr) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr))) +#define sk_OSSL_CMP_CRLSTATUS_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr)) +#define sk_OSSL_CMP_CRLSTATUS_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr)) +#define sk_OSSL_CMP_CRLSTATUS_pop(sk) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk))) +#define sk_OSSL_CMP_CRLSTATUS_shift(sk) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk))) +#define sk_OSSL_CMP_CRLSTATUS_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk),ossl_check_OSSL_CMP_CRLSTATUS_freefunc_type(freefunc)) +#define sk_OSSL_CMP_CRLSTATUS_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr), (idx)) +#define sk_OSSL_CMP_CRLSTATUS_set(sk, idx, ptr) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_set(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), (idx), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr))) +#define sk_OSSL_CMP_CRLSTATUS_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr)) +#define sk_OSSL_CMP_CRLSTATUS_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr)) +#define sk_OSSL_CMP_CRLSTATUS_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr), pnum) +#define sk_OSSL_CMP_CRLSTATUS_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CRLSTATUS_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CRLSTATUS_dup(sk) ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk))) +#define sk_OSSL_CMP_CRLSTATUS_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_CRLSTATUS_freefunc_type(freefunc))) +#define sk_OSSL_CMP_CRLSTATUS_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_CRLSTATUS_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_compfunc_type(cmp))) + typedef struct ossl_cmp_revrepcontent_st OSSL_CMP_REVREPCONTENT; typedef struct ossl_cmp_pkisi_st OSSL_CMP_PKISI; DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI) @@ -257,7 +312,7 @@ void OSSL_CMP_ITAV_set0(OSSL_CMP_ITAV *itav, ASN1_OBJECT *type, ASN1_TYPE *value); ASN1_OBJECT *OSSL_CMP_ITAV_get0_type(const OSSL_CMP_ITAV *itav); ASN1_TYPE *OSSL_CMP_ITAV_get0_value(const OSSL_CMP_ITAV *itav); -int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, +int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **sk_p, OSSL_CMP_ITAV *itav); void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav); @@ -278,6 +333,23 @@ int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav, X509 **newWithOld, X509 **oldWithNew); +OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_create(const X509_CRL *crl, + const X509 *cert, int only_DN); +OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_new1(const DIST_POINT_NAME *dpn, + const GENERAL_NAMES *issuer, + const ASN1_TIME *thisUpdate); +int OSSL_CMP_CRLSTATUS_get0(const OSSL_CMP_CRLSTATUS *crlstatus, + DIST_POINT_NAME **dpn, GENERAL_NAMES **issuer, + ASN1_TIME **thisUpdate); +void OSSL_CMP_CRLSTATUS_free(OSSL_CMP_CRLSTATUS *crlstatus); +OSSL_CMP_ITAV +*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); +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); /* from cmp_ctx.c */ diff --git a/include/openssl/cmperr.h b/include/openssl/cmperr.h index 90222e4dacfe7..0d876e501c5c2 100644 --- a/include/openssl/cmperr.h +++ b/include/openssl/cmperr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy From 2feaaf72415de0a2a550b06b7d5a17f91665cf18 Mon Sep 17 00:00:00 2001 From: Rajeev Ranjan Date: Tue, 20 Feb 2024 13:18:02 +0100 Subject: [PATCH 2/6] cmp.c: save CRL to file --- apps/cmp.c | 143 ++++++++++++++++++++++++++++++++++----- crypto/cmp/cmp_asn.c | 29 ++++++-- crypto/cmp/cmp_err.c | 3 + crypto/cmp/cmp_genm.c | 62 +++++++++++++++++ crypto/err/openssl.txt | 2 + include/openssl/cmp.h.in | 3 + include/openssl/cmperr.h | 2 + util/libcrypto.num | 10 +++ 8 files changed, 232 insertions(+), 22 deletions(-) diff --git a/apps/cmp.c b/apps/cmp.c index a280cea720597..fc9654d37c1a4 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -94,6 +94,8 @@ static char *opt_oldwithold = NULL; static char *opt_newwithnew = NULL; static char *opt_newwithold = NULL; static char *opt_oldwithnew = NULL; +static char *opt_oldcrl = NULL; +static char *opt_crlout = NULL; /* client authentication */ static char *opt_ref = NULL; @@ -237,6 +239,7 @@ typedef enum OPTION_choice { OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, OPT_NO_CACHE_EXTRACERTS, OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT, OPT_OLDWITHOLD, OPT_NEWWITHNEW, OPT_NEWWITHOLD, OPT_OLDWITHNEW, + OPT_OLDCRL, OPT_CRLOUT, OPT_REF, OPT_SECRET, OPT_CERT, OPT_OWN_TRUSTED, OPT_KEY, OPT_KEYPASS, OPT_DIGEST, OPT_MAC, OPT_EXTRACERTS, @@ -428,6 +431,10 @@ const OPTIONS cmp_options[] = { "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"}, + { "oldcrl", OPT_OLDCRL, 's', + "CRL to request update for in genm of type crlStatusList"}, + { "crlout", OPT_CRLOUT, 's', + "File to save new CRL received in genp of type 'crls'"}, OPT_SECTION("Client authentication"), {"ref", OPT_REF, 's', @@ -623,6 +630,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {(char **)&opt_no_cache_extracerts}, {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout}, {&opt_oldwithold}, {&opt_newwithnew}, {&opt_newwithold}, {&opt_oldwithnew}, + {&opt_oldcrl}, {&opt_crlout}, {&opt_ref}, {&opt_secret}, {&opt_cert}, {&opt_own_trusted}, {&opt_key}, {&opt_keypass}, @@ -1880,8 +1888,8 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POPO_METHOD, opt_popo); if (opt_oldcert != NULL) { - if (opt_cmd == CMP_GENM) { - CMP_warn("-oldcert option is ignored for 'genm' command"); + if (opt_cmd == CMP_GENM && opt_infotype != NID_id_it_crlStatusList) { + CMP_warn("-oldcert option is ignored for 'genm' command except with -infotype crlStatusList"); } else { if (!setup_cert(ctx, opt_oldcert, opt_keypass, /* needed if opt_oldcert is encrypted PKCS12 file */ @@ -1915,20 +1923,20 @@ static int add_certProfile(OSSL_CMP_CTX *ctx, const char *name) if ((sk = sk_ASN1_UTF8STRING_new_reserve(NULL, 1)) == NULL) return 0; - if ((utf8string = ASN1_UTF8STRING_new()) == NULL) - goto err; - if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) { - ASN1_STRING_free(utf8string); - goto err; - } - /* Due to sk_ASN1_UTF8STRING_new_reserve(NULL, 1), this surely succeeds: */ - (void)sk_ASN1_UTF8STRING_push(sk, utf8string); - if ((itav = OSSL_CMP_ITAV_new0_certProfile(sk)) == NULL) - goto err; - if (OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) - return 1; - OSSL_CMP_ITAV_free(itav); - return 0; + if ((utf8string = ASN1_UTF8STRING_new()) == NULL) + goto err; + if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) { + ASN1_STRING_free(utf8string); + goto err; + } + /* Due to sk_ASN1_UTF8STRING_new_reserve(NULL, 1), this surely succeeds: */ + (void)sk_ASN1_UTF8STRING_push(sk, utf8string); + if ((itav = OSSL_CMP_ITAV_new0_certProfile(sk)) == NULL) + goto err; + if (OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) + return 1; + OSSL_CMP_ITAV_free(itav); + return 0; err: sk_ASN1_UTF8STRING_pop_free(sk, ASN1_UTF8STRING_free); @@ -1973,7 +1981,7 @@ static int handle_opt_geninfo(OSSL_CMP_CTX *ctx) if (*ptr != '\0') { if (*ptr != ',') { CMP_err1("Missing ',' or end of -geninfo arg after int at %.40s", - ptr); + ptr); goto err; } ptr++; @@ -2248,6 +2256,18 @@ static int write_cert(BIO *bio, X509 *cert) return 0; } +static int write_crl(BIO *bio, X509_CRL *crl) +{ + if ((opt_certform == FORMAT_PEM && PEM_write_bio_X509_CRL(bio, crl)) + || (opt_certform == FORMAT_ASN1 && i2d_X509_CRL_bio(bio, crl))) + return 1; + if (opt_certform != FORMAT_PEM && opt_certform != FORMAT_ASN1) + BIO_printf(bio_err, + "error: unsupported type '%s' for writing CRLs\n", + opt_certform_s); + return 0; +} + /* * If file != NULL writes out a stack of certs to the given file. * If certs is NULL, the file is emptied. @@ -2295,6 +2315,35 @@ static int save_free_certs(STACK_OF(X509) *certs, return n; } +static int save_free_crl(X509_CRL *crl, + const char *file, const char *desc) +{ + BIO *bio = NULL; + int res = 0; + + if (file == NULL) + goto end; + if (crl != NULL) + CMP_info2("received %s CRL, saving to file '%s'", desc, file); + + if ((bio = BIO_new(BIO_s_file())) == NULL + || !BIO_write_filename(bio, (char *)file)) { + CMP_err3("could not open file '%s' for %s %s CRL", + file, crl == NULL ? "deleting" : "writing", desc); + goto end; + } + + if (!write_crl(bio, crl)) { + CMP_err2("cannot write %s crl to file '%s'", desc, file); + goto end; + } + res = 1; + + end: + BIO_free(bio); + return res; +} + static int delete_file(const char *file, const char *desc) { if (file == NULL) @@ -2328,6 +2377,20 @@ static int save_cert_or_delete(X509 *cert, const char *file, const char *desc) } } +static int save_crl_or_delete(X509_CRL *crl, const char *file, const char *desc) +{ + if (file == NULL) + return 1; + if (crl == NULL) { + char desc_crl[80]; + + BIO_snprintf(desc_crl, sizeof(desc_crl), "%s CRL", desc); + return delete_file(file, desc_crl); + } else { + return save_free_crl(crl, file, desc); + } +} + static int print_itavs(const STACK_OF(OSSL_CMP_ITAV) *itavs) { int i, ret = 1; @@ -2727,7 +2790,12 @@ static int get_opts(int argc, char **argv) case OPT_OLDWITHNEW: opt_oldwithnew = opt_str(); break; - + case OPT_OLDCRL: + opt_oldcrl = opt_str(); + break; + case OPT_CRLOUT: + opt_crlout = opt_str(); + break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto opthelp; @@ -3141,6 +3209,45 @@ static int do_genm(OSSL_CMP_CTX *ctx) end_upd: X509_free(oldwithold); return res; + } else if (opt_infotype == NID_id_it_crlStatusList) { + X509_CRL *oldcrl = NULL, *crl = NULL; + int res = 0; + + if (opt_oldcrl == NULL && opt_oldcert == NULL) { + CMP_err("Missing -oldcrl and no -oldcert given for -infotype crlStatusList"); + return 0; + } + if (opt_crlout == NULL) { + CMP_err("Missing -crlout for -infotype crlStatusList"); + return 0; + } + + if (opt_oldcrl == NULL) { + CMP_warn("No -oldcrl given, will use data from -oldcert"); + } else { + oldcrl = load_crl(opt_oldcrl, FORMAT_UNDEF, 0, + "CRL for genm with -infotype crlStatusList"); + if (oldcrl == NULL) + goto end_crlupd; + } + if (!OSSL_CMP_get1_crlUpdate(ctx, oldcrl, &crl)) + goto end_crlupd; + + const char *desc = "CRL from genp of type 'crls'"; + if (crl == NULL) { + CMP_info("no CRL update available"); + if (!delete_file(opt_crlout, desc)) + goto end_crlupd; + } else if (!save_crl_or_delete(crl, opt_crlout, desc)) { + goto end_crlupd; + } + res = 1; + + end_crlupd: + X509_CRL_free(oldcrl); + X509_CRL_free(crl); + return res; + } else { OSSL_CMP_ITAV *req; STACK_OF(OSSL_CMP_ITAV) *itavs; diff --git a/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c index 2156bb96de109..9f1a98afe40f0 100644 --- a/crypto/cmp/cmp_asn.c +++ b/crypto/cmp/cmp_asn.c @@ -384,9 +384,6 @@ OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_new1(const DIST_POINT_NAME *dpn, const GENERAL_NAMES *issuer, const ASN1_TIME *thisUpdate) { -#if OPENSSL_VERSION_NUMBER < 0x30000000L - return dpn == NULL && issuer == NULL && thisUpdate == NULL ? NULL : NULL; -#else OSSL_CMP_CRLSOURCE *crlsource; OSSL_CMP_CRLSTATUS *crlstatus; @@ -423,7 +420,6 @@ OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_new1(const DIST_POINT_NAME *dpn, err: OSSL_CMP_CRLSTATUS_free(crlstatus); return NULL; -#endif } static GENERAL_NAMES *gennames_new(const X509_NAME *nm) @@ -553,6 +549,31 @@ int OSSL_CMP_CRLSTATUS_get0(const OSSL_CMP_CRLSTATUS *crlstatus, return 1; } +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_crls(const X509_CRL *crl) +{ + OSSL_CMP_ITAV *itav; + X509_CRL *crl_copy = NULL; + STACK_OF(X509_CRL) *crls = NULL; + + if ((itav = OSSL_CMP_ITAV_new()) == NULL) + return NULL; + + if (crl != NULL + && ((crls = sk_X509_CRL_new_reserve(NULL, 1)) == NULL + || (crl_copy = X509_CRL_dup(crl)) == NULL + || !sk_X509_CRL_push(crls, crl_copy))) + goto err; + + itav->infoType = OBJ_nid2obj(NID_id_it_crls); + itav->infoValue.crls = crls; + return itav; + + err: + sk_X509_CRL_free(crls); + OSSL_CMP_ITAV_free(itav); + return NULL; +} + OSSL_CMP_ITAV *OSSL_CMP_ITAV_new0_crls(STACK_OF(X509_CRL) *crls) { OSSL_CMP_ITAV *itav; diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c index 808f3abbbe911..31a062f86ceeb 100644 --- a/crypto/cmp/cmp_err.c +++ b/crypto/cmp/cmp_err.c @@ -85,7 +85,10 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { "failure obtaining random"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE), "fail info out of range"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GENERATE_CRLSTATUS), + "error creating crlstatus"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GETTING_GENP), "getting genp"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GET_ITAV), "get itav"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_GENP), "invalid genp"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_OPTION), "invalid option"}, diff --git a/crypto/cmp/cmp_genm.c b/crypto/cmp/cmp_genm.c index dad6ef1189713..e524e19e69a8b 100644 --- a/crypto/cmp/cmp_genm.c +++ b/crypto/cmp/cmp_genm.c @@ -344,3 +344,65 @@ int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, X509_free(oldWithOld_copy); return res; } + +int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509_CRL *last_crl, + X509_CRL **crl) +{ + OSSL_CMP_CRLSTATUS *status = NULL; + STACK_OF(OSSL_CMP_CRLSTATUS) *list = NULL; + OSSL_CMP_ITAV *req = NULL, *itav = NULL; + STACK_OF(X509_CRL) *crls; + int res = 0; + + if (crl == NULL) { + ERR_raise_data(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT, + "No crl output parameter given"); + return 0; + } + *crl = NULL; + + if ((status = OSSL_CMP_CRLSTATUS_create(last_crl, ctx->oldCert, 1)) == NULL) { + ERR_raise_data(ERR_LIB_CMP, CMP_R_GENERATE_CRLSTATUS, + "Cannot set up CRLStatus structure"); + goto end; + } + if ((list = sk_OSSL_CMP_CRLSTATUS_new_reserve(NULL, 1)) == NULL) { + ERR_raise_data(ERR_LIB_CMP, CMP_R_GENERATE_CRLSTATUS, + "Cannot set up CRLStatus list"); + goto end; + } + (void)sk_OSSL_CMP_CRLSTATUS_push(list, status); /* cannot fail */ + + if ((req = OSSL_CMP_ITAV_new0_crlStatusList(list)) == NULL) + goto end; + + status = NULL; + list = NULL; + + itav = get_genm_itav(ctx, req, NID_id_it_crls, "crl"); + if (itav == NULL) + goto end; + + if (!OSSL_CMP_ITAV_get0_crls(itav, &crls)) + goto end; + + if (crls == NULL) /* no CRL update available */ + goto end; + if (sk_X509_CRL_num(crls) != 1) { + ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_GENP, + "Unexpected number of CRLs in genp: %d", + sk_X509_CRL_num(crls)); + goto end; + } + + if ((*crl = sk_X509_CRL_value(crls, 0)) == NULL || !X509_CRL_up_ref(*crl)) { + *crl = NULL; + goto end; + } + res = 1; + end: + OSSL_CMP_CRLSTATUS_free(status); + sk_OSSL_CMP_CRLSTATUS_free(list); + OSSL_CMP_ITAV_free(itav); + return res; +} diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 22b5de9a7adb6..f60bf49907281 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -234,7 +234,9 @@ CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range +CMP_R_GENERATE_CRLSTATUS:198:error creating crlstatus CMP_R_GETTING_GENP:192:getting genp +CMP_R_GET_ITAV:199:get itav CMP_R_INVALID_ARGS:100:invalid args CMP_R_INVALID_GENP:193:invalid genp CMP_R_INVALID_OPTION:174:invalid option diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in index f0fab5dc192a5..763162899f7f7 100644 --- a/include/openssl/cmp.h.in +++ b/include/openssl/cmp.h.in @@ -346,6 +346,7 @@ OSSL_CMP_ITAV *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_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); @@ -593,6 +594,8 @@ int OSSL_CMP_get1_caCerts(OSSL_CMP_CTX *ctx, STACK_OF(X509) **out); int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, const X509 *oldWithOld, X509 **newWithNew, X509 **newWithOld, X509 **oldWithNew); +int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509_CRL *last_crl, + X509_CRL **crl); # ifdef __cplusplus } diff --git a/include/openssl/cmperr.h b/include/openssl/cmperr.h index 0d876e501c5c2..aa2877c132d1f 100644 --- a/include/openssl/cmperr.h +++ b/include/openssl/cmperr.h @@ -60,7 +60,9 @@ # define CMP_R_FAILED_EXTRACTING_PUBKEY 141 # define CMP_R_FAILURE_OBTAINING_RANDOM 110 # define CMP_R_FAIL_INFO_OUT_OF_RANGE 129 +# define CMP_R_GENERATE_CRLSTATUS 198 # define CMP_R_GETTING_GENP 192 +# define CMP_R_GET_ITAV 199 # define CMP_R_INVALID_ARGS 100 # define CMP_R_INVALID_GENP 193 # define CMP_R_INVALID_OPTION 174 diff --git a/util/libcrypto.num b/util/libcrypto.num index 7f646cbba9926..1e980aa6f5c53 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5547,3 +5547,13 @@ ERR_pop ? 3_3_0 EXIST::FUNCTION: X509_STORE_get1_objects ? 3_3_0 EXIST::FUNCTION: OPENSSL_LH_set_thunks ? 3_3_0 EXIST::FUNCTION: OPENSSL_LH_doall_arg_thunk ? 3_3_0 EXIST::FUNCTION: +GENERAL_NAME_create ? 3_3_0 EXIST::FUNCTION:CMP +OSSL_CMP_CRLSTATUS_create ? 3_3_0 EXIST::FUNCTION:CMP +OSSL_CMP_CRLSTATUS_new1 ? 3_3_0 EXIST::FUNCTION:CMP +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 From dd8c4f8f9eaf3f62a30e2d7aa26af54a5f71e6f5 Mon Sep 17 00:00:00 2001 From: Rajeev Ranjan Date: Fri, 23 Feb 2024 10:18:26 +0100 Subject: [PATCH 3/6] 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 fc9654d37c1a4..6c2a773d533ba 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -189,6 +189,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; @@ -270,9 +271,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, @@ -551,6 +552,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', @@ -660,8 +663,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}, @@ -1018,6 +1022,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 @@ -1160,6 +1179,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)) @@ -2973,6 +2995,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 fcc1ef7bb4f0b..6b4290460aa6c 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 5fed3a9fd07a1..5116d5ae528f7 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 9f1a98afe40f0..d46fb2df5498e 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 dd2be78b47963..54c09972a75b4 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 763162899f7f7..80496672f04c1 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 0000000000000..2645c087c2e96 --- /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 5e330789c946f..e35277c54fc15 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 1e980aa6f5c53..c26273ccf3057 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5554,6 +5554,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 From 9517a1d3f3f74c13703110b499cd620e411dc90f Mon Sep 17 00:00:00 2001 From: Rajeev Ranjan Date: Fri, 23 Feb 2024 22:54:13 +0100 Subject: [PATCH 4/6] add test case of crlStatusList OSSL_CMP_exec_certreq.pod: add OSSL_CMP_get1_crlUpdate() add documentation for GENERAL_NAME_create() add OSSL_CMP_CTX_get0_oldCert() add issuer check and generate warning add error CMP_R_UNKNOWN_CRL_ISSUER Fix OSSL_CMP_get1_crlUpdate parameter in cmp_genm.c review add -crlcert option for genm with infotype crlStatusList cmp.c: Refactor CRL update logic Remove OSSL_CMP_CTX_get0_oldCert() function Add options for specifying CRL issuer and saving received CRLs Update test_commands.csv with new crlcert and old crl Add new functions and rearrange existing functions in libcrypto.num Refactor setup_crl function to use setup_mock_crlout --- apps/cmp.c | 93 ++++++++++++------- apps/lib/cmp_mock_srv.c | 50 +++++++--- crypto/cmp/cmp_asn.c | 29 +++--- crypto/cmp/cmp_err.c | 3 + crypto/cmp/cmp_genm.c | 18 ++-- crypto/cmp/cmp_hdr.c | 33 +------ crypto/err/openssl.txt | 2 + crypto/x509/v3_crld.c | 1 + crypto/x509/v3_genn.c | 29 ++++++ doc/build.info | 6 ++ doc/man1/openssl-cmp.pod.in | 25 ++++- doc/man3/GENERAL_NAME.pod | 43 +++++++++ doc/man3/OSSL_CMP_ITAV_new_caCerts.pod | 20 ++-- doc/man3/OSSL_CMP_exec_certreq.pod | 18 +++- doc/man3/X509_dup.pod | 2 + include/openssl/cmp.h.in | 6 +- include/openssl/cmperr.h | 2 + include/openssl/x509v3.h.in | 3 + .../80-test_cmp_http_data/Mock/crl.pem | 12 --- .../80-test_cmp_http_data/Mock/newcrl.pem | 12 +++ .../80-test_cmp_http_data/Mock/oldcrl.pem | 12 +++ .../80-test_cmp_http_data/Mock/server.cnf | 2 +- .../80-test_cmp_http_data/test_commands.csv | 9 ++ util/libcrypto.num | 11 ++- util/other.syms | 1 + 25 files changed, 303 insertions(+), 139 deletions(-) create mode 100644 doc/man3/GENERAL_NAME.pod delete mode 100644 test/recipes/80-test_cmp_http_data/Mock/crl.pem create mode 100644 test/recipes/80-test_cmp_http_data/Mock/newcrl.pem create mode 100644 test/recipes/80-test_cmp_http_data/Mock/oldcrl.pem diff --git a/apps/cmp.c b/apps/cmp.c index 6c2a773d533ba..9fe8d3da99371 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -94,6 +94,7 @@ static char *opt_oldwithold = NULL; static char *opt_newwithnew = NULL; static char *opt_newwithold = NULL; static char *opt_oldwithnew = NULL; +static char *opt_crlcert = NULL; static char *opt_oldcrl = NULL; static char *opt_crlout = NULL; @@ -240,7 +241,7 @@ typedef enum OPTION_choice { OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, OPT_NO_CACHE_EXTRACERTS, OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT, OPT_OLDWITHOLD, OPT_NEWWITHNEW, OPT_NEWWITHOLD, OPT_OLDWITHNEW, - OPT_OLDCRL, OPT_CRLOUT, + OPT_CRLCERT, OPT_OLDCRL, OPT_CRLOUT, OPT_REF, OPT_SECRET, OPT_CERT, OPT_OWN_TRUSTED, OPT_KEY, OPT_KEYPASS, OPT_DIGEST, OPT_MAC, OPT_EXTRACERTS, @@ -271,9 +272,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_CRL, 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, @@ -432,6 +433,8 @@ const OPTIONS cmp_options[] = { "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"}, + { "crlcert", OPT_CRLCERT, 's', + "certificate to request CRL update for in genm of type crlStatusList"}, { "oldcrl", OPT_OLDCRL, 's', "CRL to request update for in genm of type crlStatusList"}, { "crlout", OPT_CRLOUT, 's', @@ -633,7 +636,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {(char **)&opt_no_cache_extracerts}, {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout}, {&opt_oldwithold}, {&opt_newwithnew}, {&opt_newwithold}, {&opt_oldwithnew}, - {&opt_oldcrl}, {&opt_crlout}, + {&opt_crlcert}, {&opt_oldcrl}, {&opt_crlout}, {&opt_ref}, {&opt_secret}, {&opt_cert}, {&opt_own_trusted}, {&opt_key}, {&opt_keypass}, @@ -663,9 +666,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_crl}, {&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}, @@ -1022,9 +1025,7 @@ 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) +static int setup_mock_crlout(void *ctx, const char *file, const char *desc) { X509_CRL *crl; int ok; @@ -1033,7 +1034,7 @@ static int setup_crl(void *ctx, const char *file, const char *desc, return 1; if ((crl = load_crl(file, FORMAT_UNDEF, 0, desc)) == NULL) return 0; - ok = (*set1_fn)(ctx, crl); + ok = ossl_cmp_mock_srv_set1_crlOut(ctx, crl); X509_CRL_free(crl); return ok; } @@ -1179,8 +1180,8 @@ 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)) + if (!setup_mock_crlout(srv_ctx, opt_rsp_crl, + "CRL to be returned by the mock server")) goto err; if (!setup_certs(opt_rsp_extracerts, "CMP extra certificates for mock server", srv_ctx, @@ -1910,8 +1911,8 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POPO_METHOD, opt_popo); if (opt_oldcert != NULL) { - if (opt_cmd == CMP_GENM && opt_infotype != NID_id_it_crlStatusList) { - CMP_warn("-oldcert option is ignored for 'genm' command except with -infotype crlStatusList"); + if (opt_cmd == CMP_GENM) { + CMP_warn("-oldcert option is ignored for 'genm' command"); } else { if (!setup_cert(ctx, opt_oldcert, opt_keypass, /* needed if opt_oldcert is encrypted PKCS12 file */ @@ -2280,14 +2281,14 @@ static int write_cert(BIO *bio, X509 *cert) static int write_crl(BIO *bio, X509_CRL *crl) { - if ((opt_certform == FORMAT_PEM && PEM_write_bio_X509_CRL(bio, crl)) - || (opt_certform == FORMAT_ASN1 && i2d_X509_CRL_bio(bio, crl))) - return 1; - if (opt_certform != FORMAT_PEM && opt_certform != FORMAT_ASN1) - BIO_printf(bio_err, - "error: unsupported type '%s' for writing CRLs\n", + if (opt_certform != FORMAT_PEM && opt_certform != FORMAT_ASN1) { + BIO_printf(bio_err, "error: unsupported type '%s' for writing CRLs\n", opt_certform_s); - return 0; + return 0; + } + + return opt_certform == FORMAT_PEM ? PEM_write_bio_X509_CRL(bio, crl) + : i2d_X509_CRL_bio(bio, crl); } /* @@ -2350,8 +2351,8 @@ static int save_free_crl(X509_CRL *crl, if ((bio = BIO_new(BIO_s_file())) == NULL || !BIO_write_filename(bio, (char *)file)) { - CMP_err3("could not open file '%s' for %s %s CRL", - file, crl == NULL ? "deleting" : "writing", desc); + CMP_err2("could not open file '%s' for writing %s CRL", + file, desc); goto end; } @@ -2406,7 +2407,7 @@ static int save_crl_or_delete(X509_CRL *crl, const char *file, const char *desc) if (crl == NULL) { char desc_crl[80]; - BIO_snprintf(desc_crl, sizeof(desc_crl), "%s CRL", desc); + BIO_snprintf(desc_crl, sizeof(desc_crl), "%s", desc); return delete_file(file, desc_crl); } else { return save_free_crl(crl, file, desc); @@ -2812,6 +2813,9 @@ static int get_opts(int argc, char **argv) case OPT_OLDWITHNEW: opt_oldwithnew = opt_str(); break; + case OPT_CRLCERT: + opt_crlcert = opt_str(); + break; case OPT_OLDCRL: opt_oldcrl = opt_str(); break; @@ -3236,10 +3240,12 @@ static int do_genm(OSSL_CMP_CTX *ctx) return res; } else if (opt_infotype == NID_id_it_crlStatusList) { X509_CRL *oldcrl = NULL, *crl = NULL; + X509 *crlcert = NULL; int res = 0; + const char *desc = "CRL from genp of type 'crls'"; - if (opt_oldcrl == NULL && opt_oldcert == NULL) { - CMP_err("Missing -oldcrl and no -oldcert given for -infotype crlStatusList"); + if (opt_oldcrl == NULL && opt_crlcert == NULL) { + CMP_err("Missing -oldcrl and no -crlcert given for -infotype crlStatusList"); return 0; } if (opt_crlout == NULL) { @@ -3247,28 +3253,43 @@ static int do_genm(OSSL_CMP_CTX *ctx) return 0; } + if (opt_crlcert == NULL) { + CMP_warn("No -crlcert given, will use data from -oldcrl"); + } else { + crlcert = load_cert_pwd(opt_crlcert, opt_otherpass, + "Cert for genm with -infotype crlStatusList"); + if (crlcert == NULL) + goto end_crlupd; + } + if (opt_oldcrl == NULL) { - CMP_warn("No -oldcrl given, will use data from -oldcert"); + CMP_warn("No -oldcrl given, will use data from -crlcert"); } else { oldcrl = load_crl(opt_oldcrl, FORMAT_UNDEF, 0, "CRL for genm with -infotype crlStatusList"); if (oldcrl == NULL) goto end_crlupd; } - if (!OSSL_CMP_get1_crlUpdate(ctx, oldcrl, &crl)) + + if (opt_oldcrl != NULL && opt_crlcert != NULL) { + if (X509_NAME_cmp(X509_CRL_get_issuer(oldcrl), + X509_get_issuer_name(crlcert)) + != 0) + CMP_warn("-oldcrl and -crlcert have different issuer"); + } + + if (!OSSL_CMP_get1_crlUpdate(ctx, crlcert, oldcrl, &crl)) goto end_crlupd; - const char *desc = "CRL from genp of type 'crls'"; - if (crl == NULL) { + if (crl == NULL) CMP_info("no CRL update available"); - if (!delete_file(opt_crlout, desc)) - goto end_crlupd; - } else if (!save_crl_or_delete(crl, opt_crlout, desc)) { + if (!save_crl_or_delete(crl, opt_crlout, desc)) goto end_crlupd; - } + res = 1; end_crlupd: + X509_free(crlcert); X509_CRL_free(oldcrl); X509_CRL_free(crl); return res; diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c index 5116d5ae528f7..9129572341b2f 100644 --- a/apps/lib/cmp_mock_srv.c +++ b/apps/lib/cmp_mock_srv.c @@ -408,25 +408,41 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, return OSSL_CMP_PKISI_dup(ctx->statusOut); } +/* return -1 for error, 0 for no update available */ 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; + ASN1_TIME *thisupd = NULL; - if (crlStatusList == NULL || crl == NULL) - return 0; - if (sk_OSSL_CMP_CRLSTATUS_num(crlStatusList) != 1) + if (sk_OSSL_CMP_CRLSTATUS_num(crlStatusList) != 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CRLSTATUSLIST); + return -1; + } + if (crl == NULL) 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; - return 1; + if (gen != NULL) { + GENERAL_NAME *gn = sk_GENERAL_NAME_value(gen, 0); + + if (gn != NULL && gn->type == GEN_DIRNAME) { + X509_NAME *gen_name = gn->d.dirn; + + if (X509_NAME_cmp(gen_name, X509_CRL_get_issuer(crl)) != 0) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CRL_ISSUER); + return -1; + } + } + } + + return thisupd == NULL + || ASN1_TIME_compare(thisupd, X509_CRL_get0_lastUpdate(crl)) < 0; } static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid, @@ -446,12 +462,18 @@ static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid, 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); + int res = 0; + + if (!OSSL_CMP_ITAV_get0_crlStatusList(req, &crlstatuslist)) + return NULL; + + res = check_client_crl(crlstatuslist, ctx->crlOut); + if (res < 0) + rsp = NULL; + else if (res == 0) + rsp = OSSL_CMP_ITAV_new_crls(NULL); + else + rsp = OSSL_CMP_ITAV_new_crls(ctx->crlOut); } break; default: diff --git a/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c index d46fb2df5498e..2123ccb460fa6 100644 --- a/crypto/cmp/cmp_asn.c +++ b/crypto/cmp/cmp_asn.c @@ -157,8 +157,6 @@ ASN1_SEQUENCE(OSSL_CMP_CRLSTATUS) = { } ASN1_SEQUENCE_END(OSSL_CMP_CRLSTATUS) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CRLSTATUS) -IMPLEMENT_ASN1_DUP_FUNCTION(DIST_POINT_NAME) - OSSL_CMP_ITAV *OSSL_CMP_ITAV_create(ASN1_OBJECT *type, ASN1_TYPE *value) { OSSL_CMP_ITAV *itav; @@ -429,7 +427,7 @@ static GENERAL_NAMES *gennames_new(const X509_NAME *nm) if ((names = sk_GENERAL_NAME_new_reserve(NULL, 1)) == NULL) return NULL; - if (!GENERAL_NAME_create(&name, nm)) { + if (!GENERAL_NAME_set1_X509_NAME(&name, nm)) { sk_GENERAL_NAME_free(names); return NULL; } @@ -461,11 +459,11 @@ OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_create(const X509_CRL *crl, int i, NID_akid = NID_authority_key_identifier; /* - * Note: X509{,_CRL}_get_ext_d2i(..., NID, &i, ...) return the 1st extension - * with the given NID that is available, if any. There might be more such. + * Note: X509{,_CRL}_get_ext_d2i(..., NID, ..., NULL) return the 1st extension + * with the given NID that is available, if any. If there are more, this is an error. */ if (cert != NULL) { - crldps = X509_get_ext_d2i(cert, NID_crl_distribution_points, &i, NULL); + crldps = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL); /* if available, take the first suitable element */ for (i = 0; i < sk_DIST_POINT_num(crldps); i++) { DIST_POINT *dp = sk_DIST_POINT_value(crldps, i); @@ -486,21 +484,21 @@ OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_create(const X509_CRL *crl, return NULL; } idp = X509_CRL_get_ext_d2i(crl, - NID_issuing_distribution_point, &i, NULL); + NID_issuing_distribution_point, NULL, NULL); if (idp != NULL && idp->distpoint != NULL) dpn = idp->distpoint; } if (dpn == NULL && CRLissuer == NULL) { if (cert != NULL) { - akid = X509_get_ext_d2i(cert, NID_akid, &i, NULL); + akid = X509_get_ext_d2i(cert, NID_akid, NULL, NULL); if (akid != NULL && gennames_allowed(akid->issuer, only_DN)) CRLissuer = akid->issuer; else CRLissuer = issuers = gennames_new(X509_get_issuer_name(cert)); } if (CRLissuer == NULL && crl != NULL) { - akid = X509_CRL_get_ext_d2i(crl, NID_akid, &i, NULL); + akid = X509_CRL_get_ext_d2i(crl, NID_akid, NULL, NULL); if (akid != NULL && gennames_allowed(akid->issuer, only_DN)) CRLissuer = akid->issuer; else @@ -558,11 +556,12 @@ OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_crls(const X509_CRL *crl) if ((itav = OSSL_CMP_ITAV_new()) == NULL) return NULL; - if (crl != NULL - && ((crls = sk_X509_CRL_new_reserve(NULL, 1)) == NULL - || (crl_copy = X509_CRL_dup(crl)) == NULL - || !sk_X509_CRL_push(crls, crl_copy))) - goto err; + if (crl != NULL) { + if ((crls = sk_X509_CRL_new_reserve(NULL, 1)) == NULL + || (crl_copy = X509_CRL_dup(crl)) == NULL) + goto err; + (void)sk_X509_CRL_push(crls, crl_copy); /* cannot fail */ + } itav->infoType = OBJ_nid2obj(NID_id_it_crls); itav->infoValue.crls = crls; @@ -588,7 +587,7 @@ int OSSL_CMP_ITAV_get0_crls(const OSSL_CMP_ITAV *itav, STACK_OF(X509_CRL) **out) return 1; } -/* get ASN.1 encoded integer, return -1 on error */ +/* get ASN.1 encoded integer, return -2 on error; -1 is valid for certReqId */ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a) { int64_t res; diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c index 31a062f86ceeb..689aa6a9520f7 100644 --- a/crypto/cmp/cmp_err.c +++ b/crypto/cmp/cmp_err.c @@ -150,6 +150,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNCLEAN_CTX), "unclean ctx"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CERTPROFILE), "unexpected certprofile"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CRLSTATUSLIST), + "unexpected crlstatuslist"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS), "unexpected pkistatus"}, @@ -159,6 +161,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID), "unknown algorithm id"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CRL_ISSUER), "unknown crl issuer"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_PKISTATUS), "unknown pkistatus"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, diff --git a/crypto/cmp/cmp_genm.c b/crypto/cmp/cmp_genm.c index e524e19e69a8b..ec14cc2aed80f 100644 --- a/crypto/cmp/cmp_genm.c +++ b/crypto/cmp/cmp_genm.c @@ -345,7 +345,8 @@ int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, return res; } -int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509_CRL *last_crl, +int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509 *crlcert, + const X509_CRL *last_crl, X509_CRL **crl) { OSSL_CMP_CRLSTATUS *status = NULL; @@ -355,20 +356,17 @@ int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509_CRL *last_crl, int res = 0; if (crl == NULL) { - ERR_raise_data(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT, - "No crl output parameter given"); + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); return 0; } *crl = NULL; - if ((status = OSSL_CMP_CRLSTATUS_create(last_crl, ctx->oldCert, 1)) == NULL) { - ERR_raise_data(ERR_LIB_CMP, CMP_R_GENERATE_CRLSTATUS, - "Cannot set up CRLStatus structure"); + if ((status = OSSL_CMP_CRLSTATUS_create(last_crl, crlcert, 1)) == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_GENERATE_CRLSTATUS); goto end; } if ((list = sk_OSSL_CMP_CRLSTATUS_new_reserve(NULL, 1)) == NULL) { - ERR_raise_data(ERR_LIB_CMP, CMP_R_GENERATE_CRLSTATUS, - "Cannot set up CRLStatus list"); + ERR_raise(ERR_LIB_CMP, CMP_R_GENERATE_CRLSTATUS); goto end; } (void)sk_OSSL_CMP_CRLSTATUS_push(list, status); /* cannot fail */ @@ -386,8 +384,10 @@ int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509_CRL *last_crl, if (!OSSL_CMP_ITAV_get0_crls(itav, &crls)) goto end; - if (crls == NULL) /* no CRL update available */ + if (crls == NULL) { /* no CRL update available */ + res = 1; goto end; + } if (sk_X509_CRL_num(crls) != 1) { ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_GENP, "Unexpected number of CRLs in genp: %d", diff --git a/crypto/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c index c319beedb6fc8..59205ef8c72e4 100644 --- a/crypto/cmp/cmp_hdr.c +++ b/crypto/cmp/cmp_hdr.c @@ -89,35 +89,6 @@ int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name) || (name->type == GEN_DIRNAME && IS_NULL_DN(name->d.directoryName)); } -/* assign to *tgt a copy of src (which may be NULL to indicate an empty DN) */ -/* TODO move to ../x509/ and use also for OCSP, ESS, etc. */ -int GENERAL_NAME_create(GENERAL_NAME **tgt, const X509_NAME *src) -{ - GENERAL_NAME *name; - - if (!ossl_assert(tgt != NULL)) - return 0; - if ((name = GENERAL_NAME_new()) == NULL) - goto err; - name->type = GEN_DIRNAME; - - if (src == NULL) { /* NULL-DN */ - if ((name->d.directoryName = X509_NAME_new()) == NULL) - goto err; - } else if (!X509_NAME_set(&name->d.directoryName, src)) { - goto err; - } - - GENERAL_NAME_free(*tgt); - *tgt = name; - - return 1; - - err: - GENERAL_NAME_free(name); - return 0; -} - /* * Set the sender name in PKIHeader. * when nm is NULL, sender is set to an empty string @@ -127,14 +98,14 @@ int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm) { if (!ossl_assert(hdr != NULL)) return 0; - return GENERAL_NAME_create(&hdr->sender, nm); + return GENERAL_NAME_set1_X509_NAME(&hdr->sender, nm); } int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm) { if (!ossl_assert(hdr != NULL)) return 0; - return GENERAL_NAME_create(&hdr->recipient, nm); + return GENERAL_NAME_set1_X509_NAME(&hdr->recipient, nm); } int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index f60bf49907281..43377d4172ba1 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -278,6 +278,7 @@ CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched CMP_R_TRANSFER_ERROR:159:transfer error CMP_R_UNCLEAN_CTX:191:unclean ctx CMP_R_UNEXPECTED_CERTPROFILE:196:unexpected certprofile +CMP_R_UNEXPECTED_CRLSTATUSLIST:201:unexpected crlstatuslist CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus CMP_R_UNEXPECTED_POLLREQ:105:unexpected pollreq @@ -285,6 +286,7 @@ CMP_R_UNEXPECTED_PVNO:153:unexpected pvno CMP_R_UNEXPECTED_SENDER:106:unexpected sender CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type +CMP_R_UNKNOWN_CRL_ISSUER:200:unknown crl issuer CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c index e9f6e08e27a7c..110c80ac01f44 100644 --- a/crypto/x509/v3_crld.c +++ b/crypto/x509/v3_crld.c @@ -327,6 +327,7 @@ ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) +IMPLEMENT_ASN1_DUP_FUNCTION(DIST_POINT_NAME) ASN1_SEQUENCE(DIST_POINT) = { ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), diff --git a/crypto/x509/v3_genn.c b/crypto/x509/v3_genn.c index 1f67bf2f63ab8..c71e5b91116d2 100644 --- a/crypto/x509/v3_genn.c +++ b/crypto/x509/v3_genn.c @@ -58,6 +58,35 @@ GENERAL_NAME *GENERAL_NAME_dup(const GENERAL_NAME *a) (char *)a); } +int GENERAL_NAME_set1_X509_NAME(GENERAL_NAME **tgt, const X509_NAME *src) +{ + GENERAL_NAME *name; + + if (tgt == NULL){ + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT); + return 0; + } + + if ((name = GENERAL_NAME_new()) == NULL) + return 0; + name->type = GEN_DIRNAME; + + if (src == NULL) { /* NULL-DN */ + if ((name->d.directoryName = X509_NAME_new()) == NULL) + goto err; + } else if (!X509_NAME_set(&name->d.directoryName, src)) { + goto err; + } + + GENERAL_NAME_free(*tgt); + *tgt = name; + return 1; + + err: + GENERAL_NAME_free(name); + return 0; +} + static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) { int res; diff --git a/doc/build.info b/doc/build.info index b4815fcf23a79..2135c962d804c 100644 --- a/doc/build.info +++ b/doc/build.info @@ -1471,6 +1471,10 @@ DEPEND[html/man3/EVP_whirlpool.html]=man3/EVP_whirlpool.pod GENERATE[html/man3/EVP_whirlpool.html]=man3/EVP_whirlpool.pod DEPEND[man/man3/EVP_whirlpool.3]=man3/EVP_whirlpool.pod GENERATE[man/man3/EVP_whirlpool.3]=man3/EVP_whirlpool.pod +DEPEND[html/man3/GENERAL_NAME.html]=man3/GENERAL_NAME.pod +GENERATE[html/man3/GENERAL_NAME.html]=man3/GENERAL_NAME.pod +DEPEND[man/man3/GENERAL_NAME.3]=man3/GENERAL_NAME.pod +GENERATE[man/man3/GENERAL_NAME.3]=man3/GENERAL_NAME.pod DEPEND[html/man3/HMAC.html]=man3/HMAC.pod GENERATE[html/man3/HMAC.html]=man3/HMAC.pod DEPEND[man/man3/HMAC.3]=man3/HMAC.pod @@ -3299,6 +3303,7 @@ html/man3/EVP_sha3_224.html \ html/man3/EVP_sm3.html \ html/man3/EVP_sm4_cbc.html \ html/man3/EVP_whirlpool.html \ +html/man3/GENERAL_NAME.html \ html/man3/HMAC.html \ html/man3/MD5.html \ html/man3/MDC2_Init.html \ @@ -3944,6 +3949,7 @@ man/man3/EVP_sha3_224.3 \ man/man3/EVP_sm3.3 \ man/man3/EVP_sm4_cbc.3 \ man/man3/EVP_whirlpool.3 \ +man/man3/GENERAL_NAME.3 \ man/man3/HMAC.3 \ man/man3/MD5.3 \ man/man3/MDC2_Init.3 \ diff --git a/doc/man1/openssl-cmp.pod.in b/doc/man1/openssl-cmp.pod.in index d4228d8f84db5..6c4f7fa6696e7 100644 --- a/doc/man1/openssl-cmp.pod.in +++ b/doc/man1/openssl-cmp.pod.in @@ -74,6 +74,9 @@ Server authentication options: [B<-newwithnew> I] [B<-newwithold> I] [B<-oldwithnew> I] +[B<-crlcert> I] +[B<-oldcrl> I] +[B<-crlout> I] Client authentication and protection options: @@ -134,6 +137,7 @@ Mock server options: [B<-srv_untrusted> I|I] [B<-ref_cert> I|I] [B<-rsp_cert> I|I] +[B<-rsp_crl> I|I] [B<-rsp_extracerts> I|I] [B<-rsp_capubs> I|I] [B<-rsp_newwithnew> I|I] @@ -733,6 +737,21 @@ The file to save any oldWithNew certificate received in a genp message of infoType C. If on success no such cert was received, this is indicated by deleting the file. +=item B<-crlcert> I + +Certificate used for specifying a CRL issuer when requesting a CRL +in a genm message with infoType C. + +=item B<-oldcrl> I + +CRL used for specifying a CRL issuer when requesting a CRL +in a genm message with infoType C. + +=item B<-crlout> I + +The file to save CRL received in a genp message of infoType C. +If on success no such CRL was received, this is indicated by deleting the file. + =back =head2 Client authentication options @@ -866,7 +885,7 @@ See L for details. =item B<-otherpass> I Pass phrase source for certificate given with the B<-trusted>, B<-untrusted>, -B<-own_trusted>, B<-srvcert>, B<-out_trusted>, B<-extracerts>, +B<-own_trusted>, B<-srvcert>, B<-crlcert>, B<-out_trusted>, B<-extracerts>, B<-srv_trusted>, B<-srv_untrusted>, B<-ref_cert>, B<-rsp_cert>, B<-rsp_extracerts>, B<-rsp_capubs>, B<-rsp_newwithnew>, B<-rsp_newwithold>, B<-rsp_oldwithnew>, @@ -1141,6 +1160,10 @@ Certificate to be expected for RR messages and any oldCertID in KUR messages. Certificate to be returned as mock enrollment result. +=item B<-rsp_crl> I|I + +CRL to be returned in genp of type crls. + =item B<-rsp_extracerts> I|I Extra certificates to be included in mock certification responses. diff --git a/doc/man3/GENERAL_NAME.pod b/doc/man3/GENERAL_NAME.pod new file mode 100644 index 0000000000000..b803266931861 --- /dev/null +++ b/doc/man3/GENERAL_NAME.pod @@ -0,0 +1,43 @@ +=pod + +=head1 NAME + +GENERAL_NAME, +GENERAL_NAME_set1_X509_NAME +- GENERAL_NAME method routines + +=head1 SYNOPSIS + + #include + + typedef struct GENERAL_NAME_st GENERAL_NAME; + + int GENERAL_NAME_set1_X509_NAME(GENERAL_NAME **tgt, const X509_NAME *src); + +=head1 DESCRIPTION + +GENERAL_NAME_set1_X509_NAME() creates a new GENERAL_NAME of type GEN_DIRNAME +and populates it based on provided X509_NAME I which can be NULL. +I must not be NULL. If successful, I<*tgt> will be set to point +to the newly created GENERAL_NAME. + +=head1 NOTES +=head1 RETURN VALUES + +GENERAL_NAME_set1_X509_NAME() return 1 on success, 0 on error. + +=head1 SEE ALSO +=head1 HISTORY + +GENERAL_NAME_set1_X509_NAME() was added in OpenSSL 3.3. + +=head1 COPYRIGHT + +Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod b/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod index 54c09972a75b4..00b520840154b 100644 --- a/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod +++ b/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod @@ -8,8 +8,6 @@ OSSL_CMP_ITAV_new_rootCaCert, OSSL_CMP_ITAV_get0_rootCaCert, OSSL_CMP_ITAV_new_rootCaKeyUpdate, OSSL_CMP_ITAV_get0_rootCaKeyUpdate, -OSSL_CMP_ITAV_new0_certReqTemplate, -OSSL_CMP_ITAV_get1_certReqTemplate, OSSL_CMP_CRLSTATUS_new1, OSSL_CMP_CRLSTATUS_create, OSSL_CMP_CRLSTATUS_get0, @@ -25,6 +23,7 @@ OSSL_CMP_ITAV_get0_crls OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts); int OSSL_CMP_ITAV_get0_caCerts(const OSSL_CMP_ITAV *itav, STACK_OF(X509) **out); + OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaCert(const X509 *rootCaCert); int OSSL_CMP_ITAV_get0_rootCaCert(const OSSL_CMP_ITAV *itav, X509 **out); OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, @@ -34,6 +33,7 @@ OSSL_CMP_ITAV_get0_crls X509 **newWithNew, X509 **newWithOld, X509 **oldWithNew); + OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_new1(const DIST_POINT_NAME *dpn, const GENERAL_NAMES *issuer, const ASN1_TIME *thisUpdate); @@ -89,9 +89,10 @@ that contains either a copy of the distribution point name I or a copy of the certificate issuer I, while giving both is an error. If given, a copy of the CRL issuance time I is also included. -OSSL_CMP_CRLSTATUS_create() is a high-level variant of OSSL_CMP_CRLSTATUS_new1() -using data obtained from the I and/or I parameters. -The thisUpdate field is filled with the thisUpdate field of I if present. +OSSL_CMP_CRLSTATUS_create() is a high-level variant of OSSL_CMP_CRLSTATUS_new1(). +It fills the thisUpdate field with a copy of the thisUpdate field of I if present. +It fills the CRLSource field with a copy of the first data item found using the I +and/or I parameters as follows. The CRLSource field is filled with the first data item found in them as follows. Any available distribution point name is preferred over issuer names. Data from I, if present, is preferred over data from I. @@ -132,8 +133,8 @@ 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_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. +of type B including an empty list of CRLs if the I argument is NULL +or including a singleton list a with copy of the provided CRL otherwise. 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. @@ -168,6 +169,11 @@ OSSL_CMP_ITAV_new_rootCaCert(), OSSL_CMP_ITAV_get0_rootCaCert(), OSSL_CMP_ITAV_new_rootCaKeyUpdate(), and OSSL_CMP_ITAV_get0_rootCaKeyUpdate() were added in OpenSSL 3.2. +OSSL_CMP_CRLSTATUS_new1(), OSSL_CMP_CRLSTATUS_create(), +OSSL_CMP_CRLSTATUS_get0(), OSSL_CMP_ITAV_new0_crlStatusList(), +OSSL_CMP_ITAV_get0_crlStatusList(), OSSL_CMP_ITAV_new_crls() +and OSSL_CMP_ITAV_get0_crls() were added in OpenSSL 3.3. + =head1 COPYRIGHT Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/OSSL_CMP_exec_certreq.pod b/doc/man3/OSSL_CMP_exec_certreq.pod index 54632ce93697b..0a09ae3881678 100644 --- a/doc/man3/OSSL_CMP_exec_certreq.pod +++ b/doc/man3/OSSL_CMP_exec_certreq.pod @@ -15,7 +15,8 @@ OSSL_CMP_try_certreq, OSSL_CMP_exec_RR_ses, OSSL_CMP_exec_GENM_ses, OSSL_CMP_get1_caCerts, -OSSL_CMP_get1_rootCaKeyUpdate +OSSL_CMP_get1_rootCaKeyUpdate, +OSSL_CMP_get1_crlUpdate - functions implementing CMP client transactions =head1 SYNOPSIS @@ -41,6 +42,8 @@ OSSL_CMP_get1_rootCaKeyUpdate int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, const X509 *oldWithOld, X509 **newWithNew, X509 **newWithOld, X509 **oldWithNew); + int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509_CRL *last_crl, + X509_CRL **crl); =head1 DESCRIPTION @@ -157,6 +160,13 @@ The trust placed in it cannot be stronger than the trust placed in the I certificate if present, otherwise it cannot be stronger than the weakest trust in any of the certificates in the trust store of I. +OSSL_CMP_get1_crlUpdate() uses a genm request message with infoType crlStatusList +to obtain CRL from the CMP server referenced by I in a genp response message +with infoType crls. It uses oldcert referenced by I and I to create +request. On success it assigns to I<*crl> the CRL received. +NULL means that no CRL was provided by the server. +The CRL obtained this way must be freed by the caller. + =head1 NOTES CMP is defined in RFC 4210 (and CRMF in RFC 4211). @@ -193,7 +203,7 @@ and the output parameter I has been used to assign the received value unless I is NULL. OSSL_CMP_exec_RR_ses(), OSSL_CMP_get1_caCerts(), -and OSSL_CMP_get1_rootCaKeyUpdate() +OSSL_CMP_get1_rootCaKeyUpdate() and OSSL_CMP_get1_crlUpdate() return 1 on success, 0 on error. OSSL_CMP_exec_GENM_ses() returns NULL on error, @@ -220,8 +230,8 @@ The OpenSSL CMP support was added in OpenSSL 3.0. OSSL_CMP_get1_caCerts() and OSSL_CMP_get1_rootCaKeyUpdate() were added in OpenSSL 3.2. -Support for delayed delivery of all types of response messages -was added in OpenSSL 3.3. +OSSL_CMP_get1_crlUpdate() and support for delayed delivery +of all types of response messages was added in OpenSSL 3.3. =head1 COPYRIGHT diff --git a/doc/man3/X509_dup.pod b/doc/man3/X509_dup.pod index c6206e1759093..2c9758522e158 100644 --- a/doc/man3/X509_dup.pod +++ b/doc/man3/X509_dup.pod @@ -44,6 +44,7 @@ DISPLAYTEXT_free, DISPLAYTEXT_new, DIST_POINT_NAME_free, DIST_POINT_NAME_new, +DIST_POINT_NAME_dup, DIST_POINT_free, DIST_POINT_new, DSAparams_dup, @@ -132,6 +133,7 @@ OCSP_SIGNATURE_free, OCSP_SIGNATURE_new, OCSP_SINGLERESP_free, OCSP_SINGLERESP_new, +OSSL_CMP_CRLSTATUS_free, OSSL_CMP_ITAV_dup, OSSL_CMP_ITAV_free, OSSL_CMP_MSG_dup, diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in index 80496672f04c1..0facbfbee0327 100644 --- a/include/openssl/cmp.h.in +++ b/include/openssl/cmp.h.in @@ -32,9 +32,6 @@ use OpenSSL::stackhash qw(generate_stack_macros); # include # include -/* TODO move to x509v3.h.in and use also for OCSP, ESS, etc. */ -int GENERAL_NAME_create(GENERAL_NAME **tgt, const X509_NAME *src); - # ifdef __cplusplus extern "C" { # endif @@ -592,7 +589,8 @@ int OSSL_CMP_get1_caCerts(OSSL_CMP_CTX *ctx, STACK_OF(X509) **out); int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, const X509 *oldWithOld, X509 **newWithNew, X509 **newWithOld, X509 **oldWithNew); -int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509_CRL *last_crl, +int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509 *crlcert, + const X509_CRL *last_crl, X509_CRL **crl); # ifdef __cplusplus diff --git a/include/openssl/cmperr.h b/include/openssl/cmperr.h index aa2877c132d1f..700ffbeb7beb6 100644 --- a/include/openssl/cmperr.h +++ b/include/openssl/cmperr.h @@ -102,6 +102,7 @@ # define CMP_R_TRANSFER_ERROR 159 # define CMP_R_UNCLEAN_CTX 191 # define CMP_R_UNEXPECTED_CERTPROFILE 196 +# define CMP_R_UNEXPECTED_CRLSTATUSLIST 201 # define CMP_R_UNEXPECTED_PKIBODY 133 # define CMP_R_UNEXPECTED_PKISTATUS 185 # define CMP_R_UNEXPECTED_POLLREQ 105 @@ -109,6 +110,7 @@ # define CMP_R_UNEXPECTED_SENDER 106 # define CMP_R_UNKNOWN_ALGORITHM_ID 134 # define CMP_R_UNKNOWN_CERT_TYPE 135 +# define CMP_R_UNKNOWN_CRL_ISSUER 200 # define CMP_R_UNKNOWN_PKISTATUS 186 # define CMP_R_UNSUPPORTED_ALGORITHM 136 # define CMP_R_UNSUPPORTED_KEY_TYPE 137 diff --git a/include/openssl/x509v3.h.in b/include/openssl/x509v3.h.in index 569680378dfd0..e49dcfa614079 100644 --- a/include/openssl/x509v3.h.in +++ b/include/openssl/x509v3.h.in @@ -178,6 +178,8 @@ typedef struct ACCESS_DESCRIPTION_st { GENERAL_NAME *location; } ACCESS_DESCRIPTION; +int GENERAL_NAME_set1_X509_NAME(GENERAL_NAME **tgt, const X509_NAME *src); + {- generate_stack_macros("ACCESS_DESCRIPTION") .generate_stack_macros("GENERAL_NAME"); @@ -201,6 +203,7 @@ typedef struct DIST_POINT_NAME_st { /* If relativename then this contains the full distribution point name */ X509_NAME *dpname; } DIST_POINT_NAME; +DECLARE_ASN1_DUP_FUNCTION(DIST_POINT_NAME) /* All existing reasons */ # define CRLDP_ALL_REASONS 0x807f diff --git a/test/recipes/80-test_cmp_http_data/Mock/crl.pem b/test/recipes/80-test_cmp_http_data/Mock/crl.pem deleted file mode 100644 index 2645c087c2e96..0000000000000 --- a/test/recipes/80-test_cmp_http_data/Mock/crl.pem +++ /dev/null @@ -1,12 +0,0 @@ ------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/newcrl.pem b/test/recipes/80-test_cmp_http_data/Mock/newcrl.pem new file mode 100644 index 0000000000000..101d7cd67c518 --- /dev/null +++ b/test/recipes/80-test_cmp_http_data/Mock/newcrl.pem @@ -0,0 +1,12 @@ +-----BEGIN X509 CRL----- +MIIBtDCBnQIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJBVTETMBEGA1UE +CBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk +MRMwEQYDVQQDEwpzdWJpbnRlckNBFw0yNDAyMjMxNTQ3NTFaFw0zNzA5MTIxNTQ3 +NTFaoA8wDTALBgNVHRQEBAICEAcwDQYJKoZIhvcNAQELBQADggEBAFyUvxWlxjLA +DjTq/N26EXH6GZxmDyr5tjPk1KQBRY/jPNWvxloXFIH7PAtzInJmEoF2PCDw290Z +BRuftPaxVW1tcHAsZzL5QFSGa2wWSLGCHpZCg9twcLQbGrOq7+S2M2ZjOVxSMN1u +ok/QLhuqniPieOUetzafqUNknYJahILnomLhPoQBzko9EdtBJkygOGdj/3T07iLy +hicW0QlBA5B9oCIUmknnx4kCh6VlsSq9FJTs2HXZhJHF0VVFbAlbjHMFkwjTh31r +Bc8u1D35T0kqwbTbVmtPghdpW2uJ+9LsWXdrlTGGlRJXA+3d13hKlFMFcQEavf4h +wVlABZ6eEPo= +-----END X509 CRL----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/oldcrl.pem b/test/recipes/80-test_cmp_http_data/Mock/oldcrl.pem new file mode 100644 index 0000000000000..f596289d1db6f --- /dev/null +++ b/test/recipes/80-test_cmp_http_data/Mock/oldcrl.pem @@ -0,0 +1,12 @@ +-----BEGIN X509 CRL----- +MIIBtDCBnQIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJBVTETMBEGA1UE +CBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk +MRMwEQYDVQQDEwpzdWJpbnRlckNBFw0yNDAyMjMxNTQ3MzhaFw0zNDEyMTcxNTQ3 +MzhaoA8wDTALBgNVHRQEBAICEAYwDQYJKoZIhvcNAQELBQADggEBANfH339j7LXB +9X+Vpk1xjTSRwoIQ7C/LZbOJ4tiVaNsBd+3rlOgJEnYPuB883ylAy3TOPn9taMXe +kmPebHC4WDhESNbwm8kdFNz6Ghvvn4TuDcSgWV8xxtw5AHVfnCs8801KI8pcn7K6 +MwGdJ7CPvB38SFn5ssKQueLySRfL+bRWXpgB79hjFE7J1ukaUr2xg3q4YFQwexld +xuaIR0AiFyTVKWTWLEdAKRzPiYTmx1ZMyYEdwh17l6nWh/UgfUEqmK9ub2Mqh20h +g7/Nwf0iaQS7bui7DgzkW76dbXcmAmTkU8VLznOLIheus8uj6Kl2TewO5PvjVGeu +Fgt7CED5epw= +-----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 e35277c54fc15..86a11f6a36829 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/server.cnf +++ b/test/recipes/80-test_cmp_http_data/Mock/server.cnf @@ -12,7 +12,7 @@ no_cache_extracerts = 1 ref_cert = signer_only.crt rsp_cert = signer_only.crt -rsp_crl = crl.pem +rsp_crl = newcrl.pem rsp_capubs = trusted.crt rsp_extracerts = signer_issuing.crt diff --git a/test/recipes/80-test_cmp_http_data/test_commands.csv b/test/recipes/80-test_cmp_http_data/test_commands.csv index 6aa18599b1870..ee38087265560 100644 --- a/test/recipes/80-test_cmp_http_data/test_commands.csv +++ b/test/recipes/80-test_cmp_http_data/test_commands.csv @@ -86,6 +86,15 @@ expected,description, -section,val, -cmd,val,val2, -cacertsout,val,val2, -infoty 0,genm rootCaCert newwithold missig arg , -section,, -cmd,genm,, BLANK,,, -infotype,rootCaCert,, -oldwithold, oldWithOld.pem, -newwithnew, _RESULT_DIR/test.newwithnew.pem, -oldwithnew, _RESULT_DIR/test.oldwithnew.pem, -newwithold,, 1,genm rootCaCert newwithnew newwithold , -section,, -cmd,genm,, BLANK,,, -infotype,rootCaCert,, -oldwithold, oldWithOld.pem, -newwithnew, _RESULT_DIR/test.newwithnew3.pem, -newwithold, _RESULT_DIR/test.newwithold2.pem ,,,,,,,,,,,,,,,,,,,,,, +1,genm crlStatusList with crlcert , -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -crlcert, signer_only.crt,,,,, -crlout, _RESULT_DIR/test.crlout1.pem +1,genm crlStatusList with old crl , -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -oldcrl, oldcrl.pem,,,,, -crlout, _RESULT_DIR/test.crlout2.pem +1,genm crlStatusList with crlcert and old crl , -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -crlcert, signer_only.crt, -oldcrl, oldcrl.pem,,, -crlout, _RESULT_DIR/test.crlout3.pem +1,genm crlStatusList with latest crl , -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -oldcrl, _RESULT_DIR/test.crlout3.pem,,,,, -crlout, _RESULT_DIR/test.crlout4.pem +0,genm crlStatusList with -oldcrl nonexistent, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -oldcrl, _RESULT_DIR/test.crlout4.pem,,,,, -crlout, _RESULT_DIR/test.crlout.pem +0,genm crlStatusList with -crlcert nonexistent, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -crlcert, idontexist,,,,, -crlout, _RESULT_DIR/test.crlout.pem +0,genm crlStatusList with wrong issuer, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -crlcert, server.crt,,,,, -crlout, _RESULT_DIR/test.crlout.pem +0,genm crlStatusList missing -crlcert & -oldcrl, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,,,,,,,, -crlout, _RESULT_DIR/test.crlout.pem +,,,,,,,,,,,,,,,,,,,,,, 1,profile, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile1,BLANK,,BLANK, 0,profile wrong value, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile2,BLANK,,BLANK, 0,profile missing argument, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,,,,, diff --git a/util/libcrypto.num b/util/libcrypto.num index c26273ccf3057..62323e7e3734f 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5547,13 +5547,14 @@ ERR_pop ? 3_3_0 EXIST::FUNCTION: X509_STORE_get1_objects ? 3_3_0 EXIST::FUNCTION: OPENSSL_LH_set_thunks ? 3_3_0 EXIST::FUNCTION: OPENSSL_LH_doall_arg_thunk ? 3_3_0 EXIST::FUNCTION: -GENERAL_NAME_create ? 3_3_0 EXIST::FUNCTION:CMP +DIST_POINT_NAME_dup ? 3_3_0 EXIST::FUNCTION: +GENERAL_NAME_set1_X509_NAME ? 3_3_0 EXIST::FUNCTION: OSSL_CMP_CRLSTATUS_create ? 3_3_0 EXIST::FUNCTION:CMP -OSSL_CMP_CRLSTATUS_new1 ? 3_3_0 EXIST::FUNCTION:CMP -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_CRLSTATUS_get0 ? 3_3_0 EXIST::FUNCTION:CMP +OSSL_CMP_CRLSTATUS_new1 ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_ITAV_get0_crlStatusList ? 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_new0_crlStatusList ? 3_3_0 EXIST::FUNCTION:CMP OSSL_CMP_ITAV_new_crls ? 3_3_0 EXIST::FUNCTION:CMP +OSSL_CMP_get1_crlUpdate ? 3_3_0 EXIST::FUNCTION:CMP diff --git a/util/other.syms b/util/other.syms index b45ba45bb5871..5e164a76acb22 100644 --- a/util/other.syms +++ b/util/other.syms @@ -53,6 +53,7 @@ EVP_RAND datatype EVP_RAND_CTX datatype EVP_SIGNATURE datatype GEN_SESSION_CB datatype +GENERAL_NAME datatype NAMING_AUTHORITY datatype OPENSSL_Applink external OSSL_ALGORITHM datatype From ab8d3685b8b94e85a29b230f51254d48c7f8fffc Mon Sep 17 00:00:00 2001 From: Rajeev Ranjan Date: Thu, 7 Mar 2024 18:03:13 +0100 Subject: [PATCH 5/6] update as per review --- apps/cmp.c | 83 ++++++++++--------- apps/lib/cmp_mock_srv.c | 13 +-- crypto/cmp/cmp_asn.c | 7 +- crypto/cmp/cmp_genm.c | 4 +- doc/man1/openssl-cmp.pod.in | 17 +++- doc/man3/GENERAL_NAME.pod | 2 - doc/man3/OSSL_CMP_ITAV_new_caCerts.pod | 1 - doc/man3/OSSL_CMP_exec_certreq.pod | 10 ++- include/crypto/cmperr.h | 2 +- include/openssl/cmp.h.in | 58 ++----------- .../80-test_cmp_http_data/test_commands.csv | 1 + 11 files changed, 83 insertions(+), 115 deletions(-) diff --git a/apps/cmp.c b/apps/cmp.c index 9fe8d3da99371..83fd849a2df42 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -146,6 +146,8 @@ static int opt_revreason = CRL_REASON_NONE; /* credentials format */ static char *opt_certform_s = "PEM"; static int opt_certform = FORMAT_PEM; +static char *opt_crlform_s = "DER"; +static int opt_crlform = FORMAT_ASN1; static char *opt_keyform_s = NULL; static int opt_keyform = FORMAT_UNDEF; static char *opt_otherpass = NULL; @@ -247,7 +249,7 @@ typedef enum OPTION_choice { OPT_DIGEST, OPT_MAC, OPT_EXTRACERTS, OPT_UNPROTECTED_REQUESTS, - OPT_CERTFORM, OPT_KEYFORM, + OPT_CERTFORM, OPT_CRLFORM, OPT_KEYFORM, OPT_OTHERPASS, #ifndef OPENSSL_NO_ENGINE OPT_ENGINE, @@ -434,7 +436,7 @@ const OPTIONS cmp_options[] = { { "oldwithnew", OPT_OLDWITHNEW, 's', "File to save OldWithNew cert received in genp of type rootCaKeyUpdate"}, { "crlcert", OPT_CRLCERT, 's', - "certificate to request CRL update for in genm of type crlStatusList"}, + "certificate to request a CRL for in genm of type crlStatusList"}, { "oldcrl", OPT_OLDCRL, 's', "CRL to request update for in genm of type crlStatusList"}, { "crlout", OPT_CRLOUT, 's', @@ -470,6 +472,8 @@ const OPTIONS cmp_options[] = { OPT_SECTION("Credentials format"), {"certform", OPT_CERTFORM, 's', "Format (PEM or DER) to use when saving a certificate to a file. Default PEM"}, + {"crlform", OPT_CRLFORM, 's', + "Format (PEM or DER) to use when saving a CRL to a file. Default DER"}, {"keyform", OPT_KEYFORM, 's', "Format of the key input (ENGINE, other values ignored)"}, {"otherpass", OPT_OTHERPASS, 's', @@ -643,7 +647,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {&opt_digest}, {&opt_mac}, {&opt_extracerts}, {(char **)&opt_unprotected_requests}, - {&opt_certform_s}, {&opt_keyform_s}, + {&opt_certform_s}, {&opt_crlform_s}, {&opt_keyform_s}, {&opt_otherpass}, #ifndef OPENSSL_NO_ENGINE {&opt_engine}, @@ -1085,6 +1089,11 @@ static int transform_opts(void) CMP_err("unknown option given for certificate storing format"); return 0; } + if (opt_crlform_s != NULL + && !opt_format(opt_crlform_s, OPT_FMT_PEMDER, &opt_crlform)) { + CMP_err("unknown option given for CRL storing format"); + return 0; + } return 1; } @@ -1946,20 +1955,20 @@ static int add_certProfile(OSSL_CMP_CTX *ctx, const char *name) if ((sk = sk_ASN1_UTF8STRING_new_reserve(NULL, 1)) == NULL) return 0; - if ((utf8string = ASN1_UTF8STRING_new()) == NULL) - goto err; - if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) { - ASN1_STRING_free(utf8string); - goto err; - } - /* Due to sk_ASN1_UTF8STRING_new_reserve(NULL, 1), this surely succeeds: */ - (void)sk_ASN1_UTF8STRING_push(sk, utf8string); - if ((itav = OSSL_CMP_ITAV_new0_certProfile(sk)) == NULL) - goto err; - if (OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) - return 1; - OSSL_CMP_ITAV_free(itav); - return 0; + if ((utf8string = ASN1_UTF8STRING_new()) == NULL) + goto err; + if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) { + ASN1_STRING_free(utf8string); + goto err; + } + /* Due to sk_ASN1_UTF8STRING_new_reserve(NULL, 1), this surely succeeds: */ + (void)sk_ASN1_UTF8STRING_push(sk, utf8string); + if ((itav = OSSL_CMP_ITAV_new0_certProfile(sk)) == NULL) + goto err; + if (OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) + return 1; + OSSL_CMP_ITAV_free(itav); + return 0; err: sk_ASN1_UTF8STRING_pop_free(sk, ASN1_UTF8STRING_free); @@ -2004,7 +2013,7 @@ static int handle_opt_geninfo(OSSL_CMP_CTX *ctx) if (*ptr != '\0') { if (*ptr != ',') { CMP_err1("Missing ',' or end of -geninfo arg after int at %.40s", - ptr); + ptr); goto err; } ptr++; @@ -2281,13 +2290,13 @@ static int write_cert(BIO *bio, X509 *cert) static int write_crl(BIO *bio, X509_CRL *crl) { - if (opt_certform != FORMAT_PEM && opt_certform != FORMAT_ASN1) { + if (opt_crlform != FORMAT_PEM && opt_crlform != FORMAT_ASN1) { BIO_printf(bio_err, "error: unsupported type '%s' for writing CRLs\n", - opt_certform_s); + opt_crlform_s); return 0; } - return opt_certform == FORMAT_PEM ? PEM_write_bio_X509_CRL(bio, crl) + return opt_crlform == FORMAT_PEM ? PEM_write_bio_X509_CRL(bio, crl) : i2d_X509_CRL_bio(bio, crl); } @@ -2338,26 +2347,26 @@ static int save_free_certs(STACK_OF(X509) *certs, return n; } -static int save_free_crl(X509_CRL *crl, - const char *file, const char *desc) +static int save_crl(X509_CRL *crl, + const char *file, const char *desc) { BIO *bio = NULL; int res = 0; if (file == NULL) - goto end; + return 1; if (crl != NULL) - CMP_info2("received %s CRL, saving to file '%s'", desc, file); + CMP_info2("received %s, saving to file '%s'", desc, file); if ((bio = BIO_new(BIO_s_file())) == NULL || !BIO_write_filename(bio, (char *)file)) { - CMP_err2("could not open file '%s' for writing %s CRL", + CMP_err2("could not open file '%s' for writing %s", file, desc); goto end; } if (!write_crl(bio, crl)) { - CMP_err2("cannot write %s crl to file '%s'", desc, file); + CMP_err2("cannot write %s to file '%s'", desc, file); goto end; } res = 1; @@ -2404,14 +2413,7 @@ static int save_crl_or_delete(X509_CRL *crl, const char *file, const char *desc) { if (file == NULL) return 1; - if (crl == NULL) { - char desc_crl[80]; - - BIO_snprintf(desc_crl, sizeof(desc_crl), "%s", desc); - return delete_file(file, desc_crl); - } else { - return save_free_crl(crl, file, desc); - } + return (crl == NULL) ? delete_file(file, desc) : save_crl(crl, file, desc); } static int print_itavs(const STACK_OF(OSSL_CMP_ITAV) *itavs) @@ -2916,6 +2918,9 @@ static int get_opts(int argc, char **argv) case OPT_CERTFORM: opt_certform_s = opt_str(); break; + case OPT_CRLFORM: + opt_crlform_s = opt_str(); + break; case OPT_KEYFORM: opt_keyform_s = opt_str(); break; @@ -3253,18 +3258,14 @@ static int do_genm(OSSL_CMP_CTX *ctx) return 0; } - if (opt_crlcert == NULL) { - CMP_warn("No -crlcert given, will use data from -oldcrl"); - } else { + if (opt_crlcert != NULL) { crlcert = load_cert_pwd(opt_crlcert, opt_otherpass, "Cert for genm with -infotype crlStatusList"); if (crlcert == NULL) goto end_crlupd; } - if (opt_oldcrl == NULL) { - CMP_warn("No -oldcrl given, will use data from -crlcert"); - } else { + if (opt_oldcrl != NULL) { oldcrl = load_crl(opt_oldcrl, FORMAT_UNDEF, 0, "CRL for genm with -infotype crlStatusList"); if (oldcrl == NULL) diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c index 9129572341b2f..2bf32dd48310a 100644 --- a/apps/lib/cmp_mock_srv.c +++ b/apps/lib/cmp_mock_srv.c @@ -413,8 +413,8 @@ 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; + DIST_POINT_NAME *dpn; + GENERAL_NAMES *issuer; ASN1_TIME *thisupd = NULL; if (sk_OSSL_CMP_CRLSTATUS_num(crlStatusList) != 1) { @@ -425,11 +425,11 @@ static int check_client_crl(const STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList, return 0; crlstatus = sk_OSSL_CMP_CRLSTATUS_value(crlStatusList, 0); - if (!OSSL_CMP_CRLSTATUS_get0(crlstatus, &distpoint, &gen, &thisupd)) + if (!OSSL_CMP_CRLSTATUS_get0(crlstatus, &dpn, &issuer, &thisupd)) return -1; - if (gen != NULL) { - GENERAL_NAME *gn = sk_GENERAL_NAME_value(gen, 0); + if (issuer != NULL) { + GENERAL_NAME *gn = sk_GENERAL_NAME_value(issuer, 0); if (gn != NULL && gn->type == GEN_DIRNAME) { X509_NAME *gen_name = gn->d.dirn; @@ -438,6 +438,9 @@ static int check_client_crl(const STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList, ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CRL_ISSUER); return -1; } + } else { + ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); + return -1; /* error according to RFC 9483 section 4.3.4 */ } } diff --git a/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c index 2123ccb460fa6..ef167ad574524 100644 --- a/crypto/cmp/cmp_asn.c +++ b/crypto/cmp/cmp_asn.c @@ -322,7 +322,7 @@ OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, itav->infoValue.rootCaKeyUpdate = upd; return itav; - err: + err: OSSL_CMP_ROOTCAKEYUPDATE_free(upd); return NULL; } @@ -459,8 +459,9 @@ OSSL_CMP_CRLSTATUS *OSSL_CMP_CRLSTATUS_create(const X509_CRL *crl, int i, NID_akid = NID_authority_key_identifier; /* - * Note: X509{,_CRL}_get_ext_d2i(..., NID, ..., NULL) return the 1st extension - * with the given NID that is available, if any. If there are more, this is an error. + * Note: + * X509{,_CRL}_get_ext_d2i(..., NID, ..., NULL) return the 1st extension with + * given NID that is available, if any. If there are more, this is an error. */ if (cert != NULL) { crldps = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL); diff --git a/crypto/cmp/cmp_genm.c b/crypto/cmp/cmp_genm.c index ec14cc2aed80f..04077e7f787fe 100644 --- a/crypto/cmp/cmp_genm.c +++ b/crypto/cmp/cmp_genm.c @@ -373,12 +373,10 @@ int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509 *crlcert, if ((req = OSSL_CMP_ITAV_new0_crlStatusList(list)) == NULL) goto end; - status = NULL; list = NULL; - itav = get_genm_itav(ctx, req, NID_id_it_crls, "crl"); - if (itav == NULL) + if ((itav = get_genm_itav(ctx, req, NID_id_it_crls, "crl")) == NULL) goto end; if (!OSSL_CMP_ITAV_get0_crls(itav, &crls)) diff --git a/doc/man1/openssl-cmp.pod.in b/doc/man1/openssl-cmp.pod.in index 6c4f7fa6696e7..1bb7b334e3b01 100644 --- a/doc/man1/openssl-cmp.pod.in +++ b/doc/man1/openssl-cmp.pod.in @@ -94,6 +94,7 @@ Client authentication and protection options: Credentials format options: [B<-certform> I] +[B<-crlform> I] [B<-keyform> I] [B<-otherpass> I] {- $OpenSSL::safe::opt_engine_synopsis -}{- $OpenSSL::safe::opt_provider_synopsis -} @@ -251,7 +252,8 @@ ITAV Bs is printed to stdout. Set InfoType name to use for requesting specific info in B, e.g., C. -So far, there is specific support for C and C. +So far, there is specific support for C, C +and C. =item B<-profile> I @@ -741,11 +743,14 @@ If on success no such cert was received, this is indicated by deleting the file. Certificate used for specifying a CRL issuer when requesting a CRL in a genm message with infoType C. +Any available distribution point name is preferred over issuer names. =item B<-oldcrl> I CRL used for specifying a CRL issuer when requesting a CRL in a genm message with infoType C. +Any available distribution point name is preferred over issuer names. +If also -crlcrt is given, its data is preferred over data from -oldcrl. =item B<-crlout> I @@ -877,6 +882,11 @@ Send request messages without CMP-level protection. File format to use when saving a certificate to a file. Default value is PEM. +=item B<-crlform> I + +File format to use when saving a CRL to a file. +Default value is DER. + =item B<-keyform> I The format of the key input; unspecified by default. @@ -1162,7 +1172,7 @@ Certificate to be returned as mock enrollment result. =item B<-rsp_crl> I|I -CRL to be returned in genp of type crls. +CRL to be returned in genp of type C. =item B<-rsp_extracerts> I|I @@ -1461,7 +1471,8 @@ The B application was added in OpenSSL 3.0. The B<-engine> option was deprecated in OpenSSL 3.0. -The B<-profile> option was added in OpenSSL 3.3. +B<-profile>, B<-crlcert>, B<-oldcrl>, B<-crlout>, B<-crlform> +and B<-rsp_crl> options were added in OpenSSL 3.3. =head1 COPYRIGHT diff --git a/doc/man3/GENERAL_NAME.pod b/doc/man3/GENERAL_NAME.pod index b803266931861..903a33944ebf6 100644 --- a/doc/man3/GENERAL_NAME.pod +++ b/doc/man3/GENERAL_NAME.pod @@ -21,12 +21,10 @@ and populates it based on provided X509_NAME I which can be NULL. I must not be NULL. If successful, I<*tgt> will be set to point to the newly created GENERAL_NAME. -=head1 NOTES =head1 RETURN VALUES GENERAL_NAME_set1_X509_NAME() return 1 on success, 0 on error. -=head1 SEE ALSO =head1 HISTORY GENERAL_NAME_set1_X509_NAME() was added in OpenSSL 3.3. diff --git a/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod b/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod index 00b520840154b..fada72c0ce1c8 100644 --- a/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod +++ b/doc/man3/OSSL_CMP_ITAV_new_caCerts.pod @@ -93,7 +93,6 @@ OSSL_CMP_CRLSTATUS_create() is a high-level variant of OSSL_CMP_CRLSTATUS_new1() It fills the thisUpdate field with a copy of the thisUpdate field of I if present. It fills the CRLSource field with a copy of the first data item found using the I and/or I parameters as follows. -The CRLSource field is filled with the first data item found in them as follows. Any available distribution point name is preferred over issuer names. Data from I, if present, is preferred over data from I. If no distribution point names are available, diff --git a/doc/man3/OSSL_CMP_exec_certreq.pod b/doc/man3/OSSL_CMP_exec_certreq.pod index 0a09ae3881678..56e6bb8ef2cc4 100644 --- a/doc/man3/OSSL_CMP_exec_certreq.pod +++ b/doc/man3/OSSL_CMP_exec_certreq.pod @@ -42,7 +42,8 @@ OSSL_CMP_get1_crlUpdate int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, const X509 *oldWithOld, X509 **newWithNew, X509 **newWithOld, X509 **oldWithNew); - int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509_CRL *last_crl, + int OSSL_CMP_get1_crlUpdate(OSSL_CMP_CTX *ctx, const X509 *crlcert, + const X509_CRL *last_crl, X509_CRL **crl); =head1 DESCRIPTION @@ -162,8 +163,9 @@ the weakest trust in any of the certificates in the trust store of I. OSSL_CMP_get1_crlUpdate() uses a genm request message with infoType crlStatusList to obtain CRL from the CMP server referenced by I in a genp response message -with infoType crls. It uses oldcert referenced by I and I to create -request. On success it assigns to I<*crl> the CRL received. +with infoType crls. It uses I and I to create +a request with a status field as described for L. +On success it assigns to I<*crl> the CRL received. NULL means that no CRL was provided by the server. The CRL obtained this way must be freed by the caller. @@ -221,7 +223,7 @@ L, L, L, L, L, L, L, L, -L +L, L =head1 HISTORY diff --git a/include/crypto/cmperr.h b/include/crypto/cmperr.h index 89512baabb9de..2bd1637384661 100644 --- a/include/crypto/cmperr.h +++ b/include/crypto/cmperr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in index 0facbfbee0327..6f5d0660ecbca 100644 --- a/include/openssl/cmp.h.in +++ b/include/openssl/cmp.h.in @@ -225,60 +225,14 @@ typedef struct ossl_cmp_certstatus_st OSSL_CMP_CERTSTATUS; -} typedef struct ossl_cmp_itav_st OSSL_CMP_ITAV; DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV) -SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_ITAV, OSSL_CMP_ITAV, OSSL_CMP_ITAV) -#define sk_OSSL_CMP_ITAV_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk)) -#define sk_OSSL_CMP_ITAV_value(sk, idx) ((OSSL_CMP_ITAV *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk), (idx))) -#define sk_OSSL_CMP_ITAV_new(cmp) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp))) -#define sk_OSSL_CMP_ITAV_new_null() ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new_null()) -#define sk_OSSL_CMP_ITAV_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp), (n))) -#define sk_OSSL_CMP_ITAV_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (n)) -#define sk_OSSL_CMP_ITAV_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) -#define sk_OSSL_CMP_ITAV_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) -#define sk_OSSL_CMP_ITAV_delete(sk, i) ((OSSL_CMP_ITAV *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (i))) -#define sk_OSSL_CMP_ITAV_delete_ptr(sk, ptr) ((OSSL_CMP_ITAV *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr))) -#define sk_OSSL_CMP_ITAV_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) -#define sk_OSSL_CMP_ITAV_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) -#define sk_OSSL_CMP_ITAV_pop(sk) ((OSSL_CMP_ITAV *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_ITAV_sk_type(sk))) -#define sk_OSSL_CMP_ITAV_shift(sk) ((OSSL_CMP_ITAV *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_ITAV_sk_type(sk))) -#define sk_OSSL_CMP_ITAV_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_ITAV_sk_type(sk),ossl_check_OSSL_CMP_ITAV_freefunc_type(freefunc)) -#define sk_OSSL_CMP_ITAV_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr), (idx)) -#define sk_OSSL_CMP_ITAV_set(sk, idx, ptr) ((OSSL_CMP_ITAV *)OPENSSL_sk_set(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (idx), ossl_check_OSSL_CMP_ITAV_type(ptr))) -#define sk_OSSL_CMP_ITAV_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) -#define sk_OSSL_CMP_ITAV_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) -#define sk_OSSL_CMP_ITAV_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr), pnum) -#define sk_OSSL_CMP_ITAV_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) -#define sk_OSSL_CMP_ITAV_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk)) -#define sk_OSSL_CMP_ITAV_dup(sk) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk))) -#define sk_OSSL_CMP_ITAV_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_ITAV_freefunc_type(freefunc))) -#define sk_OSSL_CMP_ITAV_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_ITAV_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp))) +{- + generate_stack_macros("OSSL_CMP_ITAV"); +-} typedef struct ossl_cmp_crlstatus_st OSSL_CMP_CRLSTATUS; -SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_CRLSTATUS, OSSL_CMP_CRLSTATUS, OSSL_CMP_CRLSTATUS) -#define sk_OSSL_CMP_CRLSTATUS_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk)) -#define sk_OSSL_CMP_CRLSTATUS_value(sk, idx) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk), (idx))) -#define sk_OSSL_CMP_CRLSTATUS_new(cmp) ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_CRLSTATUS_compfunc_type(cmp))) -#define sk_OSSL_CMP_CRLSTATUS_new_null() ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_new_null()) -#define sk_OSSL_CMP_CRLSTATUS_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_CRLSTATUS_compfunc_type(cmp), (n))) -#define sk_OSSL_CMP_CRLSTATUS_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), (n)) -#define sk_OSSL_CMP_CRLSTATUS_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk)) -#define sk_OSSL_CMP_CRLSTATUS_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk)) -#define sk_OSSL_CMP_CRLSTATUS_delete(sk, i) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), (i))) -#define sk_OSSL_CMP_CRLSTATUS_delete_ptr(sk, ptr) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr))) -#define sk_OSSL_CMP_CRLSTATUS_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr)) -#define sk_OSSL_CMP_CRLSTATUS_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr)) -#define sk_OSSL_CMP_CRLSTATUS_pop(sk) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk))) -#define sk_OSSL_CMP_CRLSTATUS_shift(sk) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk))) -#define sk_OSSL_CMP_CRLSTATUS_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk),ossl_check_OSSL_CMP_CRLSTATUS_freefunc_type(freefunc)) -#define sk_OSSL_CMP_CRLSTATUS_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr), (idx)) -#define sk_OSSL_CMP_CRLSTATUS_set(sk, idx, ptr) ((OSSL_CMP_CRLSTATUS *)OPENSSL_sk_set(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), (idx), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr))) -#define sk_OSSL_CMP_CRLSTATUS_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr)) -#define sk_OSSL_CMP_CRLSTATUS_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr)) -#define sk_OSSL_CMP_CRLSTATUS_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_type(ptr), pnum) -#define sk_OSSL_CMP_CRLSTATUS_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk)) -#define sk_OSSL_CMP_CRLSTATUS_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk)) -#define sk_OSSL_CMP_CRLSTATUS_dup(sk) ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk))) -#define sk_OSSL_CMP_CRLSTATUS_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_CRLSTATUS) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_CRLSTATUS_freefunc_type(freefunc))) -#define sk_OSSL_CMP_CRLSTATUS_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_CRLSTATUS_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_CRLSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CRLSTATUS_compfunc_type(cmp))) +{- + generate_stack_macros("OSSL_CMP_CRLSTATUS"); +-} typedef struct ossl_cmp_revrepcontent_st OSSL_CMP_REVREPCONTENT; typedef struct ossl_cmp_pkisi_st OSSL_CMP_PKISI; diff --git a/test/recipes/80-test_cmp_http_data/test_commands.csv b/test/recipes/80-test_cmp_http_data/test_commands.csv index ee38087265560..acc2b4b09d0e0 100644 --- a/test/recipes/80-test_cmp_http_data/test_commands.csv +++ b/test/recipes/80-test_cmp_http_data/test_commands.csv @@ -94,6 +94,7 @@ expected,description, -section,val, -cmd,val,val2, -cacertsout,val,val2, -infoty 0,genm crlStatusList with -crlcert nonexistent, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -crlcert, idontexist,,,,, -crlout, _RESULT_DIR/test.crlout.pem 0,genm crlStatusList with wrong issuer, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -crlcert, server.crt,,,,, -crlout, _RESULT_DIR/test.crlout.pem 0,genm crlStatusList missing -crlcert & -oldcrl, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,,,,,,,, -crlout, _RESULT_DIR/test.crlout.pem +0,genm crlStatusList with wrong cert and correct crl, -section,, -cmd,genm,, BLANK,,, -infotype,crlStatusList,, -crlcert, server.crt, -oldcrl, oldcrl.pem,,, -crlout, _RESULT_DIR/test.crlout.pem ,,,,,,,,,,,,,,,,,,,,,, 1,profile, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile1,BLANK,,BLANK, 0,profile wrong value, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -profile,profile2,BLANK,,BLANK, From a9e6f4d331178b6aee5ec1f7f6771004581fff54 Mon Sep 17 00:00:00 2001 From: Rajeev Ranjan Date: Thu, 7 Mar 2024 18:29:38 +0100 Subject: [PATCH 6/6] Add support for requesting CRL in CMP --- CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d857bf846a5f6..098e40493aea8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -67,6 +67,10 @@ OpenSSL 3.3 *Neil Horman* + * Added support for requesting CRL in CMP. + + *Rajeev Ranjan, Siemens AG* + * Added `-set_issuer` and `-set_subject` options to `openssl x509` to override the Issuer and Subject when creating a certificate. The `-subj` option now is an alias for `-set_subject`.