summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2022-09-03 18:52:18 +0000
committerjsing <>2022-09-03 18:52:18 +0000
commit0cd135545398370513764fd74cd8a8871ef351cc (patch)
treec2f7e3d1627ccbe7aba894c618c04cb4d876e4dc
parent5bb948dd8541248e1d3ad5dc62cd87323e2df812 (diff)
downloadopenbsd-0cd135545398370513764fd74cd8a8871ef351cc.tar.gz
openbsd-0cd135545398370513764fd74cd8a8871ef351cc.tar.bz2
openbsd-0cd135545398370513764fd74cd8a8871ef351cc.zip
Ensure ASN.1 types are appropriately encoded.
Per X.690, some ASN.1 types must be primitive encoded, some must be constructed and some may be either. Add this data to our types table and check the encoding against this information when decoding. ok tb@
-rw-r--r--src/lib/libcrypto/asn1/asn1_locl.h6
-rw-r--r--src/lib/libcrypto/asn1/asn1_types.c42
-rw-r--r--src/lib/libcrypto/asn1/tasn_dec.c11
3 files changed, 52 insertions, 7 deletions
diff --git a/src/lib/libcrypto/asn1/asn1_locl.h b/src/lib/libcrypto/asn1/asn1_locl.h
index e2c57fd8c4..1eb7ee402e 100644
--- a/src/lib/libcrypto/asn1/asn1_locl.h
+++ b/src/lib/libcrypto/asn1/asn1_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: asn1_locl.h,v 1.36 2022/09/03 18:45:51 jsing Exp $ */ 1/* $OpenBSD: asn1_locl.h,v 1.37 2022/09/03 18:52:18 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006. 3 * project 2006.
4 */ 4 */
@@ -204,6 +204,8 @@ int asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_class,
204int asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number, 204int asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number,
205 CBS *out_content); 205 CBS *out_content);
206 206
207int asn1_must_be_constructed(int tag);
208int asn1_must_be_primitive(int tag);
207int asn1_tag2charwidth(int tag); 209int asn1_tag2charwidth(int tag);
208 210
209int asn1_abs_set_unused_bits(ASN1_BIT_STRING *abs, uint8_t unused_bits); 211int asn1_abs_set_unused_bits(ASN1_BIT_STRING *abs, uint8_t unused_bits);
@@ -211,6 +213,8 @@ int c2i_ASN1_BIT_STRING_cbs(ASN1_BIT_STRING **out_abs, CBS *cbs);
211 213
212int c2i_ASN1_ENUMERATED_cbs(ASN1_ENUMERATED **out_aenum, CBS *cbs); 214int c2i_ASN1_ENUMERATED_cbs(ASN1_ENUMERATED **out_aenum, CBS *cbs);
213 215
216int c2i_ASN1_ENUMERATED_cbs(ASN1_ENUMERATED **out_aenum, CBS *cbs);
217
214int asn1_aint_get_uint64(CBS *cbs, uint64_t *out_val); 218int asn1_aint_get_uint64(CBS *cbs, uint64_t *out_val);
215int asn1_aint_set_uint64(uint64_t val, uint8_t **out_data, int *out_len); 219int asn1_aint_set_uint64(uint64_t val, uint8_t **out_data, int *out_len);
216int asn1_aint_get_int64(CBS *cbs, int negative, int64_t *out_val); 220int asn1_aint_get_int64(CBS *cbs, int negative, int64_t *out_val);
diff --git a/src/lib/libcrypto/asn1/asn1_types.c b/src/lib/libcrypto/asn1/asn1_types.c
index c8e6b23f4f..d8b7c1e88e 100644
--- a/src/lib/libcrypto/asn1/asn1_types.c
+++ b/src/lib/libcrypto/asn1/asn1_types.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: asn1_types.c,v 1.1 2021/12/14 17:35:21 jsing Exp $ */ 1/* $OpenBSD: asn1_types.c,v 1.2 2022/09/03 18:52:18 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -19,10 +19,14 @@
19 19
20#include <openssl/asn1.h> 20#include <openssl/asn1.h>
21 21
22#define ASN1_ENCODING_CONSTRUCTED_ONLY 1
23#define ASN1_ENCODING_PRIMITIVE_ONLY 2
24
22struct asn1_type { 25struct asn1_type {
23 const char *name; 26 const char *name;
24 uint32_t bit_value; 27 uint32_t bit_value;
25 int char_width; 28 int char_width;
29 int encoding;
26}; 30};
27 31
28/* 32/*
@@ -40,12 +44,14 @@ static const struct asn1_type asn1_types[31] = {
40 .name = "BOOLEAN", 44 .name = "BOOLEAN",
41 .bit_value = 0, 45 .bit_value = 0,
42 .char_width = -1, 46 .char_width = -1,
47 .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
43 }, 48 },
44 [2] = { 49 [2] = {
45 /* Tag 2 (0x02) - Integer */ 50 /* Tag 2 (0x02) - Integer */
46 .name = "INTEGER", 51 .name = "INTEGER",
47 .bit_value = 0, 52 .bit_value = 0,
48 .char_width = -1, 53 .char_width = -1,
54 .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
49 }, 55 },
50 [3] = { 56 [3] = {
51 /* Tag 3 (0x03) - BitString */ 57 /* Tag 3 (0x03) - BitString */
@@ -64,12 +70,14 @@ static const struct asn1_type asn1_types[31] = {
64 .name = "NULL", 70 .name = "NULL",
65 .bit_value = 0, 71 .bit_value = 0,
66 .char_width = -1, 72 .char_width = -1,
73 .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
67 }, 74 },
68 [6] = { 75 [6] = {
69 /* Tag 6 (0x06) - Object Identifier */ 76 /* Tag 6 (0x06) - Object Identifier */
70 .name = "OBJECT", 77 .name = "OBJECT",
71 .bit_value = 0, 78 .bit_value = 0,
72 .char_width = -1, 79 .char_width = -1,
80 .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
73 }, 81 },
74 [7] = { 82 [7] = {
75 /* Tag 7 (0x07) - Object Descriptor */ 83 /* Tag 7 (0x07) - Object Descriptor */
@@ -88,12 +96,14 @@ static const struct asn1_type asn1_types[31] = {
88 .name = "REAL", 96 .name = "REAL",
89 .bit_value = B_ASN1_UNKNOWN, 97 .bit_value = B_ASN1_UNKNOWN,
90 .char_width = -1, 98 .char_width = -1,
99 .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
91 }, 100 },
92 [10] = { 101 [10] = {
93 /* Tag 10 (0x0a) - Enumerated */ 102 /* Tag 10 (0x0a) - Enumerated */
94 .name = "ENUMERATED", 103 .name = "ENUMERATED",
95 .bit_value = B_ASN1_UNKNOWN, 104 .bit_value = B_ASN1_UNKNOWN,
96 .char_width = -1, 105 .char_width = -1,
106 .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
97 }, 107 },
98 [11] = { 108 [11] = {
99 /* Tag 11 (0x0b) - Embedded PDV */ 109 /* Tag 11 (0x0b) - Embedded PDV */
@@ -112,12 +122,14 @@ static const struct asn1_type asn1_types[31] = {
112 .name = "<ASN1 13 RELATIVE OID>", 122 .name = "<ASN1 13 RELATIVE OID>",
113 .bit_value = B_ASN1_UNKNOWN, 123 .bit_value = B_ASN1_UNKNOWN,
114 .char_width = -1, 124 .char_width = -1,
125 .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
115 }, 126 },
116 [14] = { 127 [14] = {
117 /* Tag 14 (0x0e) - Time */ 128 /* Tag 14 (0x0e) - Time */
118 .name = "<ASN1 14 TIME>", 129 .name = "<ASN1 14 TIME>",
119 .bit_value = B_ASN1_UNKNOWN, 130 .bit_value = B_ASN1_UNKNOWN,
120 .char_width = -1, 131 .char_width = -1,
132 .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
121 }, 133 },
122 [15] = { 134 [15] = {
123 /* Tag 15 (0x0f) - Reserved */ 135 /* Tag 15 (0x0f) - Reserved */
@@ -130,12 +142,14 @@ static const struct asn1_type asn1_types[31] = {
130 .name = "SEQUENCE", 142 .name = "SEQUENCE",
131 .bit_value = B_ASN1_SEQUENCE, 143 .bit_value = B_ASN1_SEQUENCE,
132 .char_width = -1, 144 .char_width = -1,
145 .encoding = ASN1_ENCODING_CONSTRUCTED_ONLY,
133 }, 146 },
134 [17] = { 147 [17] = {
135 /* Tag 17 (0x11) - Set */ 148 /* Tag 17 (0x11) - Set */
136 .name = "SET", 149 .name = "SET",
137 .bit_value = 0, 150 .bit_value = 0,
138 .char_width = -1, 151 .char_width = -1,
152 .encoding = ASN1_ENCODING_CONSTRUCTED_ONLY,
139 }, 153 },
140 [18] = { 154 [18] = {
141 /* Tag 18 (0x12) - NumericString */ 155 /* Tag 18 (0x12) - NumericString */
@@ -227,6 +241,32 @@ asn1_type_by_tag(int tag)
227} 241}
228 242
229int 243int
244asn1_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
256int
257asn1_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
269int
230asn1_tag2charwidth(int tag) 270asn1_tag2charwidth(int tag)
231{ 271{
232 const struct asn1_type *at; 272 const struct asn1_type *at;
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c
index 22d8006d0a..457f526e71 100644
--- a/src/lib/libcrypto/asn1/tasn_dec.c
+++ b/src/lib/libcrypto/asn1/tasn_dec.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tasn_dec.c,v 1.79 2022/09/03 18:45:51 jsing Exp $ */ 1/* $OpenBSD: tasn_dec.c,v 1.80 2022/09/03 18:52:18 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -467,13 +467,14 @@ asn1_d2i_primitive_content(ASN1_VALUE **pval, CBS *cbs, CBS *cbs_object,
467 CBS_dup(cbs, &cbs_initial); 467 CBS_dup(cbs, &cbs_initial);
468 CBS_init(&cbs_content, NULL, 0); 468 CBS_init(&cbs_content, NULL, 0);
469 469
470 /* XXX - check primitive vs constructed based on utype. */ 470 if (asn1_must_be_constructed(utype) && !constructed) {
471
472 /* SEQUENCE and SET must be constructed. */
473 if ((utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET) && !constructed) {
474 ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED); 471 ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED);
475 goto err; 472 goto err;
476 } 473 }
474 if (asn1_must_be_primitive(utype) && constructed) {
475 ASN1error(ASN1_R_TYPE_NOT_PRIMITIVE);
476 goto err;
477 }
477 478
478 /* SEQUENCE, SET and "OTHER" are left in encoded form. */ 479 /* SEQUENCE, SET and "OTHER" are left in encoded form. */
479 if (utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET || 480 if (utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET ||