xref: /openbsd-src/regress/lib/libssl/bytestring/bytestringtest.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: bytestringtest.c,v 1.10 2015/10/25 20:15:06 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 #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};
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_bytes(&cbb, (const uint8_t*) "\x07\x08", 2));
286 	CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
287 
288 	ret = (buf_len == sizeof(kExpected)
289 	    && memcmp(buf, kExpected, buf_len) == 0);
290 
291 	if (0) {
292 err:
293 		CBB_cleanup(&cbb);
294 	}
295 	free(buf);
296 	return ret;
297 }
298 
299 static int
300 test_cbb_fixed(void)
301 {
302 	CBB cbb;
303 	uint8_t buf[1];
304 	uint8_t *out_buf = NULL;
305 	size_t out_size;
306 	int ret = 0;
307 
308 	CHECK(CBB_init_fixed(&cbb, NULL, 0));
309 	CHECK_GOTO(!CBB_add_u8(&cbb, 1));
310 	CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size));
311 	CHECK(out_buf == NULL && out_size == 0);
312 
313 	CHECK(CBB_init_fixed(&cbb, buf, 1));
314 	CHECK_GOTO(CBB_add_u8(&cbb, 1));
315 	CHECK_GOTO(!CBB_add_u8(&cbb, 2));
316 	CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size));
317 
318 	ret = (out_buf == buf && out_size == 1 && buf[0] == 1);
319 
320 	if (0) {
321 err:
322 		CBB_cleanup(&cbb);
323 	}
324 
325 	return ret;
326 }
327 
328 static int
329 test_cbb_finish_child(void)
330 {
331 	CBB cbb, child;
332 	uint8_t *out_buf = NULL;
333 	size_t out_size;
334 	int ret = 0;
335 
336 	CHECK(CBB_init(&cbb, 16));
337 	CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child));
338 	CHECK_GOTO(!CBB_finish(&child, &out_buf, &out_size));
339 	CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size));
340 
341 	ret = (out_size == 1 && out_buf[0] == 0);
342 
343 err:
344 	free(out_buf);
345 	return ret;
346 }
347 
348 static int
349 test_cbb_prefixed(void)
350 {
351 	static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
352 	    4, 5, 6, 5, 4, 1, 0, 1, 2};
353 	uint8_t *buf = NULL;
354 	size_t buf_len;
355 	CBB cbb, contents, inner_contents, inner_inner_contents;
356 	int ret = 0;
357 
358 	CHECK(CBB_init(&cbb, 0));
359 	CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
360 	CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
361 	CHECK_GOTO(CBB_add_u8(&contents, 1));
362 	CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents));
363 	CHECK_GOTO(CBB_add_u16(&contents, 0x203));
364 	CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents));
365 	CHECK_GOTO(CBB_add_u24(&contents, 0x40506));
366 	CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents));
367 	CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents));
368 	CHECK_GOTO(CBB_add_u8(&inner_contents, 1));
369 	CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents,
370 	    &inner_inner_contents));
371 	CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 2));
372 	CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
373 
374 	ret = (buf_len == sizeof(kExpected)
375 	    && memcmp(buf, kExpected, buf_len) == 0);
376 
377 	if (0) {
378 err:
379 		CBB_cleanup(&cbb);
380 	}
381 	free(buf);
382 	return ret;
383 }
384 
385 static int
386 test_cbb_misuse(void)
387 {
388 	CBB cbb, child, contents;
389 	uint8_t *buf = NULL;
390 	size_t buf_len;
391 	int ret = 0;
392 
393 	CHECK(CBB_init(&cbb, 0));
394 	CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child));
395 	CHECK_GOTO(CBB_add_u8(&child, 1));
396 	CHECK_GOTO(CBB_add_u8(&cbb, 2));
397 
398 	/*
399 	 * Since we wrote to |cbb|, |child| is now invalid and attempts to write
400 	 * to it should fail.
401 	 */
402 	CHECK_GOTO(!CBB_add_u8(&child, 1));
403 	CHECK_GOTO(!CBB_add_u16(&child, 1));
404 	CHECK_GOTO(!CBB_add_u24(&child, 1));
405 	CHECK_GOTO(!CBB_add_u8_length_prefixed(&child, &contents));
406 	CHECK_GOTO(!CBB_add_u16_length_prefixed(&child, &contents));
407 	CHECK_GOTO(!CBB_add_asn1(&child, &contents, 1));
408 	CHECK_GOTO(!CBB_add_bytes(&child, (const uint8_t*) "a", 1));
409 	CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
410 
411 	ret = (buf_len == 3 && memcmp(buf, "\x01\x01\x02", 3) == 0);
412 
413 	if (0) {
414 err:
415 		CBB_cleanup(&cbb);
416 	}
417 	free(buf);
418 	return ret;
419 }
420 
421 static int
422 test_cbb_asn1(void)
423 {
424 	static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
425 	uint8_t *buf = NULL, *test_data = NULL;
426 	size_t buf_len;
427 	CBB cbb, contents, inner_contents;
428 	int ret = 0;
429 	int alloc = 0;
430 
431 	CHECK_GOTO(CBB_init(&cbb, 0));
432 	alloc = 1;
433 	CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30));
434 	CHECK_GOTO(CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03",
435 	    3));
436 	CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
437 	alloc = 0;
438 
439 	CHECK_GOTO(buf_len == sizeof(kExpected));
440 	CHECK_GOTO(memcmp(buf, kExpected, buf_len) == 0);
441 
442 	free(buf);
443 	buf = NULL;
444 
445 	CHECK_GOTO(((test_data = malloc(100000)) != NULL));
446 	memset(test_data, 0x42, 100000);
447 
448 	CHECK_GOTO(CBB_init(&cbb, 0));
449 	alloc = 1;
450 	CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30));
451 	CHECK_GOTO(CBB_add_bytes(&contents, test_data, 130));
452 	CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
453 	alloc = 0;
454 
455 	CHECK_GOTO(buf_len == 3 + 130);
456 	CHECK_GOTO(memcmp(buf, "\x30\x81\x82", 3) == 0);
457 	CHECK_GOTO(memcmp(buf + 3, test_data, 130) == 0);
458 
459 	free(buf);
460 	buf = NULL;
461 
462 	CHECK_GOTO(CBB_init(&cbb, 0));
463 	alloc = 1;
464 	CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30));
465 	CHECK_GOTO(CBB_add_bytes(&contents, test_data, 1000));
466 	CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
467 	alloc = 0;
468 
469 	CHECK_GOTO(buf_len == 4 + 1000);
470 	CHECK_GOTO(memcmp(buf, "\x30\x82\x03\xe8", 4) == 0);
471 	CHECK_GOTO(!memcmp(buf + 4, test_data, 1000));
472 
473 	free(buf);
474 	buf = NULL;
475 
476 	CHECK_GOTO(CBB_init(&cbb, 0));
477 	alloc = 1;
478 	CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30));
479 	CHECK_GOTO(CBB_add_asn1(&contents, &inner_contents, 0x30));
480 	CHECK_GOTO(CBB_add_bytes(&inner_contents, test_data, 100000));
481 	CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len));
482 	alloc = 0;
483 
484 	CHECK_GOTO(buf_len == 5 + 5 + 100000);
485 	CHECK_GOTO(memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10)
486 	    == 0);
487 	CHECK_GOTO(!memcmp(buf + 10, test_data, 100000));
488 
489 	ret = 1;
490 
491 	if (0) {
492 err:
493 		if (alloc)
494 			CBB_cleanup(&cbb);
495 	}
496 	free(buf);
497 	free(test_data);
498 	return ret;
499 }
500 
501 static int
502 do_indefinite_convert(const char *name, const uint8_t *definite_expected,
503     size_t definite_len, const uint8_t *indefinite, size_t indefinite_len)
504 {
505 	CBS in;
506 	uint8_t *out = NULL;
507 	size_t out_len;
508 	int ret = 0;
509 
510 	CBS_init(&in, indefinite, indefinite_len);
511 
512 	CHECK_GOTO(CBS_asn1_indefinite_to_definite(&in, &out, &out_len));
513 
514 	if (out == NULL) {
515 
516 		if (indefinite_len != definite_len ||
517 		    memcmp(definite_expected, indefinite, indefinite_len) != 0) {
518 			PRINT_ERROR;
519 			goto err;
520 		}
521 
522 		return 1;
523 	}
524 
525 	if (out_len != definite_len ||
526 	    memcmp(out, definite_expected, definite_len) != 0) {
527 		PRINT_ERROR;
528 		goto err;
529 	}
530 
531 	ret = 1;
532 err:
533 	free(out);
534 	return ret;
535 }
536 
537 static int
538 test_indefinite_convert(void)
539 {
540 	static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
541 
542 	/* kIndefBER contains a SEQUENCE with an indefinite length. */
543 	static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00,
544 	    0x00};
545 	static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
546 
547 	/*
548 	 * kOctetStringBER contains an indefinite length OCTETSTRING with two
549 	 * parts.  These parts need to be concatenated in DER form.
550 	 */
551 	static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0,
552 	    1, 0x04, 0x02, 2,    3,    0x00, 0x00};
553 	static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3};
554 
555 	/*
556 	 * kNSSBER is part of a PKCS#12 message generated by NSS that uses
557 	 * indefinite length elements extensively.
558 	 */
559 	static const uint8_t kNSSBER[] = {
560 	    0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86,
561 	    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80,
562 	    0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
563 	    0x00, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
564 	    0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66,
565 	    0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d,
566 	    0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 0x62, 0xc6, 0x44,
567 	    0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 0x6e, 0x10, 0x9b,
568 	    0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00,
569 	};
570 
571 	static const uint8_t kNSSDER[] = {
572 	    0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86,
573 	    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04,
574 	    0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06,
575 	    0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84,
576 	    0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8,
577 	    0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38,
578 	    0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0,
579 	    0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
580 	};
581 
582 	CHECK(do_indefinite_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
583 	    kSimpleBER, sizeof(kSimpleBER)));
584 	CHECK(do_indefinite_convert("kIndefBER", kIndefDER, sizeof(kIndefDER),
585 	    kIndefBER, sizeof(kIndefBER)));
586 	CHECK(do_indefinite_convert("kOctetStringBER", kOctetStringDER,
587 	    sizeof(kOctetStringDER), kOctetStringBER,
588 	    sizeof(kOctetStringBER)));
589 	CHECK(do_indefinite_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
590 	    sizeof(kNSSBER)));
591 
592 	return 1;
593 }
594 
595 typedef struct {
596 	uint64_t value;
597 	const char *encoding;
598 	size_t encoding_len;
599 } ASN1_UINT64_TEST;
600 
601 static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = {
602 	{0, "\x02\x01\x00", 3},
603 	{1, "\x02\x01\x01", 3},
604 	{127, "\x02\x01\x7f", 3},
605 	{128, "\x02\x02\x00\x80", 4},
606 	{0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
607 	{OPENSSL_U64(0x0102030405060708),
608 	    "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
609 	{OPENSSL_U64(0xffffffffffffffff),
610 	    "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
611 };
612 
613 typedef struct {
614 	const char *encoding;
615 	size_t encoding_len;
616 } ASN1_INVALID_UINT64_TEST;
617 
618 static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = {
619 	/* Bad tag. */
620 	{"\x03\x01\x00", 3},
621 	/* Empty contents. */
622 	{"\x02\x00", 2},
623 	/* Negative number. */
624 	{"\x02\x01\x80", 3},
625 	/* Overflow. */
626 	{"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11},
627 	/* Leading zeros. */
628 	{"\x02\x02\x00\x01", 4},
629 };
630 
631 static int
632 test_asn1_uint64(void)
633 {
634 	CBB cbb;
635 	uint8_t *out = NULL;
636 	size_t i;
637 	int ret = 0;
638 	int alloc = 0;
639 
640 	for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]);
641 	     i++) {
642 		const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i];
643 		CBS cbs;
644 		uint64_t value;
645 		size_t len;
646 
647 		CBS_init(&cbs, (const uint8_t *)test->encoding,
648 		    test->encoding_len);
649 
650 		CHECK(CBS_get_asn1_uint64(&cbs, &value));
651 		CHECK(CBS_len(&cbs) == 0);
652 		CHECK(value == test->value);
653 
654 		CHECK(CBB_init(&cbb, 0));
655 		alloc = 1;
656 		CHECK_GOTO(CBB_add_asn1_uint64(&cbb, test->value));
657 		CHECK_GOTO(CBB_finish(&cbb, &out, &len));
658 		alloc = 0;
659 
660 		CHECK_GOTO(len == test->encoding_len);
661 		CHECK_GOTO(memcmp(out, test->encoding, len) == 0);
662 		free(out);
663 		out = NULL;
664 	}
665 
666 	for (i = 0; i < sizeof(kAsn1InvalidUint64Tests)
667 	    / sizeof(kAsn1InvalidUint64Tests[0]); i++) {
668 		const ASN1_INVALID_UINT64_TEST *test =
669 		    &kAsn1InvalidUint64Tests[i];
670 		CBS cbs;
671 		uint64_t value;
672 
673 		CBS_init(&cbs, (const uint8_t *)test->encoding,
674 		    test->encoding_len);
675 		CHECK(!CBS_get_asn1_uint64(&cbs, &value));
676 	}
677 
678 	ret = 1;
679 
680 	if (0) {
681 err:
682 		if (alloc)
683 			CBB_cleanup(&cbb);
684 	}
685 	free(out);
686 
687 	return ret;
688 }
689 
690 static int
691 test_offset(void)
692 {
693 	uint8_t v;
694 	static const uint8_t input[] = {1, 2, 3, 4, 5};
695 	CBS data;
696 
697 	CBS_init(&data, input, sizeof(input));
698 	CHECK(sizeof(input) == 5);
699 	CHECK(CBS_len(&data) == 5);
700 	CHECK(CBS_offset(&data) == 0);
701 	CHECK(CBS_get_u8(&data, &v));
702 	CHECK(v == 1);
703 	CHECK(CBS_len(&data) == 4);
704 	CHECK(CBS_offset(&data) == 1);
705 	CHECK(CBS_skip(&data, 2));
706 	CHECK(CBS_len(&data) == 2);
707 	CHECK(CBS_offset(&data) == 3);
708 	CHECK(CBS_get_u8(&data, &v));
709 	CHECK(v == 4);
710 	CHECK(CBS_get_u8(&data, &v));
711 	CHECK(v == 5);
712 	CHECK(CBS_len(&data) == 0);
713 	CHECK(CBS_offset(&data) == 5);
714 	CHECK(!CBS_skip(&data, 1));
715 
716 	CBS_init(&data, input, sizeof(input));
717 	CHECK(CBS_skip(&data, 2));
718 	CHECK(CBS_len(&data) == 3);
719 	CHECK(CBS_offset(&data) == 2);
720 	CHECK(CBS_skip(&data, 3));
721 	CHECK(CBS_len(&data) == 0);
722 	CHECK(CBS_offset(&data) == 5);
723 	CHECK(!CBS_get_u8(&data, &v));
724 
725 	return 1;
726 }
727 
728 static int
729 test_write_bytes(void)
730 {
731 	int ret = 0;
732 	uint8_t v;
733 	size_t len;
734 	static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'};
735 	CBS data;
736 	char *tmp = NULL;
737 
738 	CHECK_GOTO((tmp = malloc(sizeof(input))) != NULL);
739 	memset(tmp, 100, sizeof(input));
740 
741 	CBS_init(&data, input, sizeof(input));
742 	CHECK_GOTO(CBS_len(&data) == 6);
743 	CHECK_GOTO(CBS_offset(&data) == 0);
744 	CHECK_GOTO(CBS_get_u8(&data, &v));
745 	CHECK_GOTO(v == 102 /* f */);
746 	CHECK_GOTO(CBS_skip(&data, 1));
747 	CHECK_GOTO(!CBS_skip(&data, 15));
748 	CHECK_GOTO(CBS_write_bytes(&data, tmp, sizeof(input), &len));
749 	CHECK_GOTO(len == 4);
750 	CHECK_GOTO(memcmp(input + 2, tmp, len) == 0);
751 	CHECK_GOTO(tmp[4] == 100 && tmp[5] == 100);
752 
753 	ret = 1;
754 
755 err:
756 	free(tmp);
757 	return ret;
758 }
759 
760 static int
761 test_cbs_dup(void)
762 {
763 	CBS data, check;
764 	static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'};
765 
766 	CBS_init(&data, input, sizeof(input));
767 	CHECK(CBS_len(&data) == 6);
768 	CBS_dup(&data, &check);
769 	CHECK(CBS_len(&check) == 6);
770 	CHECK(CBS_data(&data) == CBS_data(&check));
771 	CHECK(CBS_skip(&data, 1));
772 	CHECK(CBS_len(&data) == 5);
773 	CHECK(CBS_len(&check) == 6);
774 	CHECK(CBS_data(&data) == CBS_data(&check) + 1);
775 	CHECK(CBS_skip(&check, 1));
776 	CHECK(CBS_len(&data) == 5);
777 	CHECK(CBS_len(&check) == 5);
778 	CHECK(CBS_data(&data) == CBS_data(&check));
779 	CHECK(CBS_offset(&data) == 1);
780 	CHECK(CBS_offset(&check) == 1);
781 
782 	CBS_init(&data, input, sizeof(input));
783 	CHECK(CBS_skip(&data, 5));
784 	CBS_dup(&data, &check);
785 	CHECK(CBS_len(&data) == 1);
786 	CHECK(CBS_len(&check) == 1);
787 	CHECK(CBS_data(&data) == input + 5);
788 	CHECK(CBS_data(&data) == CBS_data(&check));
789 	CHECK(CBS_offset(&data) == 5);
790 	CHECK(CBS_offset(&check) == 5);
791 
792 	return 1;
793 }
794 
795 int
796 main(void)
797 {
798 	int failed = 0;
799 
800 	failed |= !test_skip();
801 	failed |= !test_get_u();
802 	failed |= !test_get_prefixed();
803 	failed |= !test_get_prefixed_bad();
804 	failed |= !test_get_asn1();
805 	failed |= !test_cbb_basic();
806 	failed |= !test_cbb_fixed();
807 	failed |= !test_cbb_finish_child();
808 	failed |= !test_cbb_misuse();
809 	failed |= !test_cbb_prefixed();
810 	failed |= !test_cbb_asn1();
811 	failed |= !test_indefinite_convert();
812 	failed |= !test_asn1_uint64();
813 	failed |= !test_get_optional_asn1_bool();
814 	failed |= !test_offset();
815 	failed |= !test_write_bytes();
816 	failed |= !test_cbs_dup();
817 
818 	if (!failed)
819 		printf("PASS\n");
820 	return failed;
821 }
822