]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add support for targetingInformation X.509v3 extension
authorJonathan M. Wilbur <jonathan@wilbur.space>
Sat, 1 Jun 2024 19:23:25 +0000 (19:23 +0000)
committerTomas Mraz <tomas@openssl.org>
Mon, 17 Jun 2024 12:03:25 +0000 (14:03 +0200)
Support for the targetingInformation X.509v3 extension defined in ITU-T
Recommendation X.509 (2019), Section 17.1.2.2. This extension is used
in attribute certificates.

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22206)

17 files changed:
crypto/x509/build.info
crypto/x509/ext_dat.h
crypto/x509/standard_exts.h
crypto/x509/v3_ac_tgt.c [new file with mode: 0644]
crypto/x509/v3_crld.c
crypto/x509/v3_utl.c
doc/build.info
doc/man3/OSSL_GENERAL_NAMES_print.pod [new file with mode: 0644]
doc/man3/X509_dup.pod
doc/man3/d2i_X509.pod
fuzz/asn1.c
include/crypto/x509_acert.h
include/openssl/x509_acert.h.in
include/openssl/x509v3.h.in
test/certs/ext-targetingInformation.pem [new file with mode: 0644]
test/recipes/25-test_x509.t
util/libcrypto.num

index 6cebadea77296726012cddccc648c217134bf926..1184329b2052ffcc148895715dec0948939680f0 100644 (file)
@@ -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 x509aset.c t_acert.c x_ietfatt.c
+        x509_acert.c x509aset.c t_acert.c x_ietfatt.c v3_ac_tgt.c
 
 IF[{- !$disabled{'deprecated-3.0'} -}]
   SOURCE[../../libcrypto]=x509type.c
index 1ffc816e5eea3372f1cf4557d136dd293292e2b9..8d34e829dc5f28404cb1bf4c1b1d93d00be522a1 100644 (file)
@@ -31,3 +31,4 @@ extern const X509V3_EXT_METHOD ossl_v3_no_assertion;
 extern const X509V3_EXT_METHOD ossl_v3_no_rev_avail;
 extern const X509V3_EXT_METHOD ossl_v3_single_use;
 extern const X509V3_EXT_METHOD ossl_v3_indirect_issuer;
+extern const X509V3_EXT_METHOD ossl_v3_targeting_information;
index 87a564b238d6b200817ee395da5e7c8f7bcc5b67..eba9e31dec819546e63762b894cca9622523ba4d 100644 (file)
@@ -53,6 +53,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = {
 #endif
     &ossl_v3_sinfo,
     &ossl_v3_policy_constraints,
+    &ossl_v3_targeting_information,
     &ossl_v3_no_rev_avail,
 #ifndef OPENSSL_NO_OCSP
     &ossl_v3_crl_hold,
diff --git a/crypto/x509/v3_ac_tgt.c b/crypto/x509/v3_ac_tgt.c
new file mode 100644 (file)
index 0000000..c6b3701
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright 1999-2024 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 <stdio.h>
+#include <openssl/x509_acert.h>
+#include <crypto/x509_acert.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+#include "x509_local.h"
+#include "crypto/asn1.h"
+
+static int i2r_ISSUER_SERIAL(X509V3_EXT_METHOD *method,
+                             OSSL_ISSUER_SERIAL *iss,
+                             BIO *out, int indent);
+static int i2r_OBJECT_DIGEST_INFO(X509V3_EXT_METHOD *method,
+                                  OSSL_OBJECT_DIGEST_INFO *odi,
+                                  BIO *out, int indent);
+static int i2r_TARGET_CERT(X509V3_EXT_METHOD *method,
+                           OSSL_TARGET_CERT *tc,
+                           BIO *out, int indent);
+static int i2r_TARGET(X509V3_EXT_METHOD *method,
+                      OSSL_TARGET *target,
+                      BIO *out, int indent);
+static int i2r_TARGETING_INFORMATION(X509V3_EXT_METHOD *method,
+                                     OSSL_TARGETING_INFORMATION *tinfo,
+                                     BIO *out, int indent);
+
+ASN1_SEQUENCE(OSSL_ISSUER_SERIAL) = {
+    ASN1_SEQUENCE_OF(OSSL_ISSUER_SERIAL, issuer, GENERAL_NAME),
+    ASN1_EMBED(OSSL_ISSUER_SERIAL, serial, ASN1_INTEGER),
+    ASN1_OPT(OSSL_ISSUER_SERIAL, issuerUID, ASN1_BIT_STRING),
+} static_ASN1_SEQUENCE_END(OSSL_ISSUER_SERIAL)
+
+ASN1_SEQUENCE(OSSL_OBJECT_DIGEST_INFO) = {
+    ASN1_EMBED(OSSL_OBJECT_DIGEST_INFO, digestedObjectType, ASN1_ENUMERATED),
+    ASN1_OPT(OSSL_OBJECT_DIGEST_INFO, otherObjectTypeID, ASN1_OBJECT),
+    ASN1_EMBED(OSSL_OBJECT_DIGEST_INFO, digestAlgorithm, X509_ALGOR),
+    ASN1_EMBED(OSSL_OBJECT_DIGEST_INFO, objectDigest, ASN1_BIT_STRING),
+} static_ASN1_SEQUENCE_END(OSSL_OBJECT_DIGEST_INFO)
+
+ASN1_SEQUENCE(OSSL_TARGET_CERT) = {
+    ASN1_SIMPLE(OSSL_TARGET_CERT, targetCertificate, OSSL_ISSUER_SERIAL),
+    ASN1_OPT(OSSL_TARGET_CERT, targetName, GENERAL_NAME),
+    ASN1_OPT(OSSL_TARGET_CERT, certDigestInfo, OSSL_OBJECT_DIGEST_INFO),
+} static_ASN1_SEQUENCE_END(OSSL_TARGET_CERT)
+
+ASN1_CHOICE(OSSL_TARGET) = {
+    ASN1_EXP(OSSL_TARGET, choice.targetName, GENERAL_NAME, 0),
+    ASN1_EXP(OSSL_TARGET, choice.targetGroup, GENERAL_NAME, 1),
+    ASN1_IMP(OSSL_TARGET, choice.targetCert, OSSL_TARGET_CERT, 2),
+} ASN1_CHOICE_END(OSSL_TARGET)
+
+ASN1_ITEM_TEMPLATE(OSSL_TARGETS) =
+    ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Targets, OSSL_TARGET)
+ASN1_ITEM_TEMPLATE_END(OSSL_TARGETS)
+
+ASN1_ITEM_TEMPLATE(OSSL_TARGETING_INFORMATION) =
+    ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, TargetingInformation, OSSL_TARGETS)
+ASN1_ITEM_TEMPLATE_END(OSSL_TARGETING_INFORMATION)
+
+IMPLEMENT_ASN1_FUNCTIONS(OSSL_TARGET)
+IMPLEMENT_ASN1_FUNCTIONS(OSSL_TARGETS)
+IMPLEMENT_ASN1_FUNCTIONS(OSSL_TARGETING_INFORMATION)
+
+static int i2r_ISSUER_SERIAL(X509V3_EXT_METHOD *method,
+                             OSSL_ISSUER_SERIAL *iss,
+                             BIO *out, int indent)
+{
+    if (iss->issuer != NULL) {
+        BIO_printf(out, "%*sIssuer Names:\n", indent, "");
+        OSSL_GENERAL_NAMES_print(out, iss->issuer, indent);
+        BIO_puts(out, "\n");
+    }
+    BIO_printf(out, "%*sIssuer Serial: ", indent, "");
+    if (i2a_ASN1_INTEGER(out, &(iss->serial)) <= 0)
+        return 0;
+    BIO_puts(out, "\n");
+    if (iss->issuerUID != NULL) {
+        BIO_printf(out, "%*sIssuer UID: ", indent, "");
+        if (i2a_ASN1_STRING(out, iss->issuerUID, V_ASN1_BIT_STRING) <= 0)
+            return 0;
+        BIO_puts(out, "\n");
+    }
+    return 1;
+}
+
+static int i2r_OBJECT_DIGEST_INFO(X509V3_EXT_METHOD *method,
+                           OSSL_OBJECT_DIGEST_INFO *odi,
+                           BIO *out, int indent)
+{
+    int64_t dot = 0;
+    int sig_nid;
+    X509_ALGOR *digalg;
+    ASN1_STRING *sig;
+
+    if (odi == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    digalg = &odi->digestAlgorithm;
+    sig = &odi->objectDigest;
+    if (!ASN1_ENUMERATED_get_int64(&dot, &odi->digestedObjectType)) {
+        return 0;
+    }
+    switch (dot) {
+    case OSSL_ODI_TYPE_PUBLIC_KEY:
+        BIO_printf(out, "%*sDigest Type: Public Key\n", indent, "");
+        break;
+    case OSSL_ODI_TYPE_PUBLIC_KEY_CERT:
+        BIO_printf(out, "%*sDigest Type: Public Key Certificate\n", indent, "");
+        break;
+    case OSSL_ODI_TYPE_OTHER:
+        BIO_printf(out, "%*sDigest Type: Other\n", indent, "");
+        break;
+    }
+    if (odi->otherObjectTypeID != NULL) {
+        BIO_printf(out, "%*sDigest Type Identifier: ", indent, "");
+        i2a_ASN1_OBJECT(out, odi->otherObjectTypeID);
+        BIO_puts(out, "\n");
+    }
+    if (BIO_printf(out, "%*sSignature Algorithm: ", indent, "") <= 0)
+        return 0;
+    if (i2a_ASN1_OBJECT(out, odi->digestAlgorithm.algorithm) <= 0)
+        return 0;
+    BIO_puts(out, "\n");
+    if (BIO_printf(out, "\n%*sSignature Value: ", indent, "") <= 0)
+        return 0;
+    sig_nid = OBJ_obj2nid(odi->digestAlgorithm.algorithm);
+    if (sig_nid != NID_undef) {
+        int pkey_nid, dig_nid;
+        const EVP_PKEY_ASN1_METHOD *ameth;
+        if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
+            ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
+            if (ameth && ameth->sig_print)
+                return ameth->sig_print(out, digalg, sig, indent + 4, 0);
+        }
+    }
+    if (BIO_write(out, "\n", 1) != 1)
+        return 0;
+    if (sig)
+        return X509_signature_dump(out, sig, indent + 4);
+    return 1;
+}
+
+static int i2r_TARGET_CERT(X509V3_EXT_METHOD *method,
+                           OSSL_TARGET_CERT *tc,
+                           BIO *out, int indent)
+{
+    BIO_printf(out, "%*s", indent, "");
+    if (tc->targetCertificate != NULL) {
+        BIO_puts(out, "Target Certificate:\n");
+        i2r_ISSUER_SERIAL(method, tc->targetCertificate, out, indent + 2);
+    }
+    if (tc->targetName != NULL) {
+        BIO_printf(out, "%*sTarget Name: ", indent, "");
+        GENERAL_NAME_print(out, tc->targetName);
+        BIO_puts(out, "\n");
+    }
+    if (tc->certDigestInfo != NULL) {
+        BIO_printf(out, "%*sCertificate Digest Info:\n", indent, "");
+        i2r_OBJECT_DIGEST_INFO(method, tc->certDigestInfo, out, indent + 2);
+    }
+    BIO_puts(out, "\n");
+    return 1;
+}
+
+static int i2r_TARGET(X509V3_EXT_METHOD *method,
+                      OSSL_TARGET *target,
+                      BIO *out, int indent)
+{
+    switch (target->type) {
+    case OSSL_TGT_TARGET_NAME:
+        BIO_printf(out, "%*sTarget Name: ", indent, "");
+        GENERAL_NAME_print(out, target->choice.targetName);
+        BIO_puts(out, "\n");
+        break;
+    case OSSL_TGT_TARGET_GROUP:
+        BIO_printf(out, "%*sTarget Group: ", indent, "");
+        GENERAL_NAME_print(out, target->choice.targetGroup);
+        BIO_puts(out, "\n");
+        break;
+    case OSSL_TGT_TARGET_CERT:
+        BIO_printf(out, "%*sTarget Cert:\n", indent, "");
+        i2r_TARGET_CERT(method, target->choice.targetCert, out, indent + 2);
+        break;
+    }
+    return 1;
+}
+
+static int i2r_TARGETS(X509V3_EXT_METHOD *method,
+                      OSSL_TARGETS *targets,
+                      BIO *out, int indent)
+{
+    int i;
+    OSSL_TARGET *target;
+
+    for (i = 0; i < sk_OSSL_TARGET_num(targets); i++) {
+        BIO_printf(out, "%*sTarget:\n", indent, "");
+        target = sk_OSSL_TARGET_value(targets, i);
+        i2r_TARGET(method, target, out, indent + 2);
+    }
+    return 1;
+}
+
+static int i2r_TARGETING_INFORMATION(X509V3_EXT_METHOD *method,
+                                     OSSL_TARGETING_INFORMATION *tinfo,
+                                     BIO *out, int indent)
+{
+    int i;
+    OSSL_TARGETS *targets;
+
+    for (i = 0; i < sk_OSSL_TARGETS_num(tinfo); i++) {
+        BIO_printf(out, "%*sTargets:\n", indent, "");
+        targets = sk_OSSL_TARGETS_value(tinfo, i);
+        i2r_TARGETS(method, targets, out, indent + 2);
+    }
+    return 1;
+}
+
+const X509V3_EXT_METHOD ossl_v3_targeting_information = {
+    NID_target_information, 0, ASN1_ITEM_ref(OSSL_TARGETING_INFORMATION),
+    0, 0, 0, 0,
+    0,
+    0,
+    0, 0,
+    (X509V3_EXT_I2R)i2r_TARGETING_INFORMATION,
+    0,
+    NULL
+};
index 839b2c1afefc47acddca42fe34cc8eddd5877223..ae772cdd80aadb6b88879cf346aa1170a19df6f2 100644 (file)
@@ -419,23 +419,11 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
     return NULL;
 }
 
-static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
-{
-    int i;
-    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
-        if (i > 0)
-            BIO_puts(out, "\n");
-        BIO_printf(out, "%*s", indent + 2, "");
-        GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
-    }
-    return 1;
-}
-
 static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
 {
     if (dpn->type == 0) {
         BIO_printf(out, "%*sFull Name:\n", indent, "");
-        print_gens(out, dpn->name.fullname, indent);
+        OSSL_GENERAL_NAMES_print(out, dpn->name.fullname, indent);
     } else {
         X509_NAME ntmp;
         ntmp.entries = dpn->name.relativename;
@@ -486,7 +474,7 @@ static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
             print_reasons(out, "Reasons", point->reasons, indent);
         if (point->CRLissuer) {
             BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
-            print_gens(out, point->CRLissuer, indent);
+            OSSL_GENERAL_NAMES_print(out, point->CRLissuer, indent);
         }
     }
     return 1;
index 1a181749951965dcad6ea8838e234361a36ccaad..a036e9e9ad8226847047aff79fbb2ac47c41fd50 100644 (file)
@@ -1356,3 +1356,16 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
     }
     return 1;
 }
+
+int OSSL_GENERAL_NAMES_print(BIO *out, GENERAL_NAMES *gens, int indent)
+{
+    int i;
+
+    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+        if (i > 0)
+            BIO_puts(out, "\n");
+        BIO_printf(out, "%*s", indent + 2, "");
+        GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
+    }
+    return 1;
+}
index bff96a8a90a06454c9b454f389df7dfaa730476a..cb9c76b6a3fd44565c8992b0b5c788f845387b29 100644 (file)
@@ -1711,6 +1711,10 @@ DEPEND[html/man3/OSSL_ESS_check_signing_certs.html]=man3/OSSL_ESS_check_signing_
 GENERATE[html/man3/OSSL_ESS_check_signing_certs.html]=man3/OSSL_ESS_check_signing_certs.pod
 DEPEND[man/man3/OSSL_ESS_check_signing_certs.3]=man3/OSSL_ESS_check_signing_certs.pod
 GENERATE[man/man3/OSSL_ESS_check_signing_certs.3]=man3/OSSL_ESS_check_signing_certs.pod
+DEPEND[html/man3/OSSL_GENERAL_NAMES_print.html]=man3/OSSL_GENERAL_NAMES_print.pod
+GENERATE[html/man3/OSSL_GENERAL_NAMES_print.html]=man3/OSSL_GENERAL_NAMES_print.pod
+DEPEND[man/man3/OSSL_GENERAL_NAMES_print.3]=man3/OSSL_GENERAL_NAMES_print.pod
+GENERATE[man/man3/OSSL_GENERAL_NAMES_print.3]=man3/OSSL_GENERAL_NAMES_print.pod
 DEPEND[html/man3/OSSL_HPKE_CTX_new.html]=man3/OSSL_HPKE_CTX_new.pod
 GENERATE[html/man3/OSSL_HPKE_CTX_new.html]=man3/OSSL_HPKE_CTX_new.pod
 DEPEND[man/man3/OSSL_HPKE_CTX_new.3]=man3/OSSL_HPKE_CTX_new.pod
@@ -3403,6 +3407,7 @@ html/man3/OSSL_ENCODER_CTX_new_for_pkey.html \
 html/man3/OSSL_ENCODER_to_bio.html \
 html/man3/OSSL_ERR_STATE_save.html \
 html/man3/OSSL_ESS_check_signing_certs.html \
+html/man3/OSSL_GENERAL_NAMES_print.html \
 html/man3/OSSL_HPKE_CTX_new.html \
 html/man3/OSSL_HTTP_REQ_CTX.html \
 html/man3/OSSL_HTTP_parse_url.html \
@@ -4059,6 +4064,7 @@ man/man3/OSSL_ENCODER_CTX_new_for_pkey.3 \
 man/man3/OSSL_ENCODER_to_bio.3 \
 man/man3/OSSL_ERR_STATE_save.3 \
 man/man3/OSSL_ESS_check_signing_certs.3 \
+man/man3/OSSL_GENERAL_NAMES_print.3 \
 man/man3/OSSL_HPKE_CTX_new.3 \
 man/man3/OSSL_HTTP_REQ_CTX.3 \
 man/man3/OSSL_HTTP_parse_url.3 \
diff --git a/doc/man3/OSSL_GENERAL_NAMES_print.pod b/doc/man3/OSSL_GENERAL_NAMES_print.pod
new file mode 100644 (file)
index 0000000..84282ee
--- /dev/null
@@ -0,0 +1,36 @@
+=pod
+
+=head1 NAME
+
+OSSL_GENERAL_NAMES_print - print GeneralNames in a human-friendly, multi-line
+string
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509v3.h>
+
+ int OSSL_GENERAL_NAMES_print(BIO *out, GENERAL_NAMES *gens, int indent);
+
+=head1 DESCRIPTION
+
+OSSL_GENERAL_NAMES_print() prints a human readable version of the GeneralNames
+I<gens> to BIO I<out>. Each line is indented by I<indent> spaces.
+
+=head1 RETURN VALUES
+
+OSSL_GENERAL_NAMES_print() always returns 1.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.4.
+
+=head1 COPYRIGHT
+
+Copyright 2024 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
index 17100a45ffb5edc5707158d440b4def8a6ccbe53..6333ba698585f43dfe3bf19983ed88c867a89cd6 100644 (file)
@@ -176,6 +176,18 @@ OSSL_CRMF_PKIPUBLICATIONINFO_new,
 OSSL_CRMF_SINGLEPUBINFO_free,
 OSSL_CRMF_SINGLEPUBINFO_it,
 OSSL_CRMF_SINGLEPUBINFO_new,
+OSSL_TARGET_CERT_free,
+OSSL_TARGET_CERT_it,
+OSSL_TARGET_CERT_new,
+OSSL_TARGET_free,
+OSSL_TARGET_it,
+OSSL_TARGET_new,
+OSSL_TARGETING_INFORMATION_free,
+OSSL_TARGETING_INFORMATION_it,
+OSSL_TARGETING_INFORMATION_new,
+OSSL_TARGETS_free,
+OSSL_TARGETS_it,
+OSSL_TARGETS_new,
 OSSL_IETF_ATTR_SYNTAX_VALUE_free,
 OSSL_IETF_ATTR_SYNTAX_VALUE_it,
 OSSL_IETF_ATTR_SYNTAX_VALUE_new,
index 1c0b5bf62526d0db15e6468f60b9270eb01d01c7..373962e135161cd824ae0baad87e6053545b459c 100644 (file)
@@ -101,6 +101,12 @@ d2i_OSSL_CRMF_PBMPARAMETER,
 d2i_OSSL_CRMF_PKIPUBLICATIONINFO,
 d2i_OSSL_CRMF_SINGLEPUBINFO,
 d2i_OSSL_IETF_ATTR_SYNTAX,
+d2i_OSSL_ISSUER_SERIAL,
+d2i_OSSL_OBJECT_DIGEST_INFO,
+d2i_OSSL_TARGET_CERT,
+d2i_OSSL_TARGET,
+d2i_OSSL_TARGETING_INFORMATION,
+d2i_OSSL_TARGETS,
 d2i_OTHERNAME,
 d2i_PBE2PARAM,
 d2i_PBEPARAM,
@@ -276,6 +282,12 @@ i2d_OSSL_CRMF_PBMPARAMETER,
 i2d_OSSL_CRMF_PKIPUBLICATIONINFO,
 i2d_OSSL_CRMF_SINGLEPUBINFO,
 i2d_OSSL_IETF_ATTR_SYNTAX,
+i2d_OSSL_ISSUER_SERIAL,
+i2d_OSSL_OBJECT_DIGEST_INFO,
+i2d_OSSL_TARGET_CERT,
+i2d_OSSL_TARGET,
+i2d_OSSL_TARGETING_INFORMATION,
+i2d_OSSL_TARGETS,
 i2d_OTHERNAME,
 i2d_PBE2PARAM,
 i2d_PBEPARAM,
index f7a019774b9ddd7881a32c574f761b07f8b7497c..febb296ce924c5dc2aef6e8488b58463a63e2863 100644 (file)
@@ -37,6 +37,7 @@
 #include <openssl/bio.h>
 #include <openssl/evp.h>
 #include <openssl/ssl.h>
+#include <openssl/x509_acert.h>
 #include "internal/nelem.h"
 #include "fuzzer.h"
 
@@ -174,6 +175,7 @@ static ASN1_ITEM_EXP *item_type[] = {
 #endif
     ASN1_ITEM_ref(SXNET),
     ASN1_ITEM_ref(SXNETID),
+    ASN1_ITEM_ref(OSSL_TARGETING_INFORMATION),
     ASN1_ITEM_ref(USERNOTICE),
     ASN1_ITEM_ref(X509),
     ASN1_ITEM_ref(X509_ALGOR),
index 3223bf623447f21c2c36902fb9e3871252cb2177..faf6bf50e977356abaa878048e09152d53add90b 100644 (file)
 
 # include <openssl/x509_acert.h>
 
+#define OSSL_ODI_TYPE_PUBLIC_KEY      0
+#define OSSL_ODI_TYPE_PUBLIC_KEY_CERT 1
+#define OSSL_ODI_TYPE_OTHER           2
+
 struct ossl_object_digest_info_st {
     ASN1_ENUMERATED digestedObjectType;
     ASN1_OBJECT *otherObjectTypeID;
index 42376a6cb763efee73bf6abd0410f8b4afa2526f..70facf8ecc8d547d3dd90c01a6320410e6355962 100644 (file)
@@ -153,4 +153,40 @@ int OSSL_IETF_ATTR_SYNTAX_add1_value(OSSL_IETF_ATTR_SYNTAX *a, int type,
                                             void *data);
 int OSSL_IETF_ATTR_SYNTAX_print(BIO *bp, OSSL_IETF_ATTR_SYNTAX *a, int indent);
 
+struct TARGET_CERT_st {
+    OSSL_ISSUER_SERIAL *targetCertificate;
+    GENERAL_NAME *targetName;
+    OSSL_OBJECT_DIGEST_INFO *certDigestInfo;
+};
+
+typedef struct TARGET_CERT_st OSSL_TARGET_CERT;
+
+# define OSSL_TGT_TARGET_NAME  0
+# define OSSL_TGT_TARGET_GROUP 1
+# define OSSL_TGT_TARGET_CERT  2
+
+typedef struct TARGET_st {
+    int type;
+    union {
+        GENERAL_NAME *targetName;
+        GENERAL_NAME *targetGroup;
+        OSSL_TARGET_CERT *targetCert;
+    } choice;
+} OSSL_TARGET;
+
+typedef STACK_OF(OSSL_TARGET) OSSL_TARGETS;
+typedef STACK_OF(OSSL_TARGETS) OSSL_TARGETING_INFORMATION;
+
+{-
+    generate_stack_macros("OSSL_TARGET");
+-}
+
+{-
+    generate_stack_macros("OSSL_TARGETS");
+-}
+
+DECLARE_ASN1_FUNCTIONS(OSSL_TARGET)
+DECLARE_ASN1_FUNCTIONS(OSSL_TARGETS)
+DECLARE_ASN1_FUNCTIONS(OSSL_TARGETING_INFORMATION)
+
 #endif
index a967064f4c4b5a7dfed42a67eb9e2831cfbc0682..7c2313e424881f388d11a29f6d931cd170c9e956 100644 (file)
@@ -1019,6 +1019,8 @@ const ASN1_PRINTABLESTRING *PROFESSION_INFO_get0_registrationNumber(
 void PROFESSION_INFO_set0_registrationNumber(
     PROFESSION_INFO *pi, ASN1_PRINTABLESTRING *rn);
 
+int OSSL_GENERAL_NAMES_print(BIO *out, GENERAL_NAMES *gens, int indent);
+
 # ifdef  __cplusplus
 }
 # endif
diff --git a/test/certs/ext-targetingInformation.pem b/test/certs/ext-targetingInformation.pem
new file mode 100644 (file)
index 0000000..0ce3998
--- /dev/null
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICKzCCAhegAwIBAgIDAQIDMAsGCSqGSIb3DQEBBTAAMCIYDzIwMjEwODMwMTI1
+NDEzWhgPMjAyMTA4MzAxMjU0MTNaMAAwggEgMAsGCSqGSIb3DQEBAQOCAQ8AMIIB
+CgKCAQEAtnjLm1ts1hC4fNNt3UnQD9y73bDXgioTyWYSI3ca/KNfuTydjFTEYAmq
+nuGrBOUfgbmH3PRQ0AmpqljgWTb3d3K8H4UFvDWQTPSS21IMjm8oqd19nE5GxWir
+Gu0oDRzhWLHe1RZ7ZrohCPg/1Ocsy47QZuK2laFB0rEmrRWBmEYbDl3/wxf5XfqI
+qpOynJB02thXrTCcTM7Rz1FqCFt/ZVZB5hKY2S+CTdE9OIVKlr4WHMfuvUYeOj06
+GkwLFJHNv2tU+tovI3mYRxUuY4UupkS3MC+Otey7XKm1P+INjWWoegm6iCAt3Vus
+pVz+6pU2xgl3nrAVMQHB4fReQPH0pQIDAQABo4GxMIGuMIGrBgNVHTcEgaMwgaAw
+OqAgpB4wHDEaMBgGA1UEAwwRV2lsZGJvYXIgU29mdHdhcmWhFoIUd2lsZGJvYXJz
+b2Z0d2FyZS5jb20wYqJgMDEwJaQeMBwxGjAYBgNVBAMMEVdpbGRib2FyIFNvZnR3
+YXJliANVBAMCBAECAwQDAgOwgRVqb25hdGhhbkB3aWxidXIuc3BhY2UwFAoBADAL
+BgkqhkiG9w0BAQUDAgIkMAsGCSqGSIb3DQEBBQMBAA==
+-----END CERTIFICATE-----
\ No newline at end of file
index c727e5cdb3dcf3433cf734e0da2d85b1a41bd4ce..2ae13df615adb80194283342a4186038e2dafaea 100644 (file)
@@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
 
 setup("test_x509");
 
-plan tests => 51;
+plan tests => 60;
 
 # Prevent MSys2 filename munging for arguments that look like file paths but
 # aren't
@@ -143,6 +143,35 @@ cert_contains(srctop_file(@certs, "ext-indirectIssuer.pem"),
               "Indirect Issuer",
               1, 'X.509 Indirect Issuer');
 
+my $tgt_info_cert = srctop_file(@certs, "ext-targetingInformation.pem");
+cert_contains($tgt_info_cert,
+              "AC Targeting",
+              1, 'X.509 Targeting Information Extension');
+cert_contains($tgt_info_cert,
+              "Targets:",
+              1, 'X.509 Targeting Information Targets');
+cert_contains($tgt_info_cert,
+              "Target:",
+              1, 'X.509 Targeting Information Target');
+cert_contains($tgt_info_cert,
+              "Target Name: DirName:CN = W",
+              1, 'X.509 Targeting Information Target Name');
+cert_contains($tgt_info_cert,
+              "Target Group: DNS:wildboarsoftware.com",
+              1, 'X.509 Targeting Information Target Name');
+cert_contains($tgt_info_cert,
+              "Issuer Names:",
+              1, 'X.509 Targeting Information Issuer Names');
+cert_contains($tgt_info_cert,
+              "Issuer Serial: 01020304",
+              1, 'X.509 Targeting Information Issuer Serial');
+cert_contains($tgt_info_cert,
+              "Issuer UID: B0",
+              1, 'X.509 Targeting Information Issuer UID');
+cert_contains($tgt_info_cert,
+              "Digest Type: Public Key",
+              1, 'X.509 Targeting Information Object Digest Type');
+
 sub test_errors { # actually tests diagnostics of OSSL_STORE
     my ($expected, $cert, @opts) = @_;
     my $infile = srctop_file(@certs, $cert);
index e0474a0021dd9c06e162b0a0dc36e6f0778352e2..526cc59355dcec9e32d8fb3a0f21b18eed6cd9a0 100644 (file)
@@ -5647,3 +5647,19 @@ X509_ACERT_add_attr_nconf               ?        3_4_0   EXIST::FUNCTION:
 OSSL_LIB_CTX_get_conf_diagnostics       ?      3_4_0   EXIST::FUNCTION:
 OSSL_LIB_CTX_set_conf_diagnostics       ?      3_4_0   EXIST::FUNCTION:
 OSSL_LIB_CTX_get_data                   ?      3_4_0   EXIST::FUNCTION:
+d2i_OSSL_TARGET                         ?      3_4_0   EXIST::FUNCTION:
+i2d_OSSL_TARGET                         ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGET_free                        ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGET_new                         ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGET_it                          ?      3_4_0   EXIST::FUNCTION:
+d2i_OSSL_TARGETS                        ?      3_4_0   EXIST::FUNCTION:
+i2d_OSSL_TARGETS                        ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGETS_free                       ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGETS_new                        ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGETS_it                         ?      3_4_0   EXIST::FUNCTION:
+d2i_OSSL_TARGETING_INFORMATION          ?      3_4_0   EXIST::FUNCTION:
+i2d_OSSL_TARGETING_INFORMATION          ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGETING_INFORMATION_free         ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGETING_INFORMATION_new          ?      3_4_0   EXIST::FUNCTION:
+OSSL_TARGETING_INFORMATION_it           ?      3_4_0   EXIST::FUNCTION:
+OSSL_GENERAL_NAMES_print                ?      3_4_0   EXIST::FUNCTION: