]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
feat: support the attributeMappings X.509v3 extension
authorJonathan M. Wilbur <jonathan@wilbur.space>
Thu, 12 Dec 2024 02:10:25 +0000 (02:10 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 23 Dec 2024 09:58:15 +0000 (09:58 +0000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26157)

crypto/x509/build.info
crypto/x509/ext_dat.h
crypto/x509/standard_exts.h
crypto/x509/v3_attrmap.c [new file with mode: 0644]
include/openssl/x509v3.h.in
util/libcrypto.num

index 62e701dd5e81eb3ff4b4cf7092c3887101977630..204239f8380b528189d73a2bc1b2e07d64e5b67d 100644 (file)
@@ -18,7 +18,7 @@ SOURCE[../../libcrypto]=\
         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 v3_ac_tgt.c v3_sda.c \
         v3_usernotice.c v3_battcons.c v3_audit_id.c v3_iobo.c v3_authattid.c \
-        v3_rolespec.c v3_attrdesc.c v3_timespec.c
+        v3_rolespec.c v3_attrdesc.c v3_timespec.c v3_attrmap.c
 
 IF[{- !$disabled{'deprecated-3.0'} -}]
   SOURCE[../../libcrypto]=x509type.c
index efe8abb10456848ffb5cee2f7c3eaeed728d4a84..d1ec38779368683d2001e62eb8c4c04285db98bb 100644 (file)
@@ -46,3 +46,4 @@ extern const X509V3_EXT_METHOD ossl_v3_authority_attribute_identifier;
 extern const X509V3_EXT_METHOD ossl_v3_role_spec_cert_identifier;
 extern const X509V3_EXT_METHOD ossl_v3_attribute_descriptor;
 extern const X509V3_EXT_METHOD ossl_v3_time_specification;
+extern const X509V3_EXT_METHOD ossl_v3_attribute_mappings;
index 4ed059bd61b82718705d48b96a2b0a0eb527b466..9bf6a77d812d69596f98ff997fbcfe09851aed36 100644 (file)
@@ -91,6 +91,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = {
     &ossl_v3_issued_on_behalf_of,
     &ossl_v3_single_use,
     &ossl_v3_group_ac,
+    &ossl_v3_attribute_mappings,
     &ossl_v3_holder_name_constraints,
     &ossl_v3_associated_info,
 };
diff --git a/crypto/x509/v3_attrmap.c b/crypto/x509/v3_attrmap.c
new file mode 100644 (file)
index 0000000..a01e655
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include <crypto/x509.h>
+#include "ext_dat.h"
+
+ASN1_SEQUENCE(OSSL_ATAV) = {
+    ASN1_SIMPLE(OSSL_ATAV, type, ASN1_OBJECT),
+    ASN1_SIMPLE(OSSL_ATAV, value, ASN1_ANY)
+} ASN1_SEQUENCE_END(OSSL_ATAV)
+
+ASN1_SEQUENCE(OSSL_ATTRIBUTE_TYPE_MAPPING) = {
+    ASN1_IMP(OSSL_ATTRIBUTE_TYPE_MAPPING, local, ASN1_OBJECT, 0),
+    ASN1_IMP(OSSL_ATTRIBUTE_TYPE_MAPPING, remote, ASN1_OBJECT, 1),
+} ASN1_SEQUENCE_END(OSSL_ATTRIBUTE_TYPE_MAPPING)
+
+ASN1_SEQUENCE(OSSL_ATTRIBUTE_VALUE_MAPPING) = {
+    ASN1_IMP(OSSL_ATTRIBUTE_VALUE_MAPPING, local, OSSL_ATAV, 0),
+    ASN1_IMP(OSSL_ATTRIBUTE_VALUE_MAPPING, remote, OSSL_ATAV, 1),
+} ASN1_SEQUENCE_END(OSSL_ATTRIBUTE_VALUE_MAPPING)
+
+ASN1_CHOICE(OSSL_ATTRIBUTE_MAPPING) = {
+    ASN1_IMP(OSSL_ATTRIBUTE_MAPPING, choice.typeMappings,
+             OSSL_ATTRIBUTE_TYPE_MAPPING, OSSL_ATTR_MAP_TYPE),
+    ASN1_IMP(OSSL_ATTRIBUTE_MAPPING, choice.typeValueMappings,
+             OSSL_ATTRIBUTE_VALUE_MAPPING, OSSL_ATTR_MAP_VALUE),
+} ASN1_CHOICE_END(OSSL_ATTRIBUTE_MAPPING)
+
+ASN1_ITEM_TEMPLATE(OSSL_ATTRIBUTE_MAPPINGS) =
+    ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, OSSL_ATTRIBUTE_MAPPINGS, OSSL_ATTRIBUTE_MAPPING)
+ASN1_ITEM_TEMPLATE_END(OSSL_ATTRIBUTE_MAPPINGS)
+
+IMPLEMENT_ASN1_FUNCTIONS(OSSL_ATAV)
+IMPLEMENT_ASN1_FUNCTIONS(OSSL_ATTRIBUTE_TYPE_MAPPING)
+IMPLEMENT_ASN1_FUNCTIONS(OSSL_ATTRIBUTE_VALUE_MAPPING)
+IMPLEMENT_ASN1_FUNCTIONS(OSSL_ATTRIBUTE_MAPPING)
+IMPLEMENT_ASN1_FUNCTIONS(OSSL_ATTRIBUTE_MAPPINGS)
+
+static int i2r_ATTRIBUTE_MAPPING(X509V3_EXT_METHOD *method,
+                                 OSSL_ATTRIBUTE_MAPPING *am,
+                                 BIO *out, int indent)
+{
+    ASN1_OBJECT *local_type, *remote_type;
+    int local_attr_nid, remote_attr_nid;
+    ASN1_TYPE *local_val, *remote_val;
+
+    switch (am->type) {
+    case (OSSL_ATTR_MAP_TYPE):
+        if (i2a_ASN1_OBJECT(out, am->choice.typeMappings->local) <= 0)
+            return 0;
+        if (BIO_puts(out, " == ") <= 0)
+            return 0;
+        return i2a_ASN1_OBJECT(out, am->choice.typeMappings->remote);
+    case (OSSL_ATTR_MAP_VALUE):
+        local_type = am->choice.typeValueMappings->local->type;
+        remote_type = am->choice.typeValueMappings->remote->type;
+        local_val = am->choice.typeValueMappings->local->value;
+        remote_val = am->choice.typeValueMappings->remote->value;
+        local_attr_nid = OBJ_obj2nid(local_type);
+        remote_attr_nid = OBJ_obj2nid(remote_type);
+        if (i2a_ASN1_OBJECT(out, local_type) <= 0)
+            return 0;
+        if (BIO_puts(out, ":") <= 0)
+            return 0;
+        if (ossl_print_attribute_value(out, local_attr_nid, local_val, 0) <= 0)
+            return 0;
+        if (BIO_puts(out, " == ") <= 0)
+            return 0;
+        if (i2a_ASN1_OBJECT(out, remote_type) <= 0)
+            return 0;
+        if (BIO_puts(out, ":") <= 0)
+            return 0;
+        return ossl_print_attribute_value(out, remote_attr_nid, remote_val, 0);
+    default:
+        return 0;
+    }
+    return 1;
+}
+
+static int i2r_ATTRIBUTE_MAPPINGS(X509V3_EXT_METHOD *method,
+                                  OSSL_ATTRIBUTE_MAPPINGS *ams,
+                                  BIO *out, int indent)
+{
+    int i;
+    OSSL_ATTRIBUTE_MAPPING *am;
+
+    for (i = 0; i < sk_OSSL_ATTRIBUTE_MAPPING_num(ams); i++) {
+        am = sk_OSSL_ATTRIBUTE_MAPPING_value(ams, i);
+        if (BIO_printf(out, "%*s", indent, "") <= 0)
+            return 0;
+        if (i2r_ATTRIBUTE_MAPPING(method, am, out, indent + 4) <= 0)
+            return 0;
+        if (BIO_puts(out, "\n") <= 0)
+            return 0;
+    }
+    return 1;
+}
+
+const X509V3_EXT_METHOD ossl_v3_attribute_mappings = {
+    NID_attribute_mappings, X509V3_EXT_MULTILINE,
+    ASN1_ITEM_ref(OSSL_ATTRIBUTE_MAPPINGS),
+    0, 0, 0, 0,
+    0, 0,
+    0,
+    0,
+    (X509V3_EXT_I2R)i2r_ATTRIBUTE_MAPPINGS,
+    0,
+    NULL
+};
index 557054c630094ab4441dbe9f3ab216e168d02009..dd23a11420cedb86bc3c5e6baebd9e453340d6a1 100644 (file)
@@ -1278,6 +1278,44 @@ DECLARE_ASN1_FUNCTIONS(OSSL_TIME_PERIOD)
     generate_stack_macros("OSSL_DAY_TIME_BAND");
 -}
 
+/* Attribute Type and Value */
+typedef struct atav_st {
+    ASN1_OBJECT *type;
+    ASN1_TYPE *value;
+} OSSL_ATAV;
+
+typedef struct ATTRIBUTE_TYPE_MAPPING_st {
+    ASN1_OBJECT *local;
+    ASN1_OBJECT *remote;
+} OSSL_ATTRIBUTE_TYPE_MAPPING;
+
+typedef struct ATTRIBUTE_VALUE_MAPPING_st {
+    OSSL_ATAV *local;
+    OSSL_ATAV *remote;
+} OSSL_ATTRIBUTE_VALUE_MAPPING;
+
+# define OSSL_ATTR_MAP_TYPE   0
+# define OSSL_ATTR_MAP_VALUE  1
+
+typedef struct ATTRIBUTE_MAPPING_st {
+    int type;
+    union {
+        OSSL_ATTRIBUTE_TYPE_MAPPING *typeMappings;
+        OSSL_ATTRIBUTE_VALUE_MAPPING *typeValueMappings;
+    } choice;
+} OSSL_ATTRIBUTE_MAPPING;
+
+typedef STACK_OF(OSSL_ATTRIBUTE_MAPPING) OSSL_ATTRIBUTE_MAPPINGS;
+DECLARE_ASN1_FUNCTIONS(OSSL_ATAV)
+DECLARE_ASN1_FUNCTIONS(OSSL_ATTRIBUTE_TYPE_MAPPING)
+DECLARE_ASN1_FUNCTIONS(OSSL_ATTRIBUTE_VALUE_MAPPING)
+DECLARE_ASN1_FUNCTIONS(OSSL_ATTRIBUTE_MAPPING)
+DECLARE_ASN1_FUNCTIONS(OSSL_ATTRIBUTE_MAPPINGS)
+
+{-
+    generate_stack_macros("OSSL_ATTRIBUTE_MAPPING");
+-}
+
 # ifdef  __cplusplus
 }
 # endif
index 663fbfbbaf1b5764b5f6c214bf02cc34085e7a00..8da730bb691b769a2e79fcbdc5cc1bf8e545f6c7 100644 (file)
@@ -5836,3 +5836,28 @@ EVP_CipherPipelineEncryptInit           ?        3_5_0   EXIST::FUNCTION:
 EVP_CipherPipelineDecryptInit           ?      3_5_0   EXIST::FUNCTION:
 EVP_CipherPipelineUpdate                ?      3_5_0   EXIST::FUNCTION:
 EVP_CipherPipelineFinal                 ?      3_5_0   EXIST::FUNCTION:
+d2i_OSSL_ATTRIBUTE_TYPE_MAPPING         ?      3_5_0   EXIST::FUNCTION:
+i2d_OSSL_ATTRIBUTE_TYPE_MAPPING         ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_TYPE_MAPPING_free        ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_TYPE_MAPPING_new         ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_TYPE_MAPPING_it          ?      3_5_0   EXIST::FUNCTION:
+d2i_OSSL_ATTRIBUTE_VALUE_MAPPING        ?      3_5_0   EXIST::FUNCTION:
+i2d_OSSL_ATTRIBUTE_VALUE_MAPPING        ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_VALUE_MAPPING_free       ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_VALUE_MAPPING_new        ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_VALUE_MAPPING_it         ?      3_5_0   EXIST::FUNCTION:
+d2i_OSSL_ATTRIBUTE_MAPPING              ?      3_5_0   EXIST::FUNCTION:
+i2d_OSSL_ATTRIBUTE_MAPPING              ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_MAPPING_free             ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_MAPPING_new              ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_MAPPING_it               ?      3_5_0   EXIST::FUNCTION:
+d2i_OSSL_ATTRIBUTE_MAPPINGS             ?      3_5_0   EXIST::FUNCTION:
+i2d_OSSL_ATTRIBUTE_MAPPINGS             ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_MAPPINGS_free            ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_MAPPINGS_new             ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATTRIBUTE_MAPPINGS_it              ?      3_5_0   EXIST::FUNCTION:
+d2i_OSSL_ATAV                           ?      3_5_0   EXIST::FUNCTION:
+i2d_OSSL_ATAV                           ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATAV_free                          ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATAV_new                           ?      3_5_0   EXIST::FUNCTION:
+OSSL_ATAV_it                            ?      3_5_0   EXIST::FUNCTION: