diff options
author | Damian Hobson-Garcia <dhobsong@igel.co.jp> | 2021-06-03 15:41:27 +0900 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2024-04-24 14:08:05 +0100 |
commit | dab96a4f60f12b162f02ce2ddf4f70bb1e24bd5b (patch) | |
tree | d0f970424887398a3f5c63b63b4e43708da44ede /crypto | |
parent | d10b020e2e389f4e5f5c84ce8d4512536dd3027a (diff) |
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 <tomas@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15857)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/x509/x509_acert.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/crypto/x509/x509_acert.c b/crypto/x509/x509_acert.c index 9499a14cc0..a3c8946363 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 <string.h> +#include <crypto/ctype.h> #include <openssl/asn1t.h> +#include <openssl/err.h> #include <openssl/x509.h> #include <openssl/x509v3.h> #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); |