1 /* Copyright (c) 2014, Google Inc.
2 *
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.
6 *
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. */
14
15 #if !defined(__STDC_CONSTANT_MACROS)
16 #define __STDC_CONSTANT_MACROS
17 #endif
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <vector>
24
25 #include <openssl/bytestring.h>
26 #include <openssl/crypto.h>
27
28 #include "internal.h"
29 #include "../internal.h"
30
31
TestSkip()32 static bool TestSkip() {
33 static const uint8_t kData[] = {1, 2, 3};
34 CBS data;
35
36 CBS_init(&data, kData, sizeof(kData));
37 return CBS_len(&data) == 3 &&
38 CBS_skip(&data, 1) &&
39 CBS_len(&data) == 2 &&
40 CBS_skip(&data, 2) &&
41 CBS_len(&data) == 0 &&
42 !CBS_skip(&data, 1);
43 }
44
TestGetUint()45 static bool TestGetUint() {
46 static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
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_last_u8(&data, &u8) &&
62 u8 == 0xb &&
63 !CBS_get_u8(&data, &u8) &&
64 !CBS_get_last_u8(&data, &u8);
65 }
66
TestGetPrefixed()67 static bool TestGetPrefixed() {
68 static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
69 uint8_t u8;
70 uint16_t u16;
71 uint32_t u32;
72 CBS data, prefixed;
73
74 CBS_init(&data, kData, sizeof(kData));
75 return CBS_get_u8_length_prefixed(&data, &prefixed) &&
76 CBS_len(&prefixed) == 1 &&
77 CBS_get_u8(&prefixed, &u8) &&
78 u8 == 2 &&
79 CBS_get_u16_length_prefixed(&data, &prefixed) &&
80 CBS_len(&prefixed) == 2 &&
81 CBS_get_u16(&prefixed, &u16) &&
82 u16 == 0x304 &&
83 CBS_get_u24_length_prefixed(&data, &prefixed) &&
84 CBS_len(&prefixed) == 3 &&
85 CBS_get_u24(&prefixed, &u32) &&
86 u32 == 0x30201;
87 }
88
TestGetPrefixedBad()89 static bool TestGetPrefixedBad() {
90 static const uint8_t kData1[] = {2, 1};
91 static const uint8_t kData2[] = {0, 2, 1};
92 static const uint8_t kData3[] = {0, 0, 2, 1};
93 CBS data, prefixed;
94
95 CBS_init(&data, kData1, sizeof(kData1));
96 if (CBS_get_u8_length_prefixed(&data, &prefixed)) {
97 return false;
98 }
99
100 CBS_init(&data, kData2, sizeof(kData2));
101 if (CBS_get_u16_length_prefixed(&data, &prefixed)) {
102 return false;
103 }
104
105 CBS_init(&data, kData3, sizeof(kData3));
106 if (CBS_get_u24_length_prefixed(&data, &prefixed)) {
107 return false;
108 }
109
110 return true;
111 }
112
TestGetASN1()113 static bool TestGetASN1() {
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[4 + 0x80] = {0x30, 0x82, 0, 0x80};
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) ||
130 !CBS_peek_asn1_tag(&data, 0x30)) {
131 return false;
132 }
133 if (!CBS_get_asn1(&data, &contents, 0x30) ||
134 CBS_len(&contents) != 2 ||
135 OPENSSL_memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
136 return false;
137 }
138
139 CBS_init(&data, kData2, sizeof(kData2));
140 // data is truncated
141 if (CBS_get_asn1(&data, &contents, 0x30)) {
142 return false;
143 }
144
145 CBS_init(&data, kData3, sizeof(kData3));
146 // zero byte length of length
147 if (CBS_get_asn1(&data, &contents, 0x30)) {
148 return false;
149 }
150
151 CBS_init(&data, kData4, sizeof(kData4));
152 // long form mistakenly used.
153 if (CBS_get_asn1(&data, &contents, 0x30)) {
154 return false;
155 }
156
157 CBS_init(&data, kData5, sizeof(kData5));
158 // length takes too many bytes.
159 if (CBS_get_asn1(&data, &contents, 0x30)) {
160 return false;
161 }
162
163 CBS_init(&data, kData1, sizeof(kData1));
164 // wrong tag.
165 if (CBS_get_asn1(&data, &contents, 0x31)) {
166 return false;
167 }
168
169 CBS_init(&data, NULL, 0);
170 // peek at empty data.
171 if (CBS_peek_asn1_tag(&data, 0x30)) {
172 return false;
173 }
174
175 CBS_init(&data, NULL, 0);
176 // optional elements at empty data.
177 if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) ||
178 present ||
179 !CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) ||
180 present ||
181 CBS_len(&contents) != 0 ||
182 !CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0) ||
183 CBS_len(&contents) != 0 ||
184 !CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) ||
185 value != 42) {
186 return false;
187 }
188
189 CBS_init(&data, kData6, sizeof(kData6));
190 // optional element.
191 if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) ||
192 present ||
193 !CBS_get_optional_asn1(&data, &contents, &present, 0xa1) ||
194 !present ||
195 CBS_len(&contents) != 3 ||
196 OPENSSL_memcmp(CBS_data(&contents), "\x04\x01\x01", 3) != 0) {
197 return false;
198 }
199
200 CBS_init(&data, kData6, sizeof(kData6));
201 // optional octet string.
202 if (!CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) ||
203 present ||
204 CBS_len(&contents) != 0 ||
205 !CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1) ||
206 !present ||
207 CBS_len(&contents) != 1 ||
208 CBS_data(&contents)[0] != 1) {
209 return false;
210 }
211
212 CBS_init(&data, kData7, sizeof(kData7));
213 // invalid optional octet string.
214 if (CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1)) {
215 return false;
216 }
217
218 CBS_init(&data, kData8, sizeof(kData8));
219 // optional octet string.
220 if (!CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) ||
221 value != 42 ||
222 !CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42) ||
223 value != 1) {
224 return false;
225 }
226
227 CBS_init(&data, kData9, sizeof(kData9));
228 // invalid optional integer.
229 if (CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)) {
230 return false;
231 }
232
233 unsigned tag;
234 CBS_init(&data, kData1, sizeof(kData1));
235 if (!CBS_get_any_asn1(&data, &contents, &tag) ||
236 tag != CBS_ASN1_SEQUENCE ||
237 CBS_len(&contents) != 2 ||
238 OPENSSL_memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
239 return false;
240 }
241
242 size_t header_len;
243 CBS_init(&data, kData1, sizeof(kData1));
244 if (!CBS_get_any_asn1_element(&data, &contents, &tag, &header_len) ||
245 tag != CBS_ASN1_SEQUENCE ||
246 header_len != 2 ||
247 CBS_len(&contents) != 4 ||
248 OPENSSL_memcmp(CBS_data(&contents), "\x30\x02\x01\x02", 2) != 0) {
249 return false;
250 }
251
252 return true;
253 }
254
TestGetOptionalASN1Bool()255 static bool TestGetOptionalASN1Bool() {
256 static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff};
257 static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00};
258 static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01};
259
260 CBS data;
261 CBS_init(&data, NULL, 0);
262 int val = 2;
263 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) ||
264 val != 0) {
265 return false;
266 }
267
268 CBS_init(&data, kTrue, sizeof(kTrue));
269 val = 2;
270 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) ||
271 val != 1) {
272 return false;
273 }
274
275 CBS_init(&data, kFalse, sizeof(kFalse));
276 val = 2;
277 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1) ||
278 val != 0) {
279 return false;
280 }
281
282 CBS_init(&data, kInvalid, sizeof(kInvalid));
283 if (CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)) {
284 return false;
285 }
286
287 return true;
288 }
289
TestCBBBasic()290 static bool TestCBBBasic() {
291 static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc};
292 uint8_t *buf;
293 size_t buf_len;
294 CBB cbb;
295
296 if (!CBB_init(&cbb, 100)) {
297 return false;
298 }
299 CBB_cleanup(&cbb);
300
301 if (!CBB_init(&cbb, 0)) {
302 return false;
303 }
304 if (!CBB_add_u8(&cbb, 1) ||
305 !CBB_add_u16(&cbb, 0x203) ||
306 !CBB_add_u24(&cbb, 0x40506) ||
307 !CBB_add_u32(&cbb, 0x708090a) ||
308 !CBB_add_bytes(&cbb, (const uint8_t*) "\x0b\x0c", 2) ||
309 !CBB_finish(&cbb, &buf, &buf_len)) {
310 CBB_cleanup(&cbb);
311 return false;
312 }
313
314 bssl::UniquePtr<uint8_t> scoper(buf);
315 return buf_len == sizeof(kExpected) &&
316 OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
317 }
318
TestCBBFixed()319 static bool TestCBBFixed() {
320 bssl::ScopedCBB cbb;
321 uint8_t buf[1];
322 uint8_t *out_buf;
323 size_t out_size;
324
325 if (!CBB_init_fixed(cbb.get(), NULL, 0) ||
326 !CBB_finish(cbb.get(), &out_buf, &out_size) ||
327 out_buf != NULL ||
328 out_size != 0) {
329 return false;
330 }
331
332 cbb.Reset();
333 if (!CBB_init_fixed(cbb.get(), buf, 1) ||
334 !CBB_add_u8(cbb.get(), 1) ||
335 !CBB_finish(cbb.get(), &out_buf, &out_size) ||
336 out_buf != buf ||
337 out_size != 1 ||
338 buf[0] != 1) {
339 return false;
340 }
341
342 cbb.Reset();
343 if (!CBB_init_fixed(cbb.get(), buf, 1) ||
344 !CBB_add_u8(cbb.get(), 1) ||
345 CBB_add_u8(cbb.get(), 2)) {
346 return false;
347 }
348
349 return true;
350 }
351
TestCBBFinishChild()352 static bool TestCBBFinishChild() {
353 CBB cbb, child;
354 uint8_t *out_buf;
355 size_t out_size;
356
357 if (!CBB_init(&cbb, 16)) {
358 return false;
359 }
360 if (!CBB_add_u8_length_prefixed(&cbb, &child) ||
361 CBB_finish(&child, &out_buf, &out_size) ||
362 !CBB_finish(&cbb, &out_buf, &out_size)) {
363 CBB_cleanup(&cbb);
364 return false;
365 }
366 bssl::UniquePtr<uint8_t> scoper(out_buf);
367 return out_size == 1 && out_buf[0] == 0;
368 }
369
TestCBBPrefixed()370 static bool TestCBBPrefixed() {
371 static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
372 4, 5, 6, 5, 4, 1, 0, 1, 2};
373 uint8_t *buf;
374 size_t buf_len;
375 CBB cbb, contents, inner_contents, inner_inner_contents;
376
377 if (!CBB_init(&cbb, 0) ||
378 CBB_len(&cbb) != 0 ||
379 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
380 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
381 !CBB_add_u8(&contents, 1) ||
382 CBB_len(&contents) != 1 ||
383 !CBB_flush(&cbb) ||
384 CBB_len(&cbb) != 3 ||
385 !CBB_add_u16_length_prefixed(&cbb, &contents) ||
386 !CBB_add_u16(&contents, 0x203) ||
387 !CBB_add_u24_length_prefixed(&cbb, &contents) ||
388 !CBB_add_u24(&contents, 0x40506) ||
389 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
390 !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
391 !CBB_add_u8(&inner_contents, 1) ||
392 !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
393 !CBB_add_u8(&inner_inner_contents, 2) ||
394 !CBB_finish(&cbb, &buf, &buf_len)) {
395 CBB_cleanup(&cbb);
396 return false;
397 }
398
399 bssl::UniquePtr<uint8_t> scoper(buf);
400 return buf_len == sizeof(kExpected) &&
401 OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
402 }
403
TestCBBDiscardChild()404 static bool TestCBBDiscardChild() {
405 bssl::ScopedCBB cbb;
406 CBB contents, inner_contents, inner_inner_contents;
407
408 if (!CBB_init(cbb.get(), 0) ||
409 !CBB_add_u8(cbb.get(), 0xaa)) {
410 return false;
411 }
412
413 // Discarding |cbb|'s children preserves the byte written.
414 CBB_discard_child(cbb.get());
415
416 if (!CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
417 !CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
418 !CBB_add_u8(&contents, 0xbb) ||
419 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
420 !CBB_add_u16(&contents, 0xcccc) ||
421 !CBB_add_u24_length_prefixed(cbb.get(), &contents) ||
422 !CBB_add_u24(&contents, 0xdddddd) ||
423 !CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
424 !CBB_add_u8(&contents, 0xff) ||
425 !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
426 !CBB_add_u8(&inner_contents, 0x42) ||
427 !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
428 !CBB_add_u8(&inner_inner_contents, 0x99)) {
429 return false;
430 }
431
432 // Discard everything from |inner_contents| down.
433 CBB_discard_child(&contents);
434
435 uint8_t *buf;
436 size_t buf_len;
437 if (!CBB_finish(cbb.get(), &buf, &buf_len)) {
438 return false;
439 }
440 bssl::UniquePtr<uint8_t> scoper(buf);
441
442 static const uint8_t kExpected[] = {
443 0xaa,
444 0,
445 1, 0xbb,
446 0, 2, 0xcc, 0xcc,
447 0, 0, 3, 0xdd, 0xdd, 0xdd,
448 1, 0xff,
449 };
450 return buf_len == sizeof(kExpected) &&
451 OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
452 }
453
TestCBBMisuse()454 static bool TestCBBMisuse() {
455 CBB cbb, child, contents;
456 uint8_t *buf;
457 size_t buf_len;
458
459 if (!CBB_init(&cbb, 0)) {
460 return false;
461 }
462 if (!CBB_add_u8_length_prefixed(&cbb, &child) ||
463 !CBB_add_u8(&child, 1) ||
464 !CBB_add_u8(&cbb, 2)) {
465 CBB_cleanup(&cbb);
466 return false;
467 }
468
469 // Since we wrote to |cbb|, |child| is now invalid and attempts to write to
470 // it should fail.
471 if (CBB_add_u8(&child, 1) ||
472 CBB_add_u16(&child, 1) ||
473 CBB_add_u24(&child, 1) ||
474 CBB_add_u8_length_prefixed(&child, &contents) ||
475 CBB_add_u16_length_prefixed(&child, &contents) ||
476 CBB_add_asn1(&child, &contents, 1) ||
477 CBB_add_bytes(&child, (const uint8_t*) "a", 1)) {
478 fprintf(stderr, "CBB operation on invalid CBB did not fail.\n");
479 CBB_cleanup(&cbb);
480 return false;
481 }
482
483 if (!CBB_finish(&cbb, &buf, &buf_len)) {
484 CBB_cleanup(&cbb);
485 return false;
486 }
487 bssl::UniquePtr<uint8_t> scoper(buf);
488
489 if (buf_len != 3 ||
490 OPENSSL_memcmp(buf, "\x01\x01\x02", 3) != 0) {
491 return false;
492 }
493 return true;
494 }
495
TestCBBASN1()496 static bool TestCBBASN1() {
497 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
498 uint8_t *buf;
499 size_t buf_len;
500 CBB cbb, contents, inner_contents;
501
502 if (!CBB_init(&cbb, 0)) {
503 return false;
504 }
505 if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
506 !CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) ||
507 !CBB_finish(&cbb, &buf, &buf_len)) {
508 CBB_cleanup(&cbb);
509 return false;
510 }
511 bssl::UniquePtr<uint8_t> scoper(buf);
512
513 if (buf_len != sizeof(kExpected) ||
514 OPENSSL_memcmp(buf, kExpected, buf_len) != 0) {
515 return false;
516 }
517
518 std::vector<uint8_t> test_data(100000, 0x42);
519
520 if (!CBB_init(&cbb, 0)) {
521 return false;
522 }
523 if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
524 !CBB_add_bytes(&contents, test_data.data(), 130) ||
525 !CBB_finish(&cbb, &buf, &buf_len)) {
526 CBB_cleanup(&cbb);
527 return false;
528 }
529 scoper.reset(buf);
530
531 if (buf_len != 3 + 130 ||
532 OPENSSL_memcmp(buf, "\x30\x81\x82", 3) != 0 ||
533 OPENSSL_memcmp(buf + 3, test_data.data(), 130) != 0) {
534 return false;
535 }
536
537 if (!CBB_init(&cbb, 0)) {
538 return false;
539 }
540 if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
541 !CBB_add_bytes(&contents, test_data.data(), 1000) ||
542 !CBB_finish(&cbb, &buf, &buf_len)) {
543 CBB_cleanup(&cbb);
544 return false;
545 }
546 scoper.reset(buf);
547
548 if (buf_len != 4 + 1000 ||
549 OPENSSL_memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
550 OPENSSL_memcmp(buf + 4, test_data.data(), 1000)) {
551 return false;
552 }
553
554 if (!CBB_init(&cbb, 0)) {
555 return false;
556 }
557 if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
558 !CBB_add_asn1(&contents, &inner_contents, 0x30) ||
559 !CBB_add_bytes(&inner_contents, test_data.data(), 100000) ||
560 !CBB_finish(&cbb, &buf, &buf_len)) {
561 CBB_cleanup(&cbb);
562 return false;
563 }
564 scoper.reset(buf);
565
566 if (buf_len != 5 + 5 + 100000 ||
567 OPENSSL_memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) !=
568 0 ||
569 OPENSSL_memcmp(buf + 10, test_data.data(), 100000)) {
570 return false;
571 }
572
573 return true;
574 }
575
DoBerConvert(const char * name,const uint8_t * der_expected,size_t der_len,const uint8_t * ber,size_t ber_len)576 static bool DoBerConvert(const char *name,
577 const uint8_t *der_expected, size_t der_len,
578 const uint8_t *ber, size_t ber_len) {
579 CBS in;
580 uint8_t *out;
581 size_t out_len;
582
583 CBS_init(&in, ber, ber_len);
584 if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) {
585 fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name);
586 return false;
587 }
588 bssl::UniquePtr<uint8_t> scoper(out);
589
590 if (out == NULL) {
591 if (ber_len != der_len ||
592 OPENSSL_memcmp(der_expected, ber, ber_len) != 0) {
593 fprintf(stderr, "%s: incorrect unconverted result.\n", name);
594 return false;
595 }
596
597 return true;
598 }
599
600 if (out_len != der_len ||
601 OPENSSL_memcmp(out, der_expected, der_len) != 0) {
602 fprintf(stderr, "%s: incorrect converted result.\n", name);
603 return false;
604 }
605
606 return true;
607 }
608
TestBerConvert()609 static bool TestBerConvert() {
610 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
611
612 // kIndefBER contains a SEQUENCE with an indefinite length.
613 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00};
614 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
615
616 // kOctetStringBER contains an indefinite length OCTET STRING with two parts.
617 // These parts need to be concatenated in DER form.
618 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1,
619 0x04, 0x02, 2, 3, 0x00, 0x00};
620 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3};
621
622 // kNSSBER is part of a PKCS#12 message generated by NSS that uses indefinite
623 // length elements extensively.
624 static const uint8_t kNSSBER[] = {
625 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48,
626 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x04,
627 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
628 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
629 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90,
630 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04,
631 0x10, 0x38, 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b,
632 0xf0, 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00,
633 };
634
635 static const uint8_t kNSSDER[] = {
636 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86,
637 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04,
638 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06,
639 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84,
640 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8,
641 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38,
642 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0,
643 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
644 };
645
646 // kConstructedStringBER contains a deeply-nested constructed OCTET STRING.
647 // The BER conversion collapses this to one level deep, but not completely.
648 static const uint8_t kConstructedStringBER[] = {
649 0xa0, 0x10, 0x24, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01,
650 0x01, 0x24, 0x06, 0x04, 0x01, 0x02, 0x04, 0x01, 0x03,
651 };
652 static const uint8_t kConstructedStringDER[] = {
653 0xa0, 0x08, 0x04, 0x02, 0x00, 0x01, 0x04, 0x02, 0x02, 0x03,
654 };
655
656 return DoBerConvert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
657 kSimpleBER, sizeof(kSimpleBER)) &&
658 DoBerConvert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
659 sizeof(kIndefBER)) &&
660 DoBerConvert("kOctetStringBER", kOctetStringDER,
661 sizeof(kOctetStringDER), kOctetStringBER,
662 sizeof(kOctetStringBER)) &&
663 DoBerConvert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
664 sizeof(kNSSBER)) &&
665 DoBerConvert("kConstructedStringBER", kConstructedStringDER,
666 sizeof(kConstructedStringDER), kConstructedStringBER,
667 sizeof(kConstructedStringBER));
668 }
669
670 struct ImplicitStringTest {
671 const char *in;
672 size_t in_len;
673 bool ok;
674 const char *out;
675 size_t out_len;
676 };
677
678 static const ImplicitStringTest kImplicitStringTests[] = {
679 // A properly-encoded string.
680 {"\x80\x03\x61\x61\x61", 5, true, "aaa", 3},
681 // An implicit-tagged string.
682 {"\xa0\x09\x04\x01\x61\x04\x01\x61\x04\x01\x61", 11, true, "aaa", 3},
683 // |CBS_get_asn1_implicit_string| only accepts one level deep of nesting.
684 {"\xa0\x0b\x24\x06\x04\x01\x61\x04\x01\x61\x04\x01\x61", 13, false, nullptr,
685 0},
686 // The outer tag must match.
687 {"\x81\x03\x61\x61\x61", 5, false, nullptr, 0},
688 {"\xa1\x09\x04\x01\x61\x04\x01\x61\x04\x01\x61", 11, false, nullptr, 0},
689 // The inner tag must match.
690 {"\xa1\x09\x0c\x01\x61\x0c\x01\x61\x0c\x01\x61", 11, false, nullptr, 0},
691 };
692
TestImplicitString()693 static bool TestImplicitString() {
694 for (const auto &test : kImplicitStringTests) {
695 uint8_t *storage = nullptr;
696 CBS in, out;
697 CBS_init(&in, reinterpret_cast<const uint8_t *>(test.in), test.in_len);
698 int ok = CBS_get_asn1_implicit_string(&in, &out, &storage,
699 CBS_ASN1_CONTEXT_SPECIFIC | 0,
700 CBS_ASN1_OCTETSTRING);
701 bssl::UniquePtr<uint8_t> scoper(storage);
702
703 if (static_cast<bool>(ok) != test.ok) {
704 fprintf(stderr, "CBS_get_asn1_implicit_string unexpectedly %s\n",
705 ok ? "succeeded" : "failed");
706 return false;
707 }
708
709 if (ok && (CBS_len(&out) != test.out_len ||
710 OPENSSL_memcmp(CBS_data(&out), test.out, test.out_len) != 0)) {
711 fprintf(stderr, "CBS_get_asn1_implicit_string gave the wrong output\n");
712 return false;
713 }
714 }
715
716 return true;
717 }
718
719 struct ASN1Uint64Test {
720 uint64_t value;
721 const char *encoding;
722 size_t encoding_len;
723 };
724
725 static const ASN1Uint64Test kASN1Uint64Tests[] = {
726 {0, "\x02\x01\x00", 3},
727 {1, "\x02\x01\x01", 3},
728 {127, "\x02\x01\x7f", 3},
729 {128, "\x02\x02\x00\x80", 4},
730 {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
731 {UINT64_C(0x0102030405060708),
732 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
733 {UINT64_C(0xffffffffffffffff),
734 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
735 };
736
737 struct ASN1InvalidUint64Test {
738 const char *encoding;
739 size_t encoding_len;
740 };
741
742 static const ASN1InvalidUint64Test kASN1InvalidUint64Tests[] = {
743 // Bad tag.
744 {"\x03\x01\x00", 3},
745 // Empty contents.
746 {"\x02\x00", 2},
747 // Negative number.
748 {"\x02\x01\x80", 3},
749 // Overflow.
750 {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11},
751 // Leading zeros.
752 {"\x02\x02\x00\x01", 4},
753 };
754
TestASN1Uint64()755 static bool TestASN1Uint64() {
756 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Uint64Tests); i++) {
757 const ASN1Uint64Test *test = &kASN1Uint64Tests[i];
758 CBS cbs;
759 uint64_t value;
760 CBB cbb;
761 uint8_t *out;
762 size_t len;
763
764 CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len);
765 if (!CBS_get_asn1_uint64(&cbs, &value) ||
766 CBS_len(&cbs) != 0 ||
767 value != test->value) {
768 return false;
769 }
770
771 if (!CBB_init(&cbb, 0)) {
772 return false;
773 }
774 if (!CBB_add_asn1_uint64(&cbb, test->value) ||
775 !CBB_finish(&cbb, &out, &len)) {
776 CBB_cleanup(&cbb);
777 return false;
778 }
779 bssl::UniquePtr<uint8_t> scoper(out);
780 if (len != test->encoding_len ||
781 OPENSSL_memcmp(out, test->encoding, len) != 0) {
782 return false;
783 }
784 }
785
786 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kASN1InvalidUint64Tests); i++) {
787 const ASN1InvalidUint64Test *test = &kASN1InvalidUint64Tests[i];
788 CBS cbs;
789 uint64_t value;
790
791 CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len);
792 if (CBS_get_asn1_uint64(&cbs, &value)) {
793 return false;
794 }
795 }
796
797 return true;
798 }
799
TestZero()800 static bool TestZero() {
801 CBB cbb;
802 CBB_zero(&cbb);
803 // Calling |CBB_cleanup| on a zero-state |CBB| must not crash.
804 CBB_cleanup(&cbb);
805 return true;
806 }
807
TestCBBReserve()808 static bool TestCBBReserve() {
809 uint8_t buf[10];
810 uint8_t *ptr;
811 size_t len;
812 bssl::ScopedCBB cbb;
813 if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) ||
814 // Too large.
815 CBB_reserve(cbb.get(), &ptr, 11)) {
816 return false;
817 }
818
819 cbb.Reset();
820 if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) ||
821 // Successfully reserve the entire space.
822 !CBB_reserve(cbb.get(), &ptr, 10) ||
823 ptr != buf ||
824 // Advancing under the maximum bytes is legal.
825 !CBB_did_write(cbb.get(), 5) ||
826 !CBB_finish(cbb.get(), NULL, &len) ||
827 len != 5) {
828 return false;
829 }
830 return true;
831 }
832
TestStickyError()833 static bool TestStickyError() {
834 // Write an input that exceeds the limit for its length prefix.
835 bssl::ScopedCBB cbb;
836 CBB child;
837 static const uint8_t kZeros[256] = {0};
838 if (!CBB_init(cbb.get(), 0) ||
839 !CBB_add_u8_length_prefixed(cbb.get(), &child) ||
840 !CBB_add_bytes(&child, kZeros, sizeof(kZeros))) {
841 return false;
842 }
843
844 if (CBB_flush(cbb.get())) {
845 fprintf(stderr, "CBB_flush unexpectedly succeeded.\n");
846 return false;
847 }
848
849 // All future operations should fail.
850 uint8_t *ptr;
851 size_t len;
852 if (CBB_add_u8(cbb.get(), 0) ||
853 CBB_finish(cbb.get(), &ptr, &len)) {
854 fprintf(stderr, "Future operations unexpectedly succeeded.\n");
855 return false;
856 }
857
858 // Write an input that cannot fit in a fixed CBB.
859 cbb.Reset();
860 uint8_t buf;
861 if (!CBB_init_fixed(cbb.get(), &buf, 1)) {
862 return false;
863 }
864
865 if (CBB_add_bytes(cbb.get(), kZeros, sizeof(kZeros))) {
866 fprintf(stderr, "CBB_add_bytes unexpectedly succeeded.\n");
867 return false;
868 }
869
870 // All future operations should fail.
871 if (CBB_add_u8(cbb.get(), 0) ||
872 CBB_finish(cbb.get(), &ptr, &len)) {
873 fprintf(stderr, "Future operations unexpectedly succeeded.\n");
874 return false;
875 }
876
877 // Write a u32 that cannot fit in a u24.
878 cbb.Reset();
879 if (!CBB_init(cbb.get(), 0)) {
880 return false;
881 }
882
883 if (CBB_add_u24(cbb.get(), 1u << 24)) {
884 fprintf(stderr, "CBB_add_u24 unexpectedly succeeded.\n");
885 return false;
886 }
887
888 // All future operations should fail.
889 if (CBB_add_u8(cbb.get(), 0) ||
890 CBB_finish(cbb.get(), &ptr, &len)) {
891 fprintf(stderr, "Future operations unexpectedly succeeded.\n");
892 return false;
893 }
894
895 return true;
896 }
897
TestBitString()898 static bool TestBitString() {
899 static const std::vector<uint8_t> kValidBitStrings[] = {
900 {0x00}, // 0 bits
901 {0x07, 0x80}, // 1 bit
902 {0x04, 0xf0}, // 4 bits
903 {0x00, 0xff}, // 8 bits
904 {0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0}, // 42 bits
905 };
906 for (const auto& test : kValidBitStrings) {
907 CBS cbs;
908 CBS_init(&cbs, test.data(), test.size());
909 if (!CBS_is_valid_asn1_bitstring(&cbs)) {
910 return false;
911 }
912 }
913
914 static const std::vector<uint8_t> kInvalidBitStrings[] = {
915 // BIT STRINGs always have a leading byte.
916 std::vector<uint8_t>{},
917 // It's not possible to take an unused bit off the empty string.
918 {0x01},
919 // There can be at most 7 unused bits.
920 {0x08, 0xff},
921 {0xff, 0xff},
922 // All unused bits must be cleared.
923 {0x06, 0xff, 0xc1},
924 };
925 for (const auto& test : kInvalidBitStrings) {
926 CBS cbs;
927 CBS_init(&cbs, test.data(), test.size());
928 if (CBS_is_valid_asn1_bitstring(&cbs)) {
929 return false;
930 }
931
932 // CBS_asn1_bitstring_has_bit returns false on invalid inputs.
933 if (CBS_asn1_bitstring_has_bit(&cbs, 0)) {
934 return false;
935 }
936 }
937
938 static const struct {
939 std::vector<uint8_t> in;
940 unsigned bit;
941 bool bit_set;
942 } kBitTests[] = {
943 // Basic tests.
944 {{0x00}, 0, false},
945 {{0x07, 0x80}, 0, true},
946 {{0x06, 0x0f, 0x40}, 0, false},
947 {{0x06, 0x0f, 0x40}, 1, false},
948 {{0x06, 0x0f, 0x40}, 2, false},
949 {{0x06, 0x0f, 0x40}, 3, false},
950 {{0x06, 0x0f, 0x40}, 4, true},
951 {{0x06, 0x0f, 0x40}, 5, true},
952 {{0x06, 0x0f, 0x40}, 6, true},
953 {{0x06, 0x0f, 0x40}, 7, true},
954 {{0x06, 0x0f, 0x40}, 8, false},
955 {{0x06, 0x0f, 0x40}, 9, true},
956 // Out-of-bounds bits return 0.
957 {{0x06, 0x0f, 0x40}, 10, false},
958 {{0x06, 0x0f, 0x40}, 15, false},
959 {{0x06, 0x0f, 0x40}, 16, false},
960 {{0x06, 0x0f, 0x40}, 1000, false},
961 };
962 for (const auto& test : kBitTests) {
963 CBS cbs;
964 CBS_init(&cbs, test.in.data(), test.in.size());
965 if (CBS_asn1_bitstring_has_bit(&cbs, test.bit) !=
966 static_cast<int>(test.bit_set)) {
967 return false;
968 }
969 }
970
971 return true;
972 }
973
main()974 int main() {
975 CRYPTO_library_init();
976
977 if (!TestSkip() ||
978 !TestGetUint() ||
979 !TestGetPrefixed() ||
980 !TestGetPrefixedBad() ||
981 !TestGetASN1() ||
982 !TestCBBBasic() ||
983 !TestCBBFixed() ||
984 !TestCBBFinishChild() ||
985 !TestCBBMisuse() ||
986 !TestCBBPrefixed() ||
987 !TestCBBDiscardChild() ||
988 !TestCBBASN1() ||
989 !TestBerConvert() ||
990 !TestImplicitString() ||
991 !TestASN1Uint64() ||
992 !TestGetOptionalASN1Bool() ||
993 !TestZero() ||
994 !TestCBBReserve() ||
995 !TestStickyError() ||
996 !TestBitString()) {
997 return 1;
998 }
999
1000 printf("PASS\n");
1001 return 0;
1002 }
1003