Upstream version 9.38.198.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/bytestring.h>
19
20
21 static int test_skip() {
22   static const uint8_t kData[] = {1, 2, 3};
23   CBS data;
24
25   CBS_init(&data, kData, sizeof(kData));
26   return CBS_len(&data) == 3 &&
27       CBS_skip(&data, 1) &&
28       CBS_len(&data) == 2 &&
29       CBS_skip(&data, 2) &&
30       CBS_len(&data) == 0 &&
31       !CBS_skip(&data, 1);
32 }
33
34 static int test_get_u() {
35   static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
36   uint8_t u8;
37   uint16_t u16;
38   uint32_t u32;
39   CBS data;
40
41   CBS_init(&data, kData, sizeof(kData));
42   return CBS_get_u8(&data, &u8) &&
43     u8 == 1 &&
44     CBS_get_u16(&data, &u16) &&
45     u16 == 0x203 &&
46     CBS_get_u24(&data, &u32) &&
47     u32 == 0x40506 &&
48     CBS_get_u32(&data, &u32) &&
49     u32 == 0x708090a &&
50     !CBS_get_u8(&data, &u8);
51 }
52
53 static int test_get_prefixed() {
54   static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
55   uint8_t u8;
56   uint16_t u16;
57   uint32_t u32;
58   CBS data, prefixed;
59
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) &&
64     u8 == 2 &&
65     CBS_get_u16_length_prefixed(&data, &prefixed) &&
66     CBS_len(&prefixed) == 2 &&
67     CBS_get_u16(&prefixed, &u16) &&
68     u16 == 0x304 &&
69     CBS_get_u24_length_prefixed(&data, &prefixed) &&
70     CBS_len(&prefixed) == 3 &&
71     CBS_get_u24(&prefixed, &u32) &&
72     u32 == 0x30201;
73 }
74
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};
79   CBS data, prefixed;
80
81   CBS_init(&data, kData1, sizeof(kData1));
82   if (CBS_get_u8_length_prefixed(&data, &prefixed)) {
83     return 0;
84   }
85
86   CBS_init(&data, kData2, sizeof(kData2));
87   if (CBS_get_u16_length_prefixed(&data, &prefixed)) {
88     return 0;
89   }
90
91   CBS_init(&data, kData3, sizeof(kData3));
92   if (CBS_get_u24_length_prefixed(&data, &prefixed)) {
93     return 0;
94   }
95
96   return 1;
97 }
98
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};
105
106   CBS data, contents;
107
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) {
112     return 0;
113   }
114
115   CBS_init(&data, kData2, sizeof(kData2));
116   /* data is truncated */
117   if (CBS_get_asn1(&data, &contents, 0x30)) {
118     return 0;
119   }
120
121   CBS_init(&data, kData3, sizeof(kData3));
122   /* zero byte length of length */
123   if (CBS_get_asn1(&data, &contents, 0x30)) {
124     return 0;
125   }
126
127   CBS_init(&data, kData4, sizeof(kData4));
128   /* long form mistakenly used. */
129   if (CBS_get_asn1(&data, &contents, 0x30)) {
130     return 0;
131   }
132
133   CBS_init(&data, kData5, sizeof(kData5));
134   /* length takes too many bytes. */
135   if (CBS_get_asn1(&data, &contents, 0x30)) {
136     return 0;
137   }
138
139   CBS_init(&data, kData1, sizeof(kData1));
140   /* wrong tag. */
141   if (CBS_get_asn1(&data, &contents, 0x31)) {
142     return 0;
143   }
144
145   return 1;
146 }
147
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};
154
155   CBS data, contents;
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");
160     return 0;
161   }
162
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");
167     return 0;
168   }
169
170   CBS_init(&data, kDataWithoutEOC, sizeof(kDataWithoutEOC));
171   if (CBS_get_asn1_ber(&data, &contents, 0x30)) {
172     fprintf(stderr, "Parsed without EOC.\n");
173     return 0;
174   }
175
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");
180     return 0;
181   }
182
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");
188     return 0;
189   }
190
191   return 1;
192 }
193
194 static int test_cbb_basic() {
195   static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8};
196   uint8_t *buf;
197   size_t buf_len;
198   int ok;
199   CBB cbb;
200
201   if (!CBB_init(&cbb, 100)) {
202     return 0;
203   }
204   CBB_cleanup(&cbb);
205
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)) {
212     return 0;
213   }
214
215   ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
216   free(buf);
217   return ok;
218 }
219
220 static int test_cbb_fixed() {
221   CBB cbb;
222   uint8_t buf[1];
223   uint8_t *out_buf;
224   size_t out_size;
225
226   if (!CBB_init_fixed(&cbb, NULL, 0) ||
227       CBB_add_u8(&cbb, 1) ||
228       !CBB_finish(&cbb, &out_buf, &out_size) ||
229       out_buf != NULL ||
230       out_size != 0) {
231     return 0;
232   }
233
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) ||
238       out_buf != buf ||
239       out_size != 1 ||
240       buf[0] != 1) {
241     return 0;
242   }
243
244   return 1;
245 }
246
247 static int test_cbb_finish_child() {
248   CBB cbb, child;
249   uint8_t *out_buf;
250   size_t out_size;
251
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) ||
256       out_size != 1 ||
257       out_buf[0] != 0) {
258     return 0;
259   }
260
261   free(out_buf);
262   return 1;
263 }
264
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};
268   uint8_t *buf;
269   size_t buf_len;
270   CBB cbb, contents, inner_contents, inner_inner_contents;
271   int ok;
272
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)) {
287     return 0;
288   }
289
290   ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
291   free(buf);
292   return ok;
293 }
294
295 static int test_cbb_misuse() {
296   CBB cbb, child, contents;
297   uint8_t *buf;
298   size_t buf_len;
299
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)) {
304     return 0;
305   }
306
307   /* Since we wrote to |cbb|, |child| is now invalid and attempts to write to
308    * it should fail. */
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");
317     return 0;
318   }
319
320   if (!CBB_finish(&cbb, &buf, &buf_len) ||
321       buf_len != 3 ||
322       memcmp(buf, "\x01\x01\x02", 3) != 0) {
323     return 0;
324   }
325
326   free(buf);
327
328   return 1;
329 }
330
331 static int test_cbb_asn1() {
332   static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
333   uint8_t *buf, *test_data;
334   size_t buf_len;
335   CBB cbb, contents, inner_contents;
336
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)) {
341     return 0;
342   }
343
344   if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
345     return 0;
346   }
347   free(buf);
348
349   test_data = malloc(100000);
350   memset(test_data, 0x42, 100000);
351
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)) {
356     return 0;
357   }
358
359   if (buf_len != 3 + 130 ||
360       memcmp(buf, "\x30\x81\x82", 3) != 0 ||
361       memcmp(buf + 3, test_data, 130) != 0) {
362     return 0;
363   }
364   free(buf);
365
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)) {
370     return 0;
371   }
372
373   if (buf_len != 4 + 1000 ||
374       memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
375       memcmp(buf + 4, test_data, 1000)) {
376     return 0;
377   }
378   free(buf);
379
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)) {
385     return 0;
386   }
387
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)) {
391     return 0;
392   }
393   free(buf);
394
395   free(test_data);
396   return 1;
397 }
398
399 int main() {
400   if (!test_skip() ||
401       !test_get_u() ||
402       !test_get_prefixed() ||
403       !test_get_prefixed_bad() ||
404       !test_get_asn1() ||
405       !test_get_indef() ||
406       !test_cbb_basic() ||
407       !test_cbb_fixed() ||
408       !test_cbb_finish_child() ||
409       !test_cbb_misuse() ||
410       !test_cbb_prefixed() ||
411       !test_cbb_asn1()) {
412     return 1;
413   }
414
415   printf("PASS\n");
416   return 0;
417 }