Consolidate ASN.1 universal tag type data.
authorjsing <jsing@openbsd.org>
Tue, 14 Dec 2021 17:35:21 +0000 (17:35 +0000)
committerjsing <jsing@openbsd.org>
Tue, 14 Dec 2021 17:35:21 +0000 (17:35 +0000)
There are currently three different tables in three different files that
contain information about ASN.1 universal class tag types. Range checking
is also implemented in three different places (with different
implementations).

Consolidate all of this into a single table, provide a lookup function that
deals with the range checks and wrappers to deal with specific types.

ok inoguchi@ tb@

lib/libcrypto/Makefile
lib/libcrypto/asn1/a_strex.c
lib/libcrypto/asn1/asn1_locl.h
lib/libcrypto/asn1/asn1_par.c
lib/libcrypto/asn1/asn1_types.c [new file with mode: 0644]
lib/libcrypto/asn1/tasn_dec.c

index df4649a..c7d84b4 100644 (file)
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.55 2021/12/13 17:56:15 jsing Exp $
+# $OpenBSD: Makefile,v 1.56 2021/12/14 17:35:21 jsing Exp $
 
 LIB=   crypto
 LIBREBUILD=y
@@ -65,7 +65,7 @@ SRCS+= f_int.c f_string.c n_pkey.c
 SRCS+= f_enum.c x_pkey.c x_exten.c bio_asn1.c bio_ndef.c asn_mime.c
 SRCS+= asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_strnid.c
 SRCS+= evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c
-SRCS+= a_time_tm.c
+SRCS+= a_time_tm.c asn1_types.c
 
 # bf/
 SRCS+= bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c
index 3b66ea8..61672d2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: a_strex.c,v 1.29 2021/11/01 20:53:08 tb Exp $ */
+/* $OpenBSD: a_strex.c,v 1.30 2021/12/14 17:35:21 jsing Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
@@ -322,22 +322,6 @@ do_dump(unsigned long lflags, char_io *io_ch, void *arg, const ASN1_STRING *str)
        return outlen + 1;
 }
 
-/* Lookup table to convert tags to character widths,
- * 0 = UTF8 encoded, -1 is used for non string types
- * otherwise it is the number of bytes per character
- */
-
-static const signed char tag2nbyte[] = {
-       -1, -1, -1, -1, -1,     /* 0-4 */
-       -1, -1, -1, -1, -1,     /* 5-9 */
-       -1, -1, 0, -1,          /* 10-13 */
-       -1, -1, -1, -1,         /* 15-17 */
-       -1, 1, 1,               /* 18-20 */
-       -1, 1, 1, 1,            /* 21-24 */
-       -1, 1, -1,              /* 25-27 */
-       4, -1, 2                /* 28-30 */
-};
-
 /* This is the main function, print out an
  * ASN1_STRING taking note of various escape
  * and display options. Returns number of
@@ -371,19 +355,16 @@ do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
 
        /* Decide what to do with type, either dump content or display it */
 
-       /* Dump everything */
-       if (lflags & ASN1_STRFLGS_DUMP_ALL)
+       if (lflags & ASN1_STRFLGS_DUMP_ALL) {
+               /* Dump everything. */
                type = -1;
-       /* Ignore the string type */
-       else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
+       } else if (lflags & ASN1_STRFLGS_IGNORE_TYPE) {
+               /* Ignore the string type. */
                type = 1;
-       else {
-               /* Else determine width based on type */
-               if ((type > 0) && (type < 31))
-                       type = tag2nbyte[type];
-               else
-                       type = -1;
-               if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
+       } else {
+               /* Else determine width based on type. */
+               type = asn1_tag2charwidth(type);
+               if (type == -1 && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
                        type = 1;
        }
 
@@ -627,17 +608,15 @@ int
 ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in)
 {
        ASN1_STRING stmp, *str = &stmp;
-       int mbflag, type, ret;
+       int mbflag, ret;
 
        if (!in)
                return -1;
-       type = in->type;
-       if ((type < 0) || (type > 30))
-               return -1;
-       mbflag = tag2nbyte[type];
-       if (mbflag == -1)
+
+       if ((mbflag = asn1_tag2charwidth(in->type)) == -1)
                return -1;
        mbflag |= MBSTRING_FLAG;
+
        stmp.data = NULL;
        stmp.length = 0;
        ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
index 39779d9..f7731ec 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: asn1_locl.h,v 1.12 2019/10/24 16:36:10 jsing Exp $ */
+/* $OpenBSD: asn1_locl.h,v 1.13 2021/12/14 17:35:21 jsing Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2006.
  */
@@ -155,4 +155,6 @@ struct x509_crl_method_st {
 int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
 int UTF8_putc(unsigned char *str, int len, unsigned long value);
 
+int asn1_tag2charwidth(int tag);
+
 __END_HIDDEN_DECLS
index af948c5..4604930 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: asn1_par.c,v 1.29 2021/12/13 17:58:41 tb Exp $ */
+/* $OpenBSD: asn1_par.c,v 1.30 2021/12/14 17:35:21 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -380,25 +380,3 @@ end:
        *pp = p;
        return (ret);
 }
-
-const char *
-ASN1_tag2str(int tag)
-{
-       static const char * const tag2str[] = {
-               "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
-               "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
-               "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>",       /* 10-13 */
-               "<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET",                /* 15-17 */
-               "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",            /* 18-20 */
-               "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 */
-               "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",          /* 25-27 */
-               "UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"                 /* 28-30 */
-       };
-
-       if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
-               tag &= ~0x100;
-
-       if (tag < 0 || tag > 30)
-               return "(unknown)";
-       return tag2str[tag];
-}
diff --git a/lib/libcrypto/asn1/asn1_types.c b/lib/libcrypto/asn1/asn1_types.c
new file mode 100644 (file)
index 0000000..c8e6b23
--- /dev/null
@@ -0,0 +1,263 @@
+/* $OpenBSD: asn1_types.c,v 1.1 2021/12/14 17:35:21 jsing Exp $ */
+/*
+ * Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stddef.h>
+
+#include <openssl/asn1.h>
+
+struct asn1_type {
+       const char *name;
+       uint32_t bit_value;
+       int char_width;
+};
+
+/*
+ * Universal class tag types - ITU X.680.
+ */
+static const struct asn1_type asn1_types[31] = {
+       [0] = {
+               /* Tag 0 (0x00) - Reserved for use by encoding rules */
+               .name = "EOC",
+               .bit_value = 0,
+               .char_width = -1,
+       },
+       [1] = {
+               /* Tag 1 (0x01) - Boolean */
+               .name = "BOOLEAN",
+               .bit_value = 0,
+               .char_width = -1,
+       },
+       [2] = {
+               /* Tag 2 (0x02) - Integer */
+               .name = "INTEGER",
+               .bit_value = 0,
+               .char_width = -1,
+       },
+       [3] = {
+               /* Tag 3 (0x03) - BitString */
+               .name = "BIT STRING",
+               .bit_value = B_ASN1_BIT_STRING,
+               .char_width = -1,
+       },
+       [4] = {
+               /* Tag 4 (0x04) - OctetString */
+               .name = "OCTET STRING",
+               .bit_value = B_ASN1_OCTET_STRING,
+               .char_width = -1,
+       },
+       [5] = {
+               /* Tag 5 (0x05) - Null */
+               .name = "NULL",
+               .bit_value = 0,
+               .char_width = -1,
+       },
+       [6] = {
+               /* Tag 6 (0x06) - Object Identifier */
+               .name = "OBJECT",
+               .bit_value = 0,
+               .char_width = -1,
+       },
+       [7] = {
+               /* Tag 7 (0x07) - Object Descriptor */
+               .name = "OBJECT DESCRIPTOR",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [8] = {
+               /* Tag 8 (0x08) - External */
+               .name = "EXTERNAL",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [9] = {
+               /* Tag 9 (0x09) - Real */
+               .name = "REAL",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [10] = {
+               /* Tag 10 (0x0a) - Enumerated */
+               .name = "ENUMERATED",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [11] = {
+               /* Tag 11 (0x0b) - Embedded PDV */
+               .name = "<ASN1 11 EMBEDDED PDV>",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [12] = {
+               /* Tag 12 (0x0c) - UTF8String */
+               .name = "UTF8STRING",
+               .bit_value = B_ASN1_UTF8STRING,
+               .char_width = 0,
+       },
+       [13] = {
+               /* Tag 13 (0x0d) - Relative Object Identifier */
+               .name = "<ASN1 13 RELATIVE OID>",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [14] = {
+               /* Tag 14 (0x0e) - Time */
+               .name = "<ASN1 14 TIME>",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [15] = {
+               /* Tag 15 (0x0f) - Reserved */
+               .name = "<ASN1 15 RESERVED>",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [16] = {
+               /* Tag 16 (0x10)- Sequence */
+               .name = "SEQUENCE",
+               .bit_value = B_ASN1_SEQUENCE,
+               .char_width = -1,
+       },
+       [17] = {
+               /* Tag 17 (0x11) - Set */
+               .name = "SET",
+               .bit_value = 0,
+               .char_width = -1,
+       },
+       [18] = {
+               /* Tag 18 (0x12) - NumericString */
+               .name = "NUMERICSTRING",
+               .bit_value = B_ASN1_NUMERICSTRING,
+               .char_width = -1,
+       },
+       [19] = {
+               /* Tag 19 (0x13) - PrintableString */
+               .name = "PRINTABLESTRING",
+               .bit_value = B_ASN1_PRINTABLESTRING,
+               .char_width = 1,
+       },
+       [20] = {
+               /* Tag 20 (0x14) - TeletexString (T61String) */
+               .name = "T61STRING",
+               .bit_value = B_ASN1_T61STRING,
+               .char_width = 1,
+       },
+       [21] = {
+               /* Tag 21 (0x15) - VideotexString */
+               .name = "VIDEOTEXSTRING",
+               .bit_value = B_ASN1_VIDEOTEXSTRING,
+               .char_width = -1,
+       },
+       [22] = {
+               /* Tag 22 (0x16) - IA5String */
+               .name = "IA5STRING",
+               .bit_value = B_ASN1_IA5STRING,
+               .char_width = 1,
+       },
+       [23] = {
+               /* Tag 23 (0x17) - UTCTime */
+               .name = "UTCTIME",
+               .bit_value = B_ASN1_UTCTIME,
+               .char_width = 1,
+       },
+       [24] = {
+               /* Tag 24 (0x18) - GeneralizedTime */
+               .name = "GENERALIZEDTIME",
+               .bit_value = B_ASN1_GENERALIZEDTIME,
+               .char_width = 1,
+       },
+       [25] = {
+               /* Tag 25 (0x19) - GraphicString */
+               .name = "GRAPHICSTRING",
+               .bit_value = B_ASN1_GRAPHICSTRING,
+               .char_width = -1,
+       },
+       [26] = {
+               /* Tag 26 (0x1a) - VisibleString (ISO646String) */
+               .name = "VISIBLESTRING",
+               .bit_value = B_ASN1_ISO64STRING,
+               .char_width = 1,
+       },
+       [27] = {
+               /* Tag 27 (0x1b) - GeneralString */
+               .name = "GENERALSTRING",
+               .bit_value = B_ASN1_GENERALSTRING,
+               .char_width = -1,
+       },
+       [28] = {
+               /* Tag 28 (0x1c) - UniversalString */
+               .name = "UNIVERSALSTRING",
+               .bit_value = B_ASN1_UNIVERSALSTRING,
+               .char_width = 4,
+       },
+       [29] = {
+               /* Tag 29 (0x1d) - Unallocated */
+               .name = "<ASN1 29>",
+               .bit_value = B_ASN1_UNKNOWN,
+               .char_width = -1,
+       },
+       [30] = {
+               /* Tag 30 (0x1e) - BMPString */
+               .name = "BMPSTRING",
+               .bit_value = B_ASN1_BMPSTRING,
+               .char_width = 2,
+       },
+};
+
+static const struct asn1_type *
+asn1_type_by_tag(int tag)
+{
+       if (tag < 0 || tag > 30)
+               return NULL;
+
+       return &asn1_types[tag];
+}
+
+int
+asn1_tag2charwidth(int tag)
+{
+       const struct asn1_type *at;
+
+       if ((at = asn1_type_by_tag(tag)) != NULL)
+               return at->char_width;
+
+       return -1;
+}
+
+unsigned long
+ASN1_tag2bit(int tag)
+{
+       const struct asn1_type *at;
+
+       if ((at = asn1_type_by_tag(tag)) != NULL)
+               return (unsigned long)at->bit_value;
+
+       return 0;
+}
+
+const char *
+ASN1_tag2str(int tag)
+{
+       const struct asn1_type *at;
+
+       if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
+               tag &= ~V_ASN1_NEG;
+
+       if ((at = asn1_type_by_tag(tag)) != NULL)
+               return at->name;
+
+       return "(unknown)";
+}
index a04a84c..e207691 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tasn_dec.c,v 1.45 2021/12/13 17:50:24 jsing Exp $ */
+/* $OpenBSD: tasn_dec.c,v 1.46 2021/12/14 17:35:21 jsing Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
@@ -95,27 +95,6 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in,
     long len, const ASN1_ITEM *it, int tag, int aclass, char opt,
     ASN1_TLC *ctx);
 
-/* Table to convert tags to bit values, used for MSTRING type */
-static const unsigned long tag2bit[32] = {
-       0,      0,      0,      B_ASN1_BIT_STRING,      /* tags  0 -  3 */
-       B_ASN1_OCTET_STRING,    0,      0,              B_ASN1_UNKNOWN,/* tags  4- 7 */
-       B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags  8-11 */
-       B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
-       B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
-       B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING,       /* tags 20-22 */
-       B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,                        /* tags 23-24 */
-       B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING,  /* tags 25-27 */
-       B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
-};
-
-unsigned long
-ASN1_tag2bit(int tag)
-{
-       if ((tag < 0) || (tag > 30))
-               return 0;
-       return tag2bit[tag];
-}
-
 static void
 asn1_tlc_invalidate(ASN1_TLC *ctx)
 {