1 /* Copyright (c) 2014, Google Inc.
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
18 #include <openssl/bytestring.h>
21 static int test_skip() {
22 static const uint8_t kData[] = {1, 2, 3};
25 CBS_init(&data, kData, sizeof(kData));
26 return CBS_len(&data) == 3 &&
28 CBS_len(&data) == 2 &&
30 CBS_len(&data) == 0 &&
34 static int test_get_u() {
35 static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
41 CBS_init(&data, kData, sizeof(kData));
42 return CBS_get_u8(&data, &u8) &&
44 CBS_get_u16(&data, &u16) &&
46 CBS_get_u24(&data, &u32) &&
48 CBS_get_u32(&data, &u32) &&
50 !CBS_get_u8(&data, &u8);
53 static int test_get_prefixed() {
54 static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
60 CBS_init(&data, kData, sizeof(kData));
61 return CBS_get_u8_length_prefixed(&data, &prefixed) &&
62 CBS_len(&prefixed) == 1 &&
63 CBS_get_u8(&prefixed, &u8) &&
65 CBS_get_u16_length_prefixed(&data, &prefixed) &&
66 CBS_len(&prefixed) == 2 &&
67 CBS_get_u16(&prefixed, &u16) &&
69 CBS_get_u24_length_prefixed(&data, &prefixed) &&
70 CBS_len(&prefixed) == 3 &&
71 CBS_get_u24(&prefixed, &u32) &&
75 static int test_get_prefixed_bad() {
76 static const uint8_t kData1[] = {2, 1};
77 static const uint8_t kData2[] = {0, 2, 1};
78 static const uint8_t kData3[] = {0, 0, 2, 1};
81 CBS_init(&data, kData1, sizeof(kData1));
82 if (CBS_get_u8_length_prefixed(&data, &prefixed)) {
86 CBS_init(&data, kData2, sizeof(kData2));
87 if (CBS_get_u16_length_prefixed(&data, &prefixed)) {
91 CBS_init(&data, kData3, sizeof(kData3));
92 if (CBS_get_u24_length_prefixed(&data, &prefixed)) {
99 static int test_get_asn1() {
100 static const uint8_t kData1[] = {0x30, 2, 1, 2};
101 static const uint8_t kData2[] = {0x30, 3, 1, 2};
102 static const uint8_t kData3[] = {0x30, 0x80};
103 static const uint8_t kData4[] = {0x30, 0x81, 1, 1};
104 static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1};
108 CBS_init(&data, kData1, sizeof(kData1));
109 if (!CBS_get_asn1(&data, &contents, 0x30) ||
110 CBS_len(&contents) != 2 ||
111 memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
115 CBS_init(&data, kData2, sizeof(kData2));
116 /* data is truncated */
117 if (CBS_get_asn1(&data, &contents, 0x30)) {
121 CBS_init(&data, kData3, sizeof(kData3));
122 /* zero byte length of length */
123 if (CBS_get_asn1(&data, &contents, 0x30)) {
127 CBS_init(&data, kData4, sizeof(kData4));
128 /* long form mistakenly used. */
129 if (CBS_get_asn1(&data, &contents, 0x30)) {
133 CBS_init(&data, kData5, sizeof(kData5));
134 /* length takes too many bytes. */
135 if (CBS_get_asn1(&data, &contents, 0x30)) {
139 CBS_init(&data, kData1, sizeof(kData1));
141 if (CBS_get_asn1(&data, &contents, 0x31)) {
148 static int test_get_indef() {
149 static const uint8_t kData1[] = {0x30, 0x80, 0x00, 0x00};
150 static const uint8_t kDataWithoutEOC[] = {0x30, 0x80, 0x01, 0x00};
151 static const uint8_t kDataWithBadInternalLength[] = {0x30, 0x80, 0x01, 0x01};
152 static const uint8_t kDataNested[] = {0x30, 0x80, 0x30, 0x80, 0x30, 0x80,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
156 CBS_init(&data, kData1, sizeof(kData1));
157 if (CBS_get_asn1(&data, &contents, 0x30)) {
158 /* Indefinite lengths should not be supported in DER mode. */
159 fprintf(stderr, "Indefinite length parsed by CBS_get_asn1.\n");
163 if (!CBS_get_asn1_ber(&data, &contents, 0x30) ||
164 CBS_len(&contents) != 0 ||
165 CBS_len(&data) != 0) {
166 fprintf(stderr, "Simple indefinite length failed.\n");
170 CBS_init(&data, kDataWithoutEOC, sizeof(kDataWithoutEOC));
171 if (CBS_get_asn1_ber(&data, &contents, 0x30)) {
172 fprintf(stderr, "Parsed without EOC.\n");
176 CBS_init(&data, kDataWithBadInternalLength,
177 sizeof(kDataWithBadInternalLength));
178 if (CBS_get_asn1_ber(&data, &contents, 0x30)) {
179 fprintf(stderr, "Parsed with internal length.\n");
183 CBS_init(&data, kDataNested, sizeof(kDataNested));
184 if (!CBS_get_asn1_ber(&data, &contents, 0x30) ||
185 CBS_len(&contents) != 8 ||
186 CBS_len(&data) != 0) {
187 fprintf(stderr, "Nested indefinite lengths failed.\n");
194 static int test_cbb_basic() {
195 static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8};
201 if (!CBB_init(&cbb, 100)) {
206 if (!CBB_init(&cbb, 0) ||
207 !CBB_add_u8(&cbb, 1) ||
208 !CBB_add_u16(&cbb, 0x203) ||
209 !CBB_add_u24(&cbb, 0x40506) ||
210 !CBB_add_bytes(&cbb, (const uint8_t*) "\x07\x08", 2) ||
211 !CBB_finish(&cbb, &buf, &buf_len)) {
215 ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
220 static int test_cbb_fixed() {
226 if (!CBB_init_fixed(&cbb, NULL, 0) ||
227 CBB_add_u8(&cbb, 1) ||
228 !CBB_finish(&cbb, &out_buf, &out_size) ||
234 if (!CBB_init_fixed(&cbb, buf, 1) ||
235 !CBB_add_u8(&cbb, 1) ||
236 CBB_add_u8(&cbb, 2) ||
237 !CBB_finish(&cbb, &out_buf, &out_size) ||
247 static int test_cbb_finish_child() {
252 if (!CBB_init(&cbb, 16) ||
253 !CBB_add_u8_length_prefixed(&cbb, &child) ||
254 CBB_finish(&child, &out_buf, &out_size) ||
255 !CBB_finish(&cbb, &out_buf, &out_size) ||
265 static int test_cbb_prefixed() {
266 static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
267 4, 5, 6, 5, 4, 1, 0, 1, 2};
270 CBB cbb, contents, inner_contents, inner_inner_contents;
273 if (!CBB_init(&cbb, 0) ||
274 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
275 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
276 !CBB_add_u8(&contents, 1) ||
277 !CBB_add_u16_length_prefixed(&cbb, &contents) ||
278 !CBB_add_u16(&contents, 0x203) ||
279 !CBB_add_u24_length_prefixed(&cbb, &contents) ||
280 !CBB_add_u24(&contents, 0x40506) ||
281 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
282 !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
283 !CBB_add_u8(&inner_contents, 1) ||
284 !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
285 !CBB_add_u8(&inner_inner_contents, 2) ||
286 !CBB_finish(&cbb, &buf, &buf_len)) {
290 ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
295 static int test_cbb_misuse() {
296 CBB cbb, child, contents;
300 if (!CBB_init(&cbb, 0) ||
301 !CBB_add_u8_length_prefixed(&cbb, &child) ||
302 !CBB_add_u8(&child, 1) ||
303 !CBB_add_u8(&cbb, 2)) {
307 /* Since we wrote to |cbb|, |child| is now invalid and attempts to write to
309 if (CBB_add_u8(&child, 1) ||
310 CBB_add_u16(&child, 1) ||
311 CBB_add_u24(&child, 1) ||
312 CBB_add_u8_length_prefixed(&child, &contents) ||
313 CBB_add_u16_length_prefixed(&child, &contents) ||
314 CBB_add_asn1(&child, &contents, 1) ||
315 CBB_add_bytes(&child, (const uint8_t*) "a", 1)) {
316 fprintf(stderr, "CBB operation on invalid CBB did not fail.\n");
320 if (!CBB_finish(&cbb, &buf, &buf_len) ||
322 memcmp(buf, "\x01\x01\x02", 3) != 0) {
331 static int test_cbb_asn1() {
332 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
333 uint8_t *buf, *test_data;
335 CBB cbb, contents, inner_contents;
337 if (!CBB_init(&cbb, 0) ||
338 !CBB_add_asn1(&cbb, &contents, 0x30) ||
339 !CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) ||
340 !CBB_finish(&cbb, &buf, &buf_len)) {
344 if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
349 test_data = malloc(100000);
350 memset(test_data, 0x42, 100000);
352 if (!CBB_init(&cbb, 0) ||
353 !CBB_add_asn1(&cbb, &contents, 0x30) ||
354 !CBB_add_bytes(&contents, test_data, 130) ||
355 !CBB_finish(&cbb, &buf, &buf_len)) {
359 if (buf_len != 3 + 130 ||
360 memcmp(buf, "\x30\x81\x82", 3) != 0 ||
361 memcmp(buf + 3, test_data, 130) != 0) {
366 if (!CBB_init(&cbb, 0) ||
367 !CBB_add_asn1(&cbb, &contents, 0x30) ||
368 !CBB_add_bytes(&contents, test_data, 1000) ||
369 !CBB_finish(&cbb, &buf, &buf_len)) {
373 if (buf_len != 4 + 1000 ||
374 memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
375 memcmp(buf + 4, test_data, 1000)) {
380 if (!CBB_init(&cbb, 0) ||
381 !CBB_add_asn1(&cbb, &contents, 0x30) ||
382 !CBB_add_asn1(&contents, &inner_contents, 0x30) ||
383 !CBB_add_bytes(&inner_contents, test_data, 100000) ||
384 !CBB_finish(&cbb, &buf, &buf_len)) {
388 if (buf_len != 5 + 5 + 100000 ||
389 memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 ||
390 memcmp(buf + 10, test_data, 100000)) {
402 !test_get_prefixed() ||
403 !test_get_prefixed_bad() ||
408 !test_cbb_finish_child() ||
409 !test_cbb_misuse() ||
410 !test_cbb_prefixed() ||