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