diff options
Diffstat (limited to 'src/regress')
-rw-r--r-- | src/regress/lib/libssl/Makefile | 3 | ||||
-rw-r--r-- | src/regress/lib/libssl/bytestring/Makefile | 14 | ||||
-rw-r--r-- | src/regress/lib/libssl/bytestring/bytestringtest.c | 655 |
3 files changed, 671 insertions, 1 deletions
diff --git a/src/regress/lib/libssl/Makefile b/src/regress/lib/libssl/Makefile index f13ebf0b47..4d64dc3966 100644 --- a/src/regress/lib/libssl/Makefile +++ b/src/regress/lib/libssl/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | # $OpenBSD: Makefile,v 1.20 2015/02/06 08:48:39 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.21 2015/02/06 09:36:16 doug Exp $ |
2 | 2 | ||
3 | SUBDIR= \ | 3 | SUBDIR= \ |
4 | asn1 \ | 4 | asn1 \ |
5 | bytestring \ | ||
5 | ciphers \ | 6 | ciphers \ |
6 | ssl | 7 | ssl |
7 | 8 | ||
diff --git a/src/regress/lib/libssl/bytestring/Makefile b/src/regress/lib/libssl/bytestring/Makefile new file mode 100644 index 0000000000..439bf1cf8d --- /dev/null +++ b/src/regress/lib/libssl/bytestring/Makefile | |||
@@ -0,0 +1,14 @@ | |||
1 | # $OpenBSD: Makefile,v 1.1 2015/02/06 09:36:16 doug Exp $ | ||
2 | |||
3 | PROG= bytestringtest | ||
4 | LDADD= -lcrypto -lssl | ||
5 | DPADD= ${LIBCRYPTO} ${LIBSSL} | ||
6 | WARNINGS= Yes | ||
7 | CFLAGS+= -DLIBRESSL_INTERNAL -Werror -I/usr/src/lib/libssl/src/ssl | ||
8 | |||
9 | REGRESS_TARGETS=regress-bytestringtest | ||
10 | |||
11 | regress-bytestringtest: ${PROG} | ||
12 | ./${PROG} | ||
13 | |||
14 | .include <bsd.regress.mk> | ||
diff --git a/src/regress/lib/libssl/bytestring/bytestringtest.c b/src/regress/lib/libssl/bytestring/bytestringtest.c new file mode 100644 index 0000000000..92e33c02e7 --- /dev/null +++ b/src/regress/lib/libssl/bytestring/bytestringtest.c | |||
@@ -0,0 +1,655 @@ | |||
1 | /* $OpenBSD: bytestringtest.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2014, Google Inc. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and/or 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 ANY | ||
12 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
14 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
15 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | #include <stdlib.h> | ||
19 | #include <string.h> | ||
20 | |||
21 | #include <openssl/crypto.h> | ||
22 | |||
23 | #include "bytestring.h" | ||
24 | |||
25 | /* This is from <openssl/base.h> in boringssl */ | ||
26 | #define OPENSSL_U64(x) x##ULL | ||
27 | |||
28 | static int test_skip(void) { | ||
29 | static const uint8_t kData[] = {1, 2, 3}; | ||
30 | CBS data; | ||
31 | |||
32 | CBS_init(&data, kData, sizeof(kData)); | ||
33 | return CBS_len(&data) == 3 && | ||
34 | CBS_skip(&data, 1) && | ||
35 | CBS_len(&data) == 2 && | ||
36 | CBS_skip(&data, 2) && | ||
37 | CBS_len(&data) == 0 && | ||
38 | !CBS_skip(&data, 1); | ||
39 | } | ||
40 | |||
41 | static int test_get_u(void) { | ||
42 | static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; | ||
43 | uint8_t u8; | ||
44 | uint16_t u16; | ||
45 | uint32_t u32; | ||
46 | CBS data; | ||
47 | |||
48 | CBS_init(&data, kData, sizeof(kData)); | ||
49 | return CBS_get_u8(&data, &u8) && | ||
50 | u8 == 1 && | ||
51 | CBS_get_u16(&data, &u16) && | ||
52 | u16 == 0x203 && | ||
53 | CBS_get_u24(&data, &u32) && | ||
54 | u32 == 0x40506 && | ||
55 | CBS_get_u32(&data, &u32) && | ||
56 | u32 == 0x708090a && | ||
57 | !CBS_get_u8(&data, &u8); | ||
58 | } | ||
59 | |||
60 | static int test_get_prefixed(void) { | ||
61 | static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1}; | ||
62 | uint8_t u8; | ||
63 | uint16_t u16; | ||
64 | uint32_t u32; | ||
65 | CBS data, prefixed; | ||
66 | |||
67 | CBS_init(&data, kData, sizeof(kData)); | ||
68 | return CBS_get_u8_length_prefixed(&data, &prefixed) && | ||
69 | CBS_len(&prefixed) == 1 && | ||
70 | CBS_get_u8(&prefixed, &u8) && | ||
71 | u8 == 2 && | ||
72 | CBS_get_u16_length_prefixed(&data, &prefixed) && | ||
73 | CBS_len(&prefixed) == 2 && | ||
74 | CBS_get_u16(&prefixed, &u16) && | ||
75 | u16 == 0x304 && | ||
76 | CBS_get_u24_length_prefixed(&data, &prefixed) && | ||
77 | CBS_len(&prefixed) == 3 && | ||
78 | CBS_get_u24(&prefixed, &u32) && | ||
79 | u32 == 0x30201; | ||
80 | } | ||
81 | |||
82 | static int test_get_prefixed_bad(void) { | ||
83 | static const uint8_t kData1[] = {2, 1}; | ||
84 | static const uint8_t kData2[] = {0, 2, 1}; | ||
85 | static const uint8_t kData3[] = {0, 0, 2, 1}; | ||
86 | CBS data, prefixed; | ||
87 | |||
88 | CBS_init(&data, kData1, sizeof(kData1)); | ||
89 | if (CBS_get_u8_length_prefixed(&data, &prefixed)) { | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | CBS_init(&data, kData2, sizeof(kData2)); | ||
94 | if (CBS_get_u16_length_prefixed(&data, &prefixed)) { | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | CBS_init(&data, kData3, sizeof(kData3)); | ||
99 | if (CBS_get_u24_length_prefixed(&data, &prefixed)) { | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | return 1; | ||
104 | } | ||
105 | |||
106 | static int test_get_asn1(void) { | ||
107 | static const uint8_t kData1[] = {0x30, 2, 1, 2}; | ||
108 | static const uint8_t kData2[] = {0x30, 3, 1, 2}; | ||
109 | static const uint8_t kData3[] = {0x30, 0x80}; | ||
110 | static const uint8_t kData4[] = {0x30, 0x81, 1, 1}; | ||
111 | static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1}; | ||
112 | static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1}; | ||
113 | static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1}; | ||
114 | static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1}; | ||
115 | static const uint8_t kData9[] = {0xa1, 3, 0x2, 1, 0xff}; | ||
116 | |||
117 | CBS data, contents; | ||
118 | int present; | ||
119 | uint64_t value; | ||
120 | |||
121 | CBS_init(&data, kData1, sizeof(kData1)); | ||
122 | if (CBS_peek_asn1_tag(&data, 0x1) || | ||
123 | !CBS_peek_asn1_tag(&data, 0x30)) { | ||
124 | return 0; | ||
125 | } | ||
126 | if (!CBS_get_asn1(&data, &contents, 0x30) || | ||
127 | CBS_len(&contents) != 2 || | ||
128 | memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) { | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | CBS_init(&data, kData2, sizeof(kData2)); | ||
133 | /* data is truncated */ | ||
134 | if (CBS_get_asn1(&data, &contents, 0x30)) { | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | CBS_init(&data, kData3, sizeof(kData3)); | ||
139 | /* zero byte length of length */ | ||
140 | if (CBS_get_asn1(&data, &contents, 0x30)) { | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | CBS_init(&data, kData4, sizeof(kData4)); | ||
145 | /* long form mistakenly used. */ | ||
146 | if (CBS_get_asn1(&data, &contents, 0x30)) { | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | CBS_init(&data, kData5, sizeof(kData5)); | ||
151 | /* length takes too many bytes. */ | ||
152 | if (CBS_get_asn1(&data, &contents, 0x30)) { | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | CBS_init(&data, kData1, sizeof(kData1)); | ||
157 | /* wrong tag. */ | ||
158 | if (CBS_get_asn1(&data, &contents, 0x31)) { | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | CBS_init(&data, NULL, 0); | ||
163 | /* peek at empty data. */ | ||
164 | if (CBS_peek_asn1_tag(&data, 0x30)) { | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | CBS_init(&data, NULL, 0); | ||
169 | /* optional elements at empty data. */ | ||
170 | if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) || | ||
171 | present || | ||
172 | !CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) || | ||
173 | present || | ||
174 | CBS_len(&contents) != 0 || | ||
175 | !CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0) || | ||
176 | CBS_len(&contents) != 0 || | ||
177 | !CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) || | ||
178 | value != 42) { | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | CBS_init(&data, kData6, sizeof(kData6)); | ||
183 | /* optional element. */ | ||
184 | if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) || | ||
185 | present || | ||
186 | !CBS_get_optional_asn1(&data, &contents, &present, 0xa1) || | ||
187 | !present || | ||
188 | CBS_len(&contents) != 3 || | ||
189 | memcmp(CBS_data(&contents), "\x04\x01\x01", 3) != 0) { | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | CBS_init(&data, kData6, sizeof(kData6)); | ||
194 | /* optional octet string. */ | ||
195 | if (!CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) || | ||
196 | present || | ||
197 | CBS_len(&contents) != 0 || | ||
198 | !CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1) || | ||
199 | !present || | ||
200 | CBS_len(&contents) != 1 || | ||
201 | CBS_data(&contents)[0] != 1) { | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | CBS_init(&data, kData7, sizeof(kData7)); | ||
206 | /* invalid optional octet string. */ | ||
207 | if (CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1)) { | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | CBS_init(&data, kData8, sizeof(kData8)); | ||
212 | /* optional octet string. */ | ||
213 | if (!CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) || | ||
214 | value != 42 || | ||
215 | !CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42) || | ||
216 | value != 1) { | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | CBS_init(&data, kData9, sizeof(kData9)); | ||
221 | /* invalid optional integer. */ | ||
222 | if (CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)) { | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | return 1; | ||
227 | } | ||
228 | |||
229 | static int test_get_optional_asn1_bool(void) { | ||
230 | CBS data; | ||
231 | int val; | ||
232 | |||
233 | static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff}; | ||
234 | static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00}; | ||
235 | static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01}; | ||
236 | |||
237 | CBS_init(&data, NULL, 0); | ||
238 | val = 2; | ||
239 | if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) || | ||
240 | val != 0) { | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | CBS_init(&data, kTrue, sizeof(kTrue)); | ||
245 | val = 2; | ||
246 | if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) || | ||
247 | val != 1) { | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | CBS_init(&data, kFalse, sizeof(kFalse)); | ||
252 | val = 2; | ||
253 | if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1) || | ||
254 | val != 0) { | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | CBS_init(&data, kInvalid, sizeof(kInvalid)); | ||
259 | if (CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)) { | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | return 1; | ||
264 | } | ||
265 | |||
266 | static int test_cbb_basic(void) { | ||
267 | static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8}; | ||
268 | uint8_t *buf; | ||
269 | size_t buf_len; | ||
270 | int ok; | ||
271 | CBB cbb; | ||
272 | |||
273 | if (!CBB_init(&cbb, 100)) { | ||
274 | return 0; | ||
275 | } | ||
276 | CBB_cleanup(&cbb); | ||
277 | |||
278 | if (!CBB_init(&cbb, 0) || | ||
279 | !CBB_add_u8(&cbb, 1) || | ||
280 | !CBB_add_u16(&cbb, 0x203) || | ||
281 | !CBB_add_u24(&cbb, 0x40506) || | ||
282 | !CBB_add_bytes(&cbb, (const uint8_t*) "\x07\x08", 2) || | ||
283 | !CBB_finish(&cbb, &buf, &buf_len)) { | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0; | ||
288 | free(buf); | ||
289 | return ok; | ||
290 | } | ||
291 | |||
292 | static int test_cbb_fixed(void) { | ||
293 | CBB cbb; | ||
294 | uint8_t buf[1]; | ||
295 | uint8_t *out_buf; | ||
296 | size_t out_size; | ||
297 | |||
298 | if (!CBB_init_fixed(&cbb, NULL, 0) || | ||
299 | CBB_add_u8(&cbb, 1) || | ||
300 | !CBB_finish(&cbb, &out_buf, &out_size) || | ||
301 | out_buf != NULL || | ||
302 | out_size != 0) { | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | if (!CBB_init_fixed(&cbb, buf, 1) || | ||
307 | !CBB_add_u8(&cbb, 1) || | ||
308 | CBB_add_u8(&cbb, 2) || | ||
309 | !CBB_finish(&cbb, &out_buf, &out_size) || | ||
310 | out_buf != buf || | ||
311 | out_size != 1 || | ||
312 | buf[0] != 1) { | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | static int test_cbb_finish_child(void) { | ||
320 | CBB cbb, child; | ||
321 | uint8_t *out_buf; | ||
322 | size_t out_size; | ||
323 | |||
324 | if (!CBB_init(&cbb, 16) || | ||
325 | !CBB_add_u8_length_prefixed(&cbb, &child) || | ||
326 | CBB_finish(&child, &out_buf, &out_size) || | ||
327 | !CBB_finish(&cbb, &out_buf, &out_size) || | ||
328 | out_size != 1 || | ||
329 | out_buf[0] != 0) { | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | free(out_buf); | ||
334 | return 1; | ||
335 | } | ||
336 | |||
337 | static int test_cbb_prefixed(void) { | ||
338 | static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3, | ||
339 | 4, 5, 6, 5, 4, 1, 0, 1, 2}; | ||
340 | uint8_t *buf; | ||
341 | size_t buf_len; | ||
342 | CBB cbb, contents, inner_contents, inner_inner_contents; | ||
343 | int ok; | ||
344 | |||
345 | if (!CBB_init(&cbb, 0) || | ||
346 | !CBB_add_u8_length_prefixed(&cbb, &contents) || | ||
347 | !CBB_add_u8_length_prefixed(&cbb, &contents) || | ||
348 | !CBB_add_u8(&contents, 1) || | ||
349 | !CBB_add_u16_length_prefixed(&cbb, &contents) || | ||
350 | !CBB_add_u16(&contents, 0x203) || | ||
351 | !CBB_add_u24_length_prefixed(&cbb, &contents) || | ||
352 | !CBB_add_u24(&contents, 0x40506) || | ||
353 | !CBB_add_u8_length_prefixed(&cbb, &contents) || | ||
354 | !CBB_add_u8_length_prefixed(&contents, &inner_contents) || | ||
355 | !CBB_add_u8(&inner_contents, 1) || | ||
356 | !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) || | ||
357 | !CBB_add_u8(&inner_inner_contents, 2) || | ||
358 | !CBB_finish(&cbb, &buf, &buf_len)) { | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0; | ||
363 | free(buf); | ||
364 | return ok; | ||
365 | } | ||
366 | |||
367 | static int test_cbb_misuse(void) { | ||
368 | CBB cbb, child, contents; | ||
369 | uint8_t *buf; | ||
370 | size_t buf_len; | ||
371 | |||
372 | if (!CBB_init(&cbb, 0) || | ||
373 | !CBB_add_u8_length_prefixed(&cbb, &child) || | ||
374 | !CBB_add_u8(&child, 1) || | ||
375 | !CBB_add_u8(&cbb, 2)) { | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | /* Since we wrote to |cbb|, |child| is now invalid and attempts to write to | ||
380 | * it should fail. */ | ||
381 | if (CBB_add_u8(&child, 1) || | ||
382 | CBB_add_u16(&child, 1) || | ||
383 | CBB_add_u24(&child, 1) || | ||
384 | CBB_add_u8_length_prefixed(&child, &contents) || | ||
385 | CBB_add_u16_length_prefixed(&child, &contents) || | ||
386 | CBB_add_asn1(&child, &contents, 1) || | ||
387 | CBB_add_bytes(&child, (const uint8_t*) "a", 1)) { | ||
388 | fprintf(stderr, "CBB operation on invalid CBB did not fail.\n"); | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | if (!CBB_finish(&cbb, &buf, &buf_len) || | ||
393 | buf_len != 3 || | ||
394 | memcmp(buf, "\x01\x01\x02", 3) != 0) { | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | free(buf); | ||
399 | |||
400 | return 1; | ||
401 | } | ||
402 | |||
403 | static int test_cbb_asn1(void) { | ||
404 | static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3}; | ||
405 | uint8_t *buf, *test_data; | ||
406 | size_t buf_len; | ||
407 | CBB cbb, contents, inner_contents; | ||
408 | |||
409 | if (!CBB_init(&cbb, 0) || | ||
410 | !CBB_add_asn1(&cbb, &contents, 0x30) || | ||
411 | !CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) || | ||
412 | !CBB_finish(&cbb, &buf, &buf_len)) { | ||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) { | ||
417 | return 0; | ||
418 | } | ||
419 | free(buf); | ||
420 | |||
421 | test_data = malloc(100000); | ||
422 | memset(test_data, 0x42, 100000); | ||
423 | |||
424 | if (!CBB_init(&cbb, 0) || | ||
425 | !CBB_add_asn1(&cbb, &contents, 0x30) || | ||
426 | !CBB_add_bytes(&contents, test_data, 130) || | ||
427 | !CBB_finish(&cbb, &buf, &buf_len)) { | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | if (buf_len != 3 + 130 || | ||
432 | memcmp(buf, "\x30\x81\x82", 3) != 0 || | ||
433 | memcmp(buf + 3, test_data, 130) != 0) { | ||
434 | return 0; | ||
435 | } | ||
436 | free(buf); | ||
437 | |||
438 | if (!CBB_init(&cbb, 0) || | ||
439 | !CBB_add_asn1(&cbb, &contents, 0x30) || | ||
440 | !CBB_add_bytes(&contents, test_data, 1000) || | ||
441 | !CBB_finish(&cbb, &buf, &buf_len)) { | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | if (buf_len != 4 + 1000 || | ||
446 | memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 || | ||
447 | memcmp(buf + 4, test_data, 1000)) { | ||
448 | return 0; | ||
449 | } | ||
450 | free(buf); | ||
451 | |||
452 | if (!CBB_init(&cbb, 0) || | ||
453 | !CBB_add_asn1(&cbb, &contents, 0x30) || | ||
454 | !CBB_add_asn1(&contents, &inner_contents, 0x30) || | ||
455 | !CBB_add_bytes(&inner_contents, test_data, 100000) || | ||
456 | !CBB_finish(&cbb, &buf, &buf_len)) { | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | if (buf_len != 5 + 5 + 100000 || | ||
461 | memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 || | ||
462 | memcmp(buf + 10, test_data, 100000)) { | ||
463 | return 0; | ||
464 | } | ||
465 | free(buf); | ||
466 | |||
467 | free(test_data); | ||
468 | return 1; | ||
469 | } | ||
470 | |||
471 | static int do_ber_convert(const char *name, | ||
472 | const uint8_t *der_expected, size_t der_len, | ||
473 | const uint8_t *ber, size_t ber_len) { | ||
474 | CBS in; | ||
475 | uint8_t *out; | ||
476 | size_t out_len; | ||
477 | |||
478 | CBS_init(&in, ber, ber_len); | ||
479 | if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) { | ||
480 | fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name); | ||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | if (out == NULL) { | ||
485 | if (ber_len != der_len || | ||
486 | memcmp(der_expected, ber, ber_len) != 0) { | ||
487 | fprintf(stderr, "%s: incorrect unconverted result.\n", name); | ||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | return 1; | ||
492 | } | ||
493 | |||
494 | if (out_len != der_len || | ||
495 | memcmp(out, der_expected, der_len) != 0) { | ||
496 | fprintf(stderr, "%s: incorrect converted result.\n", name); | ||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | free(out); | ||
501 | return 1; | ||
502 | } | ||
503 | |||
504 | static int test_ber_convert(void) { | ||
505 | static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; | ||
506 | |||
507 | /* kIndefBER contains a SEQUENCE with an indefinite length. */ | ||
508 | static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00}; | ||
509 | static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02}; | ||
510 | |||
511 | /* kOctetStringBER contains an indefinite length OCTETSTRING with two parts. | ||
512 | * These parts need to be concatenated in DER form. */ | ||
513 | static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1, | ||
514 | 0x04, 0x02, 2, 3, 0x00, 0x00}; | ||
515 | static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3}; | ||
516 | |||
517 | /* kNSSBER is part of a PKCS#12 message generated by NSS that uses indefinite | ||
518 | * length elements extensively. */ | ||
519 | static const uint8_t kNSSBER[] = { | ||
520 | 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, | ||
521 | 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x04, | ||
522 | 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, | ||
523 | 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, | ||
524 | 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, | ||
525 | 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, | ||
526 | 0x10, 0x38, 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, | ||
527 | 0xf0, 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00, | ||
528 | }; | ||
529 | |||
530 | static const uint8_t kNSSDER[] = { | ||
531 | 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86, | ||
532 | 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04, | ||
533 | 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, | ||
534 | 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, | ||
535 | 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, | ||
536 | 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, | ||
537 | 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, | ||
538 | 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, | ||
539 | }; | ||
540 | |||
541 | return do_ber_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), | ||
542 | kSimpleBER, sizeof(kSimpleBER)) && | ||
543 | do_ber_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER, | ||
544 | sizeof(kIndefBER)) && | ||
545 | do_ber_convert("kOctetStringBER", kOctetStringDER, | ||
546 | sizeof(kOctetStringDER), kOctetStringBER, | ||
547 | sizeof(kOctetStringBER)) && | ||
548 | do_ber_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, | ||
549 | sizeof(kNSSBER)); | ||
550 | } | ||
551 | |||
552 | typedef struct { | ||
553 | uint64_t value; | ||
554 | const char *encoding; | ||
555 | size_t encoding_len; | ||
556 | } ASN1_UINT64_TEST; | ||
557 | |||
558 | static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = { | ||
559 | {0, "\x02\x01\x00", 3}, | ||
560 | {1, "\x02\x01\x01", 3}, | ||
561 | {127, "\x02\x01\x7f", 3}, | ||
562 | {128, "\x02\x02\x00\x80", 4}, | ||
563 | {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7}, | ||
564 | {OPENSSL_U64(0x0102030405060708), | ||
565 | "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10}, | ||
566 | {OPENSSL_U64(0xffffffffffffffff), | ||
567 | "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11}, | ||
568 | }; | ||
569 | |||
570 | typedef struct { | ||
571 | const char *encoding; | ||
572 | size_t encoding_len; | ||
573 | } ASN1_INVALID_UINT64_TEST; | ||
574 | |||
575 | static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = { | ||
576 | /* Bad tag. */ | ||
577 | {"\x03\x01\x00", 3}, | ||
578 | /* Empty contents. */ | ||
579 | {"\x02\x00", 2}, | ||
580 | /* Negative number. */ | ||
581 | {"\x02\x01\x80", 3}, | ||
582 | /* Overflow */ | ||
583 | {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11}, | ||
584 | }; | ||
585 | |||
586 | static int test_asn1_uint64(void) { | ||
587 | size_t i; | ||
588 | |||
589 | for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]); i++) { | ||
590 | const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i]; | ||
591 | CBS cbs; | ||
592 | uint64_t value; | ||
593 | CBB cbb; | ||
594 | uint8_t *out; | ||
595 | size_t len; | ||
596 | |||
597 | CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len); | ||
598 | if (!CBS_get_asn1_uint64(&cbs, &value) || | ||
599 | CBS_len(&cbs) != 0 || | ||
600 | value != test->value) { | ||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | if (!CBB_init(&cbb, 0)) { | ||
605 | return 0; | ||
606 | } | ||
607 | if (!CBB_add_asn1_uint64(&cbb, test->value) || | ||
608 | !CBB_finish(&cbb, &out, &len)) { | ||
609 | CBB_cleanup(&cbb); | ||
610 | return 0; | ||
611 | } | ||
612 | if (len != test->encoding_len || memcmp(out, test->encoding, len) != 0) { | ||
613 | free(out); | ||
614 | return 0; | ||
615 | } | ||
616 | free(out); | ||
617 | } | ||
618 | |||
619 | for (i = 0; | ||
620 | i < sizeof(kAsn1InvalidUint64Tests) / sizeof(kAsn1InvalidUint64Tests[0]); | ||
621 | i++) { | ||
622 | const ASN1_INVALID_UINT64_TEST *test = &kAsn1InvalidUint64Tests[i]; | ||
623 | CBS cbs; | ||
624 | uint64_t value; | ||
625 | |||
626 | CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len); | ||
627 | if (CBS_get_asn1_uint64(&cbs, &value)) { | ||
628 | return 0; | ||
629 | } | ||
630 | } | ||
631 | |||
632 | return 1; | ||
633 | } | ||
634 | |||
635 | int main(void) { | ||
636 | if (!test_skip() || | ||
637 | !test_get_u() || | ||
638 | !test_get_prefixed() || | ||
639 | !test_get_prefixed_bad() || | ||
640 | !test_get_asn1() || | ||
641 | !test_cbb_basic() || | ||
642 | !test_cbb_fixed() || | ||
643 | !test_cbb_finish_child() || | ||
644 | !test_cbb_misuse() || | ||
645 | !test_cbb_prefixed() || | ||
646 | !test_cbb_asn1() || | ||
647 | !test_ber_convert() || | ||
648 | !test_asn1_uint64() || | ||
649 | !test_get_optional_asn1_bool()) { | ||
650 | return 1; | ||
651 | } | ||
652 | |||
653 | printf("PASS\n"); | ||
654 | return 0; | ||
655 | } | ||