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