summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_crld.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/x509/x509_crld.c852
1 files changed, 0 insertions, 852 deletions
diff --git a/src/lib/libcrypto/x509/x509_crld.c b/src/lib/libcrypto/x509/x509_crld.c
deleted file mode 100644
index 81f2010df5..0000000000
--- a/src/lib/libcrypto/x509/x509_crld.c
+++ /dev/null
@@ -1,852 +0,0 @@
1/* $OpenBSD: x509_crld.c,v 1.9 2025/03/06 07:20:01 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
64#include <openssl/conf.h>
65#include <openssl/err.h>
66#include <openssl/x509v3.h>
67
68#include "x509_local.h"
69
70static void *v2i_crld(const X509V3_EXT_METHOD *method,
71 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
72static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
73 int indent);
74
75static const X509V3_EXT_METHOD x509v3_ext_crl_distribution_points = {
76 .ext_nid = NID_crl_distribution_points,
77 .ext_flags = 0,
78 .it = &CRL_DIST_POINTS_it,
79 .ext_new = NULL,
80 .ext_free = NULL,
81 .d2i = NULL,
82 .i2d = NULL,
83 .i2s = NULL,
84 .s2i = NULL,
85 .i2v = NULL,
86 .v2i = v2i_crld,
87 .i2r = i2r_crldp,
88 .r2i = NULL,
89 .usr_data = NULL,
90};
91
92const X509V3_EXT_METHOD *
93x509v3_ext_method_crl_distribution_points(void)
94{
95 return &x509v3_ext_crl_distribution_points;
96}
97
98static const X509V3_EXT_METHOD x509v3_ext_freshest_crl = {
99 .ext_nid = NID_freshest_crl,
100 .ext_flags = 0,
101 .it = &CRL_DIST_POINTS_it,
102 .ext_new = NULL,
103 .ext_free = NULL,
104 .d2i = NULL,
105 .i2d = NULL,
106 .i2s = NULL,
107 .s2i = NULL,
108 .i2v = NULL,
109 .v2i = v2i_crld,
110 .i2r = i2r_crldp,
111 .r2i = NULL,
112 .usr_data = NULL,
113};
114
115const X509V3_EXT_METHOD *
116x509v3_ext_method_freshest_crl(void)
117{
118 return &x509v3_ext_freshest_crl;
119}
120
121static STACK_OF(GENERAL_NAME) *
122gnames_from_sectname(X509V3_CTX *ctx, char *sect)
123{
124 STACK_OF(CONF_VALUE) *gnsect;
125 STACK_OF(GENERAL_NAME) *gens;
126
127 if (*sect == '@')
128 gnsect = X509V3_get0_section(ctx, sect + 1);
129 else
130 gnsect = X509V3_parse_list(sect);
131 if (!gnsect) {
132 X509V3error(X509V3_R_SECTION_NOT_FOUND);
133 return NULL;
134 }
135 gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
136 if (*sect != '@')
137 sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
138 return gens;
139}
140
141static int
142set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, CONF_VALUE *cnf)
143{
144 STACK_OF(GENERAL_NAME) *fnm = NULL;
145 STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
146
147 if (!strncmp(cnf->name, "fullname", 9)) {
148 fnm = gnames_from_sectname(ctx, cnf->value);
149 if (!fnm)
150 goto err;
151 } else if (!strcmp(cnf->name, "relativename")) {
152 int ret;
153 STACK_OF(CONF_VALUE) *dnsect;
154 X509_NAME *nm;
155 nm = X509_NAME_new();
156 if (!nm)
157 return -1;
158 dnsect = X509V3_get0_section(ctx, cnf->value);
159 if (!dnsect) {
160 X509V3error(X509V3_R_SECTION_NOT_FOUND);
161 X509_NAME_free(nm);
162 return -1;
163 }
164 ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
165 rnm = nm->entries;
166 nm->entries = NULL;
167 X509_NAME_free(nm);
168 if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
169 goto err;
170 /* Since its a name fragment can't have more than one
171 * RDNSequence
172 */
173 if (sk_X509_NAME_ENTRY_value(rnm,
174 sk_X509_NAME_ENTRY_num(rnm) - 1)->set) {
175 X509V3error(X509V3_R_INVALID_MULTIPLE_RDNS);
176 goto err;
177 }
178 } else
179 return 0;
180
181 if (*pdp) {
182 X509V3error(X509V3_R_DISTPOINT_ALREADY_SET);
183 goto err;
184 }
185
186 *pdp = DIST_POINT_NAME_new();
187 if (!*pdp)
188 goto err;
189 if (fnm) {
190 (*pdp)->type = 0;
191 (*pdp)->name.fullname = fnm;
192 } else {
193 (*pdp)->type = 1;
194 (*pdp)->name.relativename = rnm;
195 }
196
197 return 1;
198
199err:
200 sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
201 sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
202 return -1;
203}
204
205static const BIT_STRING_BITNAME reason_flags[] = {
206 {0, "Unused", "unused"},
207 {1, "Key Compromise", "keyCompromise"},
208 {2, "CA Compromise", "CACompromise"},
209 {3, "Affiliation Changed", "affiliationChanged"},
210 {4, "Superseded", "superseded"},
211 {5, "Cessation Of Operation", "cessationOfOperation"},
212 {6, "Certificate Hold", "certificateHold"},
213 {7, "Privilege Withdrawn", "privilegeWithdrawn"},
214 {8, "AA Compromise", "AACompromise"},
215 {-1, NULL, NULL}
216};
217
218static int
219set_reasons(ASN1_BIT_STRING **preas, char *value)
220{
221 STACK_OF(CONF_VALUE) *rsk = NULL;
222 const BIT_STRING_BITNAME *pbn;
223 const char *bnam;
224 int i, ret = 0;
225
226 if (*preas != NULL)
227 return 0;
228 rsk = X509V3_parse_list(value);
229 if (rsk == NULL)
230 return 0;
231 for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) {
232 bnam = sk_CONF_VALUE_value(rsk, i)->name;
233 if (!*preas) {
234 *preas = ASN1_BIT_STRING_new();
235 if (!*preas)
236 goto err;
237 }
238 for (pbn = reason_flags; pbn->lname; pbn++) {
239 if (!strcmp(pbn->sname, bnam)) {
240 if (!ASN1_BIT_STRING_set_bit(*preas,
241 pbn->bitnum, 1))
242 goto err;
243 break;
244 }
245 }
246 if (!pbn->lname)
247 goto err;
248 }
249 ret = 1;
250
251err:
252 sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
253 return ret;
254}
255
256static int
257print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags, int indent)
258{
259 int first = 1;
260 const BIT_STRING_BITNAME *pbn;
261
262 BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
263 for (pbn = reason_flags; pbn->lname; pbn++) {
264 if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) {
265 if (first)
266 first = 0;
267 else
268 BIO_puts(out, ", ");
269 BIO_puts(out, pbn->lname);
270 }
271 }
272 if (first)
273 BIO_puts(out, "<EMPTY>\n");
274 else
275 BIO_puts(out, "\n");
276 return 1;
277}
278
279static DIST_POINT *
280crldp_from_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
281{
282 int i;
283 CONF_VALUE *cnf;
284 DIST_POINT *point = NULL;
285
286 point = DIST_POINT_new();
287 if (!point)
288 goto err;
289 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
290 int ret;
291 cnf = sk_CONF_VALUE_value(nval, i);
292 ret = set_dist_point_name(&point->distpoint, ctx, cnf);
293 if (ret > 0)
294 continue;
295 if (ret < 0)
296 goto err;
297 if (!strcmp(cnf->name, "reasons")) {
298 if (!set_reasons(&point->reasons, cnf->value))
299 goto err;
300 }
301 else if (!strcmp(cnf->name, "CRLissuer")) {
302 point->CRLissuer =
303 gnames_from_sectname(ctx, cnf->value);
304 if (!point->CRLissuer)
305 goto err;
306 }
307 }
308
309 return point;
310
311err:
312 DIST_POINT_free(point);
313 return NULL;
314}
315
316static void *
317v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
318 STACK_OF(CONF_VALUE) *nval)
319{
320 STACK_OF(DIST_POINT) *crld = NULL;
321 GENERAL_NAMES *gens = NULL;
322 GENERAL_NAME *gen = NULL;
323 CONF_VALUE *cnf;
324 int i;
325
326 if (!(crld = sk_DIST_POINT_new_null()))
327 goto merr;
328 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
329 DIST_POINT *point;
330 cnf = sk_CONF_VALUE_value(nval, i);
331 if (!cnf->value) {
332 STACK_OF(CONF_VALUE) *dpsect;
333 dpsect = X509V3_get0_section(ctx, cnf->name);
334 if (!dpsect)
335 goto err;
336 point = crldp_from_section(ctx, dpsect);
337 if (!point)
338 goto err;
339 if (!sk_DIST_POINT_push(crld, point)) {
340 DIST_POINT_free(point);
341 goto merr;
342 }
343 } else {
344 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
345 goto err;
346 if (!(gens = GENERAL_NAMES_new()))
347 goto merr;
348 if (!sk_GENERAL_NAME_push(gens, gen))
349 goto merr;
350 gen = NULL;
351 if (!(point = DIST_POINT_new()))
352 goto merr;
353 if (!sk_DIST_POINT_push(crld, point)) {
354 DIST_POINT_free(point);
355 goto merr;
356 }
357 if (!(point->distpoint = DIST_POINT_NAME_new()))
358 goto merr;
359 point->distpoint->name.fullname = gens;
360 point->distpoint->type = 0;
361 gens = NULL;
362 }
363 }
364 return crld;
365
366merr:
367 X509V3error(ERR_R_MALLOC_FAILURE);
368err:
369 GENERAL_NAME_free(gen);
370 GENERAL_NAMES_free(gens);
371 sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
372 return NULL;
373}
374
375static int
376dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
377{
378 DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
379
380 switch (operation) {
381 case ASN1_OP_NEW_POST:
382 dpn->dpname = NULL;
383 break;
384
385 case ASN1_OP_FREE_POST:
386 if (dpn->dpname)
387 X509_NAME_free(dpn->dpname);
388 break;
389 }
390 return 1;
391}
392
393
394static const ASN1_AUX DIST_POINT_NAME_aux = {
395 .app_data = NULL,
396 .flags = 0,
397 .ref_offset = 0,
398 .ref_lock = 0,
399 .asn1_cb = dpn_cb,
400 .enc_offset = 0,
401};
402static const ASN1_TEMPLATE DIST_POINT_NAME_ch_tt[] = {
403 {
404 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF,
405 .tag = 0,
406 .offset = offsetof(DIST_POINT_NAME, name.fullname),
407 .field_name = "name.fullname",
408 .item = &GENERAL_NAME_it,
409 },
410 {
411 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF,
412 .tag = 1,
413 .offset = offsetof(DIST_POINT_NAME, name.relativename),
414 .field_name = "name.relativename",
415 .item = &X509_NAME_ENTRY_it,
416 },
417};
418
419const ASN1_ITEM DIST_POINT_NAME_it = {
420 .itype = ASN1_ITYPE_CHOICE,
421 .utype = offsetof(DIST_POINT_NAME, type),
422 .templates = DIST_POINT_NAME_ch_tt,
423 .tcount = sizeof(DIST_POINT_NAME_ch_tt) / sizeof(ASN1_TEMPLATE),
424 .funcs = &DIST_POINT_NAME_aux,
425 .size = sizeof(DIST_POINT_NAME),
426 .sname = "DIST_POINT_NAME",
427};
428LCRYPTO_ALIAS(DIST_POINT_NAME_it);
429
430
431
432DIST_POINT_NAME *
433d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, const unsigned char **in, long len)
434{
435 return (DIST_POINT_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
436 &DIST_POINT_NAME_it);
437}
438LCRYPTO_ALIAS(d2i_DIST_POINT_NAME);
439
440int
441i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out)
442{
443 return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_NAME_it);
444}
445LCRYPTO_ALIAS(i2d_DIST_POINT_NAME);
446
447DIST_POINT_NAME *
448DIST_POINT_NAME_new(void)
449{
450 return (DIST_POINT_NAME *)ASN1_item_new(&DIST_POINT_NAME_it);
451}
452LCRYPTO_ALIAS(DIST_POINT_NAME_new);
453
454void
455DIST_POINT_NAME_free(DIST_POINT_NAME *a)
456{
457 ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_NAME_it);
458}
459LCRYPTO_ALIAS(DIST_POINT_NAME_free);
460
461static const ASN1_TEMPLATE DIST_POINT_seq_tt[] = {
462 {
463 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
464 .tag = 0,
465 .offset = offsetof(DIST_POINT, distpoint),
466 .field_name = "distpoint",
467 .item = &DIST_POINT_NAME_it,
468 },
469 {
470 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
471 .tag = 1,
472 .offset = offsetof(DIST_POINT, reasons),
473 .field_name = "reasons",
474 .item = &ASN1_BIT_STRING_it,
475 },
476 {
477 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
478 .tag = 2,
479 .offset = offsetof(DIST_POINT, CRLissuer),
480 .field_name = "CRLissuer",
481 .item = &GENERAL_NAME_it,
482 },
483};
484
485const ASN1_ITEM DIST_POINT_it = {
486 .itype = ASN1_ITYPE_SEQUENCE,
487 .utype = V_ASN1_SEQUENCE,
488 .templates = DIST_POINT_seq_tt,
489 .tcount = sizeof(DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE),
490 .funcs = NULL,
491 .size = sizeof(DIST_POINT),
492 .sname = "DIST_POINT",
493};
494LCRYPTO_ALIAS(DIST_POINT_it);
495
496
497DIST_POINT *
498d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len)
499{
500 return (DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
501 &DIST_POINT_it);
502}
503LCRYPTO_ALIAS(d2i_DIST_POINT);
504
505int
506i2d_DIST_POINT(DIST_POINT *a, unsigned char **out)
507{
508 return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_it);
509}
510LCRYPTO_ALIAS(i2d_DIST_POINT);
511
512DIST_POINT *
513DIST_POINT_new(void)
514{
515 return (DIST_POINT *)ASN1_item_new(&DIST_POINT_it);
516}
517LCRYPTO_ALIAS(DIST_POINT_new);
518
519void
520DIST_POINT_free(DIST_POINT *a)
521{
522 ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_it);
523}
524LCRYPTO_ALIAS(DIST_POINT_free);
525
526static const ASN1_TEMPLATE CRL_DIST_POINTS_item_tt = {
527 .flags = ASN1_TFLG_SEQUENCE_OF,
528 .tag = 0,
529 .offset = 0,
530 .field_name = "CRLDistributionPoints",
531 .item = &DIST_POINT_it,
532};
533
534const ASN1_ITEM CRL_DIST_POINTS_it = {
535 .itype = ASN1_ITYPE_PRIMITIVE,
536 .utype = -1,
537 .templates = &CRL_DIST_POINTS_item_tt,
538 .tcount = 0,
539 .funcs = NULL,
540 .size = 0,
541 .sname = "CRL_DIST_POINTS",
542};
543LCRYPTO_ALIAS(CRL_DIST_POINTS_it);
544
545
546CRL_DIST_POINTS *
547d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len)
548{
549 return (CRL_DIST_POINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
550 &CRL_DIST_POINTS_it);
551}
552LCRYPTO_ALIAS(d2i_CRL_DIST_POINTS);
553
554int
555i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out)
556{
557 return ASN1_item_i2d((ASN1_VALUE *)a, out, &CRL_DIST_POINTS_it);
558}
559LCRYPTO_ALIAS(i2d_CRL_DIST_POINTS);
560
561CRL_DIST_POINTS *
562CRL_DIST_POINTS_new(void)
563{
564 return (CRL_DIST_POINTS *)ASN1_item_new(&CRL_DIST_POINTS_it);
565}
566LCRYPTO_ALIAS(CRL_DIST_POINTS_new);
567
568void
569CRL_DIST_POINTS_free(CRL_DIST_POINTS *a)
570{
571 ASN1_item_free((ASN1_VALUE *)a, &CRL_DIST_POINTS_it);
572}
573LCRYPTO_ALIAS(CRL_DIST_POINTS_free);
574
575static const ASN1_TEMPLATE ISSUING_DIST_POINT_seq_tt[] = {
576 {
577 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
578 .tag = 0,
579 .offset = offsetof(ISSUING_DIST_POINT, distpoint),
580 .field_name = "distpoint",
581 .item = &DIST_POINT_NAME_it,
582 },
583 {
584 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
585 .tag = 1,
586 .offset = offsetof(ISSUING_DIST_POINT, onlyuser),
587 .field_name = "onlyuser",
588 .item = &ASN1_FBOOLEAN_it,
589 },
590 {
591 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
592 .tag = 2,
593 .offset = offsetof(ISSUING_DIST_POINT, onlyCA),
594 .field_name = "onlyCA",
595 .item = &ASN1_FBOOLEAN_it,
596 },
597 {
598 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
599 .tag = 3,
600 .offset = offsetof(ISSUING_DIST_POINT, onlysomereasons),
601 .field_name = "onlysomereasons",
602 .item = &ASN1_BIT_STRING_it,
603 },
604 {
605 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
606 .tag = 4,
607 .offset = offsetof(ISSUING_DIST_POINT, indirectCRL),
608 .field_name = "indirectCRL",
609 .item = &ASN1_FBOOLEAN_it,
610 },
611 {
612 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
613 .tag = 5,
614 .offset = offsetof(ISSUING_DIST_POINT, onlyattr),
615 .field_name = "onlyattr",
616 .item = &ASN1_FBOOLEAN_it,
617 },
618};
619
620const ASN1_ITEM ISSUING_DIST_POINT_it = {
621 .itype = ASN1_ITYPE_SEQUENCE,
622 .utype = V_ASN1_SEQUENCE,
623 .templates = ISSUING_DIST_POINT_seq_tt,
624 .tcount = sizeof(ISSUING_DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE),
625 .funcs = NULL,
626 .size = sizeof(ISSUING_DIST_POINT),
627 .sname = "ISSUING_DIST_POINT",
628};
629LCRYPTO_ALIAS(ISSUING_DIST_POINT_it);
630
631
632ISSUING_DIST_POINT *
633d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len)
634{
635 return (ISSUING_DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
636 &ISSUING_DIST_POINT_it);
637}
638LCRYPTO_ALIAS(d2i_ISSUING_DIST_POINT);
639
640int
641i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out)
642{
643 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ISSUING_DIST_POINT_it);
644}
645LCRYPTO_ALIAS(i2d_ISSUING_DIST_POINT);
646
647ISSUING_DIST_POINT *
648ISSUING_DIST_POINT_new(void)
649{
650 return (ISSUING_DIST_POINT *)ASN1_item_new(&ISSUING_DIST_POINT_it);
651}
652LCRYPTO_ALIAS(ISSUING_DIST_POINT_new);
653
654void
655ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a)
656{
657 ASN1_item_free((ASN1_VALUE *)a, &ISSUING_DIST_POINT_it);
658}
659LCRYPTO_ALIAS(ISSUING_DIST_POINT_free);
660
661static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
662 int indent);
663static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
664 STACK_OF(CONF_VALUE) *nval);
665
666static const X509V3_EXT_METHOD x509v3_ext_issuing_distribution_point = {
667 .ext_nid = NID_issuing_distribution_point,
668 .ext_flags = X509V3_EXT_MULTILINE,
669 .it = &ISSUING_DIST_POINT_it,
670 .ext_new = NULL,
671 .ext_free = NULL,
672 .d2i = NULL,
673 .i2d = NULL,
674 .i2s = NULL,
675 .s2i = NULL,
676 .i2v = NULL,
677 .v2i = v2i_idp,
678 .i2r = i2r_idp,
679 .r2i = NULL,
680 .usr_data = NULL,
681};
682
683const X509V3_EXT_METHOD *
684x509v3_ext_method_issuing_distribution_point(void)
685{
686 return &x509v3_ext_issuing_distribution_point;
687}
688
689static void *
690v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
691 STACK_OF(CONF_VALUE) *nval)
692{
693 ISSUING_DIST_POINT *idp = NULL;
694 CONF_VALUE *cnf;
695 char *name, *val;
696 int i, ret;
697
698 idp = ISSUING_DIST_POINT_new();
699 if (!idp)
700 goto merr;
701 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
702 cnf = sk_CONF_VALUE_value(nval, i);
703 name = cnf->name;
704 val = cnf->value;
705 ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
706 if (ret > 0)
707 continue;
708 if (ret < 0)
709 goto err;
710 if (!strcmp(name, "onlyuser")) {
711 if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
712 goto err;
713 }
714 else if (!strcmp(name, "onlyCA")) {
715 if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
716 goto err;
717 }
718 else if (!strcmp(name, "onlyAA")) {
719 if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
720 goto err;
721 }
722 else if (!strcmp(name, "indirectCRL")) {
723 if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
724 goto err;
725 }
726 else if (!strcmp(name, "onlysomereasons")) {
727 if (!set_reasons(&idp->onlysomereasons, val))
728 goto err;
729 } else {
730 X509V3error(X509V3_R_INVALID_NAME);
731 X509V3_conf_err(cnf);
732 goto err;
733 }
734 }
735 return idp;
736
737merr:
738 X509V3error(ERR_R_MALLOC_FAILURE);
739err:
740 ISSUING_DIST_POINT_free(idp);
741 return NULL;
742}
743
744static int
745print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
746{
747 int i;
748
749 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
750 BIO_printf(out, "%*s", indent + 2, "");
751 GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
752 BIO_puts(out, "\n");
753 }
754 return 1;
755}
756
757static int
758print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
759{
760 if (dpn->type == 0) {
761 BIO_printf(out, "%*sFull Name:\n", indent, "");
762 print_gens(out, dpn->name.fullname, indent);
763 } else {
764 X509_NAME ntmp;
765 ntmp.entries = dpn->name.relativename;
766 BIO_printf(out, "%*sRelative Name:\n%*s",
767 indent, "", indent + 2, "");
768 X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
769 BIO_puts(out, "\n");
770 }
771 return 1;
772}
773
774static int
775i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, int indent)
776{
777 ISSUING_DIST_POINT *idp = pidp;
778
779 if (idp->distpoint)
780 print_distpoint(out, idp->distpoint, indent);
781 if (idp->onlyuser > 0)
782 BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
783 if (idp->onlyCA > 0)
784 BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
785 if (idp->indirectCRL > 0)
786 BIO_printf(out, "%*sIndirect CRL\n", indent, "");
787 if (idp->onlysomereasons)
788 print_reasons(out, "Only Some Reasons",
789 idp->onlysomereasons, indent);
790 if (idp->onlyattr > 0)
791 BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
792 if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) &&
793 (idp->indirectCRL <= 0) && !idp->onlysomereasons &&
794 (idp->onlyattr <= 0))
795 BIO_printf(out, "%*s<EMPTY>\n", indent, "");
796
797 return 1;
798}
799
800static int
801i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, int indent)
802{
803 STACK_OF(DIST_POINT) *crld = pcrldp;
804 DIST_POINT *point;
805 int i;
806
807 for (i = 0; i < sk_DIST_POINT_num(crld); i++) {
808 BIO_puts(out, "\n");
809 point = sk_DIST_POINT_value(crld, i);
810 if (point->distpoint)
811 print_distpoint(out, point->distpoint, indent);
812 if (point->reasons)
813 print_reasons(out, "Reasons", point->reasons,
814 indent);
815 if (point->CRLissuer) {
816 BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
817 print_gens(out, point->CRLissuer, indent);
818 }
819 }
820 return 1;
821}
822
823int
824DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
825{
826 int i;
827 STACK_OF(X509_NAME_ENTRY) *frag;
828 X509_NAME_ENTRY *ne;
829
830 if (!dpn || (dpn->type != 1))
831 return 1;
832 frag = dpn->name.relativename;
833 dpn->dpname = X509_NAME_dup(iname);
834 if (!dpn->dpname)
835 return 0;
836 for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
837 ne = sk_X509_NAME_ENTRY_value(frag, i);
838 if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
839 X509_NAME_free(dpn->dpname);
840 dpn->dpname = NULL;
841 return 0;
842 }
843 }
844 /* generate cached encoding of name */
845 if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
846 X509_NAME_free(dpn->dpname);
847 dpn->dpname = NULL;
848 return 0;
849 }
850 return 1;
851}
852LCRYPTO_ALIAS(DIST_POINT_set_dpname);