1 /*
2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License); you may
5 * not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 */
9
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <assert.h>
15 #include <gmssl/asn1.h>
16 #include <gmssl/error.h>
17
18
print_buf(const uint8_t * a,size_t len)19 static void print_buf(const uint8_t *a, size_t len)
20 {
21 size_t i;
22 for (i = 0; i < len; i++) {
23 printf("%02x ", a[i]);
24 }
25 printf("\n");
26 }
27
print_integer(const uint8_t * a,size_t alen)28 static void print_integer(const uint8_t *a, size_t alen)
29 {
30 size_t i;
31 printf("integer = ");
32 for (i = 0; i < alen; i++) {
33 printf("%02x", a[i]);
34 }
35 printf("\n");
36 }
37
print_bits(const uint8_t * bits,size_t nbits)38 static void print_bits(const uint8_t *bits, size_t nbits)
39 {
40 size_t i;
41 printf("bits (%zu) = ", nbits);
42 for (i = 0; i < (nbits + 7)/8; i++) {
43 printf("%02x", bits[i]);
44 }
45 printf("\n");
46 }
47
print_octets(const uint8_t * o,size_t olen)48 static void print_octets(const uint8_t *o, size_t olen)
49 {
50 size_t i;
51 printf("octets (%zu) = ", olen);
52 for (i = 0; i < olen; i++) {
53 printf("%02x", o[i]);
54 }
55 printf("\n");
56 }
57
test_asn1_tag(void)58 static int test_asn1_tag(void)
59 {
60 int i;
61 format_print(stderr, 0, 0, "Tags:\n");
62 for (i = 1; i <= 13; i++) {
63 format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i);
64 }
65 for (i = 18; i <= 30; i++) {
66 format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i);
67 }
68 printf("%s() ok\n", __FUNCTION__);
69 return 1;
70 }
71
test_asn1_length(void)72 static int test_asn1_length(void)
73 {
74 size_t tests[] = {
75 0,
76 5,
77 127,
78 128,
79 256,
80 344,
81 65537,
82 1<<23,
83 (size_t)1<<31,
84 };
85 size_t length;
86 uint8_t buf[256];
87 uint8_t *p = buf;
88 const uint8_t *cp = buf;
89 size_t len = 0;
90 size_t i;
91
92 format_print(stderr, 0, 0, "Length:\n");
93 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
94 if (asn1_length_to_der(tests[i], &p, &len) != 1) {
95 error_print();
96 return -1;
97 }
98 format_bytes(stderr, 0, 4, "", buf, len);
99 }
100 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
101 int ret;
102 ret = asn1_length_from_der(&length, &cp, &len);
103 if (ret != 1 && ret != -2) {
104 error_print();
105 return -1;
106 }
107 if (length != tests[i]) {
108 error_print();
109 return -1;
110 }
111 format_print(stderr, 0, 4, "%zd\n", length);
112 }
113 if (len != 0) {
114 error_print();
115 return -1;
116 }
117
118 printf("%s() ok\n", __FUNCTION__);
119 return 1;
120 }
121
test_asn1_boolean(void)122 static int test_asn1_boolean(void)
123 {
124 int tests[] = {0, 1};
125 int val;
126 uint8_t buf[128] = {0};
127 uint8_t *p = buf;
128 const uint8_t *cp = buf;
129 size_t len = 0;
130 size_t i;
131
132 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BOOLEAN));
133 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
134 if (asn1_boolean_to_der(tests[i], &p, &len) != 1) {
135 error_print();
136 return -1;
137 }
138 format_bytes(stderr, 0, 4, "", buf, len);
139 }
140 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
141 if (asn1_boolean_from_der(&val, &cp, &len) != 1
142 || asn1_check(val == tests[i]) != 1) {
143 error_print();
144 return -1;
145 }
146 format_print(stderr, 0, 4, "%s\n", val ? "true" : "false");
147 }
148 if (len != 0) {
149 error_print();
150 return -1;
151 }
152
153 printf("%s() ok\n", __FUNCTION__);
154 return 1;
155 }
156
test_asn1_int(void)157 static int test_asn1_int(void)
158 {
159 int tests[] = {
160 0,
161 1,
162 127,
163 128,
164 65535,
165 65537,
166 1<<23,
167 1<<30,
168 };
169 int val;
170 uint8_t buf[256] = {0};
171 uint8_t *p = buf;
172 const uint8_t *cp = buf;
173 size_t len = 0;
174 size_t i;
175 int rv;
176
177 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_INTEGER));
178 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
179 if (asn1_int_to_der(tests[i], &p, &len) != 1) {
180 error_print();
181 return -1;
182 }
183 format_bytes(stderr, 0, 4, "", buf, len);
184 }
185 // 测试 -1 表示默认不编码
186 if (asn1_int_to_der(-1, &p, &len) != 0) {
187 error_print();
188 return -1;
189 }
190
191 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
192 if (asn1_int_from_der(&val, &cp, &len) != 1
193 || asn1_check(val == tests[i]) != 1) {
194 error_print();
195 return -1;
196 }
197 format_print(stderr, 0, 4, "%d\n", val);
198 }
199 if (len != 0) {
200 error_print();
201 return -1;
202 }
203
204 // 测试返回0时是否对val值做初始化
205 if (asn1_int_from_der(&val, &cp, &len) != 0) {
206 error_print();
207 return -1;
208 }
209 if (val != -1) {
210 error_print();
211 return -1;
212 }
213
214 printf("%s() ok\n", __FUNCTION__);
215 return 1;
216 }
217
test_asn1_bits(void)218 static int test_asn1_bits(void)
219 {
220 int tests[] = {
221 0x01,
222 0x02,
223 0x03,
224 0x7f,
225 0xfe,
226 0xff,
227 0xffff,
228 0xfffff,
229 };
230 uint8_t der[] = {
231 0x03,0x02,0x07,0x80,
232 0x03,0x02,0x06,0x40,
233 0x03,0x02,0x06,0xC0,
234 0x03,0x02,0x01,0xFE,
235 0x03,0x02,0x00,0x7F,
236 0x03,0x02,0x00,0xFF,
237 0x03,0x03,0x00,0xFF,0xFF,
238 0x03,0x04,0x04,0xFF,0xFF,0xF0,
239 };
240 int bits;
241 uint8_t buf[256];
242 uint8_t *p = buf;
243 const uint8_t *cp = buf;
244 size_t len = 0;
245 size_t i;
246
247 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BIT_STRING));
248 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
249 if (asn1_bits_to_der(tests[i], &p, &len) != 1) {
250 error_print();
251 return -1;
252 }
253 format_bytes(stderr, 0, 4, "", buf, len);
254 }
255 if (sizeof(der) != len
256 || memcmp(der, buf, len) != 0) {
257 error_print();
258 return -1;
259 }
260 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
261 if (asn1_bits_from_der(&bits, &cp, &len) != 1
262 || asn1_check(bits == tests[i]) != 1) {
263 error_print();
264 return -1;
265 }
266 format_print(stderr, 0, 4, "%x\n", bits);
267 }
268 if (len != 0) {
269 error_print();
270 return -1;
271 }
272 printf("%s() ok\n", __FUNCTION__);
273 return 1;
274 }
275
test_asn1_null(void)276 static int test_asn1_null(void)
277 {
278 uint8_t buf[256] = {0};
279 uint8_t *p = buf;
280 const uint8_t *cp = buf;
281 size_t len = 0;
282 size_t i;
283
284 format_print(stderr, 0, 0, "NULL\n");
285 for (i = 0; i < 3; i++) {
286 if (asn1_null_to_der(&p, &len) != 1) {
287 error_print();
288 return -1;
289 }
290 format_bytes(stderr, 0, 4, "", buf, len);
291 }
292 for (i = 0; i < 3; i++) {
293 if (asn1_null_from_der(&cp, &len) != 1) {
294 error_print();
295 return -1;
296 }
297 format_print(stderr, 0, 4, "%s\n", asn1_tag_name(ASN1_TAG_NULL));
298 }
299 if (asn1_length_is_zero(len) != 1) {
300 error_print();
301 return -1;
302 }
303 printf("%s() ok\n", __FUNCTION__);
304 return 1;
305 }
306
test_asn1_object_identifier(void)307 static int test_asn1_object_identifier(void)
308 {
309 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_OBJECT_IDENTIFIER));
310
311 // test 1
312 {
313 char *name = "sm2";
314 uint32_t oid[] = { 1,2,156,10197,1,301 };
315 uint8_t der[] = { 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D };
316 uint32_t nodes[32];
317 size_t nodes_cnt;
318 uint8_t buf[128];
319 uint8_t *p = buf;
320 const uint8_t *cp = buf;
321 size_t len = 0;
322
323 format_print(stderr, 0 ,4, "%s ", name);
324 if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1
325 || asn1_check(len == sizeof(der)) != 1
326 || asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1
327 || asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1
328 || asn1_length_is_zero(len) != 1
329 || asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) {
330 fprintf(stderr, "failed\n");
331 error_print();
332 return -1;
333 } else {
334 printf("ok\n");
335 }
336 }
337
338 // test 2
339 {
340 char *name = "x9.62-ecPublicKey";
341 uint32_t oid[] = { 1,2,840,10045,2,1 };
342 uint8_t der[] = { 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 };
343 uint8_t buf[128];
344 uint32_t nodes[32];
345 size_t nodes_cnt;
346 uint8_t *p = buf;
347 const uint8_t *cp = buf;
348 size_t len = 0;
349
350 format_print(stderr, 0 ,4, "%s ", name);
351 if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1
352 || asn1_check(len == sizeof(der)) != 1
353 || asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1
354 || asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1
355 || asn1_length_is_zero(len) != 1
356 || asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) {
357 fprintf(stderr, "failed\n");
358 error_print();
359 return -1;
360 } else {
361 printf("ok\n");
362 }
363 }
364
365 printf("%s() ok\n", __FUNCTION__);
366 return 1;
367 }
368
test_asn1_printable_string(void)369 static int test_asn1_printable_string(void)
370 {
371 char *tests[] = {
372 "hello",
373 "world",
374 "Just do it!",
375 };
376 uint8_t buf[256];
377 uint8_t *p = buf;
378 const uint8_t *cp = buf;
379 size_t len = 0;
380 size_t i;
381
382 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_PrintableString));
383 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
384 if (asn1_printable_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) {
385 error_print();
386 return -1;
387 }
388 format_bytes(stderr, 0, 4, "", buf, len);
389 }
390 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
391 const char *d;
392 size_t dlen;
393 if (asn1_printable_string_from_der(&d, &dlen, &cp, &len) != 1
394 || strlen(tests[i]) != dlen
395 || memcmp(tests[i], d, dlen) != 0) {
396 error_print();
397 return -1;
398 }
399 format_string(stderr, 0, 4, "", (uint8_t *)d, dlen);
400 }
401 if (len != 0) {
402 error_print();
403 return -1;
404 }
405 printf("%s() ok\n", __FUNCTION__);
406 return 1;
407 }
408
test_asn1_utf8_string(void)409 static int test_asn1_utf8_string(void)
410 {
411 char *tests[] = {
412 "hello",
413 "world",
414 "Just do it!",
415 };
416 uint8_t buf[256];
417 uint8_t *p = buf;
418 const uint8_t *cp = buf;
419 size_t len = 0;
420 size_t i;
421
422 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTF8String));
423 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
424 if (asn1_utf8_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) {
425 error_print();
426 return -1;
427 }
428 format_bytes(stderr, 0, 4, "", buf, len);
429 }
430 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
431 const char *d;
432 size_t dlen;
433 if (asn1_utf8_string_from_der(&d, &dlen, &cp, &len) != 1
434 || strlen(tests[i]) != dlen
435 || memcmp(tests[i], d, dlen) != 0) {
436 error_print();
437 return -1;
438 }
439 format_string(stderr, 0, 4, "", (uint8_t *)d, dlen);
440 }
441 if (len != 0) {
442 error_print();
443 return -1;
444 }
445 printf("%s() ok\n", __FUNCTION__);
446 return 1;
447 }
448
test_asn1_ia5_string(void)449 static int test_asn1_ia5_string(void)
450 {
451 char *tests[] = {
452 "hello",
453 "world",
454 "Just do it!",
455 };
456 uint8_t buf[256];
457 uint8_t *p = buf;
458 const uint8_t *cp = buf;
459 size_t len = 0;
460 size_t i;
461
462 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_IA5String));
463 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
464 if (asn1_ia5_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) {
465 error_print();
466 return -1;
467 }
468 format_bytes(stderr, 0, 4, "", buf, len);
469 }
470 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
471 const char *d;
472 size_t dlen;
473 if (asn1_ia5_string_from_der(&d, &dlen, &cp, &len) != 1
474 || strlen(tests[i]) != dlen
475 || memcmp(tests[i], d, dlen) != 0) {
476 error_print();
477 return -1;
478 }
479 format_string(stderr, 0, 4, "", (uint8_t *)d, dlen);
480 }
481 if (len != 0) {
482 error_print();
483 return -1;
484 }
485 printf("%s() ok\n", __FUNCTION__);
486 return 1;
487 }
488
test_time(void)489 static int test_time(void)
490 {
491 time_t tval = 0;
492 printf("%s", ctime(&tval));
493 time(&tval);
494 printf("%s", ctime(&tval));
495
496 printf("%08x%08x\n", (uint32_t)(tval >> 32), (uint32_t)tval);
497
498 return 1;
499 }
500
test_asn1_utc_time(void)501 static int test_asn1_utc_time(void)
502 {
503 time_t tests[] = {
504 0,
505 0,
506 1<<30,
507 };
508 time_t tv;
509 uint8_t buf[256];
510 uint8_t *p = buf;
511 const uint8_t *cp = buf;
512 size_t len = 0;
513 size_t i;
514
515 time(&tests[1]);
516
517 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTCTime));
518 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
519 if (asn1_utc_time_to_der(tests[i], &p, &len) != 1) {
520 error_print();
521 return -1;
522 }
523 format_bytes(stderr, 0, 4, "", buf, len);
524 }
525 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
526 if (asn1_utc_time_from_der(&tv, &cp, &len) != 1
527 || asn1_check(tv == tests[i]) != 1) {
528 error_print();
529 return -1;
530 }
531 format_print(stderr, 0, 4, "%s", ctime(&tv));
532 }
533 if (len != 0) {
534 error_print();
535 return -1;
536 }
537 printf("%s() ok\n", __FUNCTION__);
538 return 1;
539 }
540
test_asn1_generalized_time(void)541 static int test_asn1_generalized_time(void)
542 {
543 time_t tests[] = {
544 0,
545 1<<30,
546 };
547 uint8_t buf[256];
548 uint8_t *p = buf;
549 const uint8_t *cp = buf;
550 size_t len = 0;
551 size_t i;
552
553 time(&tests[0]);
554
555 format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_GeneralizedTime));
556 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
557 if (asn1_generalized_time_to_der(tests[i], &p, &len) != 1) {
558 error_print();
559 return -1;
560 }
561 format_bytes(stderr, 0, 4, "", buf, len);
562 }
563 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
564 time_t tv;
565 if (asn1_generalized_time_from_der(&tv, &cp, &len) != 1
566 || asn1_check(tv == tests[i]) != 1) {
567 error_print();
568 return -1;
569 }
570 format_print(stderr, 0, 4, "%s", ctime(&tv));
571 }
572 if (len != 0) {
573 error_print();
574 return -1;
575 }
576 printf("%s() ok\n", __FUNCTION__);
577 return 1;
578 }
579
main(void)580 int main(void)
581 {
582 if (test_asn1_tag() != 1) goto err;
583 if (test_asn1_length() != 1) goto err;
584 if (test_asn1_boolean() != 1) goto err;
585 if (test_asn1_int() != 1) goto err;
586 if (test_asn1_bits() != 1) goto err;
587 if (test_asn1_null() != 1) goto err;
588 if (test_asn1_object_identifier() != 1) goto err;
589 if (test_asn1_printable_string() != 1) goto err;
590 if (test_asn1_utf8_string() != 1) goto err;
591 if (test_asn1_ia5_string() != 1) goto err;
592 if (test_asn1_utc_time() != 1) goto err;
593 if (test_asn1_generalized_time() != 1) goto err;
594 printf("%s all tests passed\n", __FILE__);
595 return 0;
596 err:
597 error_print();
598 return -1;
599 }
600