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