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 <stdint.h>
15 #include <assert.h>
16 #include <gmssl/sm2.h>
17 #include <gmssl/oid.h>
18 #include <gmssl/pem.h>
19 #include <gmssl/asn1.h>
20 #include <gmssl/rsa.h>
21 #include <gmssl/x509_oid.h>
22 #include <gmssl/x509_str.h>
23 #include <gmssl/x509_alg.h>
24 #include <gmssl/x509_ext.h>
25 #include <gmssl/x509.h>
26 #include <gmssl/error.h>
27
28
x509_version_name(int version)29 const char *x509_version_name(int version)
30 {
31 switch (version) {
32 case X509_version_v1: return "v1";
33 case X509_version_v2: return "v2";
34 case X509_version_v3: return "v3";
35 }
36 return NULL;
37 }
38
x509_explicit_version_to_der(int index,int version,uint8_t ** out,size_t * outlen)39 int x509_explicit_version_to_der(int index, int version, uint8_t **out, size_t *outlen)
40 {
41 size_t len = 0;
42
43 if (version < 0) {
44 return 0;
45 }
46 if (!x509_version_name(version)) {
47 error_print();
48 return -1;
49 }
50 if (asn1_int_to_der(version, NULL, &len) != 1
51 || asn1_explicit_header_to_der(index, len, out, outlen) != 1
52 || asn1_int_to_der(version, out, outlen) != 1) {
53 error_print();
54 return -1;
55 }
56 return 1;
57 }
58
x509_explicit_version_from_der(int index,int * version,const uint8_t ** in,size_t * inlen)59 int x509_explicit_version_from_der(int index, int *version, const uint8_t **in, size_t *inlen)
60 {
61 int ret;
62 const uint8_t *d;
63 size_t dlen;
64
65 if ((ret = asn1_explicit_from_der(index, &d, &dlen, in, inlen)) != 1) {
66 if (ret < 0) error_print();
67 else *version = -1;
68 return ret;
69 }
70 if (asn1_int_from_der(version, &d, &dlen) != 1
71 || asn1_length_is_zero(dlen) != 1) {
72 error_print();
73 return -1;
74 }
75 if (!x509_version_name(*version)) {
76 error_print();
77 return -1;
78 }
79 return 1;
80 }
81
82 /*
83 from RFC 5280 section 4.1.2.5
84
85 CAs conforming to this profile MUST always encode certificate
86 validity dates through the year 2049 as UTCTime; certificate validity
87 dates in 2050 or later MUST be encoded as GeneralizedTime.
88 Conforming applications MUST be able to process validity dates that
89 are encoded in either UTCTime or GeneralizedTime.
90
91 To indicate that a certificate has no well-defined expiration date,
92 the notAfter SHOULD be assigned the GeneralizedTime value of
93 99991231235959Z.
94 */
x509_time_to_der(time_t tv,uint8_t ** out,size_t * outlen)95 int x509_time_to_der(time_t tv, uint8_t **out, size_t *outlen)
96 {
97 int ret;
98 struct tm tm_val;
99
100 gmtime_r(&tv, &tm_val);
101 if (tm_val.tm_year < 2050 - 1900) {
102 if ((ret = asn1_utc_time_to_der(tv, out, outlen)) != 1) {
103 if (ret < 0) error_print();
104 }
105 } else {
106 if ((ret = asn1_generalized_time_to_der(tv, out, outlen)) !=1) {
107 if (ret < 0) error_print();
108 }
109 }
110 return ret;
111 }
112
x509_time_from_der(time_t * tv,const uint8_t ** in,size_t * inlen)113 int x509_time_from_der(time_t *tv, const uint8_t **in, size_t *inlen)
114 {
115 int ret;
116
117 if ((ret = asn1_utc_time_from_der(tv, in, inlen)) < 0) {
118 error_print();
119 return -1;
120 } else if (ret) {
121 return 1;
122 }
123
124 if ((ret = asn1_generalized_time_from_der(tv, in, inlen)) != 1) {
125 if (ret < 0) error_print();
126 return ret;
127 }
128 return 1;
129 }
130
x509_validity_add_days(time_t * not_after,time_t not_before,int days)131 int x509_validity_add_days(time_t *not_after, time_t not_before, int days)
132 {
133 struct tm tm_val;
134 if (days < X509_VALIDITY_MIN_DAYS
135 || days > X509_VALIDITY_MAX_DAYS) {
136 error_print();
137 return -1;
138 }
139 gmtime_r(¬_before, &tm_val);
140 tm_val.tm_mday += days;
141 *not_after = mktime(&tm_val);
142 return 1;
143 }
144
x509_validity_to_der(time_t not_before,time_t not_after,uint8_t ** out,size_t * outlen)145 int x509_validity_to_der(time_t not_before, time_t not_after, uint8_t **out, size_t *outlen)
146 {
147 size_t len = 0;
148 if (x509_time_to_der(not_before, NULL, &len) != 1
149 || x509_time_to_der(not_after, NULL, &len) != 1
150 || asn1_sequence_header_to_der(len, out, outlen) != 1
151 || x509_time_to_der(not_before, out, outlen) != 1
152 || x509_time_to_der(not_after, out, outlen) != 1) {
153 error_print();
154 return -1;
155 }
156 return 1;
157 }
158
x509_validity_from_der(time_t * not_before,time_t * not_after,const uint8_t ** in,size_t * inlen)159 int x509_validity_from_der(time_t *not_before, time_t *not_after, const uint8_t **in, size_t *inlen)
160 {
161 int ret;
162 const uint8_t *d;
163 size_t dlen;
164
165 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
166 if (ret < 0) error_print();
167 return ret;
168 }
169 if (x509_time_from_der(not_before, &d, &dlen) != 1
170 || x509_time_from_der(not_after, &d, &dlen) != 1
171 || asn1_length_is_zero(dlen) != 1) {
172 error_print();
173 return -1;
174 }
175 if (*not_before >= *not_after) {
176 error_print();
177 return -1;
178 }
179 return 1;
180 }
181
x509_validity_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)182 int x509_validity_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
183 {
184 time_t tv;
185
186 format_print(fp, fmt, ind, "%s\n", label);
187 ind += 4;
188
189 if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err;
190 format_print(fp, fmt, ind, "notBefore: %s", ctime(&tv));
191 if (x509_time_from_der(&tv, &d, &dlen) != 1) goto err;
192 format_print(fp, fmt, ind, "notAfter: %s", ctime(&tv));
193 if (asn1_length_is_zero(dlen) != 1) goto err;
194 return 1;
195 err:
196 error_print();
197 return -1;
198 }
199
200
201 static const struct {
202 int oid;
203 int is_printable_string_only;
204 int minlen;
205 int maxlen;
206 } x509_name_types[] = {
207 { OID_at_country_name, 1, 2, 2 },
208 { OID_at_state_or_province_name, 0, 1, X509_ub_state_name },
209 { OID_at_locality_name, 0, 1, X509_ub_locality_name },
210 { OID_at_organization_name, 0, 1, X509_ub_organization_name },
211 { OID_at_organizational_unit_name, 0, 1, X509_ub_organizational_unit_name },
212 { OID_at_common_name, 0, 1, X509_ub_common_name },
213 { OID_at_serial_number, 1, 1, X509_ub_serial_number },
214 { OID_at_dn_qualifier, 1, 1, 64 }, // max length unspecified in RFC 5280
215 { OID_at_title, 0, 1, X509_ub_title },
216 { OID_at_surname, 0, 1, X509_ub_name },
217 { OID_at_given_name, 0, 1, X509_ub_name },
218 { OID_at_initials, 0, 1, X509_ub_name },
219 { OID_at_generation_qualifier, 0, 1, X509_ub_name },
220 { OID_at_pseudonym, 0, 1, X509_ub_pseudonym },
221 };
222
223 static const int x509_name_types_count
224 = sizeof(x509_name_types)/sizeof(x509_name_types[0]);
225
x509_attr_type_and_value_check(int oid,int tag,const uint8_t * val,size_t vlen)226 int x509_attr_type_and_value_check(int oid, int tag, const uint8_t *val, size_t vlen)
227 {
228 int i;
229 for (i = 0; i < x509_name_types_count; i++) {
230 if (oid == x509_name_types[i].oid) {
231 if (x509_name_types[i].is_printable_string_only
232 && tag != ASN1_TAG_PrintableString) {
233 error_print();
234 return -1;
235 }
236 if (x509_directory_name_check_ex(tag, val, vlen,
237 x509_name_types[i].minlen, x509_name_types[i].maxlen) != 1) {
238 error_print();
239 return -1;
240 }
241 return 1;
242 }
243 }
244 error_print();
245 return -1;
246 }
247
x509_attr_type_and_value_to_der(int oid,int tag,const uint8_t * val,size_t vlen,uint8_t ** out,size_t * outlen)248 int x509_attr_type_and_value_to_der(int oid, int tag, const uint8_t *val, size_t vlen,
249 uint8_t **out, size_t *outlen)
250 {
251 size_t len = 0;
252 if (x509_attr_type_and_value_check(oid, tag, val, vlen) != 1
253 || x509_name_type_to_der(oid, NULL, &len) != 1
254 || x509_directory_name_to_der(tag, val, vlen, NULL, &len) != 1
255 || asn1_sequence_header_to_der(len, out, outlen) != 1
256 || x509_name_type_to_der(oid, out, outlen) != 1
257 || x509_directory_name_to_der(tag, val, vlen, out, outlen) != 1) {
258 error_print();
259 return -1;
260 }
261 return 1;
262 }
263
x509_attr_type_and_value_from_der(int * oid,int * tag,const uint8_t ** val,size_t * vlen,const uint8_t ** in,size_t * inlen)264 int x509_attr_type_and_value_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen,
265 const uint8_t **in, size_t *inlen)
266 {
267 int ret;
268 const uint8_t *d;
269 size_t dlen;
270
271 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
272 if (ret < 0) error_print();
273 return ret;
274 }
275 if (x509_name_type_from_der(oid, &d, &dlen) != 1
276 || x509_directory_name_from_der(tag, val, vlen, &d, &dlen) != 1
277 || x509_attr_type_and_value_check(*oid, *tag, *val, *vlen) != 1
278 || asn1_length_is_zero(dlen) != 1) {
279 error_print();
280 return -1;
281 }
282 return 1;
283 }
284
x509_attr_type_and_value_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)285 int x509_attr_type_and_value_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
286 {
287 int oid, tag;
288 const uint8_t *val;
289 size_t vlen;
290
291 if (fmt & ASN1_FMT_FULL) {
292 format_print(fp, fmt, ind, "%s\n", label);
293 ind += 4;
294
295 if (x509_name_type_from_der(&oid, &d, &dlen) != 1) goto err;
296 asn1_object_identifier_print(fp, fmt, ind, "type", x509_name_type_name(oid), NULL, 0);
297 if (oid == OID_email_address) {
298 if (asn1_ia5_string_from_der((const char **)&val, &vlen, &d, &dlen) != 1) goto err;
299 format_string(fp, fmt, ind, "value", val, vlen);
300 } else {
301 if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err;
302 x509_directory_name_print(fp, fmt, ind, "value", tag, val, vlen);
303 }
304 } else {
305 if (x509_name_type_from_der(&oid, &d, &dlen) != 1) { error_print(); goto err; }
306 if (oid == OID_email_address) {
307 if (asn1_ia5_string_from_der((const char **)&val, &vlen, &d, &dlen) != 1) goto err;
308 format_string(fp, fmt, ind, "emailAddress", val, vlen);
309 } else {
310 if (x509_directory_name_from_der(&tag, &val, &vlen, &d, &dlen) != 1) goto err;
311 x509_directory_name_print(fp, fmt, ind, x509_name_type_name(oid), tag, val, vlen);
312 }
313 }
314 if (asn1_length_is_zero(dlen) != 1) goto err;
315 return 1;
316 err:
317 error_print();
318 return -1;
319 }
320
x509_rdn_to_der(int oid,int tag,const uint8_t * val,size_t vlen,const uint8_t * more,size_t morelen,uint8_t ** out,size_t * outlen)321 int x509_rdn_to_der(int oid, int tag, const uint8_t *val, size_t vlen,
322 const uint8_t *more, size_t morelen,
323 uint8_t **out, size_t *outlen)
324 {
325 size_t len = 0;
326 if (x509_attr_type_and_value_to_der(oid, tag, val, vlen, NULL, &len) != 1
327 || asn1_data_to_der(more, morelen, NULL, &len) < 0
328 || asn1_set_header_to_der(len, out, outlen) != 1
329 || x509_attr_type_and_value_to_der(oid, tag, val, vlen, out, outlen) != 1
330 || asn1_data_to_der(more, morelen, out, outlen) < 0) {
331 error_print();
332 return -1;
333 }
334 return 1;
335 }
336
x509_rdn_from_der(int * oid,int * tag,const uint8_t ** val,size_t * vlen,const uint8_t ** more,size_t * morelen,const uint8_t ** in,size_t * inlen)337 int x509_rdn_from_der(int *oid, int *tag, const uint8_t **val, size_t *vlen,
338 const uint8_t **more, size_t *morelen,
339 const uint8_t **in, size_t *inlen)
340 {
341 int ret;
342 const uint8_t *d;
343 size_t dlen;
344
345 if ((ret = asn1_set_from_der(&d, &dlen, in, inlen)) != 1) {
346 if (ret < 0) error_print();
347 return ret;
348 }
349 if (x509_attr_type_and_value_from_der(oid, tag, val, vlen, &d, &dlen) != 1) {
350 error_print();
351 return -1;
352 }
353 if (dlen) {
354 *more = d;
355 *morelen = dlen;
356 // TODO: check more,morelen
357 } else {
358 *more = NULL;
359 *morelen = 0;
360 }
361 return 1;
362 }
363
x509_rdn_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)364 int x509_rdn_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
365 {
366 const uint8_t *p;
367 size_t len;
368
369 if (fmt & ASN1_FMT_FULL) {
370 format_print(fp, fmt, ind, "%s\n", label);
371 ind += 4;
372 }
373 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
374 error_print();
375 return -1;
376 }
377 x509_attr_type_and_value_print(fp, fmt, ind, "AttributeTypeAndValue", p, len);
378 while (dlen) {
379 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
380 error_print();
381 return -1;
382 }
383 x509_attr_type_and_value_print(fp, fmt, ind + 4, "AttributeTypeAndValue", p, len);
384 }
385 return 1;
386 }
387
x509_name_add_rdn(uint8_t * d,size_t * dlen,size_t maxlen,int oid,int tag,const uint8_t * val,size_t vlen,const uint8_t * more,size_t morelen)388 int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen,
389 int oid, int tag, const uint8_t *val, size_t vlen,
390 const uint8_t *more, size_t morelen)
391 {
392 size_t len = 0;
393 uint8_t *p = d + *dlen;
394 if (!val && !more) {
395 return 0;
396 }
397 if (x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, NULL, &len) != 1
398 || asn1_length_le(*dlen + len, maxlen) != 1
399 || x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, &p, dlen) != 1) {
400 error_print();
401 return -1;
402 }
403 return 1;
404 }
405
x509_name_add_country_name(uint8_t * d,size_t * dlen,int maxlen,const char val[2])406 int x509_name_add_country_name(uint8_t *d, size_t *dlen, int maxlen, const char val[2])
407 {
408 int ret;
409 ret = x509_name_add_rdn(d, dlen, maxlen,
410 OID_at_country_name, ASN1_TAG_PrintableString, (uint8_t *)val, 2, NULL, 0);
411 if (ret < 0) error_print();
412 return ret;
413 }
414
x509_name_add_state_or_province_name(uint8_t * d,size_t * dlen,int maxlen,int tag,const uint8_t * val,size_t vlen)415 int x509_name_add_state_or_province_name(uint8_t *d, size_t *dlen, int maxlen,
416 int tag, const uint8_t *val, size_t vlen)
417 {
418 int ret;
419 ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_state_or_province_name, tag, val, vlen, NULL, 0);
420 if (ret < 0) error_print();
421 return ret;
422 }
423
x509_name_add_locality_name(uint8_t * d,size_t * dlen,int maxlen,int tag,const uint8_t * val,size_t vlen)424 int x509_name_add_locality_name(uint8_t *d, size_t *dlen, int maxlen,
425 int tag, const uint8_t *val, size_t vlen)
426 {
427 int ret;
428 ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_locality_name, tag, val, vlen, NULL, 0);
429 if (ret < 0) error_print();
430 return ret;
431 }
432
x509_name_add_organization_name(uint8_t * d,size_t * dlen,int maxlen,int tag,const uint8_t * val,size_t vlen)433 int x509_name_add_organization_name(uint8_t *d, size_t *dlen, int maxlen,
434 int tag, const uint8_t *val, size_t vlen)
435 {
436 int ret;
437 ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_organization_name, tag, val, vlen, NULL, 0);
438 if (ret < 0) error_print();
439 return ret;
440 }
441
x509_name_add_organizational_unit_name(uint8_t * d,size_t * dlen,int maxlen,int tag,const uint8_t * val,size_t vlen)442 int x509_name_add_organizational_unit_name(uint8_t *d, size_t *dlen, int maxlen,
443 int tag, const uint8_t *val, size_t vlen)
444 {
445 int ret;
446 ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_organizational_unit_name, tag, val, vlen, NULL, 0);
447 if (ret < 0) error_print();
448 return ret;
449 }
450
x509_name_add_common_name(uint8_t * d,size_t * dlen,int maxlen,int tag,const uint8_t * val,size_t vlen)451 int x509_name_add_common_name(uint8_t *d, size_t *dlen, int maxlen,
452 int tag, const uint8_t *val, size_t vlen)
453 {
454 int ret;
455 ret = x509_name_add_rdn(d, dlen, maxlen, OID_at_common_name, tag, val, vlen, NULL, 0);
456 if (ret < 0) error_print();
457 return ret;
458 }
459
x509_name_add_domain_component(uint8_t * d,size_t * dlen,int maxlen,const char * val,size_t vlen)460 int x509_name_add_domain_component(uint8_t *d, size_t *dlen, int maxlen,
461 const char *val, size_t vlen)
462 {
463 int ret;
464 return x509_name_add_rdn(d, dlen, maxlen, OID_domain_component, ASN1_TAG_IA5String, (uint8_t *)val, vlen, NULL, 0);
465 if (ret < 0) error_print();
466 return ret;
467 }
468
_strlen(const char * s)469 static size_t _strlen(const char *s) { return s ? strlen(s) : 0; }
470
x509_name_set(uint8_t * d,size_t * dlen,size_t maxlen,const char * country,const char * state,const char * locality,const char * org,const char * org_unit,const char * common_name)471 int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen,
472 const char *country, const char *state, const char *locality,
473 const char *org, const char *org_unit, const char *common_name)
474 {
475 int tag = ASN1_TAG_PrintableString;
476 if (country && strlen(country) != 2) {
477 error_print();
478 return -1;
479 }
480 *dlen = 0;
481 if (x509_name_add_country_name(d, dlen, maxlen, country) < 0
482 || x509_name_add_state_or_province_name(d, dlen, maxlen, tag, (uint8_t *)state, _strlen(state)) < 0
483 || x509_name_add_locality_name(d, dlen, maxlen, tag, (uint8_t *)locality, _strlen(locality)) < 0
484 || x509_name_add_organization_name(d, dlen, maxlen, tag, (uint8_t *)org, _strlen(org)) < 0
485 || x509_name_add_organizational_unit_name(d, dlen, maxlen, tag, (uint8_t *)org_unit, _strlen(org_unit)) < 0
486 || x509_name_add_common_name(d, dlen, maxlen, tag, (uint8_t *)common_name, _strlen(common_name)) != 1) {
487 error_print();
488 return -1;
489 }
490 return 1;
491 }
492
x509_name_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)493 int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
494 {
495 const uint8_t *p;
496 size_t len;
497
498 if (label) {
499 format_print(fp, fmt, ind, "%s\n", label);
500 ind += 4;
501 }
502 while (dlen) {
503 if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) {
504 error_print();
505 return -1;
506 }
507 x509_rdn_print(fp, fmt, ind, "RelativeDistinguishedName", p, len);
508 }
509 return 1;
510 }
511
x509_names_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)512 int x509_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
513 {
514 const uint8_t *p;
515 size_t len;
516
517 format_print(fp, fmt, ind, "%s\n", label);
518 ind += 4;
519
520 while (dlen) {
521 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
522 error_print();
523 return -1;
524 }
525 x509_name_print(fp, fmt, ind, "Name", p, len);
526 }
527 return 1;
528 }
529
x509_name_get_value_by_type(const uint8_t * d,size_t dlen,int oid,int * tag,const uint8_t ** val,size_t * vlen)530 int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen)
531 {
532 const uint8_t *rdn_d;
533 size_t rdn_dlen;
534
535 while (dlen) {
536 int attr_oid;
537 int attr_tag;
538 const uint8_t *attr_val;
539 size_t attr_vlen;
540
541 if (asn1_set_from_der(&rdn_d, &rdn_dlen, &d, &dlen) != 1) {
542 error_print();
543 return -1;
544 }
545 while (rdn_dlen) {
546 if (x509_attr_type_and_value_from_der(&attr_oid, &attr_tag, &attr_val, &attr_vlen,
547 &rdn_d, &rdn_dlen) != 1) {
548 error_print();
549 return -1;
550 }
551 }
552 if (attr_oid == oid) {
553 *tag = attr_tag;
554 *val = attr_val;
555 *vlen = attr_vlen;
556 return 1;
557 }
558 }
559 return 0;
560 }
561
x509_name_get_common_name(const uint8_t * d,size_t dlen,int * tag,const uint8_t ** val,size_t * vlen)562 int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uint8_t **val, size_t *vlen)
563 {
564 int ret;
565 ret = x509_name_get_value_by_type(d, dlen, OID_at_common_name, tag, val, vlen);
566 if (ret < 0) error_print();
567 return -1;
568 }
569
x509_name_equ(const uint8_t * a,size_t alen,const uint8_t * b,size_t blen)570 int x509_name_equ(const uint8_t *a, size_t alen, const uint8_t *b, size_t blen)
571 {
572 if (alen != blen || memcmp(a, b, blen) != 0) {
573 return 0;
574 }
575 return 1;
576 }
577
578
x509_public_key_info_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)579 int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
580 {
581 const uint8_t *p = d;
582 size_t len = dlen;
583 int alg;
584 int params;
585
586 format_print(fp, fmt, ind, "%s\n", label);
587 ind += 4;
588
589 if (x509_public_key_algor_from_der(&alg, ¶ms, &p, &len) != 1) goto err;
590 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
591 x509_public_key_algor_print(fp, fmt, ind, "algorithm", p, len);
592 format_print(fp, fmt, ind, "subjectPublicKey\n");
593 ind += 4;
594 if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err;
595 switch (alg) {
596 case OID_ec_public_key:
597 format_bytes(fp, fmt, ind, "ECPoint", p, len);
598 break;
599 case OID_rsa_encryption:
600 rsa_public_key_print(fp, fmt, ind, "RSAPublicKey", p, len);
601 break;
602 default:
603 format_bytes(fp, fmt, ind, "raw_data", p, len);
604 }
605 if (asn1_length_is_zero(dlen) != 1) goto err;
606 return 1;
607 err:
608 error_print();
609 return -1;
610 }
611
x509_ext_to_der(int oid,int critical,const uint8_t * val,size_t vlen,uint8_t ** out,size_t * outlen)612 int x509_ext_to_der(int oid, int critical, const uint8_t *val, size_t vlen, uint8_t **out, size_t *outlen)
613 {
614 size_t len = 0;
615 if (x509_ext_id_to_der(oid, NULL, &len) != 1
616 || asn1_boolean_to_der(critical, NULL, &len) < 0
617 || asn1_octet_string_to_der(val, vlen, NULL, &len) != 1
618 || asn1_sequence_header_to_der(len, out, outlen) != 1
619 || x509_ext_id_to_der(oid, out, outlen) != 1
620 || asn1_boolean_to_der(critical, out, outlen) < 0
621 || asn1_octet_string_to_der(val, vlen, out, outlen) != 1) {
622 error_print();
623 return -1;
624 }
625 return 1;
626 }
627
x509_ext_from_der(int * oid,uint32_t * nodes,size_t * nodes_cnt,int * critical,const uint8_t ** val,size_t * vlen,const uint8_t ** in,size_t * inlen)628 int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt,
629 int *critical, const uint8_t **val, size_t *vlen,
630 const uint8_t **in, size_t *inlen)
631 {
632 int ret;
633 const uint8_t *d;
634 size_t dlen;
635
636 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
637 if (ret < 0) error_print();
638 return ret;
639 }
640 *critical = 0;
641 if (x509_ext_id_from_der(oid, nodes, nodes_cnt, &d, &dlen) != 1
642 || asn1_boolean_from_der(critical, &d, &dlen) < 0
643 || asn1_octet_string_from_der(val, vlen, &d, &dlen) != 1
644 || asn1_length_is_zero(dlen) != 1) {
645 error_print();
646 return -1;
647 }
648 return 1;
649 }
650
x509_ext_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)651 int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
652 {
653 int ret, oid, critical;
654 uint32_t nodes[32];
655 size_t nodes_cnt;
656 const uint8_t *val;
657 size_t vlen;
658
659 const uint8_t *p;
660 size_t len;
661 int ival;
662 const char *name;
663
664 if (label) {
665 format_print(fp, fmt, ind, "%s\n", label);
666 ind += 4;
667 }
668 if (x509_ext_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err;
669 asn1_object_identifier_print(fp, fmt, ind, "extnID", x509_ext_id_name(oid), nodes, nodes_cnt);
670 if ((ret = asn1_boolean_from_der(&critical, &d, &dlen)) < 0) goto err;
671 if (ret) format_print(fp, fmt, ind, "critical: %s\n", asn1_boolean_name(critical));
672 if (asn1_octet_string_from_der(&val, &vlen, &d, &dlen) != 1) goto err;
673
674 switch (oid) {
675 case OID_ce_subject_key_identifier:
676 if (asn1_octet_string_from_der(&p, &len, &val, &vlen) != 1) {
677 error_print();
678 return -1;
679 }
680 break;
681 case OID_ce_key_usage:
682 case OID_netscape_cert_type:
683 if (asn1_bits_from_der(&ival, &val, &vlen) != 1) {
684 error_print();
685 return -1;
686 }
687 break;
688 case OID_ce_inhibit_any_policy:
689 if (asn1_int_from_der(&ival, &val, &vlen) != 1) {
690 error_print();
691 return -1;
692 }
693 break;
694 case OID_netscape_cert_comment:
695 if (asn1_ia5_string_from_der((const char **)&p, &len, &val, &vlen) != 1) {
696 error_print();
697 return -1;
698 }
699 break;
700 case OID_ct_precertificate_scts:
701 case OID_undef:
702 p = val;
703 len = vlen;
704 vlen = 0;
705 break;
706 default:
707 if (asn1_sequence_from_der(&p, &len, &val, &vlen) != 1) {
708 error_print();
709 return -1;
710 }
711 }
712 if (asn1_length_is_zero(vlen) != 1) {
713 error_print();
714 return -1;
715 }
716
717 name = x509_ext_id_name(oid);
718
719 switch (oid) {
720 case OID_ce_authority_key_identifier: return x509_authority_key_identifier_print(fp, fmt, ind, name, p, len);
721 case OID_ce_subject_key_identifier: return format_bytes(fp, fmt, ind, name, p, len);
722 case OID_ce_key_usage: return x509_key_usage_print(fp, fmt, ind, name, ival);
723 case OID_ce_certificate_policies: return x509_certificate_policies_print(fp, fmt, ind, name, p, len);
724 case OID_ce_policy_mappings: return x509_policy_mappings_print(fp, fmt, ind, name, p, len);
725 case OID_ce_subject_alt_name: return x509_general_names_print(fp, fmt, ind, name, p, len);
726 case OID_ce_issuer_alt_name: return x509_general_names_print(fp, fmt, ind, name, p, len);
727 case OID_ce_subject_directory_attributes: return x509_attributes_print(fp, fmt, ind, name, p, len);
728 case OID_ce_basic_constraints: return x509_basic_constraints_print(fp, fmt, ind, name, p, len);
729 case OID_ce_name_constraints: return x509_name_constraints_print(fp, fmt, ind, name, p, len);
730 case OID_ce_policy_constraints: return x509_policy_constraints_print(fp, fmt, ind, name, p, len);
731 case OID_ce_ext_key_usage: return x509_ext_key_usage_print(fp, fmt, ind, name, p, len);
732 case OID_ce_crl_distribution_points: return x509_crl_distribution_points_print(fp, fmt, ind, name, p, len);
733 case OID_ce_inhibit_any_policy: format_print(fp, fmt, ind, "%s: %d\n", name, ival);
734 case OID_ce_freshest_crl: return x509_freshest_crl_print(fp, fmt, ind, name, p, len);
735 case OID_netscape_cert_type: return x509_netscape_cert_type_print(fp, fmt, ind, name, ival);
736 case OID_netscape_cert_comment: return format_string(fp, fmt, ind, name, p, len);
737 default: format_bytes(fp, fmt, ind, "extnValue", p, len);
738 }
739 return 1;
740 err:
741 error_print();
742 return -1;
743 }
744
x509_explicit_exts_to_der(int index,const uint8_t * d,size_t dlen,uint8_t ** out,size_t * outlen)745 int x509_explicit_exts_to_der(int index, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
746 {
747 size_t len = 0;
748 if (!d) {
749 return 0;
750 }
751 if (asn1_sequence_to_der(d, dlen, NULL, &len) != 1
752 || asn1_explicit_header_to_der(index, len, out, outlen) != 1
753 || asn1_sequence_to_der(d, dlen, out, outlen) != 1) {
754 error_print();
755 return -1;
756 }
757 return 1;
758 }
759
x509_explicit_exts_from_der(int index,const uint8_t ** d,size_t * dlen,const uint8_t ** in,size_t * inlen)760 int x509_explicit_exts_from_der(int index, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
761 {
762 int ret;
763 const uint8_t *p;
764 size_t len;
765
766 if ((ret = asn1_explicit_from_der(index, &p, &len, in, inlen)) != 1) {
767 if (ret < 0) error_print();
768 return ret;
769 }
770 if (asn1_sequence_from_der(d, dlen, &p, &len) != 1
771 || asn1_length_is_zero(len) != 1) {
772 error_print();
773 return -1;
774 }
775 return 1;
776 }
777
x509_exts_get_count(const uint8_t * d,size_t dlen,size_t * cnt)778 int x509_exts_get_count(const uint8_t *d, size_t dlen, size_t *cnt)
779 {
780 return asn1_types_get_count(d, dlen, ASN1_TAG_SEQUENCE, cnt);
781 }
782
x509_exts_get_ext_by_index(const uint8_t * d,size_t dlen,int index,int * oid,uint32_t * nodes,size_t * nodes_cnt,int * critical,const uint8_t ** val,size_t * vlen)783 int x509_exts_get_ext_by_index(const uint8_t *d, size_t dlen, int index,
784 int *oid, uint32_t *nodes, size_t *nodes_cnt, int *critical,
785 const uint8_t **val, size_t *vlen)
786 {
787 error_print();
788 return -1;
789 }
790
x509_exts_get_ext_by_oid(const uint8_t * d,size_t dlen,int oid,int * critical,const uint8_t ** val,size_t * vlen)791 int x509_exts_get_ext_by_oid(const uint8_t *d, size_t dlen, int oid,
792 int *critical, const uint8_t **val, size_t *vlen)
793 {
794 return -1;
795 }
796
x509_exts_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)797 int x509_exts_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
798 {
799 const uint8_t *p;
800 size_t len;
801
802 if (label) {
803 format_print(fp, fmt, ind, "%s\n", label);
804 ind += 4;
805 }
806 while (dlen) {
807 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
808 error_print();
809 return -1;
810 }
811 x509_ext_print(fp, fmt, ind, "Extension", p, len);
812 }
813 return 1;
814 }
815
x509_tbs_cert_to_der(int version,const uint8_t * serial,size_t serial_len,int signature_algor,const uint8_t * issuer,size_t issuer_len,time_t not_before,time_t not_after,const uint8_t * subject,size_t subject_len,const SM2_KEY * subject_public_key,const uint8_t * issuer_unique_id,size_t issuer_unique_id_len,const uint8_t * subject_unique_id,size_t subject_unique_id_len,const uint8_t * exts,size_t exts_len,uint8_t ** out,size_t * outlen)816 int x509_tbs_cert_to_der(
817 int version,
818 const uint8_t *serial, size_t serial_len,
819 int signature_algor,
820 const uint8_t *issuer, size_t issuer_len,
821 time_t not_before, time_t not_after,
822 const uint8_t *subject, size_t subject_len,
823 const SM2_KEY *subject_public_key,
824 const uint8_t *issuer_unique_id, size_t issuer_unique_id_len,
825 const uint8_t *subject_unique_id, size_t subject_unique_id_len,
826 const uint8_t *exts, size_t exts_len,
827 uint8_t **out, size_t *outlen)
828 {
829 size_t len = 0;
830 if (x509_explicit_version_to_der(0, version, NULL, &len) < 0
831 || asn1_integer_to_der(serial, serial_len, NULL, &len) != 1
832 || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1
833 || asn1_sequence_to_der(issuer, issuer_len, NULL, &len) != 1
834 || x509_validity_to_der(not_before, not_after, NULL, &len) != 1
835 || asn1_sequence_to_der(subject, subject_len, NULL, &len) != 1
836 || x509_public_key_info_to_der(subject_public_key, NULL, &len) != 1
837 || asn1_implicit_bit_octets_to_der(1, issuer_unique_id, issuer_unique_id_len, NULL, &len) < 0
838 || asn1_implicit_bit_octets_to_der(2, subject_unique_id, subject_unique_id_len, NULL, &len) < 0
839 || x509_explicit_exts_to_der(3, exts, exts_len, NULL, &len) < 0
840 || asn1_sequence_header_to_der(len, out, outlen) != 1
841 || x509_explicit_version_to_der(0, version, out, outlen) < 0
842 || asn1_integer_to_der(serial, serial_len, out, outlen) != 1
843 || x509_signature_algor_to_der(signature_algor, out, outlen) != 1
844 || asn1_sequence_to_der(issuer, issuer_len, out, outlen) != 1
845 || x509_validity_to_der(not_before, not_after, out, outlen) != 1
846 || asn1_sequence_to_der(subject, subject_len, out, outlen) != 1
847 || x509_public_key_info_to_der(subject_public_key, out, outlen) != 1
848 || asn1_implicit_bit_octets_to_der(1, issuer_unique_id, issuer_unique_id_len, out, outlen) < 0
849 || asn1_implicit_bit_octets_to_der(2, subject_unique_id, subject_unique_id_len, out, outlen) < 0
850 || x509_explicit_exts_to_der(3, exts, exts_len, out, outlen) < 0) {
851 error_print();
852 return -1;
853 }
854 return 1;
855 }
856
x509_tbs_cert_from_der(int * version,const uint8_t ** serial,size_t * serial_len,int * signature_algor,const uint8_t ** issuer,size_t * issuer_len,time_t * not_before,time_t * not_after,const uint8_t ** subject,size_t * subject_len,SM2_KEY * subject_public_key,const uint8_t ** issuer_unique_id,size_t * issuer_unique_id_len,const uint8_t ** subject_unique_id,size_t * subject_unique_id_len,const uint8_t ** exts,size_t * exts_len,const uint8_t ** in,size_t * inlen)857 int x509_tbs_cert_from_der(
858 int *version,
859 const uint8_t **serial, size_t *serial_len,
860 int *signature_algor,
861 const uint8_t **issuer, size_t *issuer_len,
862 time_t *not_before, time_t *not_after,
863 const uint8_t **subject, size_t *subject_len,
864 SM2_KEY *subject_public_key,
865 const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len,
866 const uint8_t **subject_unique_id, size_t *subject_unique_id_len,
867 const uint8_t **exts, size_t *exts_len,
868 const uint8_t **in, size_t *inlen)
869 {
870 int ret;
871 const uint8_t *d;
872 size_t dlen;
873
874 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
875 if (ret < 0) error_print();
876 return ret;
877 }
878 if (x509_explicit_version_from_der(0, version, &d, &dlen) < 0
879 || asn1_integer_from_der(serial, serial_len, &d, &dlen) != 1
880 || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1
881 || asn1_sequence_from_der(issuer, issuer_len, &d, &dlen) != 1
882 || x509_validity_from_der(not_before, not_after, &d, &dlen) != 1
883 || asn1_sequence_from_der(subject, subject_len, &d, &dlen) != 1
884 || x509_public_key_info_from_der(subject_public_key, &d, &dlen) != 1
885 || asn1_implicit_bit_octets_from_der(1, issuer_unique_id, issuer_unique_id_len, &d, &dlen) < 0
886 || asn1_implicit_bit_octets_from_der(2, subject_unique_id, subject_unique_id_len, &d, &dlen) < 0
887 || x509_explicit_exts_from_der(3, exts, exts_len, &d, &dlen) < 0
888 || asn1_length_is_zero(dlen) != 1) {
889 error_print();
890 return -1;
891 }
892 return 1;
893 }
894
x509_tbs_cert_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)895 int x509_tbs_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
896 {
897 int ret, val;
898 const uint8_t *p;
899 size_t len;
900
901 format_print(fp, fmt, ind, "%s\n", label);
902 ind += 4;
903
904 if ((ret = x509_explicit_version_from_der(0, &val, &d, &dlen)) < 0) goto err;
905 if (ret) format_print(fp, fmt, ind, "version: %s (%d)\n", x509_version_name(val), val);
906 if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1) goto err;
907 format_bytes(fp, fmt, ind, "serialNumber", p, len);
908 if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err;
909 format_print(fp, fmt, ind, "siganture: %s\n", x509_signature_algor_name(val));
910 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
911 x509_name_print(fp, fmt, ind, "issuer", p, len);
912 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
913 x509_validity_print(fp, fmt, ind, "validity", p, len);
914 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
915 x509_name_print(fp, fmt, ind, "subject", p, len);
916 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
917 x509_public_key_info_print(fp, fmt, ind, "subjectPulbicKeyInfo", p, len);
918 if ((ret = asn1_implicit_bit_octets_from_der(1, &p, &len, &d, &dlen)) < 0) goto err;
919 if (ret) format_bytes(fp, fmt, ind, "issuerUniqueID", p, len);
920 if ((ret = asn1_implicit_bit_octets_from_der(2, &p, &len, &d, &dlen)) < 0) goto err;
921 if (ret) format_bytes(fp, fmt, ind, "subjectUniqueID", p, len);
922 if ((ret = x509_explicit_exts_from_der(3, &p, &len, &d, &dlen)) < 0) goto err;
923 if (ret) x509_exts_print(fp, fmt, ind, "extensions", p, len);
924 if (asn1_length_is_zero(dlen) != 1) goto err;
925 return 1;
926 err:
927 error_print();
928 return -1;
929 }
930
x509_certificate_to_der(const uint8_t * tbs,size_t tbslen,int signature_algor,const uint8_t * sig,size_t siglen,uint8_t ** out,size_t * outlen)931 int x509_certificate_to_der(
932 const uint8_t *tbs, size_t tbslen, // full TLV
933 int signature_algor,
934 const uint8_t *sig, size_t siglen,
935 uint8_t **out, size_t *outlen)
936 {
937 size_t len = 0;
938 if (asn1_data_to_der(tbs, tbslen, NULL, &len) != 1
939 || x509_signature_algor_to_der(signature_algor, NULL, &len) != 1
940 || asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1
941 || asn1_sequence_header_to_der(len, out, outlen) != 1
942 || asn1_data_to_der(tbs, tbslen, out, outlen) != 1
943 || x509_signature_algor_to_der(signature_algor, out, outlen) != 1
944 || asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) {
945 error_print();
946 return -1;
947 }
948 return 1;
949 }
950
x509_certificate_from_der(const uint8_t ** tbs,size_t * tbslen,int * signature_algor,const uint8_t ** sig,size_t * siglen,const uint8_t ** in,size_t * inlen)951 int x509_certificate_from_der(
952 const uint8_t **tbs, size_t *tbslen, // full TLV
953 int *signature_algor,
954 const uint8_t **sig, size_t *siglen,
955 const uint8_t **in, size_t *inlen)
956 {
957 int ret;
958 const uint8_t *d;
959 size_t dlen;
960
961 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
962 if (ret < 0) error_print();
963 return ret;
964 }
965 if (asn1_any_from_der(tbs, tbslen, &d, &dlen) != 1
966 || x509_signature_algor_from_der(signature_algor, &d, &dlen) != 1
967 || asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1
968 || asn1_length_is_zero(dlen) != 1) {
969 error_print();
970 return -1;
971 }
972 return 1;
973 }
974
x509_certificate_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)975 int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
976 {
977 const uint8_t *p;
978 size_t len;
979 int val;
980
981 format_print(fp, fmt, ind, "%s\n", label);
982 ind += 4;
983
984 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
985 x509_tbs_cert_print(fp, fmt, ind, "tbsCertificate", p, len);
986 if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err;
987 format_print(fp, fmt, ind, "signatureAlgorithm: %s\n", x509_signature_algor_name(val));
988 if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err;
989 format_bytes(fp, fmt, ind, "signatureValue", p, len);
990 if (asn1_length_is_zero(dlen) != 1) goto err;
991 return 1;
992 err:
993 error_print();
994 return -1;
995 }
996
x509_cert_sign(uint8_t * cert,size_t * certlen,size_t maxlen,int version,const uint8_t * serial,size_t serial_len,int signature_algor,const uint8_t * issuer,size_t issuer_len,time_t not_before,time_t not_after,const uint8_t * subject,size_t subject_len,const SM2_KEY * subject_public_key,const uint8_t * issuer_unique_id,size_t issuer_unique_id_len,const uint8_t * subject_unique_id,size_t subject_unique_id_len,const uint8_t * exts,size_t exts_len,const SM2_KEY * sign_key,const char * signer_id,size_t signer_id_len)997 int x509_cert_sign(
998 uint8_t *cert, size_t *certlen, size_t maxlen,
999 int version,
1000 const uint8_t *serial, size_t serial_len,
1001 int signature_algor,
1002 const uint8_t *issuer, size_t issuer_len,
1003 time_t not_before, time_t not_after,
1004 const uint8_t *subject, size_t subject_len,
1005 const SM2_KEY *subject_public_key,
1006 const uint8_t *issuer_unique_id, size_t issuer_unique_id_len,
1007 const uint8_t *subject_unique_id, size_t subject_unique_id_len,
1008 const uint8_t *exts, size_t exts_len,
1009 const SM2_KEY *sign_key, const char *signer_id, size_t signer_id_len)
1010 {
1011 uint8_t tbs[1024];
1012 size_t tbslen = 0;
1013 uint8_t *p = tbs;
1014 size_t len = 0;
1015 SM2_SIGN_CTX sign_ctx;
1016 int sig_alg = OID_sm2sign_with_sm3;
1017 uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
1018 size_t siglen;
1019
1020 if (x509_tbs_cert_to_der(version, serial, serial_len, signature_algor,
1021 issuer, issuer_len, not_before, not_after,
1022 subject, subject_len, subject_public_key,
1023 issuer_unique_id, issuer_unique_id_len,
1024 subject_unique_id, subject_unique_id_len,
1025 exts, exts_len, NULL, &len) != 1
1026 || asn1_length_le(len, sizeof(tbs)) != 1
1027 || x509_tbs_cert_to_der(version, serial, serial_len, signature_algor,
1028 issuer, issuer_len, not_before, not_after,
1029 subject, subject_len, subject_public_key,
1030 issuer_unique_id, issuer_unique_id_len,
1031 subject_unique_id, subject_unique_id_len,
1032 exts, exts_len, &p, &tbslen) != 1) {
1033 error_print();
1034 return -1;
1035 }
1036
1037 if (sm2_sign_init(&sign_ctx, sign_key, signer_id, signer_id_len) != 1
1038 || sm2_sign_update(&sign_ctx, tbs, tbslen) != 1
1039 || sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) {
1040 memset(&sign_ctx, 0, sizeof(sign_ctx));
1041 error_print();
1042 return -1;
1043 }
1044 memset(&sign_ctx, 0, sizeof(sign_ctx));
1045
1046 *certlen = len = 0;
1047 if (x509_certificate_to_der(tbs, tbslen, sig_alg, sig, siglen, NULL, &len) != 1
1048 || asn1_length_le(len, maxlen) != 1
1049 || x509_certificate_to_der(tbs, tbslen, sig_alg, sig, siglen, &cert, certlen) != 1) {
1050 error_print();
1051 return -1;
1052 }
1053 return 1;
1054 }
1055
x509_cert_verify(const uint8_t * a,size_t alen,const SM2_KEY * pub_key,const char * signer_id,size_t signer_id_len)1056 int x509_cert_verify(const uint8_t *a, size_t alen,
1057 const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len)
1058 {
1059 int ret;
1060 const uint8_t *tbs;
1061 size_t tbslen;
1062 int sig_alg;
1063 const uint8_t *sig;
1064 size_t siglen;
1065 SM2_SIGN_CTX verify_ctx;
1066
1067 if (x509_certificate_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1
1068 || asn1_length_is_zero(alen) != 1) {
1069 error_print();
1070 return -1;
1071 }
1072 if (sig_alg != OID_sm2sign_with_sm3) {
1073 error_print();
1074 return -1;
1075 }
1076 if (sm2_verify_init(&verify_ctx, pub_key, signer_id, signer_id_len) != 1
1077 || sm2_verify_update(&verify_ctx, tbs, tbslen) != 1
1078 || (ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) {
1079 error_print();
1080 return -1;
1081 }
1082 if (!ret) error_print();
1083 return ret;
1084 }
1085
x509_cert_verify_by_ca_cert(const uint8_t * a,size_t alen,const uint8_t * cacert,size_t cacertlen,const char * signer_id,size_t signer_id_len)1086 int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen,
1087 const uint8_t *cacert, size_t cacertlen,
1088 const char *signer_id, size_t signer_id_len)
1089 {
1090 int ret;
1091 SM2_KEY public_key;
1092
1093 if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1
1094 || (ret = x509_cert_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) {
1095 error_print();
1096 return -1;
1097 }
1098 if (!ret) error_print();
1099 return ret;
1100 }
1101
x509_cert_to_der(const uint8_t * a,size_t alen,uint8_t ** out,size_t * outlen)1102 int x509_cert_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen)
1103 {
1104 return asn1_any_to_der(a, alen, out, outlen);
1105 }
1106
x509_cert_from_der(const uint8_t ** a,size_t * alen,const uint8_t ** in,size_t * inlen)1107 int x509_cert_from_der(const uint8_t **a, size_t *alen, const uint8_t **in, size_t *inlen)
1108 {
1109 return asn1_any_from_der(a, alen, in, inlen);
1110 }
1111
x509_cert_to_pem(const uint8_t * a,size_t alen,FILE * fp)1112 int x509_cert_to_pem(const uint8_t *a, size_t alen, FILE *fp)
1113 {
1114 if (pem_write(fp, "CERTIFICATE", a, alen) != 1) {
1115 error_print();
1116 return -1;
1117 }
1118 return 1;
1119 }
1120
x509_cert_from_pem(uint8_t * a,size_t * alen,size_t maxlen,FILE * fp)1121 int x509_cert_from_pem(uint8_t *a, size_t *alen, size_t maxlen, FILE *fp)
1122 {
1123 int ret;
1124 if ((ret = pem_read(fp, "CERTIFICATE", a, alen, maxlen)) != 1) {
1125 if (ret < 0) error_print();
1126 return ret;
1127 }
1128 return 1;
1129 }
1130
x509_cert_from_pem_by_index(uint8_t * a,size_t * alen,size_t maxlen,int index,FILE * fp)1131 int x509_cert_from_pem_by_index(uint8_t *a, size_t *alen, size_t maxlen, int index, FILE *fp)
1132 {
1133 int i;
1134 for (i = 0; i <= index; i++) {
1135 if (x509_cert_from_pem(a, alen, maxlen, fp) != 1) {
1136 error_print();
1137 return -1;
1138 }
1139 }
1140 return 1;
1141 }
1142
x509_cert_from_pem_by_subject(uint8_t * a,size_t * alen,size_t maxlen,const uint8_t * name,size_t namelen,FILE * fp)1143 int x509_cert_from_pem_by_subject(uint8_t *a, size_t *alen, size_t maxlen, const uint8_t *name, size_t namelen, FILE *fp)
1144 {
1145 int ret;
1146 const uint8_t *d;
1147 size_t dlen;
1148
1149 for (;;) {
1150 if ((ret = x509_cert_from_pem(a, alen, maxlen, fp)) != 1) {
1151 if (ret < 0) error_print();
1152 return ret;
1153 }
1154 if (x509_cert_get_subject(a, *alen, &d, &dlen) != 1) {
1155 error_print();
1156 return -1;
1157 }
1158
1159 if (dlen == namelen && memcmp(name, d, dlen) == 0) {
1160 return 1;
1161 }
1162 }
1163 return 0;
1164 }
1165
x509_cert_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * a,size_t alen)1166 int x509_cert_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
1167 {
1168 const uint8_t *d;
1169 size_t dlen;
1170
1171 if (asn1_sequence_from_der(&d, &dlen, &a, &alen) != 1) {
1172 error_print();
1173 return -1;
1174 }
1175 x509_certificate_print(fp, fmt, ind, label, d, dlen);
1176 if (asn1_length_is_zero(alen) != 1) {
1177 error_print();
1178 return -1;
1179 }
1180 return 1;
1181 }
1182
x509_cert_get_details(const uint8_t * a,size_t alen,int * version,const uint8_t ** serial_number,size_t * serial_number_len,int * inner_signature_algor,const uint8_t ** issuer,size_t * issuer_len,time_t * not_before,time_t * not_after,const uint8_t ** subject,size_t * subject_len,SM2_KEY * subject_public_key,const uint8_t ** issuer_unique_id,size_t * issuer_unique_id_len,const uint8_t ** subject_unique_id,size_t * subject_unique_id_len,const uint8_t ** extensions,size_t * extensions_len,int * signature_algor,const uint8_t ** signature,size_t * signature_len)1183 int x509_cert_get_details(const uint8_t *a, size_t alen,
1184 int *version,
1185 const uint8_t **serial_number, size_t *serial_number_len,
1186 int *inner_signature_algor,
1187 const uint8_t **issuer, size_t *issuer_len,
1188 time_t *not_before, time_t *not_after,
1189 const uint8_t **subject, size_t *subject_len,
1190 SM2_KEY *subject_public_key,
1191 const uint8_t **issuer_unique_id, size_t *issuer_unique_id_len,
1192 const uint8_t **subject_unique_id, size_t *subject_unique_id_len,
1193 const uint8_t **extensions, size_t *extensions_len,
1194 int *signature_algor,
1195 const uint8_t **signature, size_t *signature_len)
1196 {
1197 const uint8_t *tbs;
1198 size_t tbs_len;
1199 int sig_alg;
1200 const uint8_t *sig; size_t sig_len;
1201
1202 const uint8_t *d;
1203 size_t dlen;
1204
1205 int ver;
1206 const uint8_t *serial; size_t serial_len;
1207 int inner_sig_alg;
1208 const uint8_t *isur; size_t isur_len;
1209 time_t before, after;
1210 const uint8_t *subj; size_t subj_len;
1211 SM2_KEY sm2_key;
1212 const uint8_t *isur_uniq_id; size_t isur_uniq_id_len;
1213 const uint8_t *subj_uniq_id; size_t subj_uniq_id_len;
1214 const uint8_t *exts; size_t exts_len;
1215
1216 if (x509_certificate_from_der(&tbs, &tbs_len, &sig_alg, &sig, &sig_len, &a, &alen) != 1
1217 || asn1_length_is_zero(alen) != 1) {
1218 error_print();
1219 return -1;
1220 }
1221 if (asn1_sequence_from_der(&d, &dlen, &tbs, &tbs_len) != 1
1222 || asn1_length_is_zero(tbs_len) != 1) {
1223 error_print();
1224 return -1;
1225 }
1226
1227 if (x509_explicit_version_from_der(0, &ver, &d, &dlen) < 0
1228 || asn1_integer_from_der(&serial, &serial_len, &d, &dlen) != 1
1229 || x509_signature_algor_from_der(&inner_sig_alg, &d, &dlen) != 1
1230 || asn1_sequence_from_der(&isur, &isur_len, &d, &dlen) != 1
1231 || x509_validity_from_der(&before, &after, &d, &dlen) != 1
1232 || asn1_sequence_from_der(&subj, &subj_len, &d, &dlen) != 1
1233 || x509_public_key_info_from_der(&sm2_key, &d, &dlen) != 1
1234 || asn1_implicit_bit_octets_from_der(1, &isur_uniq_id, &isur_uniq_id_len, &d, &dlen) < 0
1235 || asn1_implicit_bit_octets_from_der(2, &subj_uniq_id, &subj_uniq_id_len, &d, &dlen) < 0
1236 || x509_explicit_exts_from_der(3, &exts, &exts_len, &d, &dlen) < 0) {
1237 error_print();
1238 return -1;
1239 }
1240
1241 if (version) *version = ver;
1242 if (serial_number) *serial_number = serial;
1243 if (serial_number_len) *serial_number_len = serial_len;
1244 if (inner_signature_algor) *inner_signature_algor = inner_sig_alg;
1245 if (issuer) *issuer = isur;
1246 if (issuer_len) *issuer_len = isur_len;
1247 if (not_before) *not_before = before;
1248 if (not_after) *not_after = after;
1249 if (subject) *subject = subj;
1250 if (subject_len) *subject_len = subj_len;
1251 if (subject_public_key) *subject_public_key = sm2_key;
1252 if (issuer_unique_id) *issuer_unique_id = isur_uniq_id;
1253 if (issuer_unique_id_len) *issuer_unique_id_len = isur_uniq_id_len;
1254 if (subject_unique_id) *subject_unique_id = subj_uniq_id;
1255 if (subject_unique_id_len) *subject_unique_id_len = subj_uniq_id_len;
1256 if (extensions) *extensions = exts;
1257 if (extensions_len) *extensions_len = exts_len;
1258 if (signature_algor) *signature_algor = sig_alg;
1259 if (signature) *signature = sig;
1260 if (signature_len) *signature_len = sig_len;
1261 return 1;
1262 }
1263
x509_cert_get_issuer_and_serial_number(const uint8_t * a,size_t alen,const uint8_t ** issuer,size_t * issuer_len,const uint8_t ** serial_number,size_t * serial_number_len)1264 int x509_cert_get_issuer_and_serial_number(const uint8_t *a, size_t alen,
1265 const uint8_t **issuer, size_t *issuer_len,
1266 const uint8_t **serial_number, size_t *serial_number_len)
1267 {
1268 return x509_cert_get_details(a, alen,
1269 NULL, // version
1270 serial_number, serial_number_len, // serial
1271 NULL, // signature_algor
1272 issuer, issuer_len, // issuer
1273 NULL, NULL, // validity
1274 NULL, NULL, // subject
1275 NULL, // subject_public_key
1276 NULL, NULL, // issuer_unique_id
1277 NULL, NULL, // subject_unique_id
1278 NULL, NULL, // extensions
1279 NULL, // signature_algor
1280 NULL, NULL); // signature
1281 }
1282
x509_cert_get_subject_public_key(const uint8_t * a,size_t alen,SM2_KEY * public_key)1283 int x509_cert_get_subject_public_key(const uint8_t *a, size_t alen, SM2_KEY *public_key)
1284 {
1285 return x509_cert_get_details(a, alen,
1286 NULL, // version
1287 NULL, NULL, // serial
1288 NULL, // signature_algor
1289 NULL, NULL, // issuer
1290 NULL, NULL, // validity
1291 NULL, NULL, // subject
1292 public_key, // subject_public_key
1293 NULL, NULL, // issuer_unique_id
1294 NULL, NULL, // subject_unique_id
1295 NULL, NULL, // extensions
1296 NULL, // signature_algor
1297 NULL, NULL); // signature
1298 }
1299
x509_cert_get_subject(const uint8_t * a,size_t alen,const uint8_t ** d,size_t * dlen)1300 int x509_cert_get_subject(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen)
1301 {
1302 return x509_cert_get_details(a, alen,
1303 NULL, // version
1304 NULL, NULL, // serial
1305 NULL, // signature_algor
1306 NULL, NULL, // issuer
1307 NULL, NULL, // validity
1308 d, dlen, // subject
1309 NULL, // subject_public_key
1310 NULL, NULL, // issuer_unique_id
1311 NULL, NULL, // subject_unique_id
1312 NULL, NULL, // extensions
1313 NULL, // signature_algor
1314 NULL, NULL); // signature
1315 }
1316
x509_cert_get_issuer(const uint8_t * a,size_t alen,const uint8_t ** d,size_t * dlen)1317 int x509_cert_get_issuer(const uint8_t *a, size_t alen, const uint8_t **d, size_t *dlen)
1318 {
1319 return x509_cert_get_details(a, alen,
1320 NULL, // version
1321 NULL, NULL, // serial
1322 NULL, // signature_algor
1323 d, dlen, // issuer
1324 NULL, NULL, // validity
1325 NULL, NULL, // subject
1326 NULL, // subject_public_key
1327 NULL, NULL, // issuer_unique_id
1328 NULL, NULL, // subject_unique_id
1329 NULL, NULL, // extensions
1330 NULL, // signature_algor
1331 NULL, NULL); // signature
1332 }
1333
x509_certs_to_pem(const uint8_t * d,size_t dlen,FILE * fp)1334 int x509_certs_to_pem(const uint8_t *d, size_t dlen, FILE *fp)
1335 {
1336 const uint8_t *a;
1337 size_t alen;
1338
1339 while (dlen) {
1340 if (asn1_any_from_der(&a, &alen, &d, &dlen) != 1
1341 || x509_cert_to_pem(a, alen, fp) != 1) {
1342 error_print();
1343 return -1;
1344 }
1345 }
1346 return 1;
1347 }
1348
x509_certs_from_pem(uint8_t * d,size_t * dlen,size_t maxlen,FILE * fp)1349 int x509_certs_from_pem(uint8_t *d, size_t *dlen, size_t maxlen, FILE *fp)
1350 {
1351 int ret;
1352 size_t len, total_len = 0;
1353
1354 for (;;) {
1355 if ((ret = x509_cert_from_pem(d, &len, maxlen, fp)) < 0) {
1356 error_print();
1357 return -1;
1358 } else if (ret == 0) {
1359 break;
1360 }
1361 d += len;
1362 total_len += len;
1363 maxlen -= len;
1364 }
1365 *dlen = total_len;
1366 if (!total_len) {
1367 return 0;
1368 }
1369 return 1;
1370 }
1371
x509_certs_get_count(const uint8_t * d,size_t dlen,size_t * cnt)1372 int x509_certs_get_count(const uint8_t *d, size_t dlen, size_t *cnt)
1373 {
1374 if (asn1_types_get_count(d, dlen, ASN1_TAG_SEQUENCE, cnt) != 1) {
1375 error_print();
1376 return -1;
1377 }
1378 return 1;
1379 }
1380
x509_certs_get_cert_by_index(const uint8_t * d,size_t dlen,int index,const uint8_t ** cert,size_t * certlen)1381 int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const uint8_t **cert, size_t *certlen)
1382 {
1383 const uint8_t *a;
1384 size_t alen;
1385 int ret, i;
1386
1387 for (i = 0; i <= index; i++) {
1388 if ((ret = x509_cert_from_der(&a, &alen, &d, &dlen)) != 1) {
1389 if (ret < 0) error_print();
1390 else error_print();
1391 return -1;
1392 }
1393 }
1394 *cert = a;
1395 *certlen = alen;
1396 return 1;
1397 }
1398
x509_certs_get_last(const uint8_t * d,size_t dlen,const uint8_t ** cert,size_t * certlen)1399 int x509_certs_get_last(const uint8_t *d, size_t dlen, const uint8_t **cert, size_t *certlen)
1400 {
1401 if (!dlen) {
1402 error_print();
1403 return -1;
1404 }
1405 while (dlen) {
1406 if (x509_cert_from_der(cert, certlen, &d, &dlen) != 1) {
1407 error_print();
1408 return -1;
1409 }
1410 }
1411 return 1;
1412 }
1413
x509_certs_get_cert_by_subject(const uint8_t * d,size_t dlen,const uint8_t * subject,size_t subject_len,const uint8_t ** cert,size_t * certlen)1414 int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen,
1415 const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen)
1416 {
1417 const uint8_t *a;
1418 size_t alen;
1419 const uint8_t *subj;
1420 size_t subj_len;
1421
1422 while (dlen) {
1423 if (x509_cert_from_der(&a, &alen, &d, &dlen) != 1) {
1424 error_print();
1425 return -1;
1426 }
1427 if (x509_cert_get_subject(a, alen, &subj, &subj_len) != 1) {
1428 error_print();
1429 return -1;
1430 }
1431 if (x509_name_equ(subj, subj_len, subject, subject_len) == 1) {
1432 *cert = a;
1433 *certlen = alen;
1434 return 1;
1435 }
1436 }
1437 error_print(); // 可能来自于没有找到对应的CA证书
1438 return 0;
1439 }
1440
x509_certs_get_cert_by_issuer_and_serial_number(const uint8_t * certs,size_t certs_len,const uint8_t * issuer,size_t issuer_len,const uint8_t * serial,size_t serial_len,const uint8_t ** cert,size_t * cert_len)1441 int x509_certs_get_cert_by_issuer_and_serial_number(
1442 const uint8_t *certs, size_t certs_len,
1443 const uint8_t *issuer, size_t issuer_len,
1444 const uint8_t *serial, size_t serial_len,
1445 const uint8_t **cert, size_t *cert_len)
1446 {
1447 const uint8_t *cur_issuer;
1448 size_t cur_issuer_len;
1449 const uint8_t *cur_serial;
1450 size_t cur_serial_len;
1451
1452 while (certs_len) {
1453 if (asn1_any_from_der(cert, cert_len, &certs, &certs_len) != 1
1454 || x509_cert_get_issuer_and_serial_number(*cert, *cert_len,
1455 &cur_issuer, &cur_issuer_len,
1456 &cur_serial, &cur_serial_len) != 1) {
1457 error_print();
1458 return -1;
1459 }
1460 if (cur_issuer_len == issuer_len
1461 && memcmp(cur_issuer, issuer, issuer_len) == 0
1462 && cur_serial_len == serial_len
1463 && memcmp(cur_serial, serial, serial_len) == 0) {
1464 return 1;
1465 }
1466 }
1467 return 0;
1468 }
1469
x509_cert_check(const uint8_t * cert,size_t certlen)1470 int x509_cert_check(const uint8_t *cert, size_t certlen)
1471 {
1472 time_t not_before;
1473 time_t not_after;
1474 time_t now;
1475
1476 x509_cert_get_details(cert, certlen,
1477 NULL, // version
1478 NULL, NULL, // serial
1479 NULL, // signature_algor
1480 NULL, NULL, // issuer
1481 ¬_before, ¬_after, // validity
1482 NULL, NULL, // subject
1483 NULL, // subject_public_key
1484 NULL, NULL, // issuer_unique_id
1485 NULL, NULL, // subject_unique_id
1486 NULL, NULL, // extensions
1487 NULL, // signature_algor
1488 NULL, NULL); // signature
1489
1490 // not_before < now < not_after
1491 time(&now);
1492 if (not_before >= not_after) {
1493 error_print();
1494 return -1;
1495 }
1496 if (now < not_before) {
1497 error_print();
1498 return X509_verify_err_cert_not_yet_valid;
1499 }
1500 if (not_after < now) {
1501 error_print();
1502 return X509_verify_err_cert_has_expired;
1503 }
1504
1505 return 1;
1506 }
1507
x509_certs_verify(const uint8_t * certs,size_t certslen,const uint8_t * rootcerts,size_t rootcertslen,int depth,int * verify_result)1508 int x509_certs_verify(const uint8_t *certs, size_t certslen,
1509 const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result)
1510 {
1511 const uint8_t *cert;
1512 size_t certlen;
1513 const uint8_t *cacert;
1514 size_t cacertlen;
1515 const uint8_t *name;
1516 size_t namelen;
1517 *verify_result = -1;
1518
1519 if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) {
1520 error_print();
1521 return -1;
1522 }
1523 while (certslen) {
1524
1525 if ((*verify_result = x509_cert_check(cert, certlen)) < 0) {
1526 error_print();
1527 return -1;
1528 }
1529 if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) {
1530 error_print();
1531 return -1;
1532 }
1533 // 这里应该检查证书是否有效啊, 这个函数应该返回进一步的错误信息
1534 if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
1535 SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
1536 error_print();
1537 return -1;
1538 }
1539 cert = cacert;
1540 certlen = cacertlen;
1541 }
1542 if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) {
1543 error_print();
1544 return -1;
1545 }
1546 if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen,
1547 &cacert, &cacertlen) != 1) {
1548 error_print();
1549 return -1;
1550 }
1551 if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
1552 SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
1553 error_print();
1554 return -1;
1555 }
1556
1557 return 1;
1558 }
1559
x509_certs_verify_tlcp(const uint8_t * certs,size_t certslen,const uint8_t * rootcerts,size_t rootcertslen,int depth,int * verify_result)1560 int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen,
1561 const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result)
1562 {
1563 const uint8_t *signcert;
1564 size_t signcertlen;
1565 int signcert_verified = 0;
1566 const uint8_t *cert;
1567 size_t certlen;
1568 const uint8_t *cacert;
1569 size_t cacertlen;
1570 const uint8_t *name;
1571 size_t namelen;
1572
1573 *verify_result = -1;
1574
1575 if (x509_cert_from_der(&signcert, &signcertlen, &certs, &certslen) != 1) {
1576 error_print();
1577 return -1;
1578 }
1579 if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) {
1580 error_print();
1581 return -1;
1582 }
1583 // 要检查这两个证书的类型是否分别为签名和加密证书
1584 // FIXME: 检查depth
1585 while (certslen) {
1586 if ((*verify_result = x509_cert_check(cert, certlen)) < 0) {
1587 error_print();
1588 return -1;
1589 }
1590 if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) {
1591 error_print();
1592 return -1;
1593 }
1594 if (!signcert_verified) {
1595 if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
1596 SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
1597 error_print();
1598 return -1;
1599 }
1600 signcert_verified = 1;
1601 }
1602 if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
1603 SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
1604 error_print();
1605 return -1;
1606 }
1607 cert = cacert;
1608 certlen = cacertlen;
1609 }
1610 if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) {
1611 error_print();
1612 return -1;
1613 }
1614 if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen, &cacert, &cacertlen) != 1) {
1615 // 当前证书链和提供的CA证书不匹配
1616 error_print();
1617 return -1;
1618 }
1619 if (!signcert_verified) {
1620 if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
1621 SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
1622 error_print();
1623 return -1;
1624 }
1625 }
1626 if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
1627 SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
1628 error_print();
1629 return -1;
1630 }
1631 return 1;
1632 }
1633
1634
x509_certs_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1635 int x509_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1636 {
1637 const uint8_t *p;
1638 size_t len;
1639
1640 format_print(fp, fmt, ind, "%s\n", label);
1641 ind += 4;
1642
1643 while (dlen) {
1644 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
1645 error_print();
1646 return -1;
1647 }
1648 x509_certificate_print(fp, fmt, ind, "Certficate", p, len);
1649 }
1650 return 1;
1651 }
1652
1653 #include <errno.h>
1654 #include <sys/stat.h>
1655
x509_cert_new_from_file(uint8_t ** out,size_t * outlen,const char * file)1656 int x509_cert_new_from_file(uint8_t **out, size_t *outlen, const char *file)
1657 {
1658 int ret = -1;
1659 FILE *fp = NULL;
1660 struct stat st;
1661 uint8_t *buf = NULL;
1662 size_t buflen;
1663
1664 if (!(fp = fopen(file, "r"))
1665 || fstat(fileno(fp), &st) < 0
1666 || (buflen = (st.st_size * 3)/4 + 1) < 0
1667 || (buf = malloc((st.st_size * 3)/4 + 1)) == NULL) {
1668 error_print();
1669 goto end;
1670 }
1671 if (x509_cert_from_pem(buf, outlen, buflen, fp) != 1) {
1672 error_print();
1673 goto end;
1674 }
1675 *out = buf;
1676 buf = NULL;
1677 ret = 1;
1678 end:
1679 if (fp) fclose(fp);
1680 if (buf) free(buf);
1681 return ret;
1682 }
1683
x509_certs_new_from_file(uint8_t ** out,size_t * outlen,const char * file)1684 int x509_certs_new_from_file(uint8_t **out, size_t *outlen, const char *file)
1685 {
1686 int ret = -1;
1687 FILE *fp = NULL;
1688 struct stat st;
1689 uint8_t *buf = NULL;
1690 size_t buflen;
1691
1692 if (!(fp = fopen(file, "r"))
1693 || fstat(fileno(fp), &st) < 0
1694 || (buflen = (st.st_size * 3)/4 + 1) < 0
1695 || (buf = malloc((st.st_size * 3)/4 + 1)) == NULL) {
1696 error_print();
1697 goto end;
1698 }
1699 if (x509_certs_from_pem(buf, outlen, buflen, fp) != 1) {
1700 error_print();
1701 goto end;
1702 }
1703 *out = buf;
1704 buf = NULL;
1705 ret = 1;
1706 end:
1707 if (fp) fclose(fp);
1708 if (buf) free(buf);
1709 return ret;
1710 }
1711