From: Damian Hobson-Garcia Date: Thu, 3 Jun 2021 06:41:27 +0000 (+0900) Subject: x509_acert: Load attributes from config file section X-Git-Tag: openssl-3.4.0-alpha1~639 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dab96a4f60f12b162f02ce2ddf4f70bb1e24bd5b;p=thirdparty%2Fopenssl.git x509_acert: Load attributes from config file section Several of the attribute values defined for use by attribute certificates use multi-valued data in an ASN.1 SEQUENCE. Allow reading of these values from a configuration file, similar to how generic X.509 extensions are handled. Reviewed-by: Tomas Mraz Reviewed-by: Neil Horman (Merged from https://github.com/openssl/openssl/pull/15857) --- diff --git a/crypto/x509/x509_acert.c b/crypto/x509/x509_acert.c index 9499a14cc0b..a3c89463633 100644 --- a/crypto/x509/x509_acert.c +++ b/crypto/x509/x509_acert.c @@ -7,7 +7,10 @@ * https://www.openssl.org/source/license.html */ +#include +#include #include +#include #include #include #include "x509_acert.h" @@ -243,6 +246,71 @@ int X509_ACERT_add1_attr_by_txt(X509_ACERT *x, const char *attrname, int type, return X509at_add1_attr_by_txt(attrs, attrname, type, bytes, len) != NULL; } +static int check_asn1_attribute(const char **value) +{ + const char *p = *value; + + if (strncmp(p, "ASN1:", 5) != 0) + return 0; + + p += 5; + while (ossl_isspace(*p)) + p++; + + *value = p; + return 1; +} + +int X509_ACERT_add_attr_nconf(CONF *conf, const char *section, + X509_ACERT *acert) +{ + int ret = 0, i; + STACK_OF(CONF_VALUE) *attr_sk = NCONF_get_section(conf, section); + + if (attr_sk == NULL) + goto err; + + for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) { + CONF_VALUE *v = sk_CONF_VALUE_value(attr_sk, i); + const char *value = v->value; + + if (value == NULL) { + ERR_raise_data(ERR_LIB_X509, X509_R_INVALID_ATTRIBUTES, + "name=%s,section=%s",v->name, section); + goto err; + } + + if (check_asn1_attribute(&value) == 1) { + int att_len; + unsigned char *att_data = NULL; + ASN1_TYPE *asn1 = ASN1_generate_nconf(value, conf); + + if (asn1 == NULL) + goto err; + + att_len = i2d_ASN1_TYPE(asn1, &att_data); + + ret = X509_ACERT_add1_attr_by_txt(acert, v->name, V_ASN1_SEQUENCE, + att_data, att_len); + OPENSSL_free(att_data); + ASN1_TYPE_free(asn1); + + if (!ret) + goto err; + } else { + ret = X509_ACERT_add1_attr_by_txt(acert, v->name, + V_ASN1_OCTET_STRING, + (unsigned char *)value, + strlen(value)); + if (!ret) + goto err; + } + } + ret = 1; +err: + return ret; +} + void *X509_ACERT_get_ext_d2i(const X509_ACERT *x, int nid, int *crit, int *idx) { return X509V3_get_d2i(x->acinfo->extensions, nid, crit, idx); diff --git a/doc/build.info b/doc/build.info index 373f61476e3..c7cb6d5d4fb 100644 --- a/doc/build.info +++ b/doc/build.info @@ -2811,6 +2811,10 @@ DEPEND[html/man3/X509_ACERT_add1_attr.html]=man3/X509_ACERT_add1_attr.pod GENERATE[html/man3/X509_ACERT_add1_attr.html]=man3/X509_ACERT_add1_attr.pod DEPEND[man/man3/X509_ACERT_add1_attr.3]=man3/X509_ACERT_add1_attr.pod GENERATE[man/man3/X509_ACERT_add1_attr.3]=man3/X509_ACERT_add1_attr.pod +DEPEND[html/man3/X509_ACERT_add_attr_nconf.html]=man3/X509_ACERT_add_attr_nconf.pod +GENERATE[html/man3/X509_ACERT_add_attr_nconf.html]=man3/X509_ACERT_add_attr_nconf.pod +DEPEND[man/man3/X509_ACERT_add_attr_nconf.3]=man3/X509_ACERT_add_attr_nconf.pod +GENERATE[man/man3/X509_ACERT_add_attr_nconf.3]=man3/X509_ACERT_add_attr_nconf.pod DEPEND[html/man3/X509_ACERT_get0_holder_baseCertId.html]=man3/X509_ACERT_get0_holder_baseCertId.pod GENERATE[html/man3/X509_ACERT_get0_holder_baseCertId.html]=man3/X509_ACERT_get0_holder_baseCertId.pod DEPEND[man/man3/X509_ACERT_get0_holder_baseCertId.3]=man3/X509_ACERT_get0_holder_baseCertId.pod @@ -3658,6 +3662,7 @@ html/man3/UI_new.html \ html/man3/X509V3_get_d2i.html \ html/man3/X509V3_set_ctx.html \ html/man3/X509_ACERT_add1_attr.html \ +html/man3/X509_ACERT_add_attr_nconf.html \ html/man3/X509_ACERT_get0_holder_baseCertId.html \ html/man3/X509_ACERT_get_attr.html \ html/man3/X509_ACERT_print_ex.html \ @@ -4309,6 +4314,7 @@ man/man3/UI_new.3 \ man/man3/X509V3_get_d2i.3 \ man/man3/X509V3_set_ctx.3 \ man/man3/X509_ACERT_add1_attr.3 \ +man/man3/X509_ACERT_add_attr_nconf.3 \ man/man3/X509_ACERT_get0_holder_baseCertId.3 \ man/man3/X509_ACERT_get_attr.3 \ man/man3/X509_ACERT_print_ex.3 \ diff --git a/doc/man3/X509_ACERT_add_attr_nconf.pod b/doc/man3/X509_ACERT_add_attr_nconf.pod new file mode 100644 index 00000000000..a16d31c3f36 --- /dev/null +++ b/doc/man3/X509_ACERT_add_attr_nconf.pod @@ -0,0 +1,63 @@ +=pod + +=head1 NAME + +X509_ACERT_add_attr_nconf +- Add attributes to X509_ACERT from configuration section + +=head1 SYNOPSIS + + #include + + int X509_ACERT_add_attr_nconf(CONF *conf, const char *section, + X509_ACERT *acert); + +=head1 DESCRIPTION + +X509_ACERT_add_attr_nconf() adds one or more Bs to the +existing B structure I. The attributes are read +from a I
of the I object. + +The give I
of the configuration should contain attribute +descriptions of the form: + + attribute_name = value + +The format of B will vary depending on the B. +B can either be a string value or an B +object. + +To encode an B object, use the prefix "ASN1:" followed by +the object description that uses the same syntax as L. +For example: + + id-aca-group = ASN1:SEQUENCE:ietfattr + + [ietfattr] + values = SEQUENCE:groups + + [groups] + 1.string = UTF8:mygroup1 + +=head1 RETURN VALUES + +X509_ACERT_add_attr_nconf() returns 1 for success and 0 for failure. + +=head1 SEE ALSO + +L. + +=head1 HISTORY + +The function X509_ACERT_add_attr_nconf() was added in OpenSSL 3.4. + +=head1 COPYRIGHT + +Copyright 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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/openssl/x509_acert.h.in b/include/openssl/x509_acert.h.in index a1e6704c0d9..42376a6cb76 100644 --- a/include/openssl/x509_acert.h.in +++ b/include/openssl/x509_acert.h.in @@ -98,6 +98,8 @@ int X509_ACERT_add1_attr_by_NID(X509_ACERT *x, int nid, int type, const void *bytes, int len); int X509_ACERT_add1_attr_by_txt(X509_ACERT *x, const char *attrname, int type, const unsigned char *bytes, int len); +int X509_ACERT_add_attr_nconf(CONF *conf, const char *section, + X509_ACERT *acert); int X509_ACERT_set1_issuerName(X509_ACERT *x, const X509_NAME *name); int X509_ACERT_set1_serialNumber(X509_ACERT *x, const ASN1_INTEGER *serial); diff --git a/util/libcrypto.num b/util/libcrypto.num index 70e5871fb5a..77b66ee2725 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5632,3 +5632,4 @@ OSSL_IETF_ATTR_SYNTAX_get_value_num ? 3_4_0 EXIST::FUNCTION: OSSL_IETF_ATTR_SYNTAX_get0_value ? 3_4_0 EXIST::FUNCTION: OSSL_IETF_ATTR_SYNTAX_add1_value ? 3_4_0 EXIST::FUNCTION: OSSL_IETF_ATTR_SYNTAX_print ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_add_attr_nconf ? 3_4_0 EXIST::FUNCTION: