diff options
Diffstat (limited to 'crypto/x509/x509_acert.c')
-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); |