• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&not_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, &params, &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 		&not_before, &not_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