/src/boringssl/crypto/x509/v3_crld.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <stdio.h> |
16 | | #include <string.h> |
17 | | |
18 | | #include <openssl/asn1.h> |
19 | | #include <openssl/asn1t.h> |
20 | | #include <openssl/conf.h> |
21 | | #include <openssl/err.h> |
22 | | #include <openssl/mem.h> |
23 | | #include <openssl/obj.h> |
24 | | #include <openssl/x509.h> |
25 | | |
26 | | #include "internal.h" |
27 | | |
28 | | |
29 | | static void *v2i_crld(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, |
30 | | const STACK_OF(CONF_VALUE) *nval); |
31 | | static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, |
32 | | int indent); |
33 | | |
34 | | const X509V3_EXT_METHOD v3_crld = { |
35 | | NID_crl_distribution_points, |
36 | | 0, |
37 | | ASN1_ITEM_ref(CRL_DIST_POINTS), |
38 | | 0, |
39 | | 0, |
40 | | 0, |
41 | | 0, |
42 | | 0, |
43 | | 0, |
44 | | 0, |
45 | | v2i_crld, |
46 | | i2r_crldp, |
47 | | 0, |
48 | | NULL, |
49 | | }; |
50 | | |
51 | | const X509V3_EXT_METHOD v3_freshest_crl = { |
52 | | NID_freshest_crl, |
53 | | 0, |
54 | | ASN1_ITEM_ref(CRL_DIST_POINTS), |
55 | | 0, |
56 | | 0, |
57 | | 0, |
58 | | 0, |
59 | | 0, |
60 | | 0, |
61 | | 0, |
62 | | v2i_crld, |
63 | | i2r_crldp, |
64 | | 0, |
65 | | NULL, |
66 | | }; |
67 | | |
68 | | static STACK_OF(GENERAL_NAME) *gnames_from_sectname(const X509V3_CTX *ctx, |
69 | 78.3k | char *sect) { |
70 | 78.3k | const STACK_OF(CONF_VALUE) *gnsect; |
71 | 78.3k | STACK_OF(CONF_VALUE) *gnsect_owned = NULL; |
72 | 78.3k | if (*sect == '@') { |
73 | 1.46k | gnsect = X509V3_get_section(ctx, sect + 1); |
74 | 76.9k | } else { |
75 | 76.9k | gnsect_owned = X509V3_parse_list(sect); |
76 | 76.9k | gnsect = gnsect_owned; |
77 | 76.9k | } |
78 | 78.3k | if (!gnsect) { |
79 | 9 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); |
80 | 9 | return NULL; |
81 | 9 | } |
82 | 78.3k | STACK_OF(GENERAL_NAME) *gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); |
83 | 78.3k | sk_CONF_VALUE_pop_free(gnsect_owned, X509V3_conf_free); |
84 | 78.3k | return gens; |
85 | 78.3k | } |
86 | | |
87 | | // set_dist_point_name decodes a DistributionPointName from |cnf| and writes the |
88 | | // result in |*pdp|. It returns 1 on success, -1 on error, and 0 if |cnf| used |
89 | | // an unrecognized input type. The zero return can be used by callers to support |
90 | | // additional syntax. |
91 | | static int set_dist_point_name(DIST_POINT_NAME **pdp, const X509V3_CTX *ctx, |
92 | 84.1k | const CONF_VALUE *cnf) { |
93 | 84.1k | STACK_OF(GENERAL_NAME) *fnm = NULL; |
94 | 84.1k | STACK_OF(X509_NAME_ENTRY) *rnm = NULL; |
95 | 84.1k | if (!strncmp(cnf->name, "fullname", 9)) { |
96 | | // If |cnf| comes from |X509V3_parse_list|, which is possible for a v2i |
97 | | // function, |cnf->value| may be NULL. |
98 | 72.8k | if (cnf->value == NULL) { |
99 | 5 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); |
100 | 5 | return -1; |
101 | 5 | } |
102 | 72.8k | fnm = gnames_from_sectname(ctx, cnf->value); |
103 | 72.8k | if (!fnm) { |
104 | 23 | goto err; |
105 | 23 | } |
106 | 72.8k | } else if (!strcmp(cnf->name, "relativename")) { |
107 | | // If |cnf| comes from |X509V3_parse_list|, which is possible for a v2i |
108 | | // function, |cnf->value| may be NULL. |
109 | 1.62k | if (cnf->value == NULL) { |
110 | 5 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); |
111 | 5 | return -1; |
112 | 5 | } |
113 | 1.62k | const STACK_OF(CONF_VALUE) *dnsect = X509V3_get_section(ctx, cnf->value); |
114 | 1.62k | if (!dnsect) { |
115 | 5 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); |
116 | 5 | return -1; |
117 | 5 | } |
118 | 1.61k | X509_NAME *nm = X509_NAME_new(); |
119 | 1.61k | if (!nm) { |
120 | 0 | return -1; |
121 | 0 | } |
122 | 1.61k | int ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); |
123 | 1.61k | rnm = nm->entries; |
124 | 1.61k | nm->entries = NULL; |
125 | 1.61k | X509_NAME_free(nm); |
126 | 1.61k | if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) { |
127 | 3 | goto err; |
128 | 3 | } |
129 | | // There can only be one RDN in nameRelativeToCRLIssuer. |
130 | 1.61k | if (sk_X509_NAME_ENTRY_value(rnm, sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { |
131 | 1 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS); |
132 | 1 | goto err; |
133 | 1 | } |
134 | 9.62k | } else { |
135 | 9.62k | return 0; |
136 | 9.62k | } |
137 | | |
138 | 74.4k | if (*pdp) { |
139 | 1 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET); |
140 | 1 | goto err; |
141 | 1 | } |
142 | | |
143 | 74.4k | *pdp = DIST_POINT_NAME_new(); |
144 | 74.4k | if (!*pdp) { |
145 | 0 | goto err; |
146 | 0 | } |
147 | 74.4k | if (fnm) { |
148 | 72.8k | (*pdp)->type = 0; |
149 | 72.8k | (*pdp)->name.fullname = fnm; |
150 | 72.8k | } else { |
151 | 1.61k | (*pdp)->type = 1; |
152 | 1.61k | (*pdp)->name.relativename = rnm; |
153 | 1.61k | } |
154 | | |
155 | 74.4k | return 1; |
156 | | |
157 | 28 | err: |
158 | 28 | sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); |
159 | 28 | sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); |
160 | 28 | return -1; |
161 | 74.4k | } |
162 | | |
163 | | static const BIT_STRING_BITNAME reason_flags[] = { |
164 | | {0, "Unused", "unused"}, |
165 | | {1, "Key Compromise", "keyCompromise"}, |
166 | | {2, "CA Compromise", "CACompromise"}, |
167 | | {3, "Affiliation Changed", "affiliationChanged"}, |
168 | | {4, "Superseded", "superseded"}, |
169 | | {5, "Cessation Of Operation", "cessationOfOperation"}, |
170 | | {6, "Certificate Hold", "certificateHold"}, |
171 | | {7, "Privilege Withdrawn", "privilegeWithdrawn"}, |
172 | | {8, "AA Compromise", "AACompromise"}, |
173 | | {-1, NULL, NULL}}; |
174 | | |
175 | 731 | static int set_reasons(ASN1_BIT_STRING **preas, const char *value) { |
176 | 731 | if (*preas) { |
177 | | // Duplicate "reasons" or "onlysomereasons" key. |
178 | 5 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_VALUE); |
179 | 5 | return 0; |
180 | 5 | } |
181 | 726 | int ret = 0; |
182 | 726 | STACK_OF(CONF_VALUE) *rsk = X509V3_parse_list(value); |
183 | 726 | if (!rsk) { |
184 | 4 | return 0; |
185 | 4 | } |
186 | 1.77k | for (size_t i = 0; i < sk_CONF_VALUE_num(rsk); i++) { |
187 | 1.24k | const char *bnam = sk_CONF_VALUE_value(rsk, i)->name; |
188 | 1.24k | if (!*preas) { |
189 | 722 | *preas = ASN1_BIT_STRING_new(); |
190 | 722 | if (!*preas) { |
191 | 0 | goto err; |
192 | 0 | } |
193 | 722 | } |
194 | 1.24k | const BIT_STRING_BITNAME *pbn; |
195 | 3.50k | for (pbn = reason_flags; pbn->lname; pbn++) { |
196 | 3.31k | if (!strcmp(pbn->sname, bnam)) { |
197 | 1.05k | if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) { |
198 | 0 | goto err; |
199 | 0 | } |
200 | 1.05k | break; |
201 | 1.05k | } |
202 | 3.31k | } |
203 | 1.24k | if (!pbn->lname) { |
204 | 190 | goto err; |
205 | 190 | } |
206 | 1.24k | } |
207 | 532 | ret = 1; |
208 | | |
209 | 722 | err: |
210 | 722 | sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); |
211 | 722 | return ret; |
212 | 532 | } |
213 | | |
214 | | static int print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags, |
215 | 132 | int indent) { |
216 | 132 | int first = 1; |
217 | 132 | const BIT_STRING_BITNAME *pbn; |
218 | 132 | BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); |
219 | 1.32k | for (pbn = reason_flags; pbn->lname; pbn++) { |
220 | 1.18k | if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { |
221 | 563 | if (first) { |
222 | 107 | first = 0; |
223 | 456 | } else { |
224 | 456 | BIO_puts(out, ", "); |
225 | 456 | } |
226 | 563 | BIO_puts(out, pbn->lname); |
227 | 563 | } |
228 | 1.18k | } |
229 | 132 | if (first) { |
230 | 25 | BIO_puts(out, "<EMPTY>\n"); |
231 | 107 | } else { |
232 | 107 | BIO_puts(out, "\n"); |
233 | 107 | } |
234 | 132 | return 1; |
235 | 132 | } |
236 | | |
237 | | static DIST_POINT *crldp_from_section(const X509V3_CTX *ctx, |
238 | 82.2k | const STACK_OF(CONF_VALUE) *nval) { |
239 | 82.2k | DIST_POINT *point = NULL; |
240 | 82.2k | point = DIST_POINT_new(); |
241 | 82.2k | if (!point) { |
242 | 0 | goto err; |
243 | 0 | } |
244 | 164k | for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { |
245 | 82.7k | const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); |
246 | 82.7k | int ret = set_dist_point_name(&point->distpoint, ctx, cnf); |
247 | 82.7k | if (ret > 0) { |
248 | 74.4k | continue; |
249 | 74.4k | } |
250 | 8.26k | if (ret < 0) { |
251 | 23 | goto err; |
252 | 23 | } |
253 | 8.24k | if (!strcmp(cnf->name, "reasons")) { |
254 | 713 | if (!set_reasons(&point->reasons, cnf->value)) { |
255 | 189 | goto err; |
256 | 189 | } |
257 | 7.52k | } else if (!strcmp(cnf->name, "CRLissuer")) { |
258 | 5.53k | GENERAL_NAMES_free(point->CRLissuer); |
259 | 5.53k | point->CRLissuer = gnames_from_sectname(ctx, cnf->value); |
260 | 5.53k | if (!point->CRLissuer) { |
261 | 8 | goto err; |
262 | 8 | } |
263 | 5.53k | } |
264 | 8.24k | } |
265 | | |
266 | 82.0k | return point; |
267 | | |
268 | 220 | err: |
269 | 220 | DIST_POINT_free(point); |
270 | 220 | return NULL; |
271 | 82.2k | } |
272 | | |
273 | | static void *v2i_crld(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, |
274 | 4.12k | const STACK_OF(CONF_VALUE) *nval) { |
275 | 4.12k | STACK_OF(DIST_POINT) *crld = NULL; |
276 | 4.12k | GENERAL_NAMES *gens = NULL; |
277 | 4.12k | GENERAL_NAME *gen = NULL; |
278 | 4.12k | if (!(crld = sk_DIST_POINT_new_null())) { |
279 | 0 | goto err; |
280 | 0 | } |
281 | 89.4k | for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { |
282 | 87.8k | DIST_POINT *point; |
283 | 87.8k | const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); |
284 | 87.8k | if (!cnf->value) { |
285 | 83.8k | const STACK_OF(CONF_VALUE) *dpsect = X509V3_get_section(ctx, cnf->name); |
286 | 83.8k | if (!dpsect) { |
287 | 1.57k | goto err; |
288 | 1.57k | } |
289 | 82.2k | point = crldp_from_section(ctx, dpsect); |
290 | 82.2k | if (!point) { |
291 | 220 | goto err; |
292 | 220 | } |
293 | 82.0k | if (!sk_DIST_POINT_push(crld, point)) { |
294 | 0 | DIST_POINT_free(point); |
295 | 0 | goto err; |
296 | 0 | } |
297 | 82.0k | } else { |
298 | 4.04k | if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) { |
299 | 711 | goto err; |
300 | 711 | } |
301 | 3.33k | if (!(gens = GENERAL_NAMES_new())) { |
302 | 0 | goto err; |
303 | 0 | } |
304 | 3.33k | if (!sk_GENERAL_NAME_push(gens, gen)) { |
305 | 0 | goto err; |
306 | 0 | } |
307 | 3.33k | gen = NULL; |
308 | 3.33k | if (!(point = DIST_POINT_new())) { |
309 | 0 | goto err; |
310 | 0 | } |
311 | 3.33k | if (!sk_DIST_POINT_push(crld, point)) { |
312 | 0 | DIST_POINT_free(point); |
313 | 0 | goto err; |
314 | 0 | } |
315 | 3.33k | if (!(point->distpoint = DIST_POINT_NAME_new())) { |
316 | 0 | goto err; |
317 | 0 | } |
318 | 3.33k | point->distpoint->name.fullname = gens; |
319 | 3.33k | point->distpoint->type = 0; |
320 | 3.33k | gens = NULL; |
321 | 3.33k | } |
322 | 87.8k | } |
323 | 1.61k | return crld; |
324 | | |
325 | 2.50k | err: |
326 | 2.50k | GENERAL_NAME_free(gen); |
327 | 2.50k | GENERAL_NAMES_free(gens); |
328 | 2.50k | sk_DIST_POINT_pop_free(crld, DIST_POINT_free); |
329 | 2.50k | return NULL; |
330 | 4.12k | } |
331 | | |
332 | | static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
333 | 317k | void *exarg) { |
334 | 317k | DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; |
335 | | |
336 | 317k | switch (operation) { |
337 | 78.8k | case ASN1_OP_NEW_POST: |
338 | 78.8k | dpn->dpname = NULL; |
339 | 78.8k | break; |
340 | | |
341 | 78.8k | case ASN1_OP_FREE_POST: |
342 | 78.8k | X509_NAME_free(dpn->dpname); |
343 | 78.8k | break; |
344 | 317k | } |
345 | 317k | return 1; |
346 | 317k | } |
347 | | |
348 | | |
349 | | ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { |
350 | | ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), |
351 | | ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1), |
352 | | } ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) |
353 | | |
354 | | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(DIST_POINT_NAME) |
355 | | |
356 | | ASN1_SEQUENCE(DIST_POINT) = { |
357 | | ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), |
358 | | ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), |
359 | | ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2), |
360 | | } ASN1_SEQUENCE_END(DIST_POINT) |
361 | | |
362 | | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(DIST_POINT) |
363 | | |
364 | | ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = ASN1_EX_TEMPLATE_TYPE( |
365 | | ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT) |
366 | | ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) |
367 | | |
368 | | IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) |
369 | | |
370 | | ASN1_SEQUENCE(ISSUING_DIST_POINT) = { |
371 | | ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), |
372 | | ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), |
373 | | ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), |
374 | | ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), |
375 | | ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), |
376 | | ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5), |
377 | | } ASN1_SEQUENCE_END(ISSUING_DIST_POINT) |
378 | | |
379 | | IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) |
380 | | |
381 | | static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, |
382 | | int indent); |
383 | | static void *v2i_idp(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, |
384 | | const STACK_OF(CONF_VALUE) *nval); |
385 | | |
386 | | const X509V3_EXT_METHOD v3_idp = { |
387 | | NID_issuing_distribution_point, |
388 | | X509V3_EXT_MULTILINE, |
389 | | ASN1_ITEM_ref(ISSUING_DIST_POINT), |
390 | | 0, |
391 | | 0, |
392 | | 0, |
393 | | 0, |
394 | | 0, |
395 | | 0, |
396 | | 0, |
397 | | v2i_idp, |
398 | | i2r_idp, |
399 | | 0, |
400 | | NULL, |
401 | | }; |
402 | | |
403 | | static void *v2i_idp(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, |
404 | 626 | const STACK_OF(CONF_VALUE) *nval) { |
405 | 626 | ISSUING_DIST_POINT *idp = ISSUING_DIST_POINT_new(); |
406 | 626 | if (!idp) { |
407 | 0 | goto err; |
408 | 0 | } |
409 | 1.44k | for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { |
410 | 1.41k | const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); |
411 | 1.41k | const char *name = cnf->name; |
412 | 1.41k | const char *val = cnf->value; |
413 | 1.41k | int ret = set_dist_point_name(&idp->distpoint, ctx, cnf); |
414 | 1.41k | if (ret > 0) { |
415 | 4 | continue; |
416 | 4 | } |
417 | 1.40k | if (ret < 0) { |
418 | 20 | goto err; |
419 | 20 | } |
420 | 1.38k | if (!strcmp(name, "onlyuser")) { |
421 | 6 | if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) { |
422 | 3 | goto err; |
423 | 3 | } |
424 | 1.38k | } else if (!strcmp(name, "onlyCA")) { |
425 | 561 | if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) { |
426 | 11 | goto err; |
427 | 11 | } |
428 | 822 | } else if (!strcmp(name, "onlyAA")) { |
429 | 252 | if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) { |
430 | 3 | goto err; |
431 | 3 | } |
432 | 570 | } else if (!strcmp(name, "indirectCRL")) { |
433 | 6 | if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) { |
434 | 3 | goto err; |
435 | 3 | } |
436 | 564 | } else if (!strcmp(name, "onlysomereasons")) { |
437 | 18 | if (!set_reasons(&idp->onlysomereasons, val)) { |
438 | 10 | goto err; |
439 | 10 | } |
440 | 546 | } else { |
441 | 546 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); |
442 | 546 | X509V3_conf_err(cnf); |
443 | 546 | goto err; |
444 | 546 | } |
445 | 1.38k | } |
446 | 30 | return idp; |
447 | | |
448 | 596 | err: |
449 | 596 | ISSUING_DIST_POINT_free(idp); |
450 | 596 | return NULL; |
451 | 626 | } |
452 | | |
453 | 354 | static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) { |
454 | 354 | size_t i; |
455 | 1.57k | for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { |
456 | 1.22k | BIO_printf(out, "%*s", indent + 2, ""); |
457 | 1.22k | GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); |
458 | 1.22k | BIO_puts(out, "\n"); |
459 | 1.22k | } |
460 | 354 | return 1; |
461 | 354 | } |
462 | | |
463 | 247 | static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) { |
464 | 247 | if (dpn->type == 0) { |
465 | 243 | BIO_printf(out, "%*sFull Name:\n", indent, ""); |
466 | 243 | print_gens(out, dpn->name.fullname, indent); |
467 | 243 | } else { |
468 | 4 | X509_NAME ntmp; |
469 | 4 | ntmp.entries = dpn->name.relativename; |
470 | 4 | BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); |
471 | 4 | X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); |
472 | 4 | BIO_puts(out, "\n"); |
473 | 4 | } |
474 | 247 | return 1; |
475 | 247 | } |
476 | | |
477 | | static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, |
478 | 353 | int indent) { |
479 | 353 | ISSUING_DIST_POINT *idp = reinterpret_cast<ISSUING_DIST_POINT *>(pidp); |
480 | 353 | if (idp->distpoint) { |
481 | 22 | print_distpoint(out, idp->distpoint, indent); |
482 | 22 | } |
483 | 353 | if (idp->onlyuser > 0) { |
484 | 10 | BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); |
485 | 10 | } |
486 | 353 | if (idp->onlyCA > 0) { |
487 | 9 | BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); |
488 | 9 | } |
489 | 353 | if (idp->indirectCRL > 0) { |
490 | 6 | BIO_printf(out, "%*sIndirect CRL\n", indent, ""); |
491 | 6 | } |
492 | 353 | if (idp->onlysomereasons) { |
493 | 50 | print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent); |
494 | 50 | } |
495 | 353 | if (idp->onlyattr > 0) { |
496 | 7 | BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); |
497 | 7 | } |
498 | 353 | if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) && |
499 | 353 | (idp->indirectCRL <= 0) && !idp->onlysomereasons && |
500 | 353 | (idp->onlyattr <= 0)) { |
501 | 249 | BIO_printf(out, "%*s<EMPTY>\n", indent, ""); |
502 | 249 | } |
503 | | |
504 | 353 | return 1; |
505 | 353 | } |
506 | | |
507 | | static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, |
508 | 350 | int indent) { |
509 | 350 | STACK_OF(DIST_POINT) *crld = reinterpret_cast<STACK_OF(DIST_POINT) *>(pcrldp); |
510 | 350 | DIST_POINT *point; |
511 | 350 | size_t i; |
512 | 677 | for (i = 0; i < sk_DIST_POINT_num(crld); i++) { |
513 | 327 | BIO_puts(out, "\n"); |
514 | 327 | point = sk_DIST_POINT_value(crld, i); |
515 | 327 | if (point->distpoint) { |
516 | 225 | print_distpoint(out, point->distpoint, indent); |
517 | 225 | } |
518 | 327 | if (point->reasons) { |
519 | 82 | print_reasons(out, "Reasons", point->reasons, indent); |
520 | 82 | } |
521 | 327 | if (point->CRLissuer) { |
522 | 111 | BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); |
523 | 111 | print_gens(out, point->CRLissuer, indent); |
524 | 111 | } |
525 | 327 | } |
526 | 350 | return 1; |
527 | 350 | } |
528 | | |
529 | 0 | int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) { |
530 | 0 | size_t i; |
531 | 0 | STACK_OF(X509_NAME_ENTRY) *frag; |
532 | 0 | X509_NAME_ENTRY *ne; |
533 | 0 | if (!dpn || (dpn->type != 1)) { |
534 | 0 | return 1; |
535 | 0 | } |
536 | 0 | frag = dpn->name.relativename; |
537 | 0 | dpn->dpname = X509_NAME_dup(iname); |
538 | 0 | if (!dpn->dpname) { |
539 | 0 | return 0; |
540 | 0 | } |
541 | 0 | for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { |
542 | 0 | ne = sk_X509_NAME_ENTRY_value(frag, i); |
543 | 0 | if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { |
544 | 0 | X509_NAME_free(dpn->dpname); |
545 | 0 | dpn->dpname = NULL; |
546 | 0 | return 0; |
547 | 0 | } |
548 | 0 | } |
549 | | // generate cached encoding of name |
550 | 0 | if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { |
551 | 0 | X509_NAME_free(dpn->dpname); |
552 | 0 | dpn->dpname = NULL; |
553 | 0 | return 0; |
554 | 0 | } |
555 | 0 | return 1; |
556 | 0 | } |