From: Damian Hobson-Garcia Date: Fri, 18 Jun 2021 14:37:18 +0000 (+0900) Subject: Attribute certificate getter and setter API X-Git-Tag: openssl-3.4.0-alpha1~647 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9e1a8b5ecce7bcf706f48805f2999bbc3d4ef09a;p=thirdparty%2Fopenssl.git Attribute certificate getter and setter API Only fields that are allowed by RFC 5755 are accessible through this API. Fields that are only supported in version 1 attribute certificates (e.g. the AttCertIssuer v1Form fields) are not implemented. Reviewed-by: Tomas Mraz Reviewed-by: Neil Horman (Merged from https://github.com/openssl/openssl/pull/15857) --- diff --git a/crypto/x509/build.info b/crypto/x509/build.info index 2976b37e0fc..b580d2b4f8c 100644 --- a/crypto/x509/build.info +++ b/crypto/x509/build.info @@ -16,7 +16,7 @@ SOURCE[../../libcrypto]=\ pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c v3_no_rev_avail.c \ v3_soa_id.c v3_no_ass.c v3_group_ac.c v3_single_use.c v3_ind_iss.c \ - x509_acert.c + x509_acert.c x509aset.c IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../../libcrypto]=x509type.c diff --git a/crypto/x509/x509_acert.c b/crypto/x509/x509_acert.c index 9a1c298d7a5..d6b78bfc7ca 100644 --- a/crypto/x509/x509_acert.c +++ b/crypto/x509/x509_acert.c @@ -73,3 +73,113 @@ IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X509_ACERT_ISSUER_V2FORM) IMPLEMENT_PEM_rw(X509_ACERT, X509_ACERT, PEM_STRING_ACERT, X509_ACERT) +static X509_NAME *get_dirName(const GENERAL_NAMES *names) +{ + GENERAL_NAME *dirName; + + if (sk_GENERAL_NAME_num(names) != 1) + return NULL; + + dirName = sk_GENERAL_NAME_value(names, 0); + if (dirName->type != GEN_DIRNAME) + return NULL; + + return dirName->d.directoryName; +} + +void OSSL_OBJECT_DIGEST_INFO_get0_digest(const OSSL_OBJECT_DIGEST_INFO *o, + int *digestedObjectType, + const X509_ALGOR **digestAlgorithm, + const ASN1_BIT_STRING **digest) +{ + if (digestedObjectType != NULL) + *digestedObjectType = ASN1_ENUMERATED_get(&o->digestedObjectType); + if (digestAlgorithm != NULL) + *digestAlgorithm = &o->digestAlgorithm; + if (digest != NULL) + *digest = &o->objectDigest; +} + +const X509_NAME *OSSL_ISSUER_SERIAL_get0_issuer(const OSSL_ISSUER_SERIAL *isss) +{ + return get_dirName(isss->issuer); +} + +const ASN1_INTEGER *OSSL_ISSUER_SERIAL_get0_serial(const OSSL_ISSUER_SERIAL *isss) +{ + return &isss->serial; +} + +const ASN1_BIT_STRING *OSSL_ISSUER_SERIAL_get0_issuerUID(const OSSL_ISSUER_SERIAL *isss) +{ + return isss->issuerUID; +} + +long X509_ACERT_get_version(const X509_ACERT *x) +{ + return ASN1_INTEGER_get(&x->acinfo->version); +} + +void X509_ACERT_get0_signature(const X509_ACERT *x, + const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg) +{ + if (psig != NULL) + *psig = &x->signature; + if (palg != NULL) + *palg = &x->sig_alg; +} + +int X509_ACERT_get_signature_nid(const X509_ACERT *x) +{ + return OBJ_obj2nid(x->sig_alg.algorithm); +} + +const GENERAL_NAMES *X509_ACERT_get0_holder_entityName(const X509_ACERT *x) +{ + return x->acinfo->holder.entityName; +} + +const OSSL_ISSUER_SERIAL *X509_ACERT_get0_holder_baseCertId(const X509_ACERT *x) +{ + return x->acinfo->holder.baseCertificateID; +} + +const OSSL_OBJECT_DIGEST_INFO *X509_ACERT_get0_holder_digest(const X509_ACERT *x) +{ + return x->acinfo->holder.objectDigestInfo; +} + +const X509_NAME *X509_ACERT_get0_issuerName(const X509_ACERT *x) +{ + if (x->acinfo->issuer.type != X509_ACERT_ISSUER_V2 + || x->acinfo->issuer.u.v2Form == NULL) + return NULL; + + return get_dirName(x->acinfo->issuer.u.v2Form->issuerName); +} + +const ASN1_BIT_STRING *X509_ACERT_get0_issuerUID(const X509_ACERT *x) +{ + return x->acinfo->issuerUID; +} + +const X509_ALGOR *X509_ACERT_get0_info_sigalg(const X509_ACERT *x) +{ + return &x->acinfo->signature; +} + +const ASN1_INTEGER *X509_ACERT_get0_serialNumber(const X509_ACERT *x) +{ + return &x->acinfo->serialNumber; +} + +const ASN1_GENERALIZEDTIME *X509_ACERT_get0_notBefore(const X509_ACERT *x) +{ + return x->acinfo->validityPeriod.notBefore; +} + +const ASN1_GENERALIZEDTIME *X509_ACERT_get0_notAfter(const X509_ACERT *x) +{ + return x->acinfo->validityPeriod.notAfter; +} diff --git a/crypto/x509/x509aset.c b/crypto/x509/x509aset.c new file mode 100644 index 00000000000..3d7e5fbb21d --- /dev/null +++ b/crypto/x509/x509aset.c @@ -0,0 +1,177 @@ +/* + * Copyright 2021 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 + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "x509_acert.h" + +static int replace_gentime(ASN1_STRING **dest, const ASN1_GENERALIZEDTIME *src) +{ + ASN1_STRING *s; + + if (src->type != V_ASN1_GENERALIZEDTIME) + return 0; + + if (*dest == src) + return 1; + + s = ASN1_STRING_dup(src); + if (s == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + return 0; + } + + ASN1_STRING_free(*dest); + *dest = s; + + return 1; +} + +static int replace_dirName(GENERAL_NAMES **names, const X509_NAME *dirName) +{ + GENERAL_NAME *gen_name = NULL; + STACK_OF(GENERAL_NAME) *new_names = NULL; + X509_NAME *name_copy; + + if ((name_copy = X509_NAME_dup(dirName)) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + goto err; + } + + if ((new_names = sk_GENERAL_NAME_new_null()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + goto err; + } + + if ((gen_name = GENERAL_NAME_new()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + goto err; + } + + if (sk_GENERAL_NAME_push(new_names, gen_name) <= 0) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); + goto err; + } + + GENERAL_NAME_set0_value(gen_name, GEN_DIRNAME, name_copy); + + GENERAL_NAMES_free(*names); + *names = new_names; + + return 1; + +err: + GENERAL_NAME_free(gen_name); + sk_GENERAL_NAME_free(new_names); + X509_NAME_free(name_copy); + return 0; +} + +int OSSL_OBJECT_DIGEST_INFO_set1_digest(OSSL_OBJECT_DIGEST_INFO *o, + int digestedObjectType, + X509_ALGOR *digestAlgorithm, + ASN1_BIT_STRING *digest) +{ + + if (ASN1_ENUMERATED_set(&o->digestedObjectType, digestedObjectType) <= 0) + return 0; + + if (X509_ALGOR_copy(&o->digestAlgorithm, digestAlgorithm) <= 0) + return 0; + + if (ASN1_STRING_copy(&o->objectDigest, digest) <= 0) + return 0; + + return 1; +} + +int OSSL_ISSUER_SERIAL_set1_issuer(OSSL_ISSUER_SERIAL *isss, + const X509_NAME *issuer) +{ + return replace_dirName(&isss->issuer, issuer); +} + +int OSSL_ISSUER_SERIAL_set1_serial(OSSL_ISSUER_SERIAL *isss, + const ASN1_INTEGER *serial) +{ + return ASN1_STRING_copy(&isss->serial, serial); +} + +int OSSL_ISSUER_SERIAL_set1_issuerUID(OSSL_ISSUER_SERIAL *isss, + const ASN1_BIT_STRING *uid) +{ + ASN1_BIT_STRING_free(isss->issuerUID); + isss->issuerUID = ASN1_STRING_dup(uid); + if (isss->issuerUID == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + return 0; + } + return 1; +} + +int X509_ACERT_set_version(X509_ACERT *x, long version) +{ + return ASN1_INTEGER_set(&x->acinfo->version, version); +} + +void X509_ACERT_set0_holder_entityName(X509_ACERT *x, GENERAL_NAMES *names) +{ + GENERAL_NAMES_free(x->acinfo->holder.entityName); + x->acinfo->holder.entityName = names; +} + +void X509_ACERT_set0_holder_baseCertId(X509_ACERT *x, + OSSL_ISSUER_SERIAL *isss) +{ + OSSL_ISSUER_SERIAL_free(x->acinfo->holder.baseCertificateID); + x->acinfo->holder.baseCertificateID = isss; +} + +void X509_ACERT_set0_holder_digest(X509_ACERT *x, + OSSL_OBJECT_DIGEST_INFO *dinfo) +{ + OSSL_OBJECT_DIGEST_INFO_free(x->acinfo->holder.objectDigestInfo); + x->acinfo->holder.objectDigestInfo = dinfo; +} + +int X509_ACERT_set1_issuerName(X509_ACERT *x, const X509_NAME *name) +{ + X509_ACERT_ISSUER_V2FORM *v2Form; + + v2Form = x->acinfo->issuer.u.v2Form; + + /* only v2Form is supported, so always create that version */ + if (v2Form == NULL) { + v2Form = X509_ACERT_ISSUER_V2FORM_new(); + if (v2Form == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + return 0; + } + x->acinfo->issuer.u.v2Form = v2Form; + x->acinfo->issuer.type = X509_ACERT_ISSUER_V2; + } + + return replace_dirName(&v2Form->issuerName, name); +} + +int X509_ACERT_set1_serialNumber(X509_ACERT *x, const ASN1_INTEGER *serial) +{ + return ASN1_STRING_copy(&x->acinfo->serialNumber, serial); +} + +int X509_ACERT_set1_notBefore(X509_ACERT *x, const ASN1_GENERALIZEDTIME *time) +{ + return replace_gentime(&x->acinfo->validityPeriod.notBefore, time); +} + +int X509_ACERT_set1_notAfter(X509_ACERT *x, const ASN1_GENERALIZEDTIME *time) +{ + return replace_gentime(&x->acinfo->validityPeriod.notAfter, time); +} diff --git a/doc/build.info b/doc/build.info index 326c4ea34bb..da0e7a637f7 100644 --- a/doc/build.info +++ b/doc/build.info @@ -2799,6 +2799,10 @@ DEPEND[html/man3/X509V3_set_ctx.html]=man3/X509V3_set_ctx.pod GENERATE[html/man3/X509V3_set_ctx.html]=man3/X509V3_set_ctx.pod DEPEND[man/man3/X509V3_set_ctx.3]=man3/X509V3_set_ctx.pod GENERATE[man/man3/X509V3_set_ctx.3]=man3/X509V3_set_ctx.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 +GENERATE[man/man3/X509_ACERT_get0_holder_baseCertId.3]=man3/X509_ACERT_get0_holder_baseCertId.pod DEPEND[html/man3/X509_ALGOR_dup.html]=man3/X509_ALGOR_dup.pod GENERATE[html/man3/X509_ALGOR_dup.html]=man3/X509_ALGOR_dup.pod DEPEND[man/man3/X509_ALGOR_dup.3]=man3/X509_ALGOR_dup.pod @@ -3631,6 +3635,7 @@ html/man3/UI_create_method.html \ html/man3/UI_new.html \ html/man3/X509V3_get_d2i.html \ html/man3/X509V3_set_ctx.html \ +html/man3/X509_ACERT_get0_holder_baseCertId.html \ html/man3/X509_ALGOR_dup.html \ html/man3/X509_ATTRIBUTE.html \ html/man3/X509_CRL_get0_by_serial.html \ @@ -4276,6 +4281,7 @@ man/man3/UI_create_method.3 \ man/man3/UI_new.3 \ man/man3/X509V3_get_d2i.3 \ man/man3/X509V3_set_ctx.3 \ +man/man3/X509_ACERT_get0_holder_baseCertId.3 \ man/man3/X509_ALGOR_dup.3 \ man/man3/X509_ATTRIBUTE.3 \ man/man3/X509_CRL_get0_by_serial.3 \ diff --git a/doc/man3/X509_ACERT_get0_holder_baseCertId.pod b/doc/man3/X509_ACERT_get0_holder_baseCertId.pod new file mode 100644 index 00000000000..7741f286d3c --- /dev/null +++ b/doc/man3/X509_ACERT_get0_holder_baseCertId.pod @@ -0,0 +1,122 @@ +=pod + +=head1 NAME + +X509_ACERT_get0_holder_baseCertId, +X509_ACERT_get0_holder_digest, +X509_ACERT_get0_holder_entityName, +X509_ACERT_set0_holder_baseCertId, +X509_ACERT_set0_holder_digest, +X509_ACERT_set0_holder_entityName, +OSSL_ISSUER_SERIAL_get0_issuer, +OSSL_ISSUER_SERIAL_get0_issuerUID, +OSSL_ISSUER_SERIAL_get0_serial, +OSSL_ISSUER_SERIAL_set1_issuer, +OSSL_ISSUER_SERIAL_set1_issuerUID, +OSSL_ISSUER_SERIAL_set1_serial, +OSSL_OBJECT_DIGEST_INFO_get0_digest, +OSSL_OBJECT_DIGEST_INFO_set1_digest - get and set Attribute Certificate holder fields + +=head1 SYNOPSIS + + #include + + const GENERAL_NAMES *X509_ACERT_get0_holder_entityName(const X509_ACERT *x); + OSSL_ISSUER_SERIAL *X509_ACERT_get0_holder_baseCertId(const X509_ACERT *x); + OSSL_OBJECT_DIGEST_INFO * X509_ACERT_get0_holder_digest(const X509_ACERT *x); + void X509_ACERT_set0_holder_entityName(X509_ACERT *x, GENERAL_NAMES *name); + void X509_ACERT_set0_holder_baseCertId(X509_ACERT *x, OSSL_ISSUER_SERIAL *isss); + void X509_ACERT_set0_holder_digest(X509_ACERT *x, + OSSL_OBJECT_DIGEST_INFO *dinfo); + + X509_NAME *OSSL_ISSUER_SERIAL_get0_issuer(OSSL_ISSUER_SERIAL *isss); + ASN1_INTEGER *OSSL_ISSUER_SERIAL_get0_serial(OSSL_ISSUER_SERIAL *isss); + ASN1_BIT_STRING *OSSL_ISSUER_SERIAL_get0_issuerUID(OSSL_ISSUER_SERIAL *isss); + int OSSL_ISSUER_SERIAL_set1_issuer(OSSL_ISSUER_SERIAL *isss, X509_NAME *issuer); + int OSSL_ISSUER_SERIAL_set1_serial(OSSL_ISSUER_SERIAL *isss, ASN1_INTEGER *serial); + int OSSL_ISSUER_SERIAL_set1_issuerUID(OSSL_ISSUER_SERIAL *isss, ASN1_BIT_STRING *uid); + + void OSSL_OBJECT_DIGEST_INFO_get0_digest(OSSL_OBJECT_DIGEST_INFO *o, + ASN1_ENUMERATED **digestedObjectType, + X509_ALGOR **digestAlgorithm, + ASN1_BIT_STRING **digest); + void OSSL_OBJECT_DIGEST_INFO_set1_digest(OSSL_OBJECT_DIGEST_INFO *o, + ASN1_ENUMERATED *digestedObjectType, + X509_ALGOR *digestAlgorithm, + ASN1_BIT_STRING *digest); + +=head1 DESCRIPTION + +These routines set and get the holder identity of an X509 attribute certificate. + +X509_ACERT_set0_holder_entityName() sets the identity as a B +I, X509_ACERT_set0_holder_baseCertId() sets the identity based on the +issuer and serial number of a certificate detailed in I and +X509_ACERT_set0_holder_digest() sets the holder entity based on digest +information I. Although RFC 5755 section 4.2.2 recommends that only +one of the above methods be used to set the holder identity for a given +attribute certificate I, setting multiple methods at the same time is +possible. It is up to the application to handle cases when conflicting +identity information is specified using different methods. + +Pointers to the internal structures describing the holder identity of +attribute certificate I can be retrieved with +X509_ACERT_get0_holder_entityName(), X509_ACERT_get0_holder_baseCertId(), and +X509_ACERT_get0_holder_digest(). + +A B object holds the subject name and UID of a certificate +issuer and a certificate's serial number. OSSL_ISSUER_SERIAL_set1_issuer(), +OSSL_ISSUER_SERIAL_set1_issuerUID(), and OSSL_ISSUER_SERIAL_set1_serial() +respectively copy these values into the B structure. +The application is responsible for freeing its own copy of these values after +use. OSSL_ISSUER_SERIAL_get0_issuer(), OSSL_ISSUER_SERIAL_get0_issuerUID(), +and OSSL_ISSUER_SERIAL_get0_serial() return pointers to these values in the object. + +An B object holds a digest of data to identify the +attribute certificate holder. OSSL_OBJECT_DIGEST_INFO_set1_digest() sets the +digest information of the object. The type of I information is given +by I and can be one of: + +=over 4 + +=item OSSL_OBJECT_DIGEST_INFO_PUBLIC_KEY + +Hash of a public key + +=item OSSL_OBJECT_DIGEST_INFO_PUBLIC_KEY_CERT + +Hash of a public key certificate + +=item OSSL_OBJECT_DIGEST_INFO_OTHER + +Hash of another object. See NOTES below. + +=back + +I indicates the algorithm used to compute I. + +=head1 RETURN VALUES + +All I/I routines return 1 for success and 0 for failure. +All I functions return a pointer to the object's inner structure. These +pointers must not be freed after use. + +=head1 NOTES + +Although the value of B is defined in RFC 5755, +its use is prohibited for conformant attribute certificates. + +=head1 HISTORY + +These functions were 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/doc/man3/X509_get0_notBefore.pod b/doc/man3/X509_get0_notBefore.pod index 1ca0a1b128a..84dee91850c 100644 --- a/doc/man3/X509_get0_notBefore.pod +++ b/doc/man3/X509_get0_notBefore.pod @@ -4,6 +4,8 @@ X509_get0_notBefore, X509_getm_notBefore, X509_get0_notAfter, X509_getm_notAfter, X509_set1_notBefore, X509_set1_notAfter, +X509_ACERT_get0_notBefore, X509_ACERT_get0_notAfter, +X509_ACERT_set1_notBefore, X509_ACERT_set1_notAfter, X509_CRL_get0_lastUpdate, X509_CRL_get0_nextUpdate, X509_CRL_set1_lastUpdate, X509_CRL_set1_nextUpdate - get or set certificate or CRL dates @@ -20,6 +22,12 @@ X509_CRL_set1_nextUpdate - get or set certificate or CRL dates int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); + const ASN1_GENERALIZEDTIME *X509_ACERT_get0_notBefore(const X509 *x); + const ASN1_GENERALIZEDTIME *X509_ACERT_get0_notAfter(const X509 *x); + + int X509_ACERT_set1_notBefore(X509_ACERT *x, const ASN1_GENERALIZEDTIME *tm); + int X509_ACERT_set1_notAfter(X509_ACERT *x, const ASN1_GENERALIZEDTIME *tm); + const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); @@ -43,6 +51,16 @@ and B fields of I to I. Ownership of the passed parameter I is not transferred by these functions so it must be freed up after the call. +X509_ACERT_get0_notBefore() and X509_ACERT_get0_notAfter() return +the B and B fields of certificate B respectively. +returned is an internal pointer which must not be freed up after +the call. + +X509_ACERT_set1_notBefore() and X509_ACERT_set1_notAfter() set the B +and B fields of B to B. Ownership of the passed +parameter B is not transferred by these functions so it must +be freed up after the call. + X509_CRL_get0_lastUpdate() and X509_CRL_get0_nextUpdate() return the B and B fields of I. The value returned is an internal pointer which must not be freed up after @@ -67,9 +85,16 @@ or NULL if the B field is absent. X509_set1_notBefore(), X509_set1_notAfter(), X509_CRL_set1_lastUpdate() and X509_CRL_set1_nextUpdate() return 1 for success or 0 for failure. +=head1 NOTES + +Unlike the B and B routines, the B routines +use the ASN1_GENERALIZEDTIME format instead of ASN1_TIME for holding time +data. + =head1 SEE ALSO L, +L L, L, L, diff --git a/doc/man3/X509_get0_signature.pod b/doc/man3/X509_get0_signature.pod index a49a70038e3..485d39bf251 100644 --- a/doc/man3/X509_get0_signature.pod +++ b/doc/man3/X509_get0_signature.pod @@ -5,7 +5,9 @@ X509_get0_signature, X509_REQ_set0_signature, X509_REQ_set1_signature_algo, X509_get_signature_nid, X509_get0_tbs_sigalg, X509_REQ_get0_signature, X509_REQ_get_signature_nid, X509_CRL_get0_signature, X509_CRL_get_signature_nid, -X509_get_signature_info, X509_SIG_INFO_get, X509_SIG_INFO_set - signature information +X509_ACERT_get0_signature, X509_ACERT_get0_info_sigalg, +X509_ACERT_get_signature_nid, X509_get_signature_info, +X509_SIG_INFO_get, X509_SIG_INFO_set - signature information =head1 SYNOPSIS @@ -24,6 +26,8 @@ X509_get_signature_info, X509_SIG_INFO_get, X509_SIG_INFO_set - signature inform const X509_ALGOR **palg); int X509_REQ_get_signature_nid(const X509_REQ *crl); + const X509_ALGOR *X509_ACERT_get0_info_sigalg(const X509_ACERT *x); + void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, const X509_ALGOR **palg); @@ -37,6 +41,12 @@ X509_get_signature_info, X509_SIG_INFO_get, X509_SIG_INFO_set - signature inform void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid, int secbits, uint32_t flags); + #include + + void X509_ACERT_get0_signature(const X509_ACERT *x, + const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); + int X509_ACERT_get_signature_nid(const X509_ACERT *x); =head1 DESCRIPTION X509_get0_signature() sets B<*psig> to the signature of B and B<*palg> @@ -56,6 +66,10 @@ X509_REQ_get0_signature(), X509_REQ_get_signature_nid() X509_CRL_get0_signature() and X509_CRL_get_signature_nid() perform the same function for certificate requests and CRLs. +X509_ACERT_get0_signature(), X509_ACERT_get_signature_nid() and +X509_ACERT_get0_info_sigalg() perform the same function for attribute +certificates. + X509_get_signature_info() retrieves information about the signature of certificate B. The NID of the signing digest is written to B<*mdnid>, the public key algorithm to B<*pknid>, the effective security bits to @@ -130,6 +144,9 @@ added in OpenSSL 1.1.0. The X509_REQ_set0_signature() and X509_REQ_set1_signature_algo() were added in OpenSSL 1.1.1e. +The X509_ACERT_get0_signature(), X509_ACERT_get0_info_sigalg() and +X509_ACERT_get_signature_nid() functions were added in OpenSSL 3.4. + =head1 COPYRIGHT Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/X509_get0_uids.pod b/doc/man3/X509_get0_uids.pod index 48ae5afc424..c265ce09bcf 100644 --- a/doc/man3/X509_get0_uids.pod +++ b/doc/man3/X509_get0_uids.pod @@ -2,7 +2,8 @@ =head1 NAME -X509_get0_uids - get certificate unique identifiers +X509_get0_uids, X509_ACERT_get0_issuerUID +- get certificate and attribute certificate unique identifiers =head1 SYNOPSIS @@ -11,11 +12,17 @@ X509_get0_uids - get certificate unique identifiers void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid, const ASN1_BIT_STRING **psuid); + #include + + ASN1_BIT_STRING *X509_ACERT_get0_issuerUID(X509_ACERT *x); =head1 DESCRIPTION X509_get0_uids() sets B<*piuid> and B<*psuid> to the issuer and subject unique identifiers of certificate B or NULL if the fields are not present. +X509_ACERT_get0_issuerUID() returns the issuer unique identifier of the +attribute certificate B or NULL if the field is not present. + =head1 NOTES The issuer and subject unique identifier fields are very rarely encountered in @@ -25,6 +32,9 @@ practice outside test cases. X509_get0_uids() does not return a value. +X509_ACERT_get0_issuerUID() returns a unique identifier on success or NULL +on failure. + =head1 SEE ALSO L, @@ -45,6 +55,12 @@ L, L, L +=head1 HISTORY + +X509_get0_uids() was added in OpenSSL 1.1.0. + +X509_ACERT_get0_issuerUID() was added in OpenSSL 3.4. + =head1 COPYRIGHT Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/X509_get_serialNumber.pod b/doc/man3/X509_get_serialNumber.pod index 5594c8a284b..ac93a33b8f2 100644 --- a/doc/man3/X509_get_serialNumber.pod +++ b/doc/man3/X509_get_serialNumber.pod @@ -4,7 +4,9 @@ X509_get_serialNumber, X509_get0_serialNumber, -X509_set_serialNumber +X509_set_serialNumber, +X509_ACERT_get0_serialNumber, +X509_ACERT_set1_serialNumber - get or set certificate serial number =head1 SYNOPSIS @@ -15,6 +17,11 @@ X509_set_serialNumber const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x); int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); + #include + + ASN1_INTEGER *X509_ACERT_get0_serialNumber(X509_ACERT *x); + int X509_ACERT_set1_serialNumber(X509_ACERT *x, ASN1_INTEGER *serial); + =head1 DESCRIPTION X509_get_serialNumber() returns the serial number of certificate B as an @@ -28,12 +35,19 @@ X509_set_serialNumber() sets the serial number of certificate B to B. A copy of the serial number is used internally so B should be freed up after use. +X509_ACERT_get0_serialNumber() performs the same operation as +X509_get_serialNumber() for attribute certificates. + +X509_ACERT_set1_serialNumber() performs the same operation as +X509_set_serialNumber() for attribute certificates. + =head1 RETURN VALUES -X509_get_serialNumber() and X509_get0_serialNumber() return an B -structure. +X509_get_serialNumber(), X509_get0_serialNumber() and +X509_ACERT_get0_serialNumber() return a pointer to an B structure. -X509_set_serialNumber() returns 1 for success and 0 for failure. +X509_set_serialNumber() and X509_ACERT_set1_serialNumber() return 1 for success +and 0 for failure. =head1 SEE ALSO @@ -59,6 +73,8 @@ L The X509_get_serialNumber() and X509_set_serialNumber() functions are available in all versions of OpenSSL. The X509_get0_serialNumber() function was added in OpenSSL 1.1.0. +The X509_ACERT_get0_serialNumber() and X509_ACERT_set1_serialNumber() +functions were added in OpenSSL 3.4. =head1 COPYRIGHT diff --git a/doc/man3/X509_get_subject_name.pod b/doc/man3/X509_get_subject_name.pod index 64659de6ab6..2f392ad7a2e 100644 --- a/doc/man3/X509_get_subject_name.pod +++ b/doc/man3/X509_get_subject_name.pod @@ -6,6 +6,7 @@ X509_NAME_hash_ex, X509_NAME_hash, X509_get_subject_name, X509_set_subject_name, X509_subject_name_hash, X509_get_issuer_name, X509_set_issuer_name, X509_issuer_name_hash, X509_REQ_get_subject_name, X509_REQ_set_subject_name, +X509_ACERT_get0_issuerName, X509_ACERT_set1_issuerName, X509_CRL_get_issuer, X509_CRL_set_issuer_name - get X509_NAME hashes or get and set issuer or subject names @@ -30,6 +31,11 @@ get X509_NAME hashes or get and set issuer or subject names X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); int X509_CRL_set_issuer_name(X509_CRL *x, const X509_NAME *name); + #include + + X509_NAME *X509_ACERT_get0_issuerName(const X509_ACERT *x); + int X509_ACERT_set1_issuerName(X509_ACERT *x, const X509_NAME *name); + The following macro has been deprecated since OpenSSL 3.0, and can be hidden entirely by defining B with a suitable version value, see L: @@ -63,13 +69,19 @@ X509_get_subject_name(), X509_set_subject_name(), and X509_subject_name_hash() except they relate to the issuer name of I. Similarly X509_REQ_get_subject_name(), X509_REQ_set_subject_name(), +X509_ACERT_get0_issuerName(), X509_ACERT_set1_issuerName(), X509_CRL_get_issuer() and X509_CRL_set_issuer_name() get or set the subject or issuer names of certificate requests of CRLs respectively. +Since attribute certificates do not have a subject name, only the issuer name +can be set. For details on setting X509_ACERT holder identities, see +L. + =head1 RETURN VALUES X509_get_subject_name(), X509_get_issuer_name(), X509_REQ_get_subject_name() -and X509_CRL_get_issuer() return an B pointer. +X509_ACERT_get0_issuerName() and X509_CRL_get_issuer() return +an B pointer. X509_NAME_hash_ex(), X509_NAME_hash(), X509_subject_name_hash() and X509_issuer_name_hash() @@ -77,8 +89,9 @@ return the first four bytes of the SHA1 hash value, converted to B in little endian order, or 0 on failure. -X509_set_subject_name(), X509_set_issuer_name(), X509_REQ_set_subject_name() -and X509_CRL_set_issuer_name() return 1 for success and 0 for failure. +X509_set_subject_name(), X509_set_issuer_name(), X509_REQ_set_subject_name(), +X509_ACERT_get0_issuerName() and X509_CRL_set_issuer_name() return 1 for +success and 0 for failure. =head1 BUGS diff --git a/doc/man3/X509_get_version.pod b/doc/man3/X509_get_version.pod index c5db26c5790..d6b11e454fd 100644 --- a/doc/man3/X509_get_version.pod +++ b/doc/man3/X509_get_version.pod @@ -3,7 +3,8 @@ =head1 NAME X509_get_version, X509_set_version, X509_REQ_get_version, X509_REQ_set_version, -X509_CRL_get_version, X509_CRL_set_version - get or set certificate, +X509_ACERT_get_version, X509_ACERT_set_version, X509_CRL_get_version, +X509_CRL_set_version - get or set certificate, certificate request or CRL version =head1 SYNOPSIS @@ -19,6 +20,11 @@ certificate request or CRL version long X509_CRL_get_version(const X509_CRL *crl); int X509_CRL_set_version(X509_CRL *x, long version); + #include + + int X509_ACERT_set_version(X509_ACERT *x, long version); + long X509_ACERT_get_version(const X509_ACERT *x); + =head1 DESCRIPTION X509_get_version() returns the numerical value of the version field of @@ -31,9 +37,11 @@ X509_set_version() sets the numerical value of the version field of certificate I to I. Similarly X509_REQ_get_version(), X509_REQ_set_version(), +X509_ACERT_get_version(), X509_ACERT_set_version(), X509_CRL_get_version() and X509_CRL_set_version() get and set the version number of certificate requests and CRLs. They use constants -B, B, and B. +B, B, B, +and B. =head1 NOTES diff --git a/include/openssl/x509_acert.h.in b/include/openssl/x509_acert.h.in index 1d66af95457..826f39d423c 100644 --- a/include/openssl/x509_acert.h.in +++ b/include/openssl/x509_acert.h.in @@ -45,4 +45,55 @@ DECLARE_PEM_rw(X509_ACERT, X509_ACERT) X509_ACERT *d2i_X509_ACERT_bio(BIO *bp, X509_ACERT **acert); int i2d_X509_ACERT_bio(BIO *bp, const X509_ACERT *acert); +# define X509_ACERT_VERSION_2 1 + +const GENERAL_NAMES *X509_ACERT_get0_holder_entityName(const X509_ACERT *x); +const OSSL_ISSUER_SERIAL *X509_ACERT_get0_holder_baseCertId(const X509_ACERT *x); +const OSSL_OBJECT_DIGEST_INFO * X509_ACERT_get0_holder_digest(const X509_ACERT *x); +const X509_NAME *X509_ACERT_get0_issuerName(const X509_ACERT *x); +long X509_ACERT_get_version(const X509_ACERT *x); +void X509_ACERT_get0_signature(const X509_ACERT *x, + const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +int X509_ACERT_get_signature_nid(const X509_ACERT *x); +const X509_ALGOR *X509_ACERT_get0_info_sigalg(const X509_ACERT *x); +const ASN1_INTEGER *X509_ACERT_get0_serialNumber(const X509_ACERT *x); +const ASN1_TIME *X509_ACERT_get0_notBefore(const X509_ACERT *x); +const ASN1_TIME *X509_ACERT_get0_notAfter(const X509_ACERT *x); +const ASN1_BIT_STRING *X509_ACERT_get0_issuerUID(const X509_ACERT *x); + +# define OSSL_OBJECT_DIGEST_INFO_PUBLIC_KEY 0 +# define OSSL_OBJECT_DIGEST_INFO_PUBLIC_KEY_CERT 1 +# define OSSL_OBJECT_DIGEST_INFO_OTHER 2 /* must not be used in RFC 5755 profile */ +int X509_ACERT_set_version(X509_ACERT *x, long version); +void X509_ACERT_set0_holder_entityName(X509_ACERT *x, GENERAL_NAMES *name); +void X509_ACERT_set0_holder_baseCertId(X509_ACERT *x, OSSL_ISSUER_SERIAL *isss); +void X509_ACERT_set0_holder_digest(X509_ACERT *x, + OSSL_OBJECT_DIGEST_INFO *dinfo); + +int X509_ACERT_set1_issuerName(X509_ACERT *x, const X509_NAME *name); +int X509_ACERT_set1_serialNumber(X509_ACERT *x, const ASN1_INTEGER *serial); +int X509_ACERT_set1_notBefore(X509_ACERT *x, const ASN1_GENERALIZEDTIME *time); +int X509_ACERT_set1_notAfter(X509_ACERT *x, const ASN1_GENERALIZEDTIME *time); + +void OSSL_OBJECT_DIGEST_INFO_get0_digest(const OSSL_OBJECT_DIGEST_INFO *o, + int *digestedObjectType, + const X509_ALGOR **digestAlgorithm, + const ASN1_BIT_STRING **digest); + +int OSSL_OBJECT_DIGEST_INFO_set1_digest(OSSL_OBJECT_DIGEST_INFO *o, + int digestedObjectType, + X509_ALGOR *digestAlgorithm, + ASN1_BIT_STRING *digest); + +const X509_NAME *OSSL_ISSUER_SERIAL_get0_issuer(const OSSL_ISSUER_SERIAL *isss); +const ASN1_INTEGER *OSSL_ISSUER_SERIAL_get0_serial(const OSSL_ISSUER_SERIAL *isss); +const ASN1_BIT_STRING *OSSL_ISSUER_SERIAL_get0_issuerUID(const OSSL_ISSUER_SERIAL *isss); + +int OSSL_ISSUER_SERIAL_set1_issuer(OSSL_ISSUER_SERIAL *isss, + const X509_NAME *issuer); +int OSSL_ISSUER_SERIAL_set1_serial(OSSL_ISSUER_SERIAL *isss, + const ASN1_INTEGER *serial); +int OSSL_ISSUER_SERIAL_set1_issuerUID(OSSL_ISSUER_SERIAL *isss, + const ASN1_BIT_STRING *uid); #endif diff --git a/util/libcrypto.num b/util/libcrypto.num index dbba798a3b7..57dee34ec08 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5573,3 +5573,31 @@ PEM_read_bio_X509_ACERT ? 3_4_0 EXIST::FUNCTION: PEM_write_bio_X509_ACERT ? 3_4_0 EXIST::FUNCTION: d2i_X509_ACERT_bio ? 3_4_0 EXIST::FUNCTION: i2d_X509_ACERT_bio ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_holder_entityName ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_holder_baseCertId ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_holder_digest ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_issuerName ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get_version ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_signature ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get_signature_nid ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_info_sigalg ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_serialNumber ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_notBefore ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_notAfter ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_get0_issuerUID ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_set_version ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_set0_holder_entityName ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_set0_holder_baseCertId ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_set0_holder_digest ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_set1_issuerName ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_set1_serialNumber ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_set1_notBefore ? 3_4_0 EXIST::FUNCTION: +X509_ACERT_set1_notAfter ? 3_4_0 EXIST::FUNCTION: +OSSL_OBJECT_DIGEST_INFO_get0_digest ? 3_4_0 EXIST::FUNCTION: +OSSL_OBJECT_DIGEST_INFO_set1_digest ? 3_4_0 EXIST::FUNCTION: +OSSL_ISSUER_SERIAL_get0_issuer ? 3_4_0 EXIST::FUNCTION: +OSSL_ISSUER_SERIAL_get0_serial ? 3_4_0 EXIST::FUNCTION: +OSSL_ISSUER_SERIAL_get0_issuerUID ? 3_4_0 EXIST::FUNCTION: +OSSL_ISSUER_SERIAL_set1_issuer ? 3_4_0 EXIST::FUNCTION: +OSSL_ISSUER_SERIAL_set1_serial ? 3_4_0 EXIST::FUNCTION: +OSSL_ISSUER_SERIAL_set1_issuerUID ? 3_4_0 EXIST::FUNCTION: