• 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 
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdint.h>
16 #include <assert.h>
17 #include <gmssl/sm2.h>
18 #include <gmssl/oid.h>
19 #include <gmssl/asn1.h>
20 #include <gmssl/x509.h>
21 #include <gmssl/x509_str.h>
22 #include <gmssl/x509_oid.h>
23 #include <gmssl/x509_ext.h>
24 #include <gmssl/error.h>
25 
26 
27 
x509_exts_add_sequence(uint8_t * exts,size_t * extslen,size_t maxlen,int oid,int critical,const uint8_t * d,size_t dlen)28 int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen,
29 	int oid, int critical, const uint8_t *d, size_t dlen)
30 {
31 	uint8_t val[32 + dlen];
32 	uint8_t *p = val;
33 	size_t curlen = *extslen;
34 	size_t vlen = 0;
35 
36 	exts += *extslen;
37 	if (asn1_sequence_to_der(d, dlen, &p, &vlen) != 1
38 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
39 		|| asn1_length_le(curlen, maxlen) != 1
40 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
41 		error_print();
42 		return -1;
43 	}
44 	return 1;
45 }
46 
x509_exts_add_authority_key_identifier(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * keyid,size_t keyid_len,const uint8_t * issuer,size_t issuer_len,const uint8_t * serial,size_t serial_len)47 int x509_exts_add_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen,
48 	int critical,
49 	const uint8_t *keyid, size_t keyid_len,
50 	const uint8_t *issuer, size_t issuer_len,
51 	const uint8_t *serial, size_t serial_len)
52 {
53 	int oid = OID_ce_authority_key_identifier;
54 	size_t curlen = *extslen;
55 	uint8_t val[512];
56 	uint8_t *p = val;
57 	size_t vlen = 0;
58 	size_t len = 0;
59 
60 	exts += *extslen;
61 	if (x509_authority_key_identifier_to_der(
62 			keyid, keyid_len,
63 			issuer, issuer_len,
64 			serial, serial_len,
65 			NULL, &len) != 1
66 		|| asn1_length_le(len, sizeof(val)) != 1
67 		|| x509_authority_key_identifier_to_der(
68 			keyid, keyid_len,
69 			issuer, issuer_len,
70 			serial, serial_len,
71 			&p, &vlen) != 1
72 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
73 		|| asn1_length_le(curlen, maxlen) != 1
74 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
75 		error_print();
76 		return -1;
77 	}
78 	return 1;
79 }
80 
x509_exts_add_default_authority_key_identifier(uint8_t * exts,size_t * extslen,size_t maxlen,const SM2_KEY * public_key)81 int x509_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen,
82 	const SM2_KEY *public_key)
83 {
84 	uint8_t buf[65];
85 	uint8_t id[32];
86 	int critical = -1;
87 
88 	sm2_point_to_uncompressed_octets(&public_key->public_key, buf);
89 	sm3_digest(buf, sizeof(buf), id);
90 
91 	if (x509_exts_add_authority_key_identifier(exts, extslen, maxlen, critical,
92 		id, sizeof(id), NULL, 0, NULL, 0) != 1) {
93 		error_print();
94 		return -1;
95 	}
96 	return 1;
97 }
98 
x509_exts_add_subject_key_identifier(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * d,size_t dlen)99 int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen,
100 	int critical, const uint8_t *d, size_t dlen)
101 {
102 	int oid = OID_ce_subject_key_identifier;
103 	size_t curlen = *extslen;
104 	uint8_t val[32 + X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN];
105 	uint8_t *p = val;
106 	size_t vlen = 0;
107 
108 	if (dlen < X509_SUBJECT_KEY_IDENTIFIER_MIN_LEN
109 		|| dlen > X509_SUBJECT_KEY_IDENTIFIER_MAX_LEN) {
110 		error_print();
111 		return -1;
112 	}
113 
114 	exts += *extslen;
115 	if (asn1_octet_string_to_der(d, dlen, &p, &vlen) != 1
116 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
117 		|| asn1_length_le(curlen, maxlen) != 1
118 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
119 		error_print();
120 		return -1;
121 	}
122 	return 1;
123 }
124 
x509_exts_add_key_usage(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,int bits)125 int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits)
126 {
127 	int oid = OID_ce_key_usage;
128 	size_t curlen = *extslen;
129 	uint8_t val[16];
130 	uint8_t *p = val;
131 	size_t vlen = 0;
132 
133 	if (!bits) {
134 		// TODO: 检查是否在合法范围内
135 		error_print();
136 		return -1;
137 	}
138 
139 	exts += *extslen;
140 	if (asn1_bits_to_der(bits, &p, &vlen) != 1
141 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
142 		|| asn1_length_le(curlen, maxlen) != 1
143 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
144 		error_print();
145 		return -1;
146 	}
147 	return 1;
148 }
149 
x509_exts_add_certificate_policies(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * d,size_t dlen)150 int x509_exts_add_certificate_policies(uint8_t *exts, size_t *extslen, size_t maxlen,
151 	int critical, const uint8_t *d, size_t dlen)
152 {
153 	int oid = OID_ce_certificate_policies;
154 	return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
155 }
156 
x509_exts_add_policy_mappings(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * d,size_t dlen)157 int x509_exts_add_policy_mappings(uint8_t *exts, size_t *extslen, size_t maxlen,
158 	int critical, const uint8_t *d, size_t dlen)
159 {
160 	int oid = OID_ce_policy_mappings;
161 	return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
162 }
163 
x509_exts_add_subject_alt_name(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * d,size_t dlen)164 int x509_exts_add_subject_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen,
165 	int critical, const uint8_t *d, size_t dlen)
166 {
167 	int oid = OID_ce_subject_alt_name;
168 	return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
169 }
170 
x509_exts_add_issuer_alt_name(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * d,size_t dlen)171 int x509_exts_add_issuer_alt_name(uint8_t *exts, size_t *extslen, size_t maxlen,
172 	int critical, const uint8_t *d, size_t dlen)
173 {
174 	int oid = OID_ce_issuer_alt_name;
175 	return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
176 }
177 
x509_exts_add_subject_directory_attributes(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * d,size_t dlen)178 int x509_exts_add_subject_directory_attributes(uint8_t *exts, size_t *extslen, size_t maxlen,
179 	int critical, const uint8_t *d, size_t dlen)
180 {
181 	int oid = OID_ce_subject_directory_attributes;
182 	return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
183 }
184 
x509_exts_add_name_constraints(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * permitted_subtrees,size_t permitted_subtrees_len,const uint8_t * excluded_subtrees,size_t excluded_subtrees_len)185 int x509_exts_add_name_constraints(uint8_t *exts, size_t *extslen, size_t maxlen,
186 	int critical,
187 	const uint8_t *permitted_subtrees, size_t permitted_subtrees_len,
188 	const uint8_t *excluded_subtrees, size_t excluded_subtrees_len)
189 {
190 	int oid = OID_ce_name_constraints;
191 	size_t curlen = *extslen;
192 	uint8_t val[512];
193 	uint8_t *p = val;
194 	size_t vlen = 0;
195 	size_t len = 0;
196 
197 	exts += *extslen;
198 	if (x509_name_constraints_to_der(
199 			permitted_subtrees, permitted_subtrees_len,
200 			excluded_subtrees, excluded_subtrees_len,
201 			NULL, &len) != 1
202 		|| asn1_length_le(len, sizeof(val)) != 1
203 		|| x509_name_constraints_to_der(
204 			permitted_subtrees, permitted_subtrees_len,
205 			excluded_subtrees, excluded_subtrees_len,
206 			&p, &vlen) != 1
207 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
208 		|| asn1_length_le(curlen, maxlen) != 1
209 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
210 		error_print();
211 		return -1;
212 	}
213 	return 1;
214 }
215 
x509_exts_add_policy_constraints(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,int require_explicit_policy,int inhibit_policy_mapping)216 int x509_exts_add_policy_constraints(uint8_t *exts, size_t *extslen, size_t maxlen,
217 	int critical, int require_explicit_policy, int inhibit_policy_mapping)
218 {
219 	int oid = OID_ce_policy_constraints;
220 	size_t curlen = *extslen;
221 	uint8_t val[32];
222 	uint8_t *p = val;
223 	size_t vlen = 0;
224 
225 	exts += *extslen;
226 	if (x509_policy_constraints_to_der(
227 			require_explicit_policy,
228 			inhibit_policy_mapping,
229 			&p, &vlen) != 1
230 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
231 		|| asn1_length_le(curlen, maxlen) != 1
232 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
233 		error_print();
234 		return -1;
235 	}
236 	return 1;
237 }
238 
x509_exts_add_basic_constraints(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,int ca,int path_len_constraint)239 int x509_exts_add_basic_constraints(uint8_t *exts, size_t *extslen, size_t maxlen,
240 	int critical, int ca, int path_len_constraint)
241 {
242 	int oid = OID_ce_basic_constraints;
243 	size_t curlen = *extslen;
244 	uint8_t val[32];
245 	uint8_t *p = val;
246 	size_t vlen = 0;
247 
248 	exts += *extslen;
249 	if (x509_basic_constraints_to_der(ca, path_len_constraint, &p, &vlen) != 1
250 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
251 		|| asn1_length_le(curlen, maxlen) != 1
252 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
253 		error_print();
254 		return -1;
255 	}
256 	return 1;
257 }
258 
x509_exts_add_ext_key_usage(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const int * key_purposes,size_t key_purposes_cnt)259 int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen,
260 	int critical, const int *key_purposes, size_t key_purposes_cnt)
261 {
262 	int oid = OID_ce_ext_key_usage;
263 	size_t curlen = *extslen;
264 	uint8_t val[256];
265 	uint8_t *p = val;
266 	size_t vlen = 0;
267 	size_t len = 0;
268 
269 	exts += *extslen;
270 	if (x509_ext_key_usage_to_der(key_purposes, key_purposes_cnt, NULL, &len) != 1
271 		|| asn1_length_le(len, sizeof(val)) != 1
272 		|| x509_ext_key_usage_to_der(key_purposes, key_purposes_cnt, &p, &vlen) != 1
273 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
274 		|| asn1_length_le(curlen, maxlen) != 1
275 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
276 		error_print();
277 		return -1;
278 	}
279 	return 1;
280 }
281 
x509_exts_add_crl_distribution_points(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * d,size_t dlen)282 int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen,
283 	int critical, const uint8_t *d, size_t dlen)
284 {
285 	int oid = OID_ce_crl_distribution_points;
286 	return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
287 }
288 
x509_exts_add_inhibit_any_policy(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,int skip_certs)289 int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen,
290 	int critical, int skip_certs)
291 {
292 	int oid = OID_ce_inhibit_any_policy;
293 	size_t curlen = *extslen;
294 	uint8_t val[16];
295 	uint8_t *p = val;
296 	size_t vlen = 0;
297 
298 	exts += *extslen;
299 	if (x509_inhibit_any_policy_to_der(skip_certs, &p, &vlen) != 1
300 		|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
301 		|| asn1_length_le(curlen, maxlen) != 1
302 		|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
303 		error_print();
304 		return -1;
305 	}
306 	return 1;
307 }
308 
x509_exts_add_freshest_crl(uint8_t * exts,size_t * extslen,size_t maxlen,int critical,const uint8_t * d,size_t dlen)309 int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen,
310 	int critical, const uint8_t *d, size_t dlen)
311 {
312 	int oid = OID_ce_freshest_crl;
313 	return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
314 }
315 
x509_other_name_to_der(const uint32_t * type_nodes,size_t type_nodes_cnt,const uint8_t * value,size_t value_len,uint8_t ** out,size_t * outlen)316 int x509_other_name_to_der(
317 	const uint32_t *type_nodes, size_t type_nodes_cnt,
318 	const uint8_t *value, size_t value_len,
319 	uint8_t **out, size_t *outlen)
320 {
321 	size_t len = 0;
322 	if (asn1_object_identifier_to_der(type_nodes, type_nodes_cnt, NULL, &len) != 1
323 		|| asn1_explicit_to_der(0, value, value_len, NULL, &len) != 1
324 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
325 		|| asn1_object_identifier_to_der(type_nodes, type_nodes_cnt, out, outlen) != 1
326 		|| asn1_explicit_to_der(0, value, value_len, out, outlen) != 1) {
327 		error_print();
328 		return -1;
329 	}
330 	return 1;
331 }
332 
x509_other_name_from_der(uint32_t * type_nodes,size_t * type_nodes_cnt,const uint8_t ** value,size_t * value_len,const uint8_t ** in,size_t * inlen)333 int x509_other_name_from_der(
334 	uint32_t *type_nodes, size_t *type_nodes_cnt,
335 	const uint8_t **value, size_t *value_len,
336 	const uint8_t **in, size_t *inlen)
337 {
338 	int ret;
339 	const uint8_t *p;
340 	size_t len;
341 
342 	if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) {
343 		if (ret < 0) error_print();
344 		return ret;
345 	}
346 	if (asn1_object_identifier_from_der(type_nodes, type_nodes_cnt, &p, &len) != 1
347 		|| asn1_explicit_from_der(0, value, value_len, &p, &len) != 1
348 		|| asn1_length_is_zero(len) != 1) {
349 		error_print();
350 		return -1;
351 	}
352 	return 1;
353 }
354 
x509_other_name_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)355 int x509_other_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
356 {
357 	uint32_t nodes[32];
358 	size_t nodes_cnt;
359 	const uint8_t *p;
360 	size_t len;
361 
362 	format_print(fp, fmt, ind, "%s\n", label);
363 	ind += 4;
364 
365 	if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1) goto err;
366 	asn1_object_identifier_print(fp, fmt, ind, "type-id", NULL, nodes, nodes_cnt);
367 	if (asn1_explicit_from_der(0, &p, &len, &d, &dlen) != 1) goto err;
368 	format_bytes(fp, fmt, ind, "value", p, len);
369 	if (asn1_length_is_zero(dlen) != 1) goto err;
370 	return 1;
371 err:
372 	error_print();
373 	return -1;
374 }
375 
x509_edi_party_name_to_der(int assigner_choice,const uint8_t * assigner,size_t assigner_len,int party_name_choice,const uint8_t * party_name,size_t party_name_len,uint8_t ** out,size_t * outlen)376 int x509_edi_party_name_to_der(
377 	int assigner_choice, const uint8_t *assigner, size_t assigner_len,
378 	int party_name_choice, const uint8_t *party_name, size_t party_name_len,
379 	uint8_t **out, size_t *outlen)
380 {
381 	size_t len = 0;
382 	if (x509_explicit_directory_name_to_der(0, assigner_choice, assigner, assigner_len, NULL, &len) < 0
383 		|| x509_explicit_directory_name_to_der(1, party_name_choice, party_name, party_name_len, NULL, &len) != 1
384 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
385 		|| x509_explicit_directory_name_to_der(0, assigner_choice, assigner, assigner_len, out, outlen) < 0
386 		|| x509_explicit_directory_name_to_der(1, party_name_choice, party_name, party_name_len, out, outlen) != 1) {
387 		error_print();
388 		return -1;
389 	}
390 	return 1;
391 }
392 
x509_edi_party_name_from_der(int * assigner_choice,const uint8_t ** assigner,size_t * assigner_len,int * party_name_choice,const uint8_t ** party_name,size_t * party_name_len,const uint8_t ** in,size_t * inlen)393 int x509_edi_party_name_from_der(
394 	int *assigner_choice, const uint8_t **assigner, size_t *assigner_len,
395 	int *party_name_choice, const uint8_t **party_name, size_t *party_name_len,
396 	const uint8_t **in, size_t *inlen)
397 {
398 	int ret;
399 	const uint8_t *p;
400 	size_t len;
401 
402 	if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) {
403 		if (ret < 0) error_print();
404 		return ret;
405 	}
406 	if (x509_explicit_directory_name_from_der(0, assigner_choice, assigner, assigner_len, &p, &len) < 0
407 		|| x509_explicit_directory_name_from_der(1, party_name_choice, party_name, party_name_len, &p, &len) != 1
408 		|| asn1_length_is_zero(len) != 1) {
409 		error_print();
410 		return -1;
411 	}
412 	return 1;
413 }
414 
x509_edi_party_name_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)415 int x509_edi_party_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
416 {
417 	int ret;
418 	const uint8_t *p;
419 	size_t len;
420 	int tag;
421 
422 	format_print(fp, fmt, ind, "%s\n", label);
423 	ind += 4;
424 
425 	if ((ret = x509_explicit_directory_name_from_der(0, &tag, &p, &len, &d, &dlen)) < 0) goto err;
426 	if (ret) x509_directory_name_print(fp, fmt, ind, "nameAssigner", tag, p, len);
427 	if (x509_explicit_directory_name_from_der(1, &tag, &p, &len, &d, &dlen) != 1) goto err;
428 	x509_directory_name_print(fp, fmt, ind, "partyName", tag, p, len);
429 	if (asn1_length_is_zero(dlen) != 1) goto err;
430 	return 1;
431 err:
432 	error_print();
433 	return -1;
434 }
435 
436 // GeneralName CHOICE 中有的是基本类型,有的是SEQUENCE,在设置标签时是否有区别?
437 // 这里是否支持OPTIONAL??
x509_general_name_to_der(int choice,const uint8_t * d,size_t dlen,uint8_t ** out,size_t * outlen)438 int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
439 {
440 	return asn1_implicit_to_der(choice, d, dlen, out, outlen);
441 }
442 
x509_general_name_from_der(int * choice,const uint8_t ** d,size_t * dlen,const uint8_t ** in,size_t * inlen)443 int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
444 {
445 	int ret;
446 	int tag;
447 	if ((ret = asn1_any_type_from_der(&tag, d, dlen, in, inlen)) != 1) {
448 		if (ret < 0) error_print();
449 		return ret;
450 	}
451 	switch (tag) {
452 	case ASN1_TAG_EXPLICIT(0): *choice = 0; break;
453 	case ASN1_TAG_IMPLICIT(1): *choice = 1; break;
454 	case ASN1_TAG_IMPLICIT(2): *choice = 2; break;
455 	case ASN1_TAG_EXPLICIT(3): *choice = 3; break;
456 	case ASN1_TAG_EXPLICIT(4): *choice = 4; break;
457 	case ASN1_TAG_EXPLICIT(5): *choice = 5; break;
458 	case ASN1_TAG_IMPLICIT(6): *choice = 6; break;
459 	case ASN1_TAG_IMPLICIT(7): *choice = 7; break;
460 	case ASN1_TAG_IMPLICIT(8): *choice = 8; break;
461 	default:
462 		fprintf(stderr, "%s %d: tag = %x\n", __FILE__, __LINE__, tag);
463 		error_print();
464 		return -1;
465 	}
466 	return 1;
467 }
468 
x509_general_name_print(FILE * fp,int fmt,int ind,const char * label,int choice,const uint8_t * d,size_t dlen)469 int x509_general_name_print(FILE *fp, int fmt, int ind, const char *label, int choice, const uint8_t *d, size_t dlen)
470 {
471 	const uint8_t *p;
472 	size_t len;
473 
474 	format_print(fp, fmt, ind, "%s\n", label);
475 	ind += 4;
476 
477 	switch (choice) {
478 	case 0:
479 	case 3:
480 	case 4:
481 	case 5:
482 		if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
483 			error_print();
484 			return -1;
485 		}
486 		d = p;
487 		dlen = len;
488 	}
489 	switch (choice) {
490 	case 0: return x509_other_name_print(fp, fmt, ind, "otherName", d, dlen);
491 	case 1: return asn1_string_print(fp, fmt, ind, "rfc822Name", ASN1_TAG_IA5String, d, dlen);
492 	case 2: return asn1_string_print(fp, fmt, ind, "DNSName", ASN1_TAG_IA5String, d, dlen);
493 	case 3: return format_bytes(fp, fmt, ind, "x400Address", d, dlen);
494 	case 4: return x509_name_print(fp, fmt, ind, "directoryName", d, dlen);
495 	case 5: return x509_edi_party_name_print(fp, fmt, ind, "ediPartyName", d, dlen);
496 	case 6: return asn1_string_print(fp, fmt, ind, "URI", ASN1_TAG_IA5String, d, dlen);
497 	case 7: return format_bytes(fp, fmt, ind, "IPAddress", d, dlen);
498 	case 8:
499 	{
500 		uint32_t nodes[32];
501 		size_t nodes_cnt;
502 		if (asn1_object_identifier_from_octets(nodes, &nodes_cnt, d, dlen) != 1) {
503 			error_print();
504 			return -1;
505 		}
506 		return asn1_object_identifier_print(fp, fmt, ind, "registeredID", NULL, nodes, nodes_cnt);
507 	}
508 	default:
509 		error_print();
510 		return -1;
511 	}
512 	return 1;
513 }
514 
x509_general_names_add_general_name(uint8_t * gns,size_t * gnslen,size_t maxlen,int choice,const uint8_t * d,size_t dlen)515 int x509_general_names_add_general_name(uint8_t *gns, size_t *gnslen, size_t maxlen,
516 	int choice, const uint8_t *d, size_t dlen)
517 {
518 	size_t len = 0;
519 	uint8_t *p = gns + *gnslen;
520 
521 	switch (choice) {
522 	case X509_gn_rfc822_name:
523 	case X509_gn_dns_name:
524 	case X509_gn_uniform_resource_identifier:
525 		if (asn1_ia5_string_check((char *)d, dlen) != 1) {
526 			error_print();
527 			return -1;
528 		}
529 		break;
530 	}
531 	if (x509_general_name_to_der(choice, d, dlen, NULL, &len) != 1
532 		|| asn1_length_le(*gnslen + len, maxlen) != 1
533 		|| x509_general_name_to_der(choice, d, dlen, &p, gnslen) != 1) {
534 		error_print();
535 		return -1;
536 	}
537 	return 1;
538 }
539 
x509_general_names_add_other_name(uint8_t * gns,size_t * gnslen,size_t maxlen,const uint32_t * nodes,size_t nodes_cnt,const uint8_t * value,size_t value_len)540 int x509_general_names_add_other_name(uint8_t *gns, size_t *gnslen, size_t maxlen,
541 	const uint32_t *nodes, size_t nodes_cnt,
542 	const uint8_t *value, size_t value_len)
543 {
544 	int choice = X509_gn_other_name;
545 	uint8_t buf[128];
546 	uint8_t *p = buf;
547 	const uint8_t *cp = buf;
548 	size_t len = 0;
549 	const uint8_t *d;
550 	size_t dlen;
551 
552 	if (x509_other_name_to_der(nodes, nodes_cnt, value, value_len, &p, &len) != 1
553 		|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
554 		|| x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) {
555 		error_print();
556 		return -1;
557 	}
558 	return 1;
559 }
560 
x509_general_names_add_edi_party_name(uint8_t * gns,size_t * gnslen,size_t maxlen,int assigner_tag,const uint8_t * assigner,size_t assigner_len,int party_name_tag,const uint8_t * party_name,size_t party_name_len)561 int x509_general_names_add_edi_party_name(uint8_t *gns, size_t *gnslen, size_t maxlen,
562 	int assigner_tag, const uint8_t *assigner, size_t assigner_len,
563 	int party_name_tag, const uint8_t *party_name, size_t party_name_len)
564 {
565 	int choice = X509_gn_edi_party_name;
566 	uint8_t buf[128];
567 	uint8_t *p = buf;
568 	const uint8_t *cp = buf;
569 	size_t len = 0;
570 	const uint8_t *d;
571 	size_t dlen;
572 
573 	if (x509_edi_party_name_to_der(
574 			assigner_tag, assigner, assigner_len,
575 			party_name_tag, party_name, party_name_len,
576 			&p, &len) != 1
577 		|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
578 		|| x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) {
579 		error_print();
580 		return -1;
581 	}
582 	return 1;
583 }
584 
x509_general_names_add_registered_id(uint8_t * gns,size_t * gnslen,size_t maxlen,const uint32_t * nodes,size_t nodes_cnt)585 int x509_general_names_add_registered_id(uint8_t *gns, size_t *gnslen, size_t maxlen,
586 	const uint32_t *nodes, size_t nodes_cnt)
587 {
588 	int choice = X509_gn_registered_id;
589 	uint8_t d[128];
590 	size_t dlen;
591 
592 	if (asn1_object_identifier_to_octets(nodes, nodes_cnt, d, &dlen) != 1
593 		|| x509_general_names_add_general_name(gns, gnslen, maxlen, choice, d, dlen) != 1) {
594 		error_print();
595 		return -1;
596 	}
597 	return 1;
598 }
599 
x509_general_names_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)600 int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
601 {
602 	int choice;
603 	const uint8_t *p;
604 	size_t len;
605 
606 	format_print(fp, fmt, ind, "%s\n", label);
607 	ind += 4;
608 
609 	while (dlen) {
610 		if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) {
611 			error_print();
612 			return -1;
613 		}
614 		x509_general_name_print(fp, fmt, ind, "GeneralName", choice, p, len);
615 	}
616 	return 1;
617 }
618 
x509_authority_key_identifier_to_der(const uint8_t * keyid,size_t keyid_len,const uint8_t * issuer,size_t issuer_len,const uint8_t * serial,size_t serial_len,uint8_t ** out,size_t * outlen)619 int x509_authority_key_identifier_to_der(
620 	const uint8_t *keyid, size_t keyid_len,
621 	const uint8_t *issuer, size_t issuer_len,
622 	const uint8_t *serial, size_t serial_len,
623 	uint8_t **out, size_t *outlen)
624 {
625 	size_t len = 0;
626 	if (asn1_implicit_octet_string_to_der(0, keyid, keyid_len, NULL, &len) < 0
627 		|| asn1_implicit_sequence_to_der(1, issuer, issuer_len, NULL, &len) < 0
628 		|| asn1_implicit_integer_to_der(2, serial, serial_len, NULL, &len) < 0
629 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
630 		|| asn1_implicit_octet_string_to_der(0, keyid, keyid_len, out, outlen) < 0
631 		|| asn1_implicit_sequence_to_der(1, issuer, issuer_len, out, outlen) < 0
632 		|| asn1_implicit_integer_to_der(2, serial, serial_len, out, outlen) < 0) {
633 		error_print();
634 		return -1;
635 	}
636 	return 1;
637 }
638 
x509_authority_key_identifier_from_der(const uint8_t ** keyid,size_t * keyid_len,const uint8_t ** issuer,size_t * issuer_len,const uint8_t ** serial,size_t * serial_len,const uint8_t ** in,size_t * inlen)639 int x509_authority_key_identifier_from_der(
640 	const uint8_t **keyid, size_t *keyid_len,
641 	const uint8_t **issuer, size_t *issuer_len,
642 	const uint8_t **serial, size_t *serial_len,
643 	const uint8_t **in, size_t *inlen)
644 {
645 	int ret;
646 	const uint8_t *d;
647 	size_t dlen;
648 
649 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
650 		if (ret < 0) error_print();
651 		return ret;
652 	}
653 	if (asn1_implicit_octet_string_from_der(0, keyid, keyid_len, &d, &dlen) < 0
654 		|| asn1_implicit_sequence_from_der(1, issuer, issuer_len, &d, &dlen) < 0
655 		|| asn1_implicit_integer_from_der(2, serial, serial_len, &d, &dlen) < 0
656 		|| asn1_length_is_zero(dlen) != 1) {
657 		error_print();
658 		return -1;
659 	}
660 	return 1;
661 }
662 
x509_authority_key_identifier_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)663 int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
664 {
665 	int ret;
666 	const uint8_t *p;
667 	size_t len;
668 
669 	format_print(fp, fmt, ind, "%s\n", label);
670 	ind += 4;
671 
672 	if ((ret = asn1_implicit_octet_string_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
673 	if (ret) format_bytes(fp, fmt, ind, "keyIdentifier", p, len);
674 	if ((ret = asn1_implicit_sequence_from_der(1, &p, &len, &d, &dlen)) < 0) goto err;
675 	if (ret) x509_general_names_print(fp, fmt, ind, "authorityCertIssuer", p, len);
676 	if ((ret = asn1_implicit_integer_from_der(2, &p, &len, &d, &dlen)) < 0) goto err;
677 	if (ret) format_bytes(fp, fmt, ind, "authorityCertSerialNumber", p, len);
678 	if (asn1_length_is_zero(dlen) != 1) goto err;
679 	return 1;
680 err:
681 	error_print();
682 	return -1;
683 }
684 
685 static const char *x509_key_usages[] = {
686 	"digitalSignature",
687 	"nonRepudiation",
688 	"keyEncipherment",
689 	"dataEncipherment",
690 	"keyAgreement",
691 	"keyCertSign",
692 	"cRLSign",
693 	"encipherOnly",
694 	"decipherOnly",
695 };
696 
697 static size_t x509_key_usages_count =
698 	sizeof(x509_key_usages)/sizeof(x509_key_usages[0]);
699 
x509_key_usage_name(int flag)700 const char *x509_key_usage_name(int flag)
701 {
702 	int i;
703 	for (i = 0; i < x509_key_usages_count; i++) {
704 		if (flag & 1) {
705 			if (flag >> 1) {
706 				error_print();
707 				return NULL;
708 			}
709 			return x509_key_usages[i];
710 		}
711 		flag >>= 1;
712 	}
713 	error_print();
714 	return NULL;
715 }
716 
x509_key_usage_from_name(int * flag,const char * name)717 int x509_key_usage_from_name(int *flag, const char *name)
718 {
719 	int i;
720 	for (i = 0; i < x509_key_usages_count; i++) {
721 		if (strcmp(name, x509_key_usages[i]) == 0) {
722 			*flag = 1 << i;
723 			return 1;
724 		}
725 	}
726 	*flag = 0;
727 	error_print();
728 	return -1;
729 }
730 
x509_key_usage_print(FILE * fp,int fmt,int ind,const char * label,int bits)731 int x509_key_usage_print(FILE *fp, int fmt, int ind, const char *label, int bits)
732 {
733 	return asn1_bits_print(fp, fmt, ind, label, x509_key_usages, x509_key_usages_count, bits);
734 }
735 
x509_notice_reference_to_der(int org_tag,const uint8_t * org,size_t org_len,const int * notice_numbers,size_t notice_numbers_cnt,uint8_t ** out,size_t * outlen)736 int x509_notice_reference_to_der(
737 	int org_tag, const uint8_t *org, size_t org_len,
738 	const int *notice_numbers, size_t notice_numbers_cnt,
739 	uint8_t **out, size_t *outlen)
740 {
741 	size_t len = 0;
742 	if (x509_display_text_to_der(org_tag, org, org_len, NULL, &len) != 1
743 		|| asn1_sequence_of_int_to_der(notice_numbers, notice_numbers_cnt, NULL, &len) != 1
744 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
745 		|| x509_display_text_to_der(org_tag, org, org_len, out, outlen) != 1
746 		|| asn1_sequence_of_int_to_der(notice_numbers, notice_numbers_cnt, out, outlen) != 1) {
747 		error_print();
748 		return -1;
749 	}
750 	return 1;
751 }
752 
x509_notice_reference_from_der(int * org_tag,const uint8_t ** org,size_t * org_len,int notice_numbers[X509_MAX_NOTICE_NUMBERS],size_t * notice_numbers_cnt,size_t max_notice_numbers,const uint8_t ** in,size_t * inlen)753 int x509_notice_reference_from_der(
754 	int *org_tag, const uint8_t **org, size_t *org_len,
755 	int notice_numbers[X509_MAX_NOTICE_NUMBERS], size_t *notice_numbers_cnt, size_t max_notice_numbers, //FIXME: max_notice_numbers 还没检查
756 	const uint8_t **in, size_t *inlen)
757 {
758 	int ret;
759 	const uint8_t *d;
760 	size_t dlen;
761 
762 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
763 		if (ret < 0) error_print();
764 		else error_print();
765 		return ret;
766 	}
767 	if (x509_display_text_from_der(org_tag, org, org_len, &d, &dlen) != 1
768 		|| asn1_sequence_of_int_from_der(notice_numbers, notice_numbers_cnt, &d, &dlen) != 1
769 		|| asn1_length_is_zero(dlen) != 1) {
770 		error_print();
771 		return -1;
772 	}
773 	return 1;
774 }
775 
x509_notice_reference_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)776 int x509_notice_reference_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
777 {
778 	int tag;
779 	const uint8_t *p;
780 	size_t len;
781 
782 	format_print(fp, fmt, ind,  "%s\n", label);
783 	ind += 4;
784 
785 	if (x509_display_text_from_der(&tag, &p, &len, &d, &dlen) != 1) goto err;
786 	x509_display_text_print(fp, fmt, ind, "organization", tag, p, len);
787 	if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
788 	asn1_sequence_of_int_print(fp, fmt, ind, "noticeNumbers", p, len);
789 	if (asn1_length_is_zero(dlen) != 1) goto err;
790 	return 1;
791 err:
792 	error_print();
793 	return -1;
794 }
795 
x509_user_notice_to_der(int notice_ref_org_tag,const uint8_t * notice_ref_org,size_t notice_ref_org_len,const int * notice_ref_notice_numbers,size_t notice_ref_notice_numbers_cnt,int explicit_text_tag,const uint8_t * explicit_text,size_t explicit_text_len,uint8_t ** out,size_t * outlen)796 int x509_user_notice_to_der(
797 	int notice_ref_org_tag, const uint8_t *notice_ref_org, size_t notice_ref_org_len,
798 	const int *notice_ref_notice_numbers, size_t notice_ref_notice_numbers_cnt,
799 	int explicit_text_tag, const uint8_t *explicit_text, size_t explicit_text_len,
800 	uint8_t **out, size_t *outlen)
801 {
802 	size_t len = 0;
803 	if (x509_notice_reference_to_der(
804 			notice_ref_org_tag, notice_ref_org, notice_ref_org_len,
805 			notice_ref_notice_numbers, notice_ref_notice_numbers_cnt,
806 			NULL, &len) < 0
807 		|| x509_display_text_to_der(explicit_text_tag, explicit_text, explicit_text_len, NULL, &len) < 0
808 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
809 		|| x509_notice_reference_to_der(
810 			notice_ref_org_tag, notice_ref_org, notice_ref_org_len,
811 			notice_ref_notice_numbers, notice_ref_notice_numbers_cnt,
812 			out, outlen) < 0
813 		|| x509_display_text_to_der(explicit_text_tag, explicit_text, explicit_text_len, out, outlen) < 0) {
814 		error_print();
815 		return -1;
816 	}
817 	return 1;
818 }
819 
x509_user_notice_from_der(int * notice_ref_org_tag,const uint8_t ** notice_ref_org,size_t * notice_ref_org_len,int * notice_ref_notice_numbers,size_t * notice_ref_notice_numbers_cnt,size_t max_notice_ref_notice_numbers,int * explicit_text_tag,const uint8_t ** explicit_text,size_t * explicit_text_len,const uint8_t ** in,size_t * inlen)820 int x509_user_notice_from_der(
821 	int *notice_ref_org_tag, const uint8_t **notice_ref_org, size_t *notice_ref_org_len,
822 	int *notice_ref_notice_numbers, size_t *notice_ref_notice_numbers_cnt, size_t max_notice_ref_notice_numbers, // FIXME: max_notice_ref_notice_numbers
823 	int *explicit_text_tag, const uint8_t **explicit_text, size_t *explicit_text_len,
824 	const uint8_t **in, size_t *inlen)
825 {
826 	int ret;
827 	const uint8_t *d;
828 	size_t dlen;
829 
830 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
831 		if (ret < 0) error_print();
832 		return ret;
833 	}
834 	if (x509_notice_reference_from_der(notice_ref_org_tag, notice_ref_org, notice_ref_org_len,
835 			notice_ref_notice_numbers, notice_ref_notice_numbers_cnt, max_notice_ref_notice_numbers, &d, &dlen) < 0
836 		|| x509_display_text_from_der(explicit_text_tag, explicit_text, explicit_text_len, &d, &dlen) < 0
837 		|| asn1_length_is_zero(dlen) != 1) {
838 		error_print();
839 		return -1;
840 	}
841 	return 1;
842 }
843 
x509_user_notice_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)844 int x509_user_notice_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
845 {
846 	int ret;
847 	const uint8_t *p;
848 	size_t len;
849 	int tag;
850 
851 	format_print(fp, fmt, ind, "%s\n", label);
852 	ind += 4;
853 
854 	if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err;
855 	if (ret) x509_notice_reference_print(fp, fmt, ind, "noticeRef", p, len);
856 	if ((ret = x509_display_text_from_der(&tag, &p, &len, &d, &dlen)) < 0) goto err;
857 	if (ret) x509_display_text_print(fp, fmt, ind, "explicitText", tag, p, len);
858 	if (asn1_length_is_zero(dlen) != 1) goto err;
859 	return 1;
860 err:
861 	error_print();
862 	return -1;
863 }
864 
865 // 是否要针对oid = cps的IA5String做一个方便的接口呢?毕竟oid 只有两个可选项
x509_policy_qualifier_info_to_der(int oid,const uint8_t * qualifier,size_t qualifier_len,uint8_t ** out,size_t * outlen)866 int x509_policy_qualifier_info_to_der(
867 	int oid,
868 	const uint8_t *qualifier, size_t qualifier_len,
869 	uint8_t **out, size_t *outlen)
870 {
871 	size_t len = 0;
872 	if (x509_qualifier_id_to_der(oid, NULL, &len) != 1
873 		|| asn1_any_to_der(qualifier, qualifier_len, NULL, &len) != 1
874 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
875 		|| x509_qualifier_id_to_der(oid, out, outlen) != 1
876 		|| asn1_any_to_der(qualifier, qualifier_len, out, outlen) != 1) {
877 		error_print();
878 		return -1;
879 	}
880 	return 1;
881 }
882 
x509_policy_qualifier_info_from_der(int * oid,const uint8_t ** qualifier,size_t * qualifier_len,const uint8_t ** in,size_t * inlen)883 int x509_policy_qualifier_info_from_der(int *oid, const uint8_t **qualifier, size_t *qualifier_len, const uint8_t **in, size_t *inlen)
884 {
885 	int ret;
886 	const uint8_t *p;
887 	size_t len;
888 
889 	if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) {
890 		if (ret < 0) error_print();
891 		return ret;
892 	}
893 	if (x509_qualifier_id_from_der(oid, &p, &len) != 1
894 		|| asn1_any_from_der(qualifier, qualifier_len, &p, &len) != 1
895 		|| asn1_length_is_zero(len) != 1) {
896 		error_print();
897 		return -1;
898 	}
899 	return 1;
900 }
901 
x509_policy_qualifier_info_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)902 int x509_policy_qualifier_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
903 {
904 	int oid;
905 	const uint8_t *p;
906 	size_t len;
907 
908 	if (x509_qualifier_id_from_der(&oid, &d, &dlen) != 1) goto err;
909 	switch (oid) {
910 	case OID_qt_cps:
911 		if (asn1_ia5_string_from_der((const char **)&p, &len, &d, &dlen) != 1) goto err;
912 		format_string(fp, fmt, ind, "cPSuri", p, len);
913 		break;
914 	case OID_qt_unotice:
915 		if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
916 		x509_user_notice_print(fp, fmt, ind, "userNotice", p, len);
917 		break;
918 	}
919 	return 1;
920 err:
921 	error_print();
922 	return -1;
923 }
924 
x509_policy_qualifier_infos_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)925 int x509_policy_qualifier_infos_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
926 {
927 	const uint8_t *p;
928 	size_t len;
929 
930 	format_print(fp, fmt, ind, "%s\n", label);
931 	ind += 4;
932 
933 	while (dlen) {
934 		if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
935 			error_print();
936 			return -1;
937 		}
938 		x509_policy_qualifier_info_print(fp, fmt, ind, "PolicyQualifierInfo", p, len);
939 	}
940 	return 1;
941 }
942 
x509_policy_information_to_der(int oid,const uint32_t * nodes,size_t nodes_cnt,const uint8_t * qualifiers,size_t qualifiers_len,uint8_t ** out,size_t * outlen)943 int x509_policy_information_to_der(
944 	int oid, const uint32_t *nodes, size_t nodes_cnt,
945 	const uint8_t *qualifiers, size_t qualifiers_len,
946 	uint8_t **out, size_t *outlen)
947 {
948 	size_t len = 0;
949 	if (x509_cert_policy_id_to_der(oid, nodes, nodes_cnt, NULL, &len) != 1
950 		|| asn1_sequence_to_der(qualifiers, qualifiers_len, NULL, &len) < 0
951 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
952 		|| x509_cert_policy_id_to_der(oid, nodes, nodes_cnt, out, outlen) != 1
953 		|| asn1_sequence_to_der(qualifiers, qualifiers_len, out, outlen) < 0) {
954 		error_print();
955 		return -1;
956 	}
957 	return 1;
958 }
959 
x509_policy_information_from_der(int * oid,uint32_t * nodes,size_t * nodes_cnt,const uint8_t ** qualifiers,size_t * qualifiers_len,const uint8_t ** in,size_t * inlen)960 int x509_policy_information_from_der(
961 	int *oid, uint32_t *nodes, size_t *nodes_cnt,
962 	const uint8_t **qualifiers, size_t *qualifiers_len,
963 	const uint8_t **in, size_t *inlen)
964 {
965 	int ret;
966 	const uint8_t *d;
967 	size_t dlen;
968 
969 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
970 		if (ret < 0) error_print();
971 		return ret;
972 	}
973 	if (x509_cert_policy_id_from_der(oid, nodes, nodes_cnt, &d, &dlen) != 1
974 		|| asn1_sequence_from_der(qualifiers, qualifiers_len, &d, &dlen) < 0
975 		|| asn1_length_is_zero(dlen) != 1) {
976 		error_print();
977 		return -1;
978 	}
979 	return 1;
980 }
981 
x509_policy_information_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)982 int x509_policy_information_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
983 {
984 	int ret, oid;
985 	uint32_t nodes[32];
986 	size_t nodes_cnt;
987 	const uint8_t *p;
988 	size_t len;
989 
990 	format_print(fp, fmt, ind, "%s\n", label);
991 	ind += 4;
992 
993 	if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err;
994 	asn1_object_identifier_print(fp, fmt, ind, "policyIdentifier", x509_cert_policy_id_name(oid), nodes, nodes_cnt);
995 	if ((ret = asn1_sequence_from_der(&p, &len, &d, &dlen)) < 0) goto err;
996 	if (ret) x509_policy_qualifier_infos_print(fp, fmt, ind, "policyQualifiers", p, len);
997 	if (asn1_length_is_zero(dlen) != 1) goto err;
998 	return 1;
999 err:
1000 	error_print();
1001 	return -1;
1002 }
1003 
x509_certificate_policies_add_policy_information(uint8_t * d,size_t * dlen,size_t maxlen,int policy_oid,const uint32_t * policy_nodes,size_t policy_nodes_cnt,const uint8_t * qualifiers,size_t qualifiers_len)1004 int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, size_t maxlen,
1005 	int policy_oid, const uint32_t *policy_nodes, size_t policy_nodes_cnt,
1006 	const uint8_t *qualifiers, size_t qualifiers_len)
1007 {
1008 	error_print();
1009 	return -1;
1010 }
1011 
x509_certificate_policies_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1012 int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1013 {
1014 	const uint8_t *p;
1015 	size_t len;
1016 
1017 	format_print(fp, fmt, ind, "%s\n", label);
1018 	ind += 4;
1019 
1020 	while (dlen) {
1021 		if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
1022 			error_print();
1023 			return -1;
1024 		}
1025 		x509_policy_information_print(fp, fmt, ind, label, p, len);
1026 	}
1027 	return 1;
1028 }
1029 
x509_policy_mapping_to_der(int issuer_policy_oid,const uint32_t * issuer_policy_nodes,size_t issuer_policy_nodes_cnt,int subject_policy_oid,const uint32_t * subject_policy_nodes,size_t subject_policy_nodes_cnt,uint8_t ** out,size_t * outlen)1030 int x509_policy_mapping_to_der(
1031 	int issuer_policy_oid, const uint32_t *issuer_policy_nodes, size_t issuer_policy_nodes_cnt,
1032 	int subject_policy_oid, const uint32_t *subject_policy_nodes, size_t subject_policy_nodes_cnt,
1033 	uint8_t **out, size_t *outlen)
1034 {
1035 	size_t len = 0;
1036 	if (x509_cert_policy_id_to_der(issuer_policy_oid,
1037 			issuer_policy_nodes, issuer_policy_nodes_cnt, NULL, &len) != 1
1038 		|| x509_cert_policy_id_to_der(subject_policy_oid,
1039 			subject_policy_nodes, subject_policy_nodes_cnt, NULL, &len) != 1
1040 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
1041 		|| x509_cert_policy_id_to_der(issuer_policy_oid,
1042 			issuer_policy_nodes, issuer_policy_nodes_cnt, out, outlen) != 1
1043 		|| x509_cert_policy_id_to_der(subject_policy_oid,
1044 			subject_policy_nodes, subject_policy_nodes_cnt, out, outlen) != 1) {
1045 		error_print();
1046 		return -1;
1047 	}
1048 	return 1;
1049 }
1050 
x509_policy_mapping_from_der(int * issuer_policy_oid,uint32_t * issuer_policy_nodes,size_t * issuer_policy_nodes_cnt,int * subject_policy_oid,uint32_t * subject_policy_nodes,size_t * subject_policy_nodes_cnt,const uint8_t ** in,size_t * inlen)1051 int x509_policy_mapping_from_der(
1052 	int *issuer_policy_oid, uint32_t *issuer_policy_nodes, size_t *issuer_policy_nodes_cnt,
1053 	int *subject_policy_oid, uint32_t *subject_policy_nodes, size_t *subject_policy_nodes_cnt,
1054 	const uint8_t **in, size_t *inlen)
1055 {
1056 	int ret;
1057 	const uint8_t *d;
1058 	size_t dlen;
1059 
1060 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
1061 		if (ret < 0) error_print();
1062 		return ret;
1063 	}
1064 	if (x509_cert_policy_id_from_der(issuer_policy_oid,
1065 			issuer_policy_nodes, issuer_policy_nodes_cnt, &d, &dlen) != 1
1066 		|| x509_cert_policy_id_from_der(subject_policy_oid,
1067 			subject_policy_nodes, subject_policy_nodes_cnt, &d, &dlen) != 1
1068 		|| asn1_length_is_zero(dlen) != 1) {
1069 		error_print();
1070 		return -1;
1071 	}
1072 	return 1;
1073 }
1074 
x509_policy_mapping_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1075 int x509_policy_mapping_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1076 {
1077 	int oid;
1078 	uint32_t nodes[32];
1079 	size_t nodes_cnt;
1080 
1081 	format_print(fp, fmt, ind, "%s\n", label);
1082 	ind += 4;
1083 
1084 	if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err;
1085 	asn1_object_identifier_print(fp, fmt, ind, "issuerDomainPolicy", x509_cert_policy_id_name(oid), nodes, nodes_cnt);
1086 	if (x509_cert_policy_id_from_der(&oid, nodes, &nodes_cnt, &d, &dlen) != 1) goto err;
1087 	asn1_object_identifier_print(fp, fmt, ind, "subjectDomainPolicy", x509_cert_policy_id_name(oid), nodes, nodes_cnt);
1088 	if (asn1_length_is_zero(dlen) != 1) goto err;
1089 	return 1;
1090 err:
1091 	error_print();
1092 	return -1;
1093 }
1094 
x509_policy_mappings_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1095 int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1096 {
1097 	const uint8_t *p;
1098 	size_t len;
1099 
1100 	format_print(fp, fmt, ind, "%s\n", label);
1101 	ind += 4;
1102 
1103 	while (dlen) {
1104 		if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
1105 			error_print();
1106 			return -1;
1107 		}
1108 		x509_policy_mapping_print(fp, fmt, ind, label, p, len);
1109 	}
1110 	return 1;
1111 }
1112 
1113 
x509_attribute_to_der(const uint32_t * nodes,size_t nodes_cnt,const uint8_t * values,size_t values_len,uint8_t ** out,size_t * outlen)1114 int x509_attribute_to_der(
1115 	const uint32_t *nodes, size_t nodes_cnt,
1116 	const uint8_t *values, size_t values_len,
1117 	uint8_t **out, size_t *outlen)
1118 {
1119 	size_t len = 0;
1120 	if (asn1_object_identifier_to_der(nodes, nodes_cnt, NULL, &len) != 1
1121 		|| asn1_set_to_der(values, values_len, NULL, &len) != 1
1122 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
1123 		|| asn1_object_identifier_to_der(nodes, nodes_cnt, out, outlen) != 1
1124 		|| asn1_set_to_der(values, values_len, out, outlen) != 1) {
1125 		error_print();
1126 		return -1;
1127 	}
1128 	return 1;
1129 }
1130 
x509_attribute_from_der(int * oid,uint32_t * nodes,size_t * nodes_cnt,const uint8_t ** values,size_t * values_len,const uint8_t ** in,size_t * inlen)1131 int x509_attribute_from_der(
1132 	int *oid, uint32_t *nodes, size_t *nodes_cnt,
1133 	const uint8_t **values, size_t *values_len,
1134 	const uint8_t **in, size_t *inlen)
1135 {
1136 	int ret;
1137 	const uint8_t *p;
1138 	size_t len;
1139 
1140 	*oid = OID_undef;
1141 	if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) {
1142 		if (ret < 0) error_print();
1143 		return ret;
1144 	}
1145 	if (asn1_object_identifier_from_der(nodes, nodes_cnt, &p, &len) != 1
1146 		|| asn1_set_from_der(values, values_len, &p, &len) != 1
1147 		|| asn1_length_is_zero(len) != 1) {
1148 		error_print();
1149 		return -1;
1150 	}
1151 	return 1;
1152 }
1153 
x509_attribute_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1154 int x509_attribute_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1155 {
1156 	uint32_t nodes[32];
1157 	size_t nodes_cnt;
1158 	const uint8_t *p;
1159 	size_t len;
1160 
1161 	format_print(fp, fmt, ind, "%s\n", label);
1162 	ind += 4;
1163 
1164 	if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1) goto err;
1165 	asn1_object_identifier_print(fp, fmt, ind, "type", NULL, nodes, nodes_cnt);
1166 	if (asn1_set_from_der(&p, &len, &d, &dlen) != 1) goto err;
1167 	format_bytes(fp, fmt, ind, "values", p, len);
1168 	if (asn1_length_is_zero(dlen) != 1) goto err;
1169 	return 1;
1170 err:
1171 	error_print();
1172 	return -1;
1173 }
1174 
x509_attributes_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1175 int x509_attributes_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1176 {
1177 	const uint8_t *p;
1178 	size_t len;
1179 
1180 	if (label) {
1181 		format_print(fp, fmt, ind, "%s\n", label);
1182 		ind += 4;
1183 	}
1184 	while (dlen) {
1185 		if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
1186 			error_print();
1187 			return -1;
1188 		}
1189 		x509_attribute_print(fp, fmt, ind, "Attribute", p, len);
1190 	}
1191 	return 1;
1192 }
1193 
x509_basic_constraints_to_der(int ca,int path_len_cons,uint8_t ** out,size_t * outlen)1194 int x509_basic_constraints_to_der(int ca, int path_len_cons, uint8_t **out, size_t *outlen)
1195 {
1196 	size_t len = 0;
1197 	if (asn1_boolean_to_der(ca, NULL, &len) < 0
1198 		|| asn1_int_to_der(path_len_cons, NULL, &len) < 0
1199 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
1200 		|| asn1_boolean_to_der(ca, out, outlen) < 0
1201 		|| asn1_int_to_der(path_len_cons, out, outlen) < 0) {
1202 		error_print();
1203 		return -1;
1204 	}
1205 	return 1;
1206 }
1207 
x509_basic_constraints_from_der(int * ca,int * path_len_cons,const uint8_t ** in,size_t * inlen)1208 int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t **in, size_t *inlen)
1209 {
1210 	int ret;
1211 	const uint8_t *d;
1212 	size_t dlen;
1213 
1214 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
1215 		if (ret < 0) error_print();
1216 		return ret;
1217 	}
1218 	if (asn1_boolean_from_der(ca, &d, &dlen) < 0
1219 		|| asn1_int_from_der(path_len_cons, &d, &dlen) < 0
1220 		|| asn1_length_is_zero(dlen) != 1) {
1221 		error_print();
1222 		return -1;
1223 	}
1224 	if (*ca < 0 && *path_len_cons < 0) {
1225 		error_print();
1226 		return -1;
1227 	}
1228 	if (*ca < 0) *ca = 0;
1229 	return 1;
1230 }
1231 
x509_basic_constraints_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1232 int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1233 {
1234 	int ret, val;
1235 
1236 	format_print(fp, fmt, ind, "%s\n", label);
1237 	ind += 4;
1238 
1239 	if ((ret = asn1_boolean_from_der(&val, &d, &dlen)) < 0) goto err;
1240 	if (ret) format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(val));
1241 	else format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(0)); // 特殊对待,无论cA值是否编码均输出结果
1242 	if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err;
1243 	if (ret) format_print(fp, fmt, ind, "pathLenConstraint: %d\n", val);
1244 	if (asn1_length_is_zero(dlen) != 1) goto err;
1245 	return 1;
1246 err:
1247 	error_print();
1248 	return -1;
1249 }
1250 
x509_general_subtree_to_der(int base_choice,const uint8_t * base,size_t base_len,int minimum,int maximum,uint8_t ** out,size_t * outlen)1251 int x509_general_subtree_to_der(
1252 	int base_choice, const uint8_t *base, size_t base_len,
1253 	int minimum,
1254 	int maximum,
1255 	uint8_t **out, size_t *outlen)
1256 {
1257 	size_t len = 0;
1258 	if (x509_general_name_to_der(base_choice, base, base_len, NULL, &len) != 1
1259 		|| asn1_implicit_int_to_der(0, minimum, NULL, &len) < 0
1260 		|| asn1_implicit_int_to_der(1, maximum, NULL, &len) < 0
1261 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
1262 		|| x509_general_name_to_der(base_choice, base, base_len, out, outlen) != 1
1263 		|| asn1_implicit_int_to_der(0, minimum, out, outlen) < 0
1264 		|| asn1_implicit_int_to_der(1, maximum, out, outlen) < 0) {
1265 		error_print();
1266 		return -1;
1267 	}
1268 	return 1;
1269 }
1270 
x509_general_subtree_from_der(int * base_choice,const uint8_t ** base,size_t * base_len,int * minimum,int * maximum,const uint8_t ** in,size_t * inlen)1271 int x509_general_subtree_from_der(
1272 	int *base_choice, const uint8_t **base, size_t *base_len,
1273 	int *minimum,
1274 	int *maximum,
1275 	const uint8_t **in, size_t *inlen)
1276 {
1277 	int ret;
1278 	const uint8_t *d;
1279 	size_t dlen;
1280 
1281 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
1282 		if (ret < 0) error_print();
1283 		return ret;
1284 	}
1285 	if (x509_general_name_from_der(base_choice, base, base_len, &d, &dlen) != 1
1286 		|| asn1_implicit_int_from_der(0, minimum, &d, &dlen) < 0
1287 		|| asn1_implicit_int_from_der(1, maximum, &d, &dlen) < 0
1288 		|| asn1_length_is_zero(dlen) != 1) {
1289 		error_print();
1290 		return -1;
1291 	}
1292 	if (*minimum < 0) *minimum = 0;
1293 	return 1;
1294 }
1295 
x509_general_subtree_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1296 int x509_general_subtree_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1297 {
1298 	int ret, choice, val;
1299 	const uint8_t *p;
1300 	size_t len;
1301 
1302 	format_print(fp, fmt, ind, "%s\n", label);
1303 	ind += 4;
1304 
1305 	if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) goto err;
1306 	x509_general_name_print(fp, fmt, ind, "base", choice, p, len);
1307 	if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err;
1308 	if (ret) format_print(fp, fmt, ind, "minimum: %d\n", val);
1309 	if ((ret = asn1_implicit_int_from_der(1, &val, &d, &dlen)) < 0) goto err;
1310 	if (ret) format_print(fp, fmt, ind, "maximum: %d\n", val);
1311 	if (asn1_length_is_zero(dlen) != 1) goto err;
1312 	return 1;
1313 err:
1314 	error_print();
1315 	return -1;
1316 }
1317 
x509_general_subtrees_add_general_subtree(uint8_t * d,size_t * dlen,size_t maxlen,int base_choice,const uint8_t * base,size_t base_len,int minimum,int maximum)1318 int x509_general_subtrees_add_general_subtree(uint8_t *d, size_t *dlen, size_t maxlen,
1319 	int base_choice, const uint8_t *base, size_t base_len,
1320 	int minimum, int maximum)
1321 {
1322 	error_print();
1323 	return -1;
1324 }
1325 
x509_general_subtrees_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1326 int x509_general_subtrees_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1327 {
1328 	const uint8_t *p;
1329 	size_t len;
1330 
1331 	format_print(fp, fmt, ind, "%s\n", label);
1332 	ind += 4;
1333 
1334 	while (dlen) {
1335 		if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
1336 			error_print();
1337 			return -1;
1338 		}
1339 		x509_general_subtree_print(fp, fmt, ind, "GeneralSubtree", p, len);
1340 	}
1341 	return 1;
1342 }
1343 
x509_name_constraints_to_der(const uint8_t * permitted_subtrees,size_t permitted_subtrees_len,const uint8_t * excluded_subtrees,size_t excluded_subtrees_len,uint8_t ** out,size_t * outlen)1344 int x509_name_constraints_to_der(
1345 	const uint8_t *permitted_subtrees, size_t permitted_subtrees_len,
1346 	const uint8_t *excluded_subtrees, size_t excluded_subtrees_len,
1347 	uint8_t **out, size_t *outlen)
1348 {
1349 	size_t len = 0;
1350 	if (asn1_implicit_sequence_to_der(0, permitted_subtrees, permitted_subtrees_len, NULL, &len) < 0
1351 		|| asn1_implicit_sequence_to_der(1, excluded_subtrees, excluded_subtrees_len, NULL, &len) < 0
1352 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
1353 		|| asn1_implicit_sequence_to_der(0, permitted_subtrees, permitted_subtrees_len, out, outlen) < 0
1354 		|| asn1_implicit_sequence_to_der(1, excluded_subtrees, excluded_subtrees_len, out, outlen) < 0) {
1355 		error_print();
1356 		return -1;
1357 	}
1358 	return 1;
1359 }
1360 
x509_name_constraints_from_der(const uint8_t ** permitted_subtrees,size_t * permitted_subtrees_len,const uint8_t ** excluded_subtrees,size_t * excluded_subtrees_len,const uint8_t ** in,size_t * inlen)1361 int x509_name_constraints_from_der(
1362 	const uint8_t **permitted_subtrees, size_t *permitted_subtrees_len,
1363 	const uint8_t **excluded_subtrees, size_t *excluded_subtrees_len,
1364 	const uint8_t **in, size_t *inlen)
1365 {
1366 	int ret;
1367 	const uint8_t *d;
1368 	size_t dlen;
1369 
1370 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
1371 		if (ret < 0) error_print();
1372 		return ret;
1373 	}
1374 	*permitted_subtrees = NULL;
1375 	*permitted_subtrees_len = 0;
1376 	*excluded_subtrees = NULL;
1377 	*excluded_subtrees_len = 0;
1378 	if (asn1_implicit_sequence_from_der(0, permitted_subtrees, permitted_subtrees_len, &d, &dlen) < 0
1379 		|| asn1_implicit_sequence_from_der(1, excluded_subtrees, excluded_subtrees_len, &d, &dlen) < 0
1380 		|| asn1_length_is_zero(dlen) != 1) {
1381 		error_print();
1382 		return -1;
1383 	}
1384 	return 1;
1385 }
1386 
x509_name_constraints_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1387 int x509_name_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1388 {
1389 	int ret;
1390 	const uint8_t *p;
1391 	size_t len;
1392 
1393 	format_print(fp, fmt, ind, "%s\n", label);
1394 	ind += 4;
1395 
1396 	if ((ret = asn1_implicit_sequence_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
1397 	if (ret) x509_general_subtrees_print(fp, fmt, ind, "permittedSubtrees", p, len);
1398 	if ((ret = asn1_implicit_sequence_from_der(1, &p, &len, &d, &dlen)) < 0) goto err;
1399 	if (ret) x509_general_subtrees_print(fp, fmt, ind, "excludedSubtrees", p, len);
1400 	if (asn1_length_is_zero(dlen) != 1) goto err;
1401 	return 1;
1402 err:
1403 	error_print();
1404 	return -1;
1405 }
1406 
x509_policy_constraints_to_der(int require_explicit_policy,int inhibit_policy_mapping,uint8_t ** out,size_t * outlen)1407 int x509_policy_constraints_to_der(
1408 	int require_explicit_policy,
1409 	int inhibit_policy_mapping,
1410 	uint8_t **out, size_t *outlen)
1411 {
1412 	size_t len = 0;
1413 	if (asn1_implicit_int_to_der(0, require_explicit_policy, NULL, &len) < 0
1414 		|| asn1_implicit_int_to_der(1, inhibit_policy_mapping, NULL, &len) < 0
1415 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
1416 		|| asn1_implicit_int_to_der(0, require_explicit_policy, out, outlen) < 0
1417 		|| asn1_implicit_int_to_der(1, inhibit_policy_mapping, out, outlen) < 0) {
1418 		error_print();
1419 		return -1;
1420 	}
1421 	return 1;
1422 }
1423 
x509_policy_constraints_from_der(int * require_explicit_policy,int * inhibit_policy_mapping,const uint8_t ** in,size_t * inlen)1424 int x509_policy_constraints_from_der(
1425 	int *require_explicit_policy,
1426 	int *inhibit_policy_mapping,
1427 	const uint8_t **in, size_t *inlen)
1428 {
1429 	int ret;
1430 	const uint8_t *d;
1431 	size_t dlen;
1432 
1433 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
1434 		if (ret < 0) error_print();
1435 		return ret;
1436 	}
1437 	*require_explicit_policy = -1;
1438 	*inhibit_policy_mapping = -1;
1439 	if (asn1_implicit_int_from_der(0, require_explicit_policy, &d, &dlen) < 0
1440 		|| asn1_implicit_int_from_der(1, inhibit_policy_mapping, &d, &dlen) < 0
1441 		|| asn1_length_is_zero(dlen) != 1) {
1442 		error_print();
1443 		return -1;
1444 	}
1445 	return 1;
1446 }
1447 
x509_policy_constraints_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1448 int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1449 {
1450 	int ret, val;
1451 
1452 	format_print(fp, fmt, ind, "%s\n", label);
1453 	ind += 4;
1454 
1455 	if ((ret = asn1_implicit_int_from_der(0, &val, &d, &dlen)) < 0) goto err;
1456 	if (ret) format_print(fp, fmt, ind, "requireExplicitPolicy: %d\n", val);
1457 	if ((ret = asn1_implicit_int_from_der(1, &val, &d, &dlen)) < 0) goto err;
1458 	if (ret) format_print(fp, fmt, ind, "inhibitPolicyMapping: %d\n", val);
1459 	if (asn1_length_is_zero(dlen) != 1) goto err;
1460 	return 1;
1461 err:
1462 	error_print();
1463 	return -1;
1464 }
1465 
x509_ext_key_usage_to_der(const int * oids,size_t oids_cnt,uint8_t ** out,size_t * outlen)1466 int x509_ext_key_usage_to_der(const int *oids, size_t oids_cnt, uint8_t **out, size_t *outlen)
1467 {
1468 	size_t len = 0;
1469 	size_t i;
1470 
1471 	if (oids_cnt > X509_MAX_KEY_PURPOSES) {
1472 		error_print();
1473 		return -1;
1474 	}
1475 	for (i = 0; i < oids_cnt; i++) {
1476 		if (x509_key_purpose_to_der(oids[i], NULL, &len) != 1) {
1477 			error_print();
1478 			return -1;
1479 		}
1480 	}
1481 	if (asn1_sequence_header_to_der(len, out, outlen) != 1) {
1482 		error_print();
1483 		return -1;
1484 	}
1485 	for (i = 0; i < oids_cnt; i++) {
1486 		if (x509_key_purpose_to_der(oids[i], out, outlen) != 1) {
1487 			error_print();
1488 			return -1;
1489 		}
1490 	}
1491 	return 1;
1492 }
1493 
x509_ext_key_usage_from_der(int * oids,size_t * oids_cnt,size_t max_cnt,const uint8_t ** in,size_t * inlen)1494 int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, const uint8_t **in, size_t *inlen)
1495 {
1496 	int ret;
1497 	const uint8_t *p;
1498 	size_t len;
1499 
1500 	*oids_cnt = 0;
1501 	if ((ret = asn1_sequence_from_der(&p, &len, in, inlen)) != 1) {
1502 		if (ret < 0) error_print();
1503 		return ret;
1504 	}
1505 	while (len && (*oids_cnt < max_cnt)) {
1506 		if (x509_key_purpose_from_der(oids, &p, &len) != 1) {
1507 			error_print();
1508 			return -1;
1509 		}
1510 		oids++;
1511 		(*oids_cnt)++;
1512 	}
1513 	if (len) {
1514 		error_print();
1515 		return -1;
1516 	}
1517 	return 1;
1518 }
1519 
x509_ext_key_usage_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1520 int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1521 {
1522 	int oid;
1523 	format_print(fp, fmt, ind, "%s\n", label);
1524 	ind += 4;
1525 
1526 	while (dlen) {
1527 		if (x509_key_purpose_from_der(&oid, &d, &dlen) != 1) {
1528 			error_print();
1529 			return -1;
1530 		}
1531 		format_print(fp, fmt, ind, "%s\n", x509_key_purpose_name(oid));
1532 	}
1533 	return 1;
1534 }
1535 
1536 static const char *x509_revoke_reasons[] = {
1537 	"unused",
1538 	"keyCompromise",
1539 	"cACompromise",
1540 	"affiliationChanged",
1541 	"superseded",
1542 	"cessationOfOperation",
1543 	"certificateHold",
1544 	"privilegeWithdrawn",
1545 	"aACompromise",
1546 };
1547 
1548 static size_t x509_revoke_reasons_count =
1549 	sizeof(x509_revoke_reasons)/sizeof(x509_revoke_reasons[0]);
1550 
x509_revoke_reason_name(int flag)1551 const char *x509_revoke_reason_name(int flag)
1552 {
1553 	int i;
1554 	for (i = 0; i < x509_revoke_reasons_count; i++) {
1555 		if (flag & 1) {
1556 			if (flag >> 1) {
1557 				error_print();
1558 				return NULL;
1559 			}
1560 			return x509_revoke_reasons[i];
1561 		}
1562 		flag >>= 1;
1563 	}
1564 	return NULL;
1565 }
1566 
x509_revoke_reason_from_name(int * flag,const char * name)1567 int x509_revoke_reason_from_name(int *flag, const char *name)
1568 {
1569 	int i;
1570 	for (i = 0; i < x509_revoke_reasons_count; i++) {
1571 		if (strcmp(name, x509_revoke_reasons[i]) == 0) {
1572 			*flag = 1 << i;
1573 			return 1;
1574 		}
1575 	}
1576 	*flag = 0;
1577 	error_print();
1578 	return -1;
1579 }
1580 
x509_revoke_reasons_print(FILE * fp,int fmt,int ind,const char * label,int bits)1581 int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits)
1582 {
1583 	return asn1_bits_print(fp, fmt, ind, label, x509_revoke_reasons, x509_revoke_reasons_count, bits);
1584 }
1585 
x509_distribution_point_name_to_der(int choice,const uint8_t * d,size_t dlen,uint8_t ** out,size_t * outlen)1586 int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
1587 {
1588 	switch (choice) {
1589 	case 0:
1590 	case 1:
1591 		if (asn1_implicit_to_der(choice, d, dlen, out, outlen) != 1) {
1592 			error_print();
1593 			return -1;
1594 		}
1595 		return 1;
1596 	default:
1597 		error_print();
1598 		return -1;
1599 	}
1600 }
1601 
x509_distribution_point_name_from_der(int * choice,const uint8_t ** d,size_t * dlen,const uint8_t ** in,size_t * inlen)1602 int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
1603 {
1604 	int ret;
1605 
1606 	if ((ret = asn1_implicit_from_der(*choice, d, dlen, in, inlen)) != 1) {
1607 		if (ret < 0) error_print();
1608 		return -1;
1609 	}
1610 	switch (*choice) {
1611 	case 0:
1612 	case 1:
1613 		break;
1614 	default:
1615 		error_print();
1616 		return -1;
1617 	}
1618 	return 1;
1619 }
1620 
x509_explicit_distribution_point_name_to_der(int index,int choice,const uint8_t * d,size_t dlen,uint8_t ** out,size_t * outlen)1621 int x509_explicit_distribution_point_name_to_der(int index, int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
1622 {
1623 	// 注意:要能够解决d == NULL的情况
1624 	error_print();
1625 	return -1;
1626 }
1627 
x509_explicit_distribution_point_name_from_der(int index,int * choice,const uint8_t ** d,size_t * dlen,const uint8_t ** in,size_t * inlen)1628 int x509_explicit_distribution_point_name_from_der(int index, int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
1629 {
1630 	// 注意:要能够解决d == NULL的情况
1631 	error_print();
1632 	return -1;
1633 }
1634 
x509_distribution_point_name_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * a,size_t alen)1635 int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
1636 {
1637 	int tag;
1638 	const uint8_t *d;
1639 	size_t dlen;
1640 
1641 	format_print(fp, fmt, ind, "%s\n", label);
1642 	ind += 4;
1643 
1644 	if (asn1_any_type_from_der(&tag, &d, &dlen, &a, &alen) != 1) {
1645 		error_print();
1646 		return -1;
1647 	}
1648 	switch (tag) {
1649 	case ASN1_TAG_EXPLICIT(0): return x509_general_names_print(fp, fmt, ind, "fullName", d, dlen);
1650 	case ASN1_TAG_IMPLICIT(1): return x509_rdn_print(fp, fmt, ind, "nameRelativeToCRLIssuer", d, dlen);
1651 	default:
1652 		error_print();
1653 		return -1;
1654 	}
1655 	return 1;
1656 }
1657 
x509_distribution_point_to_der(int dist_point_choice,const uint8_t * dist_point,size_t dist_point_len,int reasons,const uint8_t * crl_issuer,size_t crl_issuer_len,uint8_t ** out,size_t * outlen)1658 int x509_distribution_point_to_der(
1659 	int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len,
1660 	int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
1661 	uint8_t **out, size_t *outlen)
1662 {
1663 	size_t len = 0;
1664 	if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0
1665 		|| asn1_implicit_bits_to_der(1, reasons, NULL, &len) < 0
1666 		|| asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, NULL, &len) < 0
1667 		|| asn1_sequence_header_to_der(len, out, outlen) != 1
1668 		|| x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, out, outlen) < 0
1669 		|| asn1_implicit_bits_to_der(1, reasons, out, outlen) < 0
1670 		|| asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, out, outlen) < 0) {
1671 		error_print();
1672 		return -1;
1673 	}
1674 	return 1;
1675 }
1676 
x509_distribution_point_from_der(int * dist_point_choice,const uint8_t ** dist_point,size_t * dist_point_len,int * reasons,const uint8_t ** crl_issuer,size_t * crl_issuer_len,const uint8_t ** in,size_t * inlen)1677 int x509_distribution_point_from_der(
1678 	int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len,
1679 	int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len,
1680 	const uint8_t **in, size_t *inlen)
1681 {
1682 	int ret;
1683 	const uint8_t *d;
1684 	size_t dlen;
1685 
1686 	if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
1687 		if (ret < 0) error_print();
1688 		return ret;
1689 	}
1690 	if (x509_explicit_distribution_point_name_from_der(0, dist_point_choice, dist_point, dist_point_len, &d, &dlen) < 0
1691 		|| asn1_implicit_bits_from_der(1, reasons, &d, &dlen) < 0
1692 		|| asn1_implicit_sequence_from_der(2, crl_issuer, crl_issuer_len, &d, &dlen) < 0
1693 		|| asn1_length_is_zero(dlen) != 1) {
1694 		error_print();
1695 		return -1;
1696 	}
1697 	return 1;
1698 }
1699 
x509_distribution_point_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1700 int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1701 {
1702 	int ret;
1703 	const uint8_t *p;
1704 	size_t len;
1705 	int bits;
1706 
1707 	format_print(fp, fmt, ind, "%s\n", label);
1708 	ind += 4;
1709 
1710 	if ((ret = asn1_explicit_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
1711 	if (ret) x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len);
1712 
1713 	if ((ret = asn1_implicit_bits_from_der(1, &bits, &d, &dlen)) < 0) goto err;
1714 	if (ret) x509_revoke_reasons_print(fp, fmt, ind, "reasons", bits);
1715 
1716 	if ((ret = asn1_implicit_sequence_from_der(2, &p, &len, &d, &dlen)) < 0) goto err;
1717 	if (ret) x509_general_names_print(fp, fmt, ind, "cRLIssuer", p, len);
1718 	if (asn1_length_is_zero(dlen) != 1) goto err;
1719 	return 1;
1720 err:
1721 	error_print();
1722 	return -1;
1723 }
1724 
1725 /*
1726                 extnID: CRLDistributionPoints (2.5.29.31)
1727                     DistributionPoint
1728                         distributionPoint
1729                             fullName
1730                                 GeneralName
1731                                     URI: http://www.rootca.gov.cn/Civil_Servant_arl/Civil_Servant_ARL.crl
1732                     DistributionPoint
1733                         distributionPoint
1734                             fullName
1735                                 GeneralName
1736                                     URI: ldap://ldap.rootca.gov.cn:390/CN=Civil_Servant_ARL,OU=ARL,O=NRCAC,C=CN
1737 
1738 */
1739 
x509_distribution_points_add_url(uint8_t * d,size_t * dlen,size_t maxlen,const char * url)1740 int x509_distribution_points_add_url(uint8_t *d, size_t *dlen, size_t maxlen, const char *url)
1741 {
1742 	return 0;
1743 }
1744 
x509_distribution_points_add_distribution_point(uint8_t * d,size_t * dlen,size_t maxlen,int dist_point_choice,const uint8_t * dist_point,size_t dist_point_len,int reasons,const uint8_t * crl_issuer,size_t crl_issuer_len)1745 int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, size_t maxlen,
1746 	int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len,
1747 	int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len)
1748 {
1749 	error_print();
1750 	return -1;
1751 }
1752 
x509_distribution_points_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)1753 int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
1754 {
1755 	const uint8_t *p;
1756 	size_t len;
1757 
1758 	if (label) {
1759 		format_print(fp, fmt, ind, "%s\n", label);
1760 		ind += 4;
1761 	}
1762 	while (dlen) {
1763 		if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
1764 			error_print();
1765 			return -1;
1766 		}
1767 		x509_distribution_point_print(fp, fmt, ind, "DistributionPoint", p, len);
1768 	}
1769 	return 1;
1770 }
1771 
1772 static const char *netscape_cert_types[] = {
1773 	"SSL Client certificate",
1774 	"SSL Server certificate",
1775 	"S/MIME certificate",
1776 	"Object-signing certificate",
1777 	"Reserved for future use",
1778 	"SSL CA certificate",
1779 	"S/MIME CA certificate",
1780 	"Object-signing CA certificate",
1781 };
1782 
x509_netscape_cert_type_print(FILE * fp,int fmt,int ind,const char * label,int bits)1783 int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label, int bits)
1784 {
1785 	return asn1_bits_print(fp, fmt, ind, label, netscape_cert_types,
1786 		sizeof(netscape_cert_types)/sizeof(netscape_cert_types[0]), bits);
1787 }
1788 
1789