From 0d8cc7c69904371c396a6c6eda58fde0201046c2 Mon Sep 17 00:00:00 2001 From: "Jonathan M. Wilbur" Date: Fri, 13 Dec 2024 06:36:24 +0000 Subject: feat: support the aAissuingDistributionPoint X.509v3 extension Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/26174) --- crypto/x509/ext_dat.h | 1 + crypto/x509/standard_exts.h | 1 + crypto/x509/v3_crld.c | 170 ++++++++++++++++++++++++++++++++++++++++++++ include/openssl/x509v3.h.in | 12 ++++ util/libcrypto.num | 5 ++ 5 files changed, 189 insertions(+) diff --git a/crypto/x509/ext_dat.h b/crypto/x509/ext_dat.h index 291a3df580..d28b1f7ff8 100644 --- a/crypto/x509/ext_dat.h +++ b/crypto/x509/ext_dat.h @@ -48,3 +48,4 @@ extern const X509V3_EXT_METHOD ossl_v3_attribute_descriptor; extern const X509V3_EXT_METHOD ossl_v3_time_specification; extern const X509V3_EXT_METHOD ossl_v3_attribute_mappings; extern const X509V3_EXT_METHOD ossl_v3_allowed_attribute_assignments; +extern const X509V3_EXT_METHOD ossl_v3_aa_issuing_dist_point; diff --git a/crypto/x509/standard_exts.h b/crypto/x509/standard_exts.h index 2fe142f9cf..e8c2295d2d 100644 --- a/crypto/x509/standard_exts.h +++ b/crypto/x509/standard_exts.h @@ -88,6 +88,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = { &ossl_v3_acc_priv_policies, &ossl_v3_indirect_issuer, &ossl_v3_no_assertion, + &ossl_v3_aa_issuing_dist_point, &ossl_v3_issued_on_behalf_of, &ossl_v3_single_use, &ossl_v3_group_ac, diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c index 032695c01a..234d2a2b09 100644 --- a/crypto/x509/v3_crld.c +++ b/crypto/x509/v3_crld.c @@ -509,3 +509,173 @@ int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname) dpn->dpname = NULL; return 0; } + +ASN1_SEQUENCE(OSSL_AA_DIST_POINT) = { + ASN1_EXP_OPT(OSSL_AA_DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(OSSL_AA_DIST_POINT, reasons, ASN1_BIT_STRING, 1), + ASN1_IMP_OPT(OSSL_AA_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 2), + ASN1_IMP_OPT(OSSL_AA_DIST_POINT, containsUserAttributeCerts, ASN1_TBOOLEAN, 3), + ASN1_IMP_OPT(OSSL_AA_DIST_POINT, containsAACerts, ASN1_TBOOLEAN, 4), + ASN1_IMP_OPT(OSSL_AA_DIST_POINT, containsSOAPublicKeyCerts, ASN1_TBOOLEAN, 5) +} ASN1_SEQUENCE_END(OSSL_AA_DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(OSSL_AA_DIST_POINT) + +static int print_boolean(BIO *out, ASN1_BOOLEAN b) +{ + return BIO_puts(out, b ? "TRUE" : "FALSE"); +} + +static OSSL_AA_DIST_POINT *aaidp_from_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + int i, ret; + CONF_VALUE *cnf; + OSSL_AA_DIST_POINT *point = OSSL_AA_DIST_POINT_new(); + + if (point == NULL) + goto err; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (strcmp(cnf->name, "reasons") == 0) { + if (!set_reasons(&point->reasons, cnf->value)) + goto err; + } else if (strcmp(cnf->name, "indirectCRL") == 0) { + if (!X509V3_get_value_bool(cnf, &point->indirectCRL)) + goto err; + } else if (strcmp(cnf->name, "containsUserAttributeCerts") == 0) { + if (!X509V3_get_value_bool(cnf, &point->containsUserAttributeCerts)) + goto err; + } else if (strcmp(cnf->name, "containsAACerts") == 0) { + if (!X509V3_get_value_bool(cnf, &point->containsAACerts)) + goto err; + } else if (strcmp(cnf->name, "containsSOAPublicKeyCerts") == 0) { + if (!X509V3_get_value_bool(cnf, &point->containsSOAPublicKeyCerts)) + goto err; + } + } + + return point; + + err: + OSSL_AA_DIST_POINT_free(point); + return NULL; +} + +static void *v2i_aaidp(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + CONF_VALUE *cnf; + OSSL_AA_DIST_POINT *point = NULL; + STACK_OF(CONF_VALUE) *dpsect; + + cnf = sk_CONF_VALUE_value(nval, 0); + if (cnf == NULL) + return NULL; + if (cnf->value == NULL) { + dpsect = X509V3_get_section(ctx, cnf->name); + if (dpsect == NULL) + goto err; + point = aaidp_from_section(ctx, dpsect); + X509V3_section_free(ctx, dpsect); + if (point == NULL) + goto err; + } else { + if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) + goto err; + if ((gens = GENERAL_NAMES_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + if (!sk_GENERAL_NAME_push(gens, gen)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); + goto err; + } + gen = NULL; + if ((point = OSSL_AA_DIST_POINT_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + if ((point->distpoint = DIST_POINT_NAME_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } + return point; + + err: + OSSL_AA_DIST_POINT_free(point); + GENERAL_NAME_free(gen); + GENERAL_NAMES_free(gens); + return NULL; +} + +static int i2r_aaidp(const X509V3_EXT_METHOD *method, void *dp, BIO *out, + int indent) +{ + OSSL_AA_DIST_POINT *pdp = dp; + + if (pdp->distpoint) + if (print_distpoint(out, pdp->distpoint, indent) <= 0) + return 0; + if (pdp->reasons) + if (print_reasons(out, "Reasons", pdp->reasons, indent) <= 0) + return 0; + if (pdp->indirectCRL) { + if (BIO_printf(out, "%*sIndirect CRL: ", indent, "") <= 0) + return 0; + if (print_boolean(out, pdp->indirectCRL) <= 0) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + } + if (pdp->containsUserAttributeCerts) { + if (BIO_printf(out, "%*sContains User Attribute Certificates: ", indent, "") <= 0) + return 0; + if (print_boolean(out, pdp->containsUserAttributeCerts) <= 0) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + } + if (pdp->containsAACerts) { + if (BIO_printf(out, "%*sContains Attribute Authority (AA) Certificates: ", + indent, "") <= 0) + return 0; + if (print_boolean(out, pdp->containsAACerts) <= 0) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + } + if (pdp->containsSOAPublicKeyCerts) { + if (BIO_printf(out, + "%*sContains Source Of Authority (SOA) Public Key Certificates: ", + indent, "") <= 0) + return 0; + if (print_boolean(out, pdp->containsSOAPublicKeyCerts) <= 0) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_aa_issuing_dist_point = { + NID_id_aa_issuing_distribution_point, 0, + ASN1_ITEM_ref(OSSL_AA_DIST_POINT), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_aaidp, + i2r_aaidp, 0, + NULL +}; diff --git a/include/openssl/x509v3.h.in b/include/openssl/x509v3.h.in index b22334d14f..a0d80e2eec 100644 --- a/include/openssl/x509v3.h.in +++ b/include/openssl/x509v3.h.in @@ -1346,6 +1346,18 @@ DECLARE_ASN1_FUNCTIONS(OSSL_ALLOWED_ATTRIBUTES_SYNTAX) generate_stack_macros("OSSL_ALLOWED_ATTRIBUTES_ITEM"); -} +typedef struct AA_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + int dp_reasons; + ASN1_BOOLEAN indirectCRL; + ASN1_BOOLEAN containsUserAttributeCerts; + ASN1_BOOLEAN containsAACerts; + ASN1_BOOLEAN containsSOAPublicKeyCerts; +} OSSL_AA_DIST_POINT; + +DECLARE_ASN1_FUNCTIONS(OSSL_AA_DIST_POINT) + # ifdef __cplusplus } # endif diff --git a/util/libcrypto.num b/util/libcrypto.num index 158e54022c..fe5d32e21c 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5878,3 +5878,8 @@ OSSL_ALLOWED_ATTRIBUTES_SYNTAX_new ? 3_5_0 EXIST::FUNCTION: OSSL_ALLOWED_ATTRIBUTES_SYNTAX_it ? 3_5_0 EXIST::FUNCTION: OSSL_PROVIDER_add_conf_parameter ? 3_5_0 EXIST::FUNCTION: OSSL_PROVIDER_get_conf_parameters ? 3_5_0 EXIST::FUNCTION: +d2i_OSSL_AA_DIST_POINT ? 3_5_0 EXIST::FUNCTION: +i2d_OSSL_AA_DIST_POINT ? 3_5_0 EXIST::FUNCTION: +OSSL_AA_DIST_POINT_free ? 3_5_0 EXIST::FUNCTION: +OSSL_AA_DIST_POINT_new ? 3_5_0 EXIST::FUNCTION: +OSSL_AA_DIST_POINT_it ? 3_5_0 EXIST::FUNCTION: -- cgit v1.2.3