1 /* $OpenBSD: asn1_types.c,v 1.3 2023/07/05 21:23:36 beck 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 LCRYPTO_ALIAS(ASN1_tag2bit);
291
292 const char *
ASN1_tag2str(int tag)293 ASN1_tag2str(int tag)
294 {
295 const struct asn1_type *at;
296
297 if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
298 tag &= ~V_ASN1_NEG;
299
300 if ((at = asn1_type_by_tag(tag)) != NULL)
301 return at->name;
302
303 return "(unknown)";
304 }
305 LCRYPTO_ALIAS(ASN1_tag2str);
306