summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2022-12-03 17:49:08 +0100
committerTomas Mraz <tomas@openssl.org>2024-05-01 14:58:35 +0200
commit40a200f9e781381d72d234c886e38bcfce36bbc8 (patch)
tree229fdb094d3a05485c504e66da8934a9d585648a /crypto
parent1848c561ec39a9ea91ff1bf740a554be274f98b0 (diff)
CMP: add support for genm with crlStatusList and genp with crls
Introduce the capability to retrieve and update Certificate Revocation Lists (CRLs) in the CMP client, as specified in section 4.3.4 of RFC 9483. To request a CRL update, the CMP client can send a genm message with the option -infotype crlStatusList. The server will respond with a genp message containing the updated CRL, using the -infoType id-it-crls. The client can then save the CRL in a specified file using the -crlout parameter. Co-authored-by: Rajeev Ranjan <ranjan.rajeev@siemens.com> Reviewed-by: Todd Short <todd.short@me.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/23768)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/cmp/cmp_asn.c256
-rw-r--r--crypto/cmp/cmp_err.c10
-rw-r--r--crypto/cmp/cmp_genm.c60
-rw-r--r--crypto/cmp/cmp_hdr.c32
-rw-r--r--crypto/cmp/cmp_local.h35
-rw-r--r--crypto/err/openssl.txt4
-rw-r--r--crypto/x509/v3_crld.c1
-rw-r--r--crypto/x509/v3_genn.c29
8 files changed, 395 insertions, 32 deletions
diff --git a/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c
index daa6a4c49b..f20e5098ca 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,20 @@ 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)
+
OSSL_CMP_ITAV *OSSL_CMP_ITAV_create(ASN1_OBJECT *type, ASN1_TYPE *value)
{
OSSL_CMP_ITAV *itav;
@@ -339,6 +358,243 @@ int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav,
return 1;
}
+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)
+{
+ 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;
+}
+
+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_set1_X509_NAME(&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, ..., 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);
+ /* 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, 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, 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, NULL, 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_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) {
+ 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;
+ return itav;
+
+ err:
+ sk_X509_CRL_free(crls);
+ OSSL_CMP_ITAV_free(itav);
+ return NULL;
+}
+
+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 -2 on error; -1 is valid for certReqId */
int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a)
{
diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c
index 56ac3691d7..689aa6a952 100644
--- a/crypto/cmp/cmp_err.c
+++ b/crypto/cmp/cmp_err.c
@@ -85,12 +85,15 @@ 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"},
{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 +149,9 @@ 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_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"},
@@ -156,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 7c38d3367c..8d92019c83 100644
--- a/crypto/cmp/cmp_genm.c
+++ b/crypto/cmp/cmp_genm.c
@@ -346,3 +346,63 @@ 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 *crlcert,
+ 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(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ *crl = NULL;
+
+ 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(ERR_LIB_CMP, CMP_R_GENERATE_CRLSTATUS);
+ 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;
+
+ if ((itav = get_genm_itav(ctx, req, NID_id_it_crls, "crl")) == NULL)
+ goto end;
+
+ if (!OSSL_CMP_ITAV_get0_crls(itav, &crls))
+ goto end;
+
+ 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",
+ 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/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c
index 4358b38873..59205ef8c7 100644
--- a/crypto/cmp/cmp_hdr.c
+++ b/crypto/cmp/cmp_hdr.c
@@ -89,34 +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) */
-static int set1_general_name(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
@@ -126,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 set1_general_name(&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 set1_general_name(&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/cmp/cmp_local.h b/crypto/cmp/cmp_local.h
index 89f05d7536..9ebd1858a5 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/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 1607ad835f..5102c481e3 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
@@ -276,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
@@ -283,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 8f560e171c..839b2c1afe 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 1f67bf2f63..c71e5b9111 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;