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