xref: /dragonfly/crypto/libressl/crypto/asn1/asn1_types.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1 /* $OpenBSD: asn1_types.c,v 1.2 2022/09/03 18:52:18 jsing Exp $ */
2 /*
3  * Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <stddef.h>
19 
20 #include <openssl/asn1.h>
21 
22 #define ASN1_ENCODING_CONSTRUCTED_ONLY  1
23 #define ASN1_ENCODING_PRIMITIVE_ONLY    2
24 
25 struct asn1_type {
26           const char *name;
27           uint32_t bit_value;
28           int char_width;
29           int encoding;
30 };
31 
32 /*
33  * Universal class tag types - ITU X.680.
34  */
35 static const struct asn1_type asn1_types[31] = {
36           [0] = {
37                     /* Tag 0 (0x00) - Reserved for use by encoding rules */
38                     .name = "EOC",
39                     .bit_value = 0,
40                     .char_width = -1,
41           },
42           [1] = {
43                     /* Tag 1 (0x01) - Boolean */
44                     .name = "BOOLEAN",
45                     .bit_value = 0,
46                     .char_width = -1,
47                     .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
48           },
49           [2] = {
50                     /* Tag 2 (0x02) - Integer */
51                     .name = "INTEGER",
52                     .bit_value = 0,
53                     .char_width = -1,
54                     .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
55           },
56           [3] = {
57                     /* Tag 3 (0x03) - BitString */
58                     .name = "BIT STRING",
59                     .bit_value = B_ASN1_BIT_STRING,
60                     .char_width = -1,
61           },
62           [4] = {
63                     /* Tag 4 (0x04) - OctetString */
64                     .name = "OCTET STRING",
65                     .bit_value = B_ASN1_OCTET_STRING,
66                     .char_width = -1,
67           },
68           [5] = {
69                     /* Tag 5 (0x05) - Null */
70                     .name = "NULL",
71                     .bit_value = 0,
72                     .char_width = -1,
73                     .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
74           },
75           [6] = {
76                     /* Tag 6 (0x06) - Object Identifier */
77                     .name = "OBJECT",
78                     .bit_value = 0,
79                     .char_width = -1,
80                     .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
81           },
82           [7] = {
83                     /* Tag 7 (0x07) - Object Descriptor */
84                     .name = "OBJECT DESCRIPTOR",
85                     .bit_value = B_ASN1_UNKNOWN,
86                     .char_width = -1,
87           },
88           [8] = {
89                     /* Tag 8 (0x08) - External */
90                     .name = "EXTERNAL",
91                     .bit_value = B_ASN1_UNKNOWN,
92                     .char_width = -1,
93           },
94           [9] = {
95                     /* Tag 9 (0x09) - Real */
96                     .name = "REAL",
97                     .bit_value = B_ASN1_UNKNOWN,
98                     .char_width = -1,
99                     .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
100           },
101           [10] = {
102                     /* Tag 10 (0x0a) - Enumerated */
103                     .name = "ENUMERATED",
104                     .bit_value = B_ASN1_UNKNOWN,
105                     .char_width = -1,
106                     .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
107           },
108           [11] = {
109                     /* Tag 11 (0x0b) - Embedded PDV */
110                     .name = "<ASN1 11 EMBEDDED PDV>",
111                     .bit_value = B_ASN1_UNKNOWN,
112                     .char_width = -1,
113           },
114           [12] = {
115                     /* Tag 12 (0x0c) - UTF8String */
116                     .name = "UTF8STRING",
117                     .bit_value = B_ASN1_UTF8STRING,
118                     .char_width = 0,
119           },
120           [13] = {
121                     /* Tag 13 (0x0d) - Relative Object Identifier */
122                     .name = "<ASN1 13 RELATIVE OID>",
123                     .bit_value = B_ASN1_UNKNOWN,
124                     .char_width = -1,
125                     .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
126           },
127           [14] = {
128                     /* Tag 14 (0x0e) - Time */
129                     .name = "<ASN1 14 TIME>",
130                     .bit_value = B_ASN1_UNKNOWN,
131                     .char_width = -1,
132                     .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
133           },
134           [15] = {
135                     /* Tag 15 (0x0f) - Reserved */
136                     .name = "<ASN1 15 RESERVED>",
137                     .bit_value = B_ASN1_UNKNOWN,
138                     .char_width = -1,
139           },
140           [16] = {
141                     /* Tag 16 (0x10)- Sequence */
142                     .name = "SEQUENCE",
143                     .bit_value = B_ASN1_SEQUENCE,
144                     .char_width = -1,
145                     .encoding = ASN1_ENCODING_CONSTRUCTED_ONLY,
146           },
147           [17] = {
148                     /* Tag 17 (0x11) - Set */
149                     .name = "SET",
150                     .bit_value = 0,
151                     .char_width = -1,
152                     .encoding = ASN1_ENCODING_CONSTRUCTED_ONLY,
153           },
154           [18] = {
155                     /* Tag 18 (0x12) - NumericString */
156                     .name = "NUMERICSTRING",
157                     .bit_value = B_ASN1_NUMERICSTRING,
158                     .char_width = -1,
159           },
160           [19] = {
161                     /* Tag 19 (0x13) - PrintableString */
162                     .name = "PRINTABLESTRING",
163                     .bit_value = B_ASN1_PRINTABLESTRING,
164                     .char_width = 1,
165           },
166           [20] = {
167                     /* Tag 20 (0x14) - TeletexString (T61String) */
168                     .name = "T61STRING",
169                     .bit_value = B_ASN1_T61STRING,
170                     .char_width = 1,
171           },
172           [21] = {
173                     /* Tag 21 (0x15) - VideotexString */
174                     .name = "VIDEOTEXSTRING",
175                     .bit_value = B_ASN1_VIDEOTEXSTRING,
176                     .char_width = -1,
177           },
178           [22] = {
179                     /* Tag 22 (0x16) - IA5String */
180                     .name = "IA5STRING",
181                     .bit_value = B_ASN1_IA5STRING,
182                     .char_width = 1,
183           },
184           [23] = {
185                     /* Tag 23 (0x17) - UTCTime */
186                     .name = "UTCTIME",
187                     .bit_value = B_ASN1_UTCTIME,
188                     .char_width = 1,
189           },
190           [24] = {
191                     /* Tag 24 (0x18) - GeneralizedTime */
192                     .name = "GENERALIZEDTIME",
193                     .bit_value = B_ASN1_GENERALIZEDTIME,
194                     .char_width = 1,
195           },
196           [25] = {
197                     /* Tag 25 (0x19) - GraphicString */
198                     .name = "GRAPHICSTRING",
199                     .bit_value = B_ASN1_GRAPHICSTRING,
200                     .char_width = -1,
201           },
202           [26] = {
203                     /* Tag 26 (0x1a) - VisibleString (ISO646String) */
204                     .name = "VISIBLESTRING",
205                     .bit_value = B_ASN1_ISO64STRING,
206                     .char_width = 1,
207           },
208           [27] = {
209                     /* Tag 27 (0x1b) - GeneralString */
210                     .name = "GENERALSTRING",
211                     .bit_value = B_ASN1_GENERALSTRING,
212                     .char_width = -1,
213           },
214           [28] = {
215                     /* Tag 28 (0x1c) - UniversalString */
216                     .name = "UNIVERSALSTRING",
217                     .bit_value = B_ASN1_UNIVERSALSTRING,
218                     .char_width = 4,
219           },
220           [29] = {
221                     /* Tag 29 (0x1d) - Unallocated */
222                     .name = "<ASN1 29>",
223                     .bit_value = B_ASN1_UNKNOWN,
224                     .char_width = -1,
225           },
226           [30] = {
227                     /* Tag 30 (0x1e) - BMPString */
228                     .name = "BMPSTRING",
229                     .bit_value = B_ASN1_BMPSTRING,
230                     .char_width = 2,
231           },
232 };
233 
234 static const struct asn1_type *
asn1_type_by_tag(int tag)235 asn1_type_by_tag(int tag)
236 {
237           if (tag < 0 || tag > 30)
238                     return NULL;
239 
240           return &asn1_types[tag];
241 }
242 
243 int
asn1_must_be_constructed(int tag)244 asn1_must_be_constructed(int tag)
245 {
246           const struct asn1_type *at;
247 
248           if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
249                     tag &= ~V_ASN1_NEG;
250           if ((at = asn1_type_by_tag(tag)) != NULL)
251                     return at->encoding == ASN1_ENCODING_CONSTRUCTED_ONLY;
252 
253           return 0;
254 }
255 
256 int
asn1_must_be_primitive(int tag)257 asn1_must_be_primitive(int tag)
258 {
259           const struct asn1_type *at;
260 
261           if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
262                     tag &= ~V_ASN1_NEG;
263           if ((at = asn1_type_by_tag(tag)) != NULL)
264                     return at->encoding == ASN1_ENCODING_PRIMITIVE_ONLY;
265 
266           return 0;
267 }
268 
269 int
asn1_tag2charwidth(int tag)270 asn1_tag2charwidth(int tag)
271 {
272           const struct asn1_type *at;
273 
274           if ((at = asn1_type_by_tag(tag)) != NULL)
275                     return at->char_width;
276 
277           return -1;
278 }
279 
280 unsigned long
ASN1_tag2bit(int tag)281 ASN1_tag2bit(int tag)
282 {
283           const struct asn1_type *at;
284 
285           if ((at = asn1_type_by_tag(tag)) != NULL)
286                     return (unsigned long)at->bit_value;
287 
288           return 0;
289 }
290 
291 const char *
ASN1_tag2str(int tag)292 ASN1_tag2str(int tag)
293 {
294           const struct asn1_type *at;
295 
296           if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
297                     tag &= ~V_ASN1_NEG;
298 
299           if ((at = asn1_type_by_tag(tag)) != NULL)
300                     return at->name;
301 
302           return "(unknown)";
303 }
304