Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / crypto / bytestring / bytestring_test.c
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 #include <stdio.h>
16 #include <stdlib.h>
17
18 #include <openssl/crypto.h>
19 #include <openssl/bytestring.h>
20
21 #include "internal.h"
22
23
24 static int test_skip(void) {
25   static const uint8_t kData[] = {1, 2, 3};
26   CBS data;
27
28   CBS_init(&data, kData, sizeof(kData));
29   return CBS_len(&data) == 3 &&
30       CBS_skip(&data, 1) &&
31       CBS_len(&data) == 2 &&
32       CBS_skip(&data, 2) &&
33       CBS_len(&data) == 0 &&
34       !CBS_skip(&data, 1);
35 }
36
37 static int test_get_u(void) {
38   static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
39   uint8_t u8;
40   uint16_t u16;
41   uint32_t u32;
42   CBS data;
43
44   CBS_init(&data, kData, sizeof(kData));
45   return CBS_get_u8(&data, &u8) &&
46     u8 == 1 &&
47     CBS_get_u16(&data, &u16) &&
48     u16 == 0x203 &&
49     CBS_get_u24(&data, &u32) &&
50     u32 == 0x40506 &&
51     CBS_get_u32(&data, &u32) &&
52     u32 == 0x708090a &&
53     !CBS_get_u8(&data, &u8);
54 }
55
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};
58   uint8_t u8;
59   uint16_t u16;
60   uint32_t u32;
61   CBS data, prefixed;
62
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) &&
67     u8 == 2 &&
68     CBS_get_u16_length_prefixed(&data, &prefixed) &&
69     CBS_len(&prefixed) == 2 &&
70     CBS_get_u16(&prefixed, &u16) &&
71     u16 == 0x304 &&
72     CBS_get_u24_length_prefixed(&data, &prefixed) &&
73     CBS_len(&prefixed) == 3 &&
74     CBS_get_u24(&prefixed, &u32) &&
75     u32 == 0x30201;
76 }
77
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};
82   CBS data, prefixed;
83
84   CBS_init(&data, kData1, sizeof(kData1));
85   if (CBS_get_u8_length_prefixed(&data, &prefixed)) {
86     return 0;
87   }
88
89   CBS_init(&data, kData2, sizeof(kData2));
90   if (CBS_get_u16_length_prefixed(&data, &prefixed)) {
91     return 0;
92   }
93
94   CBS_init(&data, kData3, sizeof(kData3));
95   if (CBS_get_u24_length_prefixed(&data, &prefixed)) {
96     return 0;
97   }
98
99   return 1;
100 }
101
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};
108
109   CBS data, contents;
110
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) {
115     return 0;
116   }
117
118   CBS_init(&data, kData2, sizeof(kData2));
119   /* data is truncated */
120   if (CBS_get_asn1(&data, &contents, 0x30)) {
121     return 0;
122   }
123
124   CBS_init(&data, kData3, sizeof(kData3));
125   /* zero byte length of length */
126   if (CBS_get_asn1(&data, &contents, 0x30)) {
127     return 0;
128   }
129
130   CBS_init(&data, kData4, sizeof(kData4));
131   /* long form mistakenly used. */
132   if (CBS_get_asn1(&data, &contents, 0x30)) {
133     return 0;
134   }
135
136   CBS_init(&data, kData5, sizeof(kData5));
137   /* length takes too many bytes. */
138   if (CBS_get_asn1(&data, &contents, 0x30)) {
139     return 0;
140   }
141
142   CBS_init(&data, kData1, sizeof(kData1));
143   /* wrong tag. */
144   if (CBS_get_asn1(&data, &contents, 0x31)) {
145     return 0;
146   }
147
148   return 1;
149 }
150
151 static int test_cbb_basic(void) {
152   static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8};
153   uint8_t *buf;
154   size_t buf_len;
155   int ok;
156   CBB cbb;
157
158   if (!CBB_init(&cbb, 100)) {
159     return 0;
160   }
161   CBB_cleanup(&cbb);
162
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)) {
169     return 0;
170   }
171
172   ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
173   free(buf);
174   return ok;
175 }
176
177 static int test_cbb_fixed(void) {
178   CBB cbb;
179   uint8_t buf[1];
180   uint8_t *out_buf;
181   size_t out_size;
182
183   if (!CBB_init_fixed(&cbb, NULL, 0) ||
184       CBB_add_u8(&cbb, 1) ||
185       !CBB_finish(&cbb, &out_buf, &out_size) ||
186       out_buf != NULL ||
187       out_size != 0) {
188     return 0;
189   }
190
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) ||
195       out_buf != buf ||
196       out_size != 1 ||
197       buf[0] != 1) {
198     return 0;
199   }
200
201   return 1;
202 }
203
204 static int test_cbb_finish_child(void) {
205   CBB cbb, child;
206   uint8_t *out_buf;
207   size_t out_size;
208
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) ||
213       out_size != 1 ||
214       out_buf[0] != 0) {
215     return 0;
216   }
217
218   free(out_buf);
219   return 1;
220 }
221
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};
225   uint8_t *buf;
226   size_t buf_len;
227   CBB cbb, contents, inner_contents, inner_inner_contents;
228   int ok;
229
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)) {
244     return 0;
245   }
246
247   ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
248   free(buf);
249   return ok;
250 }
251
252 static int test_cbb_misuse(void) {
253   CBB cbb, child, contents;
254   uint8_t *buf;
255   size_t buf_len;
256
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)) {
261     return 0;
262   }
263
264   /* Since we wrote to |cbb|, |child| is now invalid and attempts to write to
265    * it should fail. */
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");
274     return 0;
275   }
276
277   if (!CBB_finish(&cbb, &buf, &buf_len) ||
278       buf_len != 3 ||
279       memcmp(buf, "\x01\x01\x02", 3) != 0) {
280     return 0;
281   }
282
283   free(buf);
284
285   return 1;
286 }
287
288 static int test_cbb_asn1(void) {
289   static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
290   uint8_t *buf, *test_data;
291   size_t buf_len;
292   CBB cbb, contents, inner_contents;
293
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)) {
298     return 0;
299   }
300
301   if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
302     return 0;
303   }
304   free(buf);
305
306   test_data = malloc(100000);
307   memset(test_data, 0x42, 100000);
308
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)) {
313     return 0;
314   }
315
316   if (buf_len != 3 + 130 ||
317       memcmp(buf, "\x30\x81\x82", 3) != 0 ||
318       memcmp(buf + 3, test_data, 130) != 0) {
319     return 0;
320   }
321   free(buf);
322
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)) {
327     return 0;
328   }
329
330   if (buf_len != 4 + 1000 ||
331       memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
332       memcmp(buf + 4, test_data, 1000)) {
333     return 0;
334   }
335   free(buf);
336
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)) {
342     return 0;
343   }
344
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)) {
348     return 0;
349   }
350   free(buf);
351
352   free(test_data);
353   return 1;
354 }
355
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) {
359   CBS in;
360   uint8_t *out;
361   size_t out_len;
362
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);
366     return 0;
367   }
368
369   if (out == NULL) {
370     if (ber_len != der_len ||
371         memcmp(der_expected, ber, ber_len) != 0) {
372       fprintf(stderr, "%s: incorrect unconverted result.\n", name);
373       return 0;
374     }
375
376     return 1;
377   }
378
379   if (out_len != der_len ||
380       memcmp(out, der_expected, der_len) != 0) {
381     fprintf(stderr, "%s: incorrect converted result.\n", name);
382     return 0;
383   }
384
385   free(out);
386   return 1;
387 }
388
389 static int test_ber_convert(void) {
390   static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
391
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};
395
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};
401
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,
413   };
414
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,
424   };
425
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,
434                         sizeof(kNSSBER));
435 }
436
437 int main(void) {
438   CRYPTO_library_init();
439
440   if (!test_skip() ||
441       !test_get_u() ||
442       !test_get_prefixed() ||
443       !test_get_prefixed_bad() ||
444       !test_get_asn1() ||
445       !test_cbb_basic() ||
446       !test_cbb_fixed() ||
447       !test_cbb_finish_child() ||
448       !test_cbb_misuse() ||
449       !test_cbb_prefixed() ||
450       !test_cbb_asn1() ||
451       !test_ber_convert()) {
452     return 1;
453   }
454
455   printf("PASS\n");
456   return 0;
457 }