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/crypto.h>
19 #include <openssl/bytestring.h>
24 static int test_skip(void) {
25 static const uint8_t kData[] = {1, 2, 3};
28 CBS_init(&data, kData, sizeof(kData));
29 return CBS_len(&data) == 3 &&
31 CBS_len(&data) == 2 &&
33 CBS_len(&data) == 0 &&
37 static int test_get_u(void) {
38 static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
44 CBS_init(&data, kData, sizeof(kData));
45 return CBS_get_u8(&data, &u8) &&
47 CBS_get_u16(&data, &u16) &&
49 CBS_get_u24(&data, &u32) &&
51 CBS_get_u32(&data, &u32) &&
53 !CBS_get_u8(&data, &u8);
56 static int test_get_prefixed(void) {
57 static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
63 CBS_init(&data, kData, sizeof(kData));
64 return CBS_get_u8_length_prefixed(&data, &prefixed) &&
65 CBS_len(&prefixed) == 1 &&
66 CBS_get_u8(&prefixed, &u8) &&
68 CBS_get_u16_length_prefixed(&data, &prefixed) &&
69 CBS_len(&prefixed) == 2 &&
70 CBS_get_u16(&prefixed, &u16) &&
72 CBS_get_u24_length_prefixed(&data, &prefixed) &&
73 CBS_len(&prefixed) == 3 &&
74 CBS_get_u24(&prefixed, &u32) &&
78 static int test_get_prefixed_bad(void) {
79 static const uint8_t kData1[] = {2, 1};
80 static const uint8_t kData2[] = {0, 2, 1};
81 static const uint8_t kData3[] = {0, 0, 2, 1};
84 CBS_init(&data, kData1, sizeof(kData1));
85 if (CBS_get_u8_length_prefixed(&data, &prefixed)) {
89 CBS_init(&data, kData2, sizeof(kData2));
90 if (CBS_get_u16_length_prefixed(&data, &prefixed)) {
94 CBS_init(&data, kData3, sizeof(kData3));
95 if (CBS_get_u24_length_prefixed(&data, &prefixed)) {
102 static int test_get_asn1(void) {
103 static const uint8_t kData1[] = {0x30, 2, 1, 2};
104 static const uint8_t kData2[] = {0x30, 3, 1, 2};
105 static const uint8_t kData3[] = {0x30, 0x80};
106 static const uint8_t kData4[] = {0x30, 0x81, 1, 1};
107 static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1};
111 CBS_init(&data, kData1, sizeof(kData1));
112 if (!CBS_get_asn1(&data, &contents, 0x30) ||
113 CBS_len(&contents) != 2 ||
114 memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
118 CBS_init(&data, kData2, sizeof(kData2));
119 /* data is truncated */
120 if (CBS_get_asn1(&data, &contents, 0x30)) {
124 CBS_init(&data, kData3, sizeof(kData3));
125 /* zero byte length of length */
126 if (CBS_get_asn1(&data, &contents, 0x30)) {
130 CBS_init(&data, kData4, sizeof(kData4));
131 /* long form mistakenly used. */
132 if (CBS_get_asn1(&data, &contents, 0x30)) {
136 CBS_init(&data, kData5, sizeof(kData5));
137 /* length takes too many bytes. */
138 if (CBS_get_asn1(&data, &contents, 0x30)) {
142 CBS_init(&data, kData1, sizeof(kData1));
144 if (CBS_get_asn1(&data, &contents, 0x31)) {
151 static int test_cbb_basic(void) {
152 static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8};
158 if (!CBB_init(&cbb, 100)) {
163 if (!CBB_init(&cbb, 0) ||
164 !CBB_add_u8(&cbb, 1) ||
165 !CBB_add_u16(&cbb, 0x203) ||
166 !CBB_add_u24(&cbb, 0x40506) ||
167 !CBB_add_bytes(&cbb, (const uint8_t*) "\x07\x08", 2) ||
168 !CBB_finish(&cbb, &buf, &buf_len)) {
172 ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
177 static int test_cbb_fixed(void) {
183 if (!CBB_init_fixed(&cbb, NULL, 0) ||
184 CBB_add_u8(&cbb, 1) ||
185 !CBB_finish(&cbb, &out_buf, &out_size) ||
191 if (!CBB_init_fixed(&cbb, buf, 1) ||
192 !CBB_add_u8(&cbb, 1) ||
193 CBB_add_u8(&cbb, 2) ||
194 !CBB_finish(&cbb, &out_buf, &out_size) ||
204 static int test_cbb_finish_child(void) {
209 if (!CBB_init(&cbb, 16) ||
210 !CBB_add_u8_length_prefixed(&cbb, &child) ||
211 CBB_finish(&child, &out_buf, &out_size) ||
212 !CBB_finish(&cbb, &out_buf, &out_size) ||
222 static int test_cbb_prefixed(void) {
223 static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
224 4, 5, 6, 5, 4, 1, 0, 1, 2};
227 CBB cbb, contents, inner_contents, inner_inner_contents;
230 if (!CBB_init(&cbb, 0) ||
231 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
232 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
233 !CBB_add_u8(&contents, 1) ||
234 !CBB_add_u16_length_prefixed(&cbb, &contents) ||
235 !CBB_add_u16(&contents, 0x203) ||
236 !CBB_add_u24_length_prefixed(&cbb, &contents) ||
237 !CBB_add_u24(&contents, 0x40506) ||
238 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
239 !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
240 !CBB_add_u8(&inner_contents, 1) ||
241 !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
242 !CBB_add_u8(&inner_inner_contents, 2) ||
243 !CBB_finish(&cbb, &buf, &buf_len)) {
247 ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
252 static int test_cbb_misuse(void) {
253 CBB cbb, child, contents;
257 if (!CBB_init(&cbb, 0) ||
258 !CBB_add_u8_length_prefixed(&cbb, &child) ||
259 !CBB_add_u8(&child, 1) ||
260 !CBB_add_u8(&cbb, 2)) {
264 /* Since we wrote to |cbb|, |child| is now invalid and attempts to write to
266 if (CBB_add_u8(&child, 1) ||
267 CBB_add_u16(&child, 1) ||
268 CBB_add_u24(&child, 1) ||
269 CBB_add_u8_length_prefixed(&child, &contents) ||
270 CBB_add_u16_length_prefixed(&child, &contents) ||
271 CBB_add_asn1(&child, &contents, 1) ||
272 CBB_add_bytes(&child, (const uint8_t*) "a", 1)) {
273 fprintf(stderr, "CBB operation on invalid CBB did not fail.\n");
277 if (!CBB_finish(&cbb, &buf, &buf_len) ||
279 memcmp(buf, "\x01\x01\x02", 3) != 0) {
288 static int test_cbb_asn1(void) {
289 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
290 uint8_t *buf, *test_data;
292 CBB cbb, contents, inner_contents;
294 if (!CBB_init(&cbb, 0) ||
295 !CBB_add_asn1(&cbb, &contents, 0x30) ||
296 !CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) ||
297 !CBB_finish(&cbb, &buf, &buf_len)) {
301 if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
306 test_data = malloc(100000);
307 memset(test_data, 0x42, 100000);
309 if (!CBB_init(&cbb, 0) ||
310 !CBB_add_asn1(&cbb, &contents, 0x30) ||
311 !CBB_add_bytes(&contents, test_data, 130) ||
312 !CBB_finish(&cbb, &buf, &buf_len)) {
316 if (buf_len != 3 + 130 ||
317 memcmp(buf, "\x30\x81\x82", 3) != 0 ||
318 memcmp(buf + 3, test_data, 130) != 0) {
323 if (!CBB_init(&cbb, 0) ||
324 !CBB_add_asn1(&cbb, &contents, 0x30) ||
325 !CBB_add_bytes(&contents, test_data, 1000) ||
326 !CBB_finish(&cbb, &buf, &buf_len)) {
330 if (buf_len != 4 + 1000 ||
331 memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
332 memcmp(buf + 4, test_data, 1000)) {
337 if (!CBB_init(&cbb, 0) ||
338 !CBB_add_asn1(&cbb, &contents, 0x30) ||
339 !CBB_add_asn1(&contents, &inner_contents, 0x30) ||
340 !CBB_add_bytes(&inner_contents, test_data, 100000) ||
341 !CBB_finish(&cbb, &buf, &buf_len)) {
345 if (buf_len != 5 + 5 + 100000 ||
346 memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 ||
347 memcmp(buf + 10, test_data, 100000)) {
356 static int do_ber_convert(const char *name,
357 const uint8_t *der_expected, size_t der_len,
358 const uint8_t *ber, size_t ber_len) {
363 CBS_init(&in, ber, ber_len);
364 if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) {
365 fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name);
370 if (ber_len != der_len ||
371 memcmp(der_expected, ber, ber_len) != 0) {
372 fprintf(stderr, "%s: incorrect unconverted result.\n", name);
379 if (out_len != der_len ||
380 memcmp(out, der_expected, der_len) != 0) {
381 fprintf(stderr, "%s: incorrect converted result.\n", name);
389 static int test_ber_convert(void) {
390 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
392 /* kIndefBER contains a SEQUENCE with an indefinite length. */
393 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00};
394 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
396 /* kOctetStringBER contains an indefinite length OCTETSTRING with two parts.
397 * These parts need to be concatenated in DER form. */
398 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1,
399 0x04, 0x02, 2, 3, 0x00, 0x00};
400 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3};
402 /* kNSSBER is part of a PKCS#12 message generated by NSS that uses indefinite
403 * length elements extensively. */
404 static const uint8_t kNSSBER[] = {
405 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48,
406 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x04,
407 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
408 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
409 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90,
410 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04,
411 0x10, 0x38, 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b,
412 0xf0, 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00,
415 static const uint8_t kNSSDER[] = {
416 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86,
417 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04,
418 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06,
419 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84,
420 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8,
421 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38,
422 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0,
423 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
426 return do_ber_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
427 kSimpleBER, sizeof(kSimpleBER)) &&
428 do_ber_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
429 sizeof(kIndefBER)) &&
430 do_ber_convert("kOctetStringBER", kOctetStringDER,
431 sizeof(kOctetStringDER), kOctetStringBER,
432 sizeof(kOctetStringBER)) &&
433 do_ber_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
438 CRYPTO_library_init();
442 !test_get_prefixed() ||
443 !test_get_prefixed_bad() ||
447 !test_cbb_finish_child() ||
448 !test_cbb_misuse() ||
449 !test_cbb_prefixed() ||
451 !test_ber_convert()) {