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)
This commit is contained in:
Damian Hobson-Garcia 2021-06-03 15:41:27 +09:00 committed by Matt Caswell
parent d10b020e2e
commit dab96a4f60
5 changed files with 140 additions and 0 deletions

View File

@ -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);

View File

@ -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 \

View File

@ -0,0 +1,63 @@
=pod
=head1 NAME
X509_ACERT_add_attr_nconf
- Add attributes to X509_ACERT from configuration section
=head1 SYNOPSIS
#include <openssl/x509_acert.h>
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 B<X509_ATTRIBUTE>s to the
existing B<X509_ACERT> structure I<acert>. The attributes are read
from a I<section> of the I<conf> object.
The give I<section> of the configuration should contain attribute
descriptions of the form:
attribute_name = value
The format of B<value> will vary depending on the B<attribute_name>.
B<value> can either be a string value or an B<ASN1_TYPE>
object.
To encode an B<ASN1_TYPE> object, use the prefix "ASN1:" followed by
the object description that uses the same syntax as L<ASN1_generate_nconf(3)>.
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<ASN1_generate_nconf(3)>.
=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<https://www.openssl.org/source/license.html>.
=cut

View File

@ -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);

View File

@ -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: