summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2021-12-09 16:30:57 +0000
committerjsing <>2021-12-09 16:30:57 +0000
commit46edbde341caa08ff7f9e3650eb3d68366fc7f4f (patch)
tree68886d91b7f9556ff76405fde641c83a6b483a7e /src
parent1d0a3160a32be269bed995b2f6e28d49333a4e1d (diff)
downloadopenbsd-46edbde341caa08ff7f9e3650eb3d68366fc7f4f.tar.gz
openbsd-46edbde341caa08ff7f9e3650eb3d68366fc7f4f.tar.bz2
openbsd-46edbde341caa08ff7f9e3650eb3d68366fc7f4f.zip
Add initial tests for coverage of ASN.1 complex/constructed types.
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/asn1/Makefile3
-rw-r--r--src/regress/lib/libcrypto/asn1/asn1complex.c226
2 files changed, 228 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/asn1/Makefile b/src/regress/lib/libcrypto/asn1/Makefile
index 046d85bc81..1c4a42b80b 100644
--- a/src/regress/lib/libcrypto/asn1/Makefile
+++ b/src/regress/lib/libcrypto/asn1/Makefile
@@ -1,7 +1,8 @@
1# $OpenBSD: Makefile,v 1.8 2021/12/09 16:30:05 jsing Exp $ 1# $OpenBSD: Makefile,v 1.9 2021/12/09 16:30:57 jsing Exp $
2 2
3TESTS = \ 3TESTS = \
4 asn1basic \ 4 asn1basic \
5 asn1complex \
5 asn1evp \ 6 asn1evp \
6 asn1string_copy \ 7 asn1string_copy \
7 asn1time \ 8 asn1time \
diff --git a/src/regress/lib/libcrypto/asn1/asn1complex.c b/src/regress/lib/libcrypto/asn1/asn1complex.c
new file mode 100644
index 0000000000..eaabd9e8c3
--- /dev/null
+++ b/src/regress/lib/libcrypto/asn1/asn1complex.c
@@ -0,0 +1,226 @@
1/* $OpenBSD: asn1complex.c,v 1.1 2021/12/09 16:30:57 jsing Exp $ */
2/*
3 * Copyright (c) 2017, 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 <openssl/asn1.h>
19#include <openssl/err.h>
20
21#include <err.h>
22#include <stdio.h>
23#include <string.h>
24
25static void
26hexdump(const unsigned char *buf, size_t len)
27{
28 size_t i;
29
30 for (i = 1; i <= len; i++)
31 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
32
33 fprintf(stderr, "\n");
34}
35
36static int
37asn1_compare_bytes(const char *label, const unsigned char *d1, int len1,
38 const unsigned char *d2, int len2)
39{
40 if (len1 != len2) {
41 fprintf(stderr, "FAIL: %s - byte lengths differ "
42 "(%i != %i)\n", label, len1, len2);
43 return 0;
44 }
45 if (memcmp(d1, d2, len1) != 0) {
46 fprintf(stderr, "FAIL: %s - bytes differ\n", label);
47 fprintf(stderr, "Got:\n");
48 hexdump(d1, len1);
49 fprintf(stderr, "Want:\n");
50 hexdump(d2, len2);
51 return 0;
52 }
53 return 1;
54}
55
56/* Constructed octet string with length 12. */
57const uint8_t asn1_constructed_basic_ber[] = {
58 0x24, 0x0c,
59 0x04, 0x01, 0x01,
60 0x04, 0x02, 0x01, 0x02,
61 0x04, 0x03, 0x01, 0x02, 0x03
62};
63const uint8_t asn1_constructed_basic_content[] = {
64 0x01, 0x01, 0x02, 0x01, 0x02, 0x03,
65};
66
67/* Nested constructed octet string. */
68const uint8_t asn1_constructed_nested_ber[] = {
69 0x24, 0x1a,
70 0x04, 0x01, 0x01,
71 0x24, 0x15,
72 0x04, 0x02, 0x02, 0x03,
73 0x24, 0x0f,
74 0x24, 0x0d,
75 0x04, 0x03, 0x04, 0x05, 0x06,
76 0x24, 0x06,
77 0x24, 0x04,
78 0x04, 0x02, 0x07, 0x08,
79};
80const uint8_t asn1_constructed_nested_content[] = {
81 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
82};
83
84/* Deeply nested constructed octet string. */
85const uint8_t asn1_constructed_deep_nested_ber[] = {
86 0x24, 0x1b,
87 0x04, 0x01, 0x01,
88 0x24, 0x16,
89 0x04, 0x02, 0x02, 0x03,
90 0x24, 0x10,
91 0x24, 0x0e,
92 0x04, 0x03, 0x04, 0x05, 0x06,
93 0x24, 0x07,
94 0x24, 0x05,
95 0x24, 0x03,
96 0x04, 0x01, 0x07,
97};
98
99/* Constructed octet string with indefinite length. */
100const uint8_t asn1_constructed_indefinite_ber[] = {
101 0x24, 0x80,
102 0x04, 0x01, 0x01,
103 0x04, 0x02, 0x01, 0x02,
104 0x04, 0x03, 0x01, 0x02, 0x03,
105 0x00, 0x00,
106};
107const uint8_t asn1_constructed_indefinite_content[] = {
108 0x01, 0x01, 0x02, 0x01, 0x02, 0x03,
109};
110
111struct asn1_constructed_test {
112 const char *name;
113 const uint8_t *asn1;
114 size_t asn1_len;
115 const uint8_t *want;
116 size_t want_len;
117 int want_error;
118 int valid;
119};
120
121const struct asn1_constructed_test asn1_constructed_tests[] = {
122 {
123 .name = "basic constructed",
124 .asn1 = asn1_constructed_basic_ber,
125 .asn1_len = sizeof(asn1_constructed_basic_ber),
126 .want = asn1_constructed_basic_content,
127 .want_len = sizeof(asn1_constructed_basic_content),
128 .valid = 1,
129 },
130 {
131 .name = "nested constructed",
132 .asn1 = asn1_constructed_nested_ber,
133 .asn1_len = sizeof(asn1_constructed_nested_ber),
134 .want = asn1_constructed_nested_content,
135 .want_len = sizeof(asn1_constructed_nested_content),
136 .valid = 1,
137 },
138 {
139 .name = "deep nested constructed",
140 .asn1 = asn1_constructed_deep_nested_ber,
141 .asn1_len = sizeof(asn1_constructed_deep_nested_ber),
142 .want_error = ASN1_R_NESTED_ASN1_STRING,
143 .valid = 0,
144 },
145 {
146 .name = "indefinite length constructed",
147 .asn1 = asn1_constructed_indefinite_ber,
148 .asn1_len = sizeof(asn1_constructed_indefinite_ber),
149 .want = asn1_constructed_indefinite_content,
150 .want_len = sizeof(asn1_constructed_indefinite_content),
151 .valid = 1,
152 },
153};
154
155#define N_CONSTRUCTED_TESTS \
156 (sizeof(asn1_constructed_tests) / sizeof(*asn1_constructed_tests))
157
158static int
159do_asn1_constructed_test(const struct asn1_constructed_test *act)
160{
161 ASN1_OCTET_STRING *aos = NULL;
162 const uint8_t *p;
163 long err;
164 int failed = 1;
165
166 p = act->asn1;
167 aos = d2i_ASN1_OCTET_STRING(NULL, &p, act->asn1_len);
168 if (!act->valid) {
169 if (aos != NULL) {
170 fprintf(stderr, "FAIL: invalid ASN.1 decoded\n");
171 goto failed;
172 }
173 if (act->want_error != 0) {
174 err = ERR_peek_error();
175 if (ERR_GET_REASON(err) != act->want_error) {
176 fprintf(stderr, "FAIL: got error reason %d,"
177 "want %d", ERR_GET_REASON(err),
178 act->want_error);
179 goto failed;
180 }
181 }
182 goto done;
183 }
184 if (aos == NULL) {
185 fprintf(stderr, "FAIL: failed to decode ASN.1 constructed "
186 "octet string\n");
187 ERR_print_errors_fp(stderr);
188 goto failed;
189 }
190 if (!asn1_compare_bytes(act->name, ASN1_STRING_data(aos),
191 ASN1_STRING_length(aos), act->want, act->want_len))
192 goto failed;
193
194 done:
195 failed = 0;
196
197 failed:
198 ASN1_OCTET_STRING_free(aos);
199
200 return failed;
201}
202
203static int
204do_asn1_constructed_tests(void)
205{
206 const struct asn1_constructed_test *act;
207 int failed = 0;
208 size_t i;
209
210 for (i = 0; i < N_CONSTRUCTED_TESTS; i++) {
211 act = &asn1_constructed_tests[i];
212 failed |= do_asn1_constructed_test(act);
213 }
214
215 return failed;
216}
217
218int
219main(int argc, char **argv)
220{
221 int failed = 0;
222
223 failed |= do_asn1_constructed_tests();
224
225 return (failed);
226}