1 /* $OpenBSD: bytestringtest.c,v 1.17 2023/01/01 17:43:04 miod 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 #define PRINT_ERROR printf("Error in %s [%s:%d]\n", __func__, __FILE__, \
29 __LINE__)
30
31 #define CHECK(a) do { \
32 if (!(a)) { \
33 PRINT_ERROR; \
34 return 0; \
35 } \
36 } while (0)
37
38 #define CHECK_GOTO(a) do { \
39 if (!(a)) { \
40 PRINT_ERROR; \
41 goto err; \
42 } \
43 } while (0)
44
45 static int
test_skip(void)46 test_skip(void)
47 {
48 static const uint8_t kData[] = {1, 2, 3};
49 CBS data;
50
51 CBS_init(&data, kData, sizeof(kData));
52
53 CHECK(CBS_len(&data) == 3);
54 CHECK(CBS_skip(&data, 1));
55 CHECK(CBS_len(&data) == 2);
56 CHECK(CBS_skip(&data, 2));
57 CHECK(CBS_len(&data) == 0);
58 CHECK(!CBS_skip(&data, 1));
59
60 return 1;
61 }
62
63 static int
test_get_u(void)64 test_get_u(void)
65 {
66 static const uint8_t kData[] = {
67 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
68 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
69 };
70 uint8_t u8;
71 uint16_t u16;
72 uint32_t u32;
73 uint64_t u64;
74 CBS data;
75
76 CBS_init(&data, kData, sizeof(kData));
77
78 CHECK(CBS_get_u8(&data, &u8));
79 CHECK(u8 == 1);
80 CHECK(CBS_get_u16(&data, &u16));
81 CHECK(u16 == 0x203);
82 CHECK(CBS_get_u24(&data, &u32));
83 CHECK(u32 == 0x40506);
84 CHECK(CBS_get_u32(&data, &u32));
85 CHECK(u32 == 0x708090a);
86 CHECK(CBS_get_u64(&data, &u64));
87 CHECK(u64 == 0x0b0c0d0e0f101112ULL);
88 CHECK(CBS_get_last_u8(&data, &u8));
89 CHECK(u8 == 20);
90 CHECK(CBS_get_last_u8(&data, &u8));
91 CHECK(u8 == 19);
92 CHECK(!CBS_get_u8(&data, &u8));
93 CHECK(!CBS_get_last_u8(&data, &u8));
94
95 return 1;
96 }
97
98 static int
test_get_prefixed(void)99 test_get_prefixed(void)
100 {
101 static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
102 uint8_t u8;
103 uint16_t u16;
104 uint32_t u32;
105 CBS data, prefixed;
106
107 CBS_init(&data, kData, sizeof(kData));
108
109 CHECK(CBS_get_u8_length_prefixed(&data, &prefixed));
110 CHECK(CBS_len(&prefixed) == 1);
111 CHECK(CBS_get_u8(&prefixed, &u8));
112 CHECK(u8 == 2);
113 CHECK(CBS_get_u16_length_prefixed(&data, &prefixed));
114 CHECK(CBS_len(&prefixed) == 2);
115 CHECK(CBS_get_u16(&prefixed, &u16));
116 CHECK(u16 == 0x304);
117 CHECK(CBS_get_u24_length_prefixed(&data, &prefixed));
118 CHECK(CBS_len(&prefixed) == 3);
119 CHECK(CBS_get_u24(&prefixed, &u32));
120 CHECK(u32 == 0x30201);
121
122 return 1;
123 }
124
125 static int
test_get_prefixed_bad(void)126 test_get_prefixed_bad(void)
127 {
128 static const uint8_t kData1[] = {2, 1};
129 static const uint8_t kData2[] = {0, 2, 1};
130 static const uint8_t kData3[] = {0, 0, 2, 1};
131 CBS data, prefixed;
132
133 CBS_init(&data, kData1, sizeof(kData1));
134 CHECK(!CBS_get_u8_length_prefixed(&data, &prefixed));
135
136 CBS_init(&data, kData2, sizeof(kData2));
137 CHECK(!CBS_get_u16_length_prefixed(&data, &prefixed));
138
139 CBS_init(&data, kData3, sizeof(kData3));
140 CHECK(!CBS_get_u24_length_prefixed(&data, &prefixed));
141
142 return 1;
143 }
144
145 static int
test_peek_u(void)146 test_peek_u(void)
147 {
148 static const uint8_t kData[] = {
149 1, 2, 3, 4, 5, 6, 7, 8, 9,
150 };
151 uint8_t u8;
152 uint16_t u16;
153 uint32_t u32;
154 CBS data;
155
156 CBS_init(&data, kData, sizeof(kData));
157
158 CHECK(CBS_peek_u8(&data, &u8));
159 CHECK(u8 == 1);
160 CHECK(CBS_peek_u16(&data, &u16));
161 CHECK(u16 == 0x102);
162 CHECK(CBS_peek_u24(&data, &u32));
163 CHECK(u32 == 0x10203);
164 CHECK(CBS_peek_u32(&data, &u32));
165 CHECK(u32 == 0x1020304);
166 CHECK(CBS_get_u32(&data, &u32));
167 CHECK(u32 == 0x1020304);
168 CHECK(CBS_peek_last_u8(&data, &u8));
169 CHECK(u8 == 9);
170 CHECK(CBS_peek_u32(&data, &u32));
171 CHECK(u32 == 0x5060708);
172 CHECK(CBS_get_u32(&data, &u32));
173 CHECK(u32 == 0x5060708);
174 CHECK(CBS_get_u8(&data, &u8));
175 CHECK(u8 == 9);
176 CHECK(!CBS_get_u8(&data, &u8));
177
178 return 1;
179 }
180
181 static int
test_get_asn1(void)182 test_get_asn1(void)
183 {
184 static const uint8_t kData1[] = {0x30, 2, 1, 2};
185 static const uint8_t kData2[] = {0x30, 3, 1, 2};
186 static const uint8_t kData3[] = {0x30, 0x80};
187 static const uint8_t kData4[] = {0x30, 0x81, 1, 1};
188 static const uint8_t kData5[4 + 0x80] = {0x30, 0x82, 0, 0x80};
189 static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1};
190 static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1};
191 static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1};
192 static const uint8_t kData9[] = {0xa1, 3, 0x2, 1, 0xff};
193
194 CBS data, contents;
195 int present;
196 uint64_t value;
197
198 CBS_init(&data, kData1, sizeof(kData1));
199
200 CHECK(!CBS_peek_asn1_tag(&data, 0x1));
201 CHECK(CBS_peek_asn1_tag(&data, 0x30));
202
203 CHECK(CBS_get_asn1(&data, &contents, 0x30));
204 CHECK(CBS_len(&contents) == 2);
205 CHECK(memcmp(CBS_data(&contents), "\x01\x02", 2) == 0);
206
207 CBS_init(&data, kData2, sizeof(kData2));
208 /* data is truncated */
209 CHECK(!CBS_get_asn1(&data, &contents, 0x30));
210
211 CBS_init(&data, kData3, sizeof(kData3));
212 /* zero byte length of length */
213 CHECK(!CBS_get_asn1(&data, &contents, 0x30));
214
215 CBS_init(&data, kData4, sizeof(kData4));
216 /* long form mistakenly used. */
217 CHECK(!CBS_get_asn1(&data, &contents, 0x30));
218
219 CBS_init(&data, kData5, sizeof(kData5));
220 /* length takes too many bytes. */
221 CHECK(!CBS_get_asn1(&data, &contents, 0x30));
222
223 CBS_init(&data, kData1, sizeof(kData1));
224 /* wrong tag. */
225 CHECK(!CBS_get_asn1(&data, &contents, 0x31));
226
227 CBS_init(&data, NULL, 0);
228 /* peek at empty data. */
229 CHECK(!CBS_peek_asn1_tag(&data, 0x30));
230
231 CBS_init(&data, NULL, 0);
232 /* optional elements at empty data. */
233 CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa0));
234 CHECK(!present);
235 CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present,
236 0xa0));
237 CHECK(!present);
238 CHECK(CBS_len(&contents) == 0);
239 CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0));
240 CHECK(CBS_len(&contents) == 0);
241 CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42));
242 CHECK(value == 42);
243
244 CBS_init(&data, kData6, sizeof(kData6));
245 /* optional element. */
246 CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa0));
247 CHECK(!present);
248 CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa1));
249 CHECK(present);
250 CHECK(CBS_len(&contents) == 3);
251 CHECK(memcmp(CBS_data(&contents), "\x04\x01\x01", 3) == 0);
252
253 CBS_init(&data, kData6, sizeof(kData6));
254 /* optional octet string. */
255 CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present,
256 0xa0));
257 CHECK(!present);
258 CHECK(CBS_len(&contents) == 0);
259 CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present,
260 0xa1));
261 CHECK(present);
262 CHECK(CBS_len(&contents) == 1);
263 CHECK(CBS_data(&contents)[0] == 1);
264
265 CBS_init(&data, kData7, sizeof(kData7));
266 /* invalid optional octet string. */
267 CHECK(!CBS_get_optional_asn1_octet_string(&data, &contents, &present,
268 0xa1));
269
270 CBS_init(&data, kData8, sizeof(kData8));
271 /* optional octet string. */
272 CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42));
273 CHECK(value == 42);
274 CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42));
275 CHECK(value == 1);
276
277 CBS_init(&data, kData9, sizeof(kData9));
278 /* invalid optional integer. */
279 CHECK(!CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42));
280
281 return 1;
282 }
283
284 static int
test_get_optional_asn1_bool(void)285 test_get_optional_asn1_bool(void)
286 {
287 CBS data;
288 int val;
289
290 static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff};
291 static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00};
292 static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01};
293
294 CBS_init(&data, NULL, 0);
295 val = 2;
296 CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0));
297 CHECK(val == 0);
298
299 CBS_init(&data, kTrue, sizeof(kTrue));
300 val = 2;
301 CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0));
302 CHECK(val == 1);
303
304 CBS_init(&data, kFalse, sizeof(kFalse));
305 val = 2;
306 CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1));
307 CHECK(val == 0);
308
309 CBS_init(&data, kInvalid, sizeof(kInvalid));
310 CHECK(!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1));
311
312 return 1;
313 }
314
315 static int
test_cbb_basic(void)316 test_cbb_basic(void)
317 {
318 static const uint8_t kExpected[] = {
319 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
320 13, 14, 15, 16, 17, 18, 19, 20,
321 };
322 uint8_t *buf = NULL;
323 size_t buf_len;
324 int ret = 0;
325 CBB cbb;
326
327 CHECK(CBB_init(&cbb, 100));
328
329 CBB_cleanup(&cbb);
330
331 CHECK(CBB_init(&cbb, 0));
332 CHECK_GOTO(CBB_add_u8(&cbb, 1));
333 CHECK_GOTO(CBB_add_u16(&cbb, 0x203));
334 CHECK_GOTO(CBB_add_u24(&cbb, 0x40506));
335 CHECK_GOTO(CBB_add_u32(&cbb, 0x708090a));
336 CHECK_GOTO(CBB_add_bytes(&cbb, (const uint8_t*) "\x0b\x0c", 2));
337 CHECK_GOTO(CBB_add_u64(&cbb, 0xd0e0f1011121314LL));
338 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
339
340 ret = (buf_len == sizeof(kExpected)
341 && memcmp(buf, kExpected, buf_len) == 0);
342
343 if (0) {
344 err:
345 CBB_cleanup(&cbb);
346 }
347 free(buf);
348 return ret;
349 }
350
351 static int
test_cbb_add_space(void)352 test_cbb_add_space(void)
353 {
354 static const uint8_t kExpected[] = {1, 2, 0, 0, 0, 0, 7, 8};
355 uint8_t *buf = NULL;
356 size_t buf_len;
357 uint8_t *data;
358 int ret = 0;
359 CBB cbb;
360
361 CHECK(CBB_init(&cbb, 100));
362
363 CHECK_GOTO(CBB_add_u16(&cbb, 0x102));
364 CHECK_GOTO(CBB_add_space(&cbb, &data, 4));
365 CHECK_GOTO(CBB_add_u16(&cbb, 0x708));
366 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
367
368 ret |= (buf_len == sizeof(kExpected)
369 && memcmp(buf, kExpected, buf_len) == 0);
370
371 memset(buf, 0xa5, buf_len);
372 CHECK(CBB_init_fixed(&cbb, buf, buf_len));
373
374 CHECK_GOTO(CBB_add_u16(&cbb, 0x102));
375 CHECK_GOTO(CBB_add_space(&cbb, &data, 4));
376 CHECK_GOTO(CBB_add_u16(&cbb, 0x708));
377 CHECK_GOTO(CBB_finish(&cbb, NULL, NULL));
378
379 ret |= (buf_len == sizeof(kExpected)
380 && memcmp(buf, kExpected, buf_len) == 0);
381
382 if (0) {
383 err:
384 CBB_cleanup(&cbb);
385 }
386 free(buf);
387 return ret;
388 }
389
390 static int
test_cbb_fixed(void)391 test_cbb_fixed(void)
392 {
393 CBB cbb;
394 uint8_t buf[1];
395 uint8_t *out_buf = NULL;
396 size_t out_size;
397 int ret = 0;
398
399 CHECK(CBB_init_fixed(&cbb, NULL, 0));
400 CHECK_GOTO(!CBB_add_u8(&cbb, 1));
401 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size));
402 CHECK(out_buf == NULL && out_size == 0);
403
404 CHECK(CBB_init_fixed(&cbb, buf, 1));
405 CHECK_GOTO(CBB_add_u8(&cbb, 1));
406 CHECK_GOTO(!CBB_add_u8(&cbb, 2));
407 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size));
408
409 ret = (out_buf == buf && out_size == 1 && buf[0] == 1);
410
411 if (0) {
412 err:
413 CBB_cleanup(&cbb);
414 }
415
416 return ret;
417 }
418
419 static int
test_cbb_finish_child(void)420 test_cbb_finish_child(void)
421 {
422 CBB cbb, child;
423 uint8_t *out_buf = NULL;
424 size_t out_size;
425 int ret = 0;
426
427 CHECK(CBB_init(&cbb, 16));
428 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child));
429 CHECK_GOTO(!CBB_finish(&child, &out_buf, &out_size));
430 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size));
431
432 ret = (out_size == 1 && out_buf[0] == 0);
433
434 err:
435 free(out_buf);
436 return ret;
437 }
438
439 static int
test_cbb_prefixed(void)440 test_cbb_prefixed(void)
441 {
442 static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
443 4, 5, 6, 5, 4, 1, 0, 1, 2};
444 CBB cbb, contents, inner_contents, inner_inner_contents;
445 uint8_t *buf = NULL;
446 size_t buf_len;
447 int ret = 0;
448
449 CHECK(CBB_init(&cbb, 0));
450 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
451 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
452 CHECK_GOTO(CBB_add_u8(&contents, 1));
453 CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents));
454 CHECK_GOTO(CBB_add_u16(&contents, 0x203));
455 CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents));
456 CHECK_GOTO(CBB_add_u24(&contents, 0x40506));
457 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
458 CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents));
459 CHECK_GOTO(CBB_add_u8(&inner_contents, 1));
460 CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents,
461 &inner_inner_contents));
462 CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 2));
463 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
464
465 ret = (buf_len == sizeof(kExpected)
466 && memcmp(buf, kExpected, buf_len) == 0);
467
468 if (0) {
469 err:
470 CBB_cleanup(&cbb);
471 }
472 free(buf);
473 return ret;
474 }
475
476 static int
test_cbb_discard_child(void)477 test_cbb_discard_child(void)
478 {
479 static const uint8_t kExpected[] = {
480 0xaa,
481 0,
482 1, 0xbb,
483 0, 2, 0xcc, 0xcc,
484 0, 0, 3, 0xdd, 0xdd, 0xdd,
485 1, 0xff,
486 };
487 CBB cbb, contents, inner_contents, inner_inner_contents;
488 uint8_t *buf = NULL;
489 size_t buf_len;
490 int ret = 0;
491
492 CHECK(CBB_init(&cbb, 0));
493 CHECK_GOTO(CBB_add_u8(&cbb, 0xaa));
494
495 // Discarding |cbb|'s children preserves the byte written.
496 CBB_discard_child(&cbb);
497
498 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
499 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
500 CHECK_GOTO(CBB_add_u8(&contents, 0xbb));
501 CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents));
502 CHECK_GOTO(CBB_add_u16(&contents, 0xcccc));
503 CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents));
504 CHECK_GOTO(CBB_add_u24(&contents, 0xdddddd));
505 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
506 CHECK_GOTO(CBB_add_u8(&contents, 0xff));
507 CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents));
508 CHECK_GOTO(CBB_add_u8(&inner_contents, 0x42));
509 CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents,
510 &inner_inner_contents));
511 CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 0x99));
512
513 // Discard everything from |inner_contents| down.
514 CBB_discard_child(&contents);
515
516 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
517
518 ret = (buf_len == sizeof(kExpected)
519 && memcmp(buf, kExpected, buf_len) == 0);
520
521 if (0) {
522 err:
523 CBB_cleanup(&cbb);
524 }
525 free(buf);
526 return ret;
527 }
528
529 static int
test_cbb_misuse(void)530 test_cbb_misuse(void)
531 {
532 CBB cbb, child, contents;
533 uint8_t *buf = NULL;
534 size_t buf_len;
535 int ret = 0;
536
537 CHECK(CBB_init(&cbb, 0));
538 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child));
539 CHECK_GOTO(CBB_add_u8(&child, 1));
540 CHECK_GOTO(CBB_add_u8(&cbb, 2));
541
542 /*
543 * Since we wrote to |cbb|, |child| is now invalid and attempts to write
544 * to it should fail.
545 */
546 CHECK_GOTO(!CBB_add_u8(&child, 1));
547 CHECK_GOTO(!CBB_add_u16(&child, 1));
548 CHECK_GOTO(!CBB_add_u24(&child, 1));
549 CHECK_GOTO(!CBB_add_u8_length_prefixed(&child, &contents));
550 CHECK_GOTO(!CBB_add_u16_length_prefixed(&child, &contents));
551 CHECK_GOTO(!CBB_add_asn1(&child, &contents, 1));
552 CHECK_GOTO(!CBB_add_bytes(&child, (const uint8_t*) "a", 1));
553 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
554
555 ret = (buf_len == 3 && memcmp(buf, "\x01\x01\x02", 3) == 0);
556
557 if (0) {
558 err:
559 CBB_cleanup(&cbb);
560 }
561 free(buf);
562 return ret;
563 }
564
565 static int
test_cbb_asn1(void)566 test_cbb_asn1(void)
567 {
568 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
569 uint8_t *buf = NULL, *test_data = NULL;
570 size_t buf_len;
571 CBB cbb, contents, inner_contents;
572 int ret = 0;
573 int alloc = 0;
574
575 CHECK_GOTO(CBB_init(&cbb, 0));
576 alloc = 1;
577 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30));
578 CHECK_GOTO(CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03",
579 3));
580 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
581 alloc = 0;
582
583 CHECK_GOTO(buf_len == sizeof(kExpected));
584 CHECK_GOTO(memcmp(buf, kExpected, buf_len) == 0);
585
586 free(buf);
587 buf = NULL;
588
589 CHECK_GOTO(((test_data = malloc(100000)) != NULL));
590 memset(test_data, 0x42, 100000);
591
592 CHECK_GOTO(CBB_init(&cbb, 0));
593 alloc = 1;
594 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30));
595 CHECK_GOTO(CBB_add_bytes(&contents, test_data, 130));
596 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
597 alloc = 0;
598
599 CHECK_GOTO(buf_len == 3 + 130);
600 CHECK_GOTO(memcmp(buf, "\x30\x81\x82", 3) == 0);
601 CHECK_GOTO(memcmp(buf + 3, test_data, 130) == 0);
602
603 free(buf);
604 buf = NULL;
605
606 CHECK_GOTO(CBB_init(&cbb, 0));
607 alloc = 1;
608 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30));
609 CHECK_GOTO(CBB_add_bytes(&contents, test_data, 1000));
610 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
611 alloc = 0;
612
613 CHECK_GOTO(buf_len == 4 + 1000);
614 CHECK_GOTO(memcmp(buf, "\x30\x82\x03\xe8", 4) == 0);
615 CHECK_GOTO(!memcmp(buf + 4, test_data, 1000));
616
617 free(buf);
618 buf = NULL;
619
620 CHECK_GOTO(CBB_init(&cbb, 0));
621 alloc = 1;
622 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30));
623 CHECK_GOTO(CBB_add_asn1(&contents, &inner_contents, 0x30));
624 CHECK_GOTO(CBB_add_bytes(&inner_contents, test_data, 100000));
625 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
626 alloc = 0;
627
628 CHECK_GOTO(buf_len == 5 + 5 + 100000);
629 CHECK_GOTO(memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10)
630 == 0);
631 CHECK_GOTO(!memcmp(buf + 10, test_data, 100000));
632
633 ret = 1;
634
635 if (0) {
636 err:
637 if (alloc)
638 CBB_cleanup(&cbb);
639 }
640 free(buf);
641 free(test_data);
642 return ret;
643 }
644
645 static int
do_indefinite_convert(const char * name,const uint8_t * definite_expected,size_t definite_len,const uint8_t * indefinite,size_t indefinite_len)646 do_indefinite_convert(const char *name, const uint8_t *definite_expected,
647 size_t definite_len, const uint8_t *indefinite, size_t indefinite_len)
648 {
649 CBS in;
650 uint8_t *out = NULL;
651 size_t out_len;
652 int ret = 0;
653
654 CBS_init(&in, indefinite, indefinite_len);
655
656 CHECK_GOTO(CBS_asn1_indefinite_to_definite(&in, &out, &out_len));
657
658 if (out == NULL) {
659
660 if (indefinite_len != definite_len ||
661 memcmp(definite_expected, indefinite, indefinite_len) != 0) {
662 PRINT_ERROR;
663 goto err;
664 }
665
666 return 1;
667 }
668
669 if (out_len != definite_len ||
670 memcmp(out, definite_expected, definite_len) != 0) {
671 PRINT_ERROR;
672 goto err;
673 }
674
675 ret = 1;
676 err:
677 free(out);
678 return ret;
679 }
680
681 static int
test_indefinite_convert(void)682 test_indefinite_convert(void)
683 {
684 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
685
686 /* kIndefBER contains a SEQUENCE with an indefinite length. */
687 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00,
688 0x00};
689 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
690
691 /*
692 * kOctetStringBER contains an indefinite length OCTETSTRING with two
693 * parts. These parts need to be concatenated in DER form.
694 */
695 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0,
696 1, 0x04, 0x02, 2, 3, 0x00, 0x00};
697 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3};
698
699 /*
700 * kNSSBER is part of a PKCS#12 message generated by NSS that uses
701 * indefinite length elements extensively.
702 */
703 static const uint8_t kNSSBER[] = {
704 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86,
705 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80,
706 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
707 0x00, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
708 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66,
709 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d,
710 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 0x62, 0xc6, 0x44,
711 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 0x6e, 0x10, 0x9b,
712 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00,
713 };
714
715 static const uint8_t kNSSDER[] = {
716 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86,
717 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04,
718 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06,
719 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84,
720 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8,
721 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38,
722 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0,
723 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
724 };
725
726 CHECK(do_indefinite_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
727 kSimpleBER, sizeof(kSimpleBER)));
728 CHECK(do_indefinite_convert("kIndefBER", kIndefDER, sizeof(kIndefDER),
729 kIndefBER, sizeof(kIndefBER)));
730 CHECK(do_indefinite_convert("kOctetStringBER", kOctetStringDER,
731 sizeof(kOctetStringDER), kOctetStringBER,
732 sizeof(kOctetStringBER)));
733 CHECK(do_indefinite_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
734 sizeof(kNSSBER)));
735
736 return 1;
737 }
738
739 typedef struct {
740 uint64_t value;
741 const char *encoding;
742 size_t encoding_len;
743 } ASN1_UINT64_TEST;
744
745 static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = {
746 {0, "\x02\x01\x00", 3},
747 {1, "\x02\x01\x01", 3},
748 {127, "\x02\x01\x7f", 3},
749 {128, "\x02\x02\x00\x80", 4},
750 {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
751 {OPENSSL_U64(0x0102030405060708),
752 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
753 {OPENSSL_U64(0xffffffffffffffff),
754 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
755 };
756
757 typedef struct {
758 const char *encoding;
759 size_t encoding_len;
760 } ASN1_INVALID_UINT64_TEST;
761
762 static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = {
763 /* Bad tag. */
764 {"\x03\x01\x00", 3},
765 /* Empty contents. */
766 {"\x02\x00", 2},
767 /* Negative number. */
768 {"\x02\x01\x80", 3},
769 /* Overflow. */
770 {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11},
771 /* Leading zeros. */
772 {"\x02\x02\x00\x01", 4},
773 };
774
775 static int
test_asn1_uint64(void)776 test_asn1_uint64(void)
777 {
778 CBB cbb;
779 uint8_t *out = NULL;
780 size_t i;
781 int ret = 0;
782 int alloc = 0;
783
784 for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]);
785 i++) {
786 const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i];
787 CBS cbs;
788 uint64_t value;
789 size_t len;
790
791 CBS_init(&cbs, (const uint8_t *)test->encoding,
792 test->encoding_len);
793
794 CHECK(CBS_get_asn1_uint64(&cbs, &value));
795 CHECK(CBS_len(&cbs) == 0);
796 CHECK(value == test->value);
797
798 CHECK(CBB_init(&cbb, 0));
799 alloc = 1;
800 CHECK_GOTO(CBB_add_asn1_uint64(&cbb, test->value));
801 CHECK_GOTO(CBB_finish(&cbb, &out, &len));
802 alloc = 0;
803
804 CHECK_GOTO(len == test->encoding_len);
805 CHECK_GOTO(memcmp(out, test->encoding, len) == 0);
806 free(out);
807 out = NULL;
808 }
809
810 for (i = 0; i < sizeof(kAsn1InvalidUint64Tests)
811 / sizeof(kAsn1InvalidUint64Tests[0]); i++) {
812 const ASN1_INVALID_UINT64_TEST *test =
813 &kAsn1InvalidUint64Tests[i];
814 CBS cbs;
815 uint64_t value;
816
817 CBS_init(&cbs, (const uint8_t *)test->encoding,
818 test->encoding_len);
819 CHECK(!CBS_get_asn1_uint64(&cbs, &value));
820 }
821
822 ret = 1;
823
824 if (0) {
825 err:
826 if (alloc)
827 CBB_cleanup(&cbb);
828 }
829 free(out);
830
831 return ret;
832 }
833
834 static int
test_offset(void)835 test_offset(void)
836 {
837 uint8_t v;
838 static const uint8_t input[] = {1, 2, 3, 4, 5};
839 CBS data;
840
841 CBS_init(&data, input, sizeof(input));
842 CHECK(sizeof(input) == 5);
843 CHECK(CBS_len(&data) == 5);
844 CHECK(CBS_offset(&data) == 0);
845 CHECK(CBS_get_u8(&data, &v));
846 CHECK(v == 1);
847 CHECK(CBS_len(&data) == 4);
848 CHECK(CBS_offset(&data) == 1);
849 CHECK(CBS_skip(&data, 2));
850 CHECK(CBS_len(&data) == 2);
851 CHECK(CBS_offset(&data) == 3);
852 CHECK(CBS_get_u8(&data, &v));
853 CHECK(v == 4);
854 CHECK(CBS_get_u8(&data, &v));
855 CHECK(v == 5);
856 CHECK(CBS_len(&data) == 0);
857 CHECK(CBS_offset(&data) == 5);
858 CHECK(!CBS_skip(&data, 1));
859
860 CBS_init(&data, input, sizeof(input));
861 CHECK(CBS_skip(&data, 2));
862 CHECK(CBS_len(&data) == 3);
863 CHECK(CBS_offset(&data) == 2);
864 CHECK(CBS_skip(&data, 3));
865 CHECK(CBS_len(&data) == 0);
866 CHECK(CBS_offset(&data) == 5);
867 CHECK(!CBS_get_u8(&data, &v));
868
869 return 1;
870 }
871
872 static int
test_write_bytes(void)873 test_write_bytes(void)
874 {
875 int ret = 0;
876 uint8_t v;
877 size_t len;
878 static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'};
879 CBS data;
880 uint8_t *tmp = NULL;
881
882 CHECK_GOTO((tmp = malloc(sizeof(input))) != NULL);
883 memset(tmp, 100, sizeof(input));
884
885 CBS_init(&data, input, sizeof(input));
886 CHECK_GOTO(CBS_len(&data) == 6);
887 CHECK_GOTO(CBS_offset(&data) == 0);
888 CHECK_GOTO(CBS_get_u8(&data, &v));
889 CHECK_GOTO(v == 102 /* f */);
890 CHECK_GOTO(CBS_skip(&data, 1));
891 CHECK_GOTO(!CBS_skip(&data, 15));
892 CHECK_GOTO(CBS_write_bytes(&data, tmp, sizeof(input), &len));
893 CHECK_GOTO(len == 4);
894 CHECK_GOTO(memcmp(input + 2, tmp, len) == 0);
895 CHECK_GOTO(tmp[4] == 100 && tmp[5] == 100);
896
897 ret = 1;
898
899 err:
900 free(tmp);
901 return ret;
902 }
903
904 static int
test_cbs_dup(void)905 test_cbs_dup(void)
906 {
907 CBS data, check;
908 static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'};
909
910 CBS_init(&data, input, sizeof(input));
911 CHECK(CBS_len(&data) == 6);
912 CBS_dup(&data, &check);
913 CHECK(CBS_len(&check) == 6);
914 CHECK(CBS_data(&data) == CBS_data(&check));
915 CHECK(CBS_skip(&data, 1));
916 CHECK(CBS_len(&data) == 5);
917 CHECK(CBS_len(&check) == 6);
918 CHECK(CBS_data(&data) == CBS_data(&check) + 1);
919 CHECK(CBS_skip(&check, 1));
920 CHECK(CBS_len(&data) == 5);
921 CHECK(CBS_len(&check) == 5);
922 CHECK(CBS_data(&data) == CBS_data(&check));
923 CHECK(CBS_offset(&data) == 1);
924 CHECK(CBS_offset(&check) == 1);
925
926 CBS_init(&data, input, sizeof(input));
927 CHECK(CBS_skip(&data, 5));
928 CBS_dup(&data, &check);
929 CHECK(CBS_len(&data) == 1);
930 CHECK(CBS_len(&check) == 1);
931 CHECK(CBS_data(&data) == input + 5);
932 CHECK(CBS_data(&data) == CBS_data(&check));
933 CHECK(CBS_offset(&data) == 5);
934 CHECK(CBS_offset(&check) == 5);
935
936 return 1;
937 }
938
939 int
main(void)940 main(void)
941 {
942 int failed = 0;
943
944 failed |= !test_skip();
945 failed |= !test_get_u();
946 failed |= !test_get_prefixed();
947 failed |= !test_get_prefixed_bad();
948 failed |= !test_peek_u();
949 failed |= !test_get_asn1();
950 failed |= !test_cbb_basic();
951 failed |= !test_cbb_add_space();
952 failed |= !test_cbb_fixed();
953 failed |= !test_cbb_finish_child();
954 failed |= !test_cbb_discard_child();
955 failed |= !test_cbb_misuse();
956 failed |= !test_cbb_prefixed();
957 failed |= !test_cbb_asn1();
958 failed |= !test_indefinite_convert();
959 failed |= !test_asn1_uint64();
960 failed |= !test_get_optional_asn1_bool();
961 failed |= !test_offset();
962 failed |= !test_write_bytes();
963 failed |= !test_cbs_dup();
964
965 if (!failed)
966 printf("PASS\n");
967 return failed;
968 }
969