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 <string.h>
13 #include <stdlib.h>
14 #include <gmssl/oid.h>
15 #include <gmssl/x509_alg.h>
16 #include <gmssl/x509_oid.h>
17 #include <gmssl/x509_str.h>
18 #include <gmssl/x509_ext.h>
19 #include <gmssl/x509.h>
20 #include <gmssl/rand.h>
21 #include <gmssl/error.h>
22
23 #define cnt(nodes) (sizeof(nodes)/sizeof(int))
24
test_x509_other_name(void)25 static int test_x509_other_name(void)
26 {
27 const uint32_t oid[] = { 1,3,5 };
28 const uint8_t value[] = { 0x30,0x01,0x00 };
29 uint8_t buf[256];
30 uint8_t *p = buf;
31 const uint8_t *cp = buf;
32 size_t len = 0;
33 const uint8_t *d;
34 size_t dlen;
35
36 uint32_t nodes[32];
37 size_t nodes_cnt;
38 const uint8_t *val;
39 size_t vlen;
40
41 if (x509_other_name_to_der(oid, sizeof(oid)/sizeof(int), value, sizeof(value), &p, &len) != 1
42 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
43 || asn1_length_is_zero(len) != 1) {
44 error_print();
45 return -1;
46 }
47 x509_other_name_print(stderr, 0, 0, "OtherName", d, dlen);
48
49 p = buf;
50 cp = buf;
51 len = 0;
52
53 if (x509_other_name_to_der(oid, sizeof(oid)/sizeof(int), value, sizeof(value), &p, &len) != 1
54 || x509_other_name_from_der(nodes, &nodes_cnt, &val, &vlen, &cp, &len) != 1
55 || asn1_length_is_zero(len) != 1) {
56 error_print();
57 return -1;
58 }
59 asn1_object_identifier_print(stderr, 0, 4, "type-id", NULL, nodes, nodes_cnt);
60 format_bytes(stderr, 0, 4, "value", val, vlen);
61 printf("%s() ok\n", __FUNCTION__);
62 return 1;
63 }
64
test_x509_edi_party_name(void)65 static int test_x509_edi_party_name(void)
66 {
67 uint8_t buf[256];
68 uint8_t *p = buf;
69 const uint8_t *cp = buf;
70 size_t len = 0;
71 const uint8_t *d;
72 size_t dlen;
73
74 int assigner_tag;
75 const uint8_t *assigner;
76 size_t assigner_len;
77 int party_name_tag;
78 const uint8_t *party_name;
79 size_t party_name_len;
80
81 if (x509_edi_party_name_to_der(
82 ASN1_TAG_PrintableString, (uint8_t *)"Hello", 5,
83 ASN1_TAG_PrintableString, (uint8_t *)"World", 5,
84 &p, &len) != 1
85 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
86 || asn1_length_is_zero(len) != 1) {
87 error_print();
88 return -1;
89 }
90 x509_edi_party_name_print(stderr, 0, 0, "EDIPartyName", d, dlen);
91
92 p = buf;
93 cp = buf;
94 len = 0;
95
96 if (x509_edi_party_name_to_der(
97 ASN1_TAG_PrintableString, (uint8_t *)"Hello", 5,
98 ASN1_TAG_PrintableString, (uint8_t *)"World", 5,
99 &p, &len) != 1
100 || x509_edi_party_name_from_der(
101 &assigner_tag, &assigner, &assigner_len,
102 &party_name_tag, &party_name, &party_name_len,
103 &cp, &len) != 1
104 || asn1_length_is_zero(len) != 1) {
105 error_print();
106 return -1;
107 }
108 x509_directory_name_print(stderr, 0, 4, "nameAssigner", assigner_tag, assigner, assigner_len);
109 x509_directory_name_print(stderr, 0, 4, "partyName", party_name_tag, party_name, party_name_len);
110
111 printf("%s() ok\n", __FUNCTION__);
112 return 1;
113 }
114
test_x509_general_name(void)115 static int test_x509_general_name(void)
116 {
117 uint8_t buf[256];
118 uint8_t *p = buf;
119 const uint8_t *cp = buf;
120 size_t len = 0;
121 const uint8_t *d;
122 size_t dlen;
123
124 uint8_t gns[512];
125 size_t gnslen;
126 uint32_t other_id[] = { 1,3,5,7 };
127 uint8_t value[] = { ASN1_TAG_OCTET_STRING, 0x02, 0x05, 0x05 };
128 uint8_t x400[] = { ASN1_TAG_SEQUENCE, 0x00 };
129 uint8_t name[512];
130 size_t namelen;
131 uint32_t reg_id[] = { 2,4,6,8 };
132
133 if (x509_name_set(name, &namelen, sizeof(name),
134 "CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1) {
135 error_print();
136 return -1;
137 }
138 gnslen = 0;
139 if (x509_general_names_add_other_name(gns, &gnslen, sizeof(gns), other_id, cnt(other_id), value, sizeof(value)) != 1
140 || x509_general_names_add_rfc822_name(gns, &gnslen, sizeof(gns), "guan@pku.edu.cn") != 1
141 || x509_general_names_add_dns_name(gns, &gnslen, sizeof(gns), "www.pku.edu.cn") != 1
142 || x509_general_names_add_x400_address(gns, &gnslen, sizeof(gns), x400, sizeof(x400)) != 1
143 || x509_general_names_add_directory_name(gns, &gnslen, sizeof(gns), name, namelen) != 1
144 || x509_general_names_add_edi_party_name(gns, &gnslen, sizeof(gns),
145 ASN1_TAG_PrintableString, (uint8_t *)"Assigner", strlen("Assigner"),
146 ASN1_TAG_PrintableString, (uint8_t *)"PartyName", strlen("PartyName")) != 1
147 || x509_general_names_add_uniform_resource_identifier(gns, &gnslen, sizeof(gns), "http://localhost") != 1
148 || x509_general_names_add_ip_address(gns, &gnslen, sizeof(gns), "127.0.0.1") != 1
149 || x509_general_names_add_registered_id(gns, &gnslen, sizeof(gns), reg_id, cnt(reg_id)) != 1
150 || x509_general_names_to_der(gns, gnslen, &p, &len) != 1
151 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
152 || asn1_length_is_zero(len) != 1) {
153 error_print();
154 return -1;
155 }
156 x509_general_names_print(stderr, 0, 0, "GeneralNames", d, dlen);
157 {
158 size_t i;
159 printf("uint8_t general_names[%zu] = {", dlen);
160 for (i = 0; i < dlen; i++) {
161 if (i % 16 == 0) {
162 printf("\n\t");
163 }
164 printf("0x%02x,", d[i]);
165 }
166 printf("\n};\n");
167 }
168
169 printf("%s() ok\n", __FUNCTION__);
170 return 1;
171 }
172
173 uint8_t general_names[202] = {
174 0x80,0x0b,0x06,0x03,0x2b,0x05,0x07,0xa0,0x04,0x04,0x02,0x05,0x05,0x81,0x0f,0x67,
175 0x75,0x61,0x6e,0x40,0x70,0x6b,0x75,0x2e,0x65,0x64,0x75,0x2e,0x63,0x6e,0x82,0x0e,
176 0x77,0x77,0x77,0x2e,0x70,0x6b,0x75,0x2e,0x65,0x64,0x75,0x2e,0x63,0x6e,0x83,0x02,
177 0x30,0x00,0x84,0x59,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,
178 0x4e,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x08,0x13,0x07,0x42,0x65,0x69,0x6a,
179 0x69,0x6e,0x67,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x48,0x61,
180 0x69,0x64,0x69,0x61,0x6e,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x0a,0x13,0x03,
181 0x50,0x4b,0x55,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x0b,0x13,0x02,0x43,0x53,
182 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x03,0x13,0x02,0x43,0x41,0x85,0x19,0xa0,
183 0x0a,0x13,0x08,0x41,0x73,0x73,0x69,0x67,0x6e,0x65,0x72,0xa1,0x0b,0x13,0x09,0x50,
184 0x61,0x72,0x74,0x79,0x4e,0x61,0x6d,0x65,0x86,0x10,0x68,0x74,0x74,0x70,0x3a,0x2f,
185 0x2f,0x6c,0x6f,0x63,0x61,0x6c,0x68,0x6f,0x73,0x74,0x87,0x09,0x31,0x32,0x37,0x2e,
186 0x30,0x2e,0x30,0x2e,0x31,0x88,0x03,0x54,0x06,0x08,
187 };
188
test_x509_authority_key_identifier(void)189 static int test_x509_authority_key_identifier(void)
190 {
191 uint8_t buf[512];
192 uint8_t *p = buf;
193 const uint8_t *cp = buf;
194 size_t len = 0;
195 const uint8_t *d;
196 size_t dlen;
197
198 uint8_t keyid[32];
199 uint8_t serial[20];
200
201 const uint8_t *keyidp;
202 size_t keyidlen;
203 const uint8_t *issuerp;
204 size_t issuerlen;
205 const uint8_t *serialp;
206 size_t seriallen;
207
208 sm3_digest((uint8_t *)"abc", 3, keyid);
209 rand_bytes(serial, sizeof(serial));
210
211 if (x509_authority_key_identifier_to_der(
212 keyid, sizeof(keyid),
213 general_names, sizeof(general_names),
214 serial, sizeof(serial),
215 &p, &len) != 1
216 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
217 || asn1_length_is_zero(len) != 1) {
218 error_print();
219 return -1;
220 }
221 x509_authority_key_identifier_print(stderr, 0, 0, "AuthorityKeyIdentifier", d, dlen);
222
223 p = buf;
224 cp = buf;
225 len = 0;
226 if (x509_authority_key_identifier_to_der(
227 keyid, sizeof(keyid),
228 general_names, sizeof(general_names),
229 serial, sizeof(serial),
230 &p, &len) != 1
231 || x509_authority_key_identifier_from_der(
232 &keyidp, &keyidlen,
233 &issuerp, &issuerlen,
234 &serialp, &seriallen,
235 &cp, &len) != 1
236 || asn1_length_is_zero(len) != 1) {
237 error_print();
238 return -1;
239 }
240
241 printf("%s() ok\n", __FUNCTION__);
242 return 1;
243 }
244
test_x509_key_usage(void)245 static int test_x509_key_usage(void)
246 {
247 int tests[] = {
248 0,
249 1,
250 2,
251 X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN,
252 7,
253 8,
254 X509_KU_DIGITAL_SIGNATURE|X509_KU_NON_REPUDIATION|X509_KU_DECIPHER_ONLY,
255 0x1ff,
256 // 0x3ff, // this should return error
257 };
258
259 uint8_t buf[256];
260 uint8_t *p = buf;
261 const uint8_t *cp = buf;
262 size_t len = 0;
263 int usage;
264 int i;
265
266 for (i = 0; i <= 8; i++) {
267 format_print(stderr, 0, 4, "%d %s\n", i, x509_key_usage_name(1 << i));
268 }
269 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
270 if (x509_key_usage_to_der(tests[i], &p, &len) != 1) {
271 error_print();
272 return -1;
273 }
274 format_bytes(stderr, 0, 4, "", buf, len);
275 }
276 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
277 if (x509_key_usage_from_der(&usage, &cp, &len) != 1
278 || asn1_check(usage == tests[i]) != 1) {
279 error_print();
280 return -1;
281 }
282 x509_key_usage_print(stderr, 0, 4, "KeyUsage", usage);
283 }
284 (void)asn1_length_is_zero(len);
285
286 printf("%s() ok\n", __FUNCTION__);
287 return 1;
288 }
289
test_x509_notice_reference(void)290 static int test_x509_notice_reference(void)
291 {
292 uint8_t buf[256];
293 uint8_t *p = buf;
294 const uint8_t *cp = buf;
295 size_t len = 0;
296 const uint8_t *d;
297 size_t dlen;
298
299 int notice_nums[] = { 1,2,3,4,5 };
300
301 int org_tag;
302 const uint8_t *org;
303 size_t orglen;
304 int nums[32];
305 size_t nums_cnt;
306
307 if (x509_notice_reference_to_der(
308 ASN1_TAG_IA5String, (uint8_t *)"Hello", 5,
309 notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]),
310 &p, &len) != 1
311 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
312 || asn1_length_is_zero(len) != 1) {
313 error_print();
314 return -1;
315 }
316 x509_notice_reference_print(stderr, 0, 0, "NoticeReference", d, dlen);
317
318 p = buf;
319 cp = buf;
320 len = 0;
321
322 if (x509_notice_reference_to_der(
323 ASN1_TAG_IA5String, (uint8_t *)"Hello", 5,
324 notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]),
325 &p, &len) != 1
326 || x509_notice_reference_from_der(
327 &org_tag, &org, &orglen,
328 nums, &nums_cnt, sizeof(nums)/sizeof(nums[0]),
329 &cp, &len) != 1
330 || asn1_length_is_zero(len) != 1) {
331 error_print();
332 return -1;
333 }
334
335 printf("%s() ok\n", __FUNCTION__);
336 return 1;
337 }
338
test_x509_user_notice(void)339 static int test_x509_user_notice(void)
340 {
341 uint8_t buf[256];
342 uint8_t *p = buf;
343 const uint8_t *cp = buf;
344 size_t len = 0;
345 const uint8_t *d;
346 size_t dlen;
347
348 int notice_nums[] = { 1,2,3,4,5 };
349
350 int org_tag;
351 const uint8_t *org;
352 size_t orglen;
353 int nums[32];
354 size_t nums_cnt;
355 int text_tag;
356 const uint8_t *text;
357 size_t textlen;
358
359 if (x509_user_notice_to_der(
360 ASN1_TAG_IA5String, (uint8_t *)"Hello", 5,
361 notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]),
362 ASN1_TAG_IA5String, (uint8_t *)"World", 5,
363 &p, &len) != 1
364 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
365 || asn1_length_is_zero(len) != 1) {
366 error_print();
367 return -1;
368 }
369 x509_user_notice_print(stderr, 0, 0, "UserNotice", d, dlen);
370
371 p = buf;
372 cp = buf;
373 len = 0;
374
375 if (x509_user_notice_to_der(
376 ASN1_TAG_IA5String, (uint8_t *)"Hello", 5,
377 notice_nums, sizeof(notice_nums)/sizeof(notice_nums[0]),
378 ASN1_TAG_IA5String, (uint8_t *)"World", 5,
379 &p, &len) != 1
380 || x509_user_notice_from_der(
381 &org_tag, &org, &orglen,
382 nums, &nums_cnt, sizeof(nums)/sizeof(nums[0]),
383 &text_tag, &text, &textlen,
384 &cp, &len) != 1
385 || asn1_length_is_zero(len) != 1) {
386 error_print();
387 return -1;
388 }
389
390 printf("%s() ok\n", __FUNCTION__);
391 return 1;
392 }
393
test_x509_policy_qualifier_info(void)394 static int test_x509_policy_qualifier_info(void)
395 {
396 uint8_t buf[256];
397 uint8_t *p = buf;
398 const uint8_t *cp = buf;
399 size_t len = 0;
400 const uint8_t *d;
401 size_t dlen;
402
403
404 if (x509_policy_qualifier_info_to_der(
405 OID_qt_cps,
406 (uint8_t *)"Qualifier", strlen("Qualifier"),
407 &p, &len) != 1
408 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
409 || asn1_length_is_zero(len) != 1) {
410 error_print();
411 return -1;
412 }
413 x509_policy_qualifier_info_print(stderr, 0, 0, "PolicyQualifierInfo", d, dlen);
414
415
416 printf("%s() ok\n", __FUNCTION__);
417 return 1;
418 }
419
test_x509_policy_mapping(void)420 static int test_x509_policy_mapping(void)
421 {
422 uint8_t buf[256];
423 uint8_t *p = buf;
424 const uint8_t *cp = buf;
425 size_t len = 0;
426 const uint8_t *d;
427 size_t dlen;
428
429 int issuer_policy_oid;
430 uint32_t issuer_policy_nodes[32];
431 size_t issuer_policy_nodes_cnt;
432 int subject_policy_oid;
433 uint32_t subject_policy_nodes[32];
434 size_t subject_policy_nodes_cnt;
435
436 if (x509_policy_mapping_to_der(
437 OID_any_policy, NULL, 0,
438 OID_any_policy, NULL, 0,
439 &p, &len) != 1
440 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
441 || asn1_length_is_zero(len) != 1) {
442 error_print();
443 return -1;
444 }
445 x509_policy_mapping_print(stderr, 0, 0, "PolicyMapping", d, dlen);
446
447 p = buf;
448 cp = buf;
449 len = 0;
450
451 if (x509_policy_mapping_to_der(
452 OID_any_policy, NULL, 0,
453 OID_any_policy, NULL, 0,
454 &p, &len) != 1
455 || x509_policy_mapping_from_der(
456 &issuer_policy_oid, issuer_policy_nodes, &issuer_policy_nodes_cnt,
457 &subject_policy_oid, subject_policy_nodes, &subject_policy_nodes_cnt,
458 &cp, &len) != 1
459 || asn1_length_is_zero(len) != 1) {
460 error_print();
461 return -1;
462 }
463
464 printf("%s() ok\n", __FUNCTION__);
465 return 1;
466 }
467
468 // 这里的一些OID应该在RFC中有,但是我们不实现
test_x509_attribute(void)469 static int test_x509_attribute(void)
470 {
471 // TODO
472 return 1;
473 }
474
test_x509_basic_constraints(void)475 static int test_x509_basic_constraints(void)
476 {
477 uint8_t buf[256];
478 uint8_t *p = buf;
479 const uint8_t *cp = buf;
480 size_t len = 0;
481 const uint8_t *d;
482 size_t dlen;
483
484 int ca;
485 int path;
486
487 if (x509_basic_constraints_to_der(1, 4, &p, &len) != 1
488 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
489 || asn1_length_is_zero(len) != 1) {
490 error_print();
491 return -1;
492 }
493 x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen);
494
495 cp = p = buf; len = 0;
496 if (x509_basic_constraints_to_der(-1, 4, &p, &len) != 1
497 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
498 || asn1_length_is_zero(len) != 1) {
499 error_print();
500 return -1;
501 }
502 x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen);
503
504
505 cp = p = buf; len = 0;
506 if (x509_basic_constraints_to_der(-1, -1, &p, &len) != 1
507 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
508 || asn1_length_is_zero(len) != 1) {
509 error_print();
510 return -1;
511 }
512 x509_basic_constraints_print(stderr, 0, 0, "BasicConstraints", d, dlen);
513
514 cp = p = buf; len = 0;
515 if (x509_basic_constraints_to_der(1, 4, &p, &len) != 1
516 || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != 1
517 || asn1_check(ca == 1) != 1
518 || asn1_check(path == 4) != 1
519 || asn1_length_is_zero(len) != 1) {
520 error_print();
521 return -1;
522 }
523
524 cp = p = buf; len = 0;
525 if (x509_basic_constraints_to_der(-1, 4, &p, &len) != 1
526 || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != 1
527 || asn1_check(ca == 0) != 1
528 || asn1_check(path == 4) != 1
529 || asn1_length_is_zero(len) != 1) {
530 error_print();
531 return -1;
532 }
533
534 cp = p = buf; len = 0;
535 if (x509_basic_constraints_to_der(-1, -1, &p, &len) != 1 // should return error
536 || x509_basic_constraints_from_der(&ca, &path, &cp, &len) != -1) {
537 error_print();
538 return -1;
539 }
540
541 printf("%s() ok\n", __FUNCTION__);
542 return 1;
543 }
544
test_x509_general_subtree(void)545 static int test_x509_general_subtree(void)
546 {
547 uint8_t buf[256];
548 uint8_t *p = buf;
549 const uint8_t *cp = buf;
550 size_t len = 0;
551 const uint8_t *d;
552 size_t dlen;
553
554 uint8_t *dns = (uint8_t *)"www.pku.edu.cn";
555 size_t dnslen = strlen((char *)dns);
556
557 int choice;
558 const uint8_t *dns_name;
559 size_t dns_name_len;
560 int min_dis;
561 int max_dis;
562
563 if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, 1, 5, &p, &len) != 1
564 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
565 || asn1_length_is_zero(len) != 1) {
566 error_print();
567 return -1;
568 }
569 x509_general_subtree_print(stderr, 0, 0, "GeneralSubtree", d, dlen);
570
571 cp = p = buf; len = 0;
572 min_dis = max_dis = 99;
573 if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, -1, 5, &p, &len) != 1
574 || x509_general_subtree_from_der(&choice, &dns_name, &dns_name_len, &min_dis, &max_dis, &cp, &len) != 1
575 || asn1_check(choice == X509_gn_dns_name) != 1
576 || asn1_check(dns_name_len == dnslen && memcmp(dns_name, dns, dnslen) == 0) != 1
577 || asn1_check(min_dis == 0) != 1
578 || asn1_check(max_dis == 5) != 1
579 || asn1_length_is_zero(len) != 1) {
580 error_print();
581 return -1;
582 }
583
584 cp = p = buf; len = 0;
585 min_dis = max_dis = 99;
586 if (x509_general_subtree_to_der(X509_gn_dns_name, dns, dnslen, 1, -1, &p, &len) != 1
587 || x509_general_subtree_from_der(&choice, &dns_name, &dns_name_len, &min_dis, &max_dis, &cp, &len) != 1
588 || asn1_check(choice == X509_gn_dns_name) != 1
589 || asn1_check(dns_name_len == dnslen && memcmp(dns_name, dns, dnslen) == 0) != 1
590 || asn1_check(min_dis == 1) != 1
591 || asn1_check(max_dis == -1) != 1
592 || asn1_length_is_zero(len) != 1) {
593 error_print();
594 return -1;
595 }
596
597 printf("%s() ok\n", __FUNCTION__);
598 return 1;
599 }
600
test_x509_policy_constraints(void)601 static int test_x509_policy_constraints(void)
602 {
603 uint8_t buf[256];
604 uint8_t *p = buf;
605 const uint8_t *cp = buf;
606 size_t len = 0;
607 const uint8_t *d;
608 size_t dlen;
609
610 int val1;
611 int val2;
612
613 if (x509_policy_constraints_to_der(2, 5, &p, &len) != 1
614 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
615 || asn1_length_is_zero(len) != 1) {
616 error_print();
617 return -1;
618 }
619 x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen);
620
621 cp = p = buf; len = 0;
622 if (x509_policy_constraints_to_der(2, -1, &p, &len) != 1
623 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
624 || asn1_length_is_zero(len) != 1) {
625 error_print();
626 return -1;
627 }
628 x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen);
629
630 cp = p = buf; len = 0;
631 if (x509_policy_constraints_to_der(-1, 5, &p, &len) != 1
632 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
633 || asn1_length_is_zero(len) != 1) {
634 error_print();
635 return -1;
636 }
637 x509_policy_constraints_print(stderr, 0, 0, "PolicyConstraints", d, dlen);
638
639 cp = p = buf; len = 0;
640 val1 = val2 = 99;
641 if (x509_policy_constraints_to_der(2, 5, &p, &len) != 1
642 || x509_policy_constraints_from_der(&val1, &val2, &cp, &len) != 1
643 || asn1_check(val1 == 2) != 1
644 || asn1_check(val2 == 5) != 1
645 || asn1_length_is_zero(len) != 1) {
646 error_print();
647 return -1;
648 }
649
650 cp = p = buf; len = 0;
651 val1 = val2 = 99;
652 if (x509_policy_constraints_to_der(-1, -1, &p, &len) != 1
653 || x509_policy_constraints_from_der(&val1, &val2, &cp, &len) != 1
654 || asn1_check(val1 == -1) != 1
655 || asn1_check(val2 == -1) != 1
656 || asn1_length_is_zero(len) != 1) {
657 error_print();
658 return -1;
659 }
660
661 printf("%s() ok\n", __FUNCTION__);
662 return 1;
663 }
664
test_x509_ext_key_usage(void)665 static int test_x509_ext_key_usage(void)
666 {
667 uint8_t buf[256];
668 uint8_t *p = buf;
669 const uint8_t *cp = buf;
670 size_t len = 0;
671 const uint8_t *d;
672 size_t dlen;
673
674 int kp[] = {
675 OID_kp_server_auth,
676 OID_kp_client_auth,
677 OID_kp_code_signing,
678 OID_kp_email_protection,
679 OID_kp_time_stamping,
680 OID_kp_ocsp_signing,
681 };
682 int oids[16] = {0};
683 size_t oids_cnt;
684 int i;
685
686 if (x509_ext_key_usage_to_der(kp, sizeof(kp)/sizeof(int), &p, &len) != 1
687 || asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
688 || asn1_length_is_zero(len) != 1) {
689 error_print();
690 return -1;
691 }
692 x509_ext_key_usage_print(stderr, 0, 0, "ExtKeyUsageSyntax", d, dlen);
693
694 if (x509_ext_key_usage_to_der(kp, sizeof(kp)/sizeof(int), &p, &len) != 1
695 || x509_ext_key_usage_from_der(oids, &oids_cnt, sizeof(oids)/sizeof(oids[0]), &cp, &len) != 1
696 || asn1_check(oids_cnt == sizeof(kp)/sizeof(int)) != 1
697 || asn1_check(memcmp(oids, kp, sizeof(kp)) == 0) != 1
698 || asn1_length_is_zero(len) != 1) {
699 error_print();
700 return -1;
701 }
702
703 printf("%s() ok\n", __FUNCTION__);
704 return 1;
705 }
706
test_x509_revoke_reasons(void)707 static int test_x509_revoke_reasons(void)
708 {
709 int tests[] = {
710 0,
711 1,
712 2,
713 X509_RF_SUPERSEDED|X509_RF_PRIVILEGE_WITHDRAWN|X509_RF_AA_COMPROMISE,
714 0x1ff,
715 };
716 uint8_t buf[256];
717 uint8_t *p = buf;
718 const uint8_t *cp = buf;
719 size_t len = 0;
720 int bits;
721 int i;
722
723 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
724 if (x509_revoke_reasons_to_der(tests[i], &p, &len) != 1) {
725 error_print();
726 return -1;
727 }
728 format_bytes(stderr, 0, 4, "", buf, len);
729 }
730 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
731 if (x509_revoke_reasons_from_der(&bits, &cp, &len) != 1
732 || asn1_check(bits == tests[i]) != 1) {
733 error_print();
734 return -1;
735 }
736 x509_revoke_reasons_print(stderr, 0, 4, "ReasonFlags", bits);
737 }
738 (void)asn1_length_is_zero(len);
739
740 printf("%s() ok\n", __FUNCTION__);
741 return 1;
742 }
743
test_x509_exts(void)744 static int test_x509_exts(void)
745 {
746 uint8_t buf[1024];
747 uint8_t *p = buf;
748 const uint8_t *cp = buf;
749 size_t len = 0;
750 const uint8_t *d;
751 size_t dlen;
752
753 uint8_t exts[512];
754 size_t extslen = 0;
755 uint8_t keyid[32] = {1};
756 uint8_t serial[20] = {2};
757
758 if (0
759 || x509_exts_add_authority_key_identifier(exts, &extslen, sizeof(exts), 1,
760 keyid, sizeof(keyid),
761 general_names, sizeof(general_names),
762 serial, sizeof(serial)) != 1
763 || x509_exts_add_subject_key_identifier(exts, &extslen, sizeof(exts), 0,
764 keyid, sizeof(keyid)) != 1
765 || x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 0,
766 X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN) != 1
767 || x509_exts_to_der(exts, extslen, &p, &len) != 1
768 || x509_exts_from_der(&d, &dlen, &cp, &len) != 1
769 || asn1_length_is_zero(len) != 1) {
770 error_print();
771 return -1;
772 }
773 x509_exts_print(stderr, 0, 0, "Extensions", d, dlen);
774
775
776 printf("%s() ok\n", __FUNCTION__);
777 return 1;
778 }
779
test_x509_cert_with_exts(void)780 static int test_x509_cert_with_exts(void)
781 {
782 uint8_t cert[1024];
783 size_t certlen;
784 uint8_t serial[20];
785 uint8_t name[256];
786 size_t namelen;
787 time_t not_before, not_after;
788 SM2_KEY sm2_key;
789 uint8_t uniq_id[32];
790 uint8_t exts[512];
791 size_t extslen = 0;
792 uint8_t keyid[32] = {1};
793
794
795 rand_bytes(serial, sizeof(serial));
796 x509_name_set(name, &namelen, sizeof(name), "CN", "Beijing", "Haidian", "PKU", "CS", "CA");
797 time(¬_before);
798 x509_validity_add_days(¬_after, not_before, 365);
799 sm2_key_generate(&sm2_key);
800 sm3_digest((uint8_t *)&(sm2_key.public_key), sizeof(SM2_POINT), uniq_id);
801
802 if (x509_exts_add_authority_key_identifier(exts, &extslen, sizeof(exts), 1,
803 keyid, sizeof(keyid),
804 general_names, sizeof(general_names),
805 serial, sizeof(serial)) != 1
806 || x509_exts_add_subject_key_identifier(exts, &extslen, sizeof(exts), 0,
807 keyid, sizeof(keyid)) != 1
808 || x509_exts_add_key_usage(exts, &extslen, sizeof(exts), 0,
809 X509_KU_NON_REPUDIATION|X509_KU_CRL_SIGN) != 1) {
810 error_print();
811 return -1;
812 }
813
814 if (x509_cert_sign(
815 cert, &certlen, sizeof(cert),
816 X509_version_v3,
817 serial, sizeof(serial),
818 OID_sm2sign_with_sm3,
819 name, namelen,
820 not_before, not_after,
821 name, namelen,
822 &sm2_key,
823 uniq_id, sizeof(uniq_id),
824 uniq_id, sizeof(uniq_id),
825 exts, extslen,
826 &sm2_key,
827 SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) {
828 error_print();
829 return -1;
830 }
831 x509_cert_print(stderr, 0, 0, "Certificate", cert, certlen);
832
833
834 return 1;
835 }
836
main(int argc,char ** argv)837 int main(int argc, char **argv)
838 {
839 if (test_x509_other_name() != 1) goto err;
840 if (test_x509_edi_party_name() != 1) goto err;
841 if (test_x509_general_name() != 1) goto err;
842 if (test_x509_authority_key_identifier() != 1) goto err;
843 if (test_x509_key_usage() != 1) goto err;
844 if (test_x509_notice_reference() != 1) goto err;
845 if (test_x509_user_notice() != 1) goto err;
846 if (test_x509_policy_qualifier_info() != 1) goto err;
847 if (test_x509_policy_mapping() != 1) goto err;
848 if (test_x509_basic_constraints() != 1) goto err;
849 if (test_x509_general_subtree() != 1) goto err;
850 if (test_x509_policy_constraints() != 1) goto err;
851 if (test_x509_ext_key_usage() != 1) goto err;
852 if (test_x509_revoke_reasons() != 1) goto err;
853 if (test_x509_exts() != 1) goto err;
854 if (test_x509_cert_with_exts() != 1) goto err;
855 printf("%s all tests passed!\n", __FILE__);
856 return 0;
857 err:
858 error_print();
859 return 1;
860 }
861