xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/crypto/x509/v3_crld.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 /*
2  * Written by Dr Stephen N Henson ([email protected]) for the OpenSSL project
3  * 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  *    [email protected].
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  * ([email protected]).  This product includes software written by Tim
55  * Hudson ([email protected]). */
56 
57 #include <stdio.h>
58 #include <string.h>
59 
60 #include <openssl/asn1.h>
61 #include <openssl/asn1t.h>
62 #include <openssl/conf.h>
63 #include <openssl/err.h>
64 #include <openssl/mem.h>
65 #include <openssl/obj.h>
66 #include <openssl/x509.h>
67 
68 #include "internal.h"
69 
70 
71 static void *v2i_crld(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx,
72                       const STACK_OF(CONF_VALUE) *nval);
73 static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
74                      int indent);
75 
76 const X509V3_EXT_METHOD v3_crld = {
77     NID_crl_distribution_points,
78     0,
79     ASN1_ITEM_ref(CRL_DIST_POINTS),
80     0,
81     0,
82     0,
83     0,
84     0,
85     0,
86     0,
87     v2i_crld,
88     i2r_crldp,
89     0,
90     NULL,
91 };
92 
93 const X509V3_EXT_METHOD v3_freshest_crl = {
94     NID_freshest_crl,
95     0,
96     ASN1_ITEM_ref(CRL_DIST_POINTS),
97     0,
98     0,
99     0,
100     0,
101     0,
102     0,
103     0,
104     v2i_crld,
105     i2r_crldp,
106     0,
107     NULL,
108 };
109 
STACK_OF(GENERAL_NAME)110 static STACK_OF(GENERAL_NAME) *gnames_from_sectname(const X509V3_CTX *ctx,
111                                                     char *sect) {
112   const STACK_OF(CONF_VALUE) *gnsect;
113   STACK_OF(CONF_VALUE) *gnsect_owned = NULL;
114   if (*sect == '@') {
115     gnsect = X509V3_get_section(ctx, sect + 1);
116   } else {
117     gnsect_owned = X509V3_parse_list(sect);
118     gnsect = gnsect_owned;
119   }
120   if (!gnsect) {
121     OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
122     return NULL;
123   }
124   STACK_OF(GENERAL_NAME) *gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
125   sk_CONF_VALUE_pop_free(gnsect_owned, X509V3_conf_free);
126   return gens;
127 }
128 
129 // set_dist_point_name decodes a DistributionPointName from |cnf| and writes the
130 // result in |*pdp|. It returns 1 on success, -1 on error, and 0 if |cnf| used
131 // an unrecognized input type. The zero return can be used by callers to support
132 // additional syntax.
set_dist_point_name(DIST_POINT_NAME ** pdp,const X509V3_CTX * ctx,const CONF_VALUE * cnf)133 static int set_dist_point_name(DIST_POINT_NAME **pdp, const X509V3_CTX *ctx,
134                                const CONF_VALUE *cnf) {
135   STACK_OF(GENERAL_NAME) *fnm = NULL;
136   STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
137   if (!strncmp(cnf->name, "fullname", 9)) {
138     // If |cnf| comes from |X509V3_parse_list|, which is possible for a v2i
139     // function, |cnf->value| may be NULL.
140     if (cnf->value == NULL) {
141       OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
142       return -1;
143     }
144     fnm = gnames_from_sectname(ctx, cnf->value);
145     if (!fnm) {
146       goto err;
147     }
148   } else if (!strcmp(cnf->name, "relativename")) {
149     // If |cnf| comes from |X509V3_parse_list|, which is possible for a v2i
150     // function, |cnf->value| may be NULL.
151     if (cnf->value == NULL) {
152       OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
153       return -1;
154     }
155     const STACK_OF(CONF_VALUE) *dnsect = X509V3_get_section(ctx, cnf->value);
156     if (!dnsect) {
157       OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
158       return -1;
159     }
160     X509_NAME *nm = X509_NAME_new();
161     if (!nm) {
162       return -1;
163     }
164     int 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     }
171     // There can only be one RDN in nameRelativeToCRLIssuer.
172     if (sk_X509_NAME_ENTRY_value(rnm, sk_X509_NAME_ENTRY_num(rnm) - 1)->set) {
173       OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS);
174       goto err;
175     }
176   } else {
177     return 0;
178   }
179 
180   if (*pdp) {
181     OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET);
182     goto err;
183   }
184 
185   *pdp = DIST_POINT_NAME_new();
186   if (!*pdp) {
187     goto err;
188   }
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 
199 err:
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 
205 static 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 
set_reasons(ASN1_BIT_STRING ** preas,const char * value)217 static int set_reasons(ASN1_BIT_STRING **preas, const char *value) {
218   if (*preas) {
219     // Duplicate "reasons" or "onlysomereasons" key.
220     OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_VALUE);
221     return 0;
222   }
223   int ret = 0;
224   STACK_OF(CONF_VALUE) *rsk = X509V3_parse_list(value);
225   if (!rsk) {
226     return 0;
227   }
228   for (size_t i = 0; i < sk_CONF_VALUE_num(rsk); i++) {
229     const char *bnam = sk_CONF_VALUE_value(rsk, i)->name;
230     if (!*preas) {
231       *preas = ASN1_BIT_STRING_new();
232       if (!*preas) {
233         goto err;
234       }
235     }
236     const BIT_STRING_BITNAME *pbn;
237     for (pbn = reason_flags; pbn->lname; pbn++) {
238       if (!strcmp(pbn->sname, bnam)) {
239         if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) {
240           goto err;
241         }
242         break;
243       }
244     }
245     if (!pbn->lname) {
246       goto err;
247     }
248   }
249   ret = 1;
250 
251 err:
252   sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
253   return ret;
254 }
255 
print_reasons(BIO * out,const char * rname,ASN1_BIT_STRING * rflags,int indent)256 static int print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags,
257                          int indent) {
258   int first = 1;
259   const BIT_STRING_BITNAME *pbn;
260   BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
261   for (pbn = reason_flags; pbn->lname; pbn++) {
262     if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) {
263       if (first) {
264         first = 0;
265       } else {
266         BIO_puts(out, ", ");
267       }
268       BIO_puts(out, pbn->lname);
269     }
270   }
271   if (first) {
272     BIO_puts(out, "<EMPTY>\n");
273   } else {
274     BIO_puts(out, "\n");
275   }
276   return 1;
277 }
278 
crldp_from_section(const X509V3_CTX * ctx,const STACK_OF (CONF_VALUE)* nval)279 static DIST_POINT *crldp_from_section(const X509V3_CTX *ctx,
280                                       const STACK_OF(CONF_VALUE) *nval) {
281   DIST_POINT *point = NULL;
282   point = DIST_POINT_new();
283   if (!point) {
284     goto err;
285   }
286   for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
287     const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
288     int ret = set_dist_point_name(&point->distpoint, ctx, cnf);
289     if (ret > 0) {
290       continue;
291     }
292     if (ret < 0) {
293       goto err;
294     }
295     if (!strcmp(cnf->name, "reasons")) {
296       if (!set_reasons(&point->reasons, cnf->value)) {
297         goto err;
298       }
299     } else if (!strcmp(cnf->name, "CRLissuer")) {
300       GENERAL_NAMES_free(point->CRLissuer);
301       point->CRLissuer = gnames_from_sectname(ctx, cnf->value);
302       if (!point->CRLissuer) {
303         goto err;
304       }
305     }
306   }
307 
308   return point;
309 
310 err:
311   DIST_POINT_free(point);
312   return NULL;
313 }
314 
v2i_crld(const X509V3_EXT_METHOD * method,const X509V3_CTX * ctx,const STACK_OF (CONF_VALUE)* nval)315 static void *v2i_crld(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx,
316                       const STACK_OF(CONF_VALUE) *nval) {
317   STACK_OF(DIST_POINT) *crld = NULL;
318   GENERAL_NAMES *gens = NULL;
319   GENERAL_NAME *gen = NULL;
320   if (!(crld = sk_DIST_POINT_new_null())) {
321     goto err;
322   }
323   for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
324     DIST_POINT *point;
325     const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
326     if (!cnf->value) {
327       const STACK_OF(CONF_VALUE) *dpsect = X509V3_get_section(ctx, cnf->name);
328       if (!dpsect) {
329         goto err;
330       }
331       point = crldp_from_section(ctx, dpsect);
332       if (!point) {
333         goto err;
334       }
335       if (!sk_DIST_POINT_push(crld, point)) {
336         DIST_POINT_free(point);
337         goto err;
338       }
339     } else {
340       if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) {
341         goto err;
342       }
343       if (!(gens = GENERAL_NAMES_new())) {
344         goto err;
345       }
346       if (!sk_GENERAL_NAME_push(gens, gen)) {
347         goto err;
348       }
349       gen = NULL;
350       if (!(point = DIST_POINT_new())) {
351         goto err;
352       }
353       if (!sk_DIST_POINT_push(crld, point)) {
354         DIST_POINT_free(point);
355         goto err;
356       }
357       if (!(point->distpoint = DIST_POINT_NAME_new())) {
358         goto err;
359       }
360       point->distpoint->name.fullname = gens;
361       point->distpoint->type = 0;
362       gens = NULL;
363     }
364   }
365   return crld;
366 
367 err:
368   GENERAL_NAME_free(gen);
369   GENERAL_NAMES_free(gens);
370   sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
371   return NULL;
372 }
373 
dpn_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)374 static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
375                   void *exarg) {
376   DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
377 
378   switch (operation) {
379     case ASN1_OP_NEW_POST:
380       dpn->dpname = NULL;
381       break;
382 
383     case ASN1_OP_FREE_POST:
384       X509_NAME_free(dpn->dpname);
385       break;
386   }
387   return 1;
388 }
389 
390 
391 ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
392     ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
393     ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1),
394 } ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
395 
396 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(DIST_POINT_NAME)
397 
398 ASN1_SEQUENCE(DIST_POINT) = {
399     ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
400     ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
401     ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2),
402 } ASN1_SEQUENCE_END(DIST_POINT)
403 
404 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(DIST_POINT)
405 
406 ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = ASN1_EX_TEMPLATE_TYPE(
407     ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
408 ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
409 
410 IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
411 
412 ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
413     ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
414     ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
415     ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
416     ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
417     ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
418     ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5),
419 } ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
420 
421 IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
422 
423 static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
424                    int indent);
425 static void *v2i_idp(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx,
426                      const STACK_OF(CONF_VALUE) *nval);
427 
428 const X509V3_EXT_METHOD v3_idp = {
429     NID_issuing_distribution_point,
430     X509V3_EXT_MULTILINE,
431     ASN1_ITEM_ref(ISSUING_DIST_POINT),
432     0,
433     0,
434     0,
435     0,
436     0,
437     0,
438     0,
439     v2i_idp,
440     i2r_idp,
441     0,
442     NULL,
443 };
444 
v2i_idp(const X509V3_EXT_METHOD * method,const X509V3_CTX * ctx,const STACK_OF (CONF_VALUE)* nval)445 static void *v2i_idp(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx,
446                      const STACK_OF(CONF_VALUE) *nval) {
447   ISSUING_DIST_POINT *idp = ISSUING_DIST_POINT_new();
448   if (!idp) {
449     goto err;
450   }
451   for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
452     const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
453     const char *name = cnf->name;
454     const char *val = cnf->value;
455     int ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
456     if (ret > 0) {
457       continue;
458     }
459     if (ret < 0) {
460       goto err;
461     }
462     if (!strcmp(name, "onlyuser")) {
463       if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) {
464         goto err;
465       }
466     } else if (!strcmp(name, "onlyCA")) {
467       if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) {
468         goto err;
469       }
470     } else if (!strcmp(name, "onlyAA")) {
471       if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) {
472         goto err;
473       }
474     } else if (!strcmp(name, "indirectCRL")) {
475       if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) {
476         goto err;
477       }
478     } else if (!strcmp(name, "onlysomereasons")) {
479       if (!set_reasons(&idp->onlysomereasons, val)) {
480         goto err;
481       }
482     } else {
483       OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
484       X509V3_conf_err(cnf);
485       goto err;
486     }
487   }
488   return idp;
489 
490 err:
491   ISSUING_DIST_POINT_free(idp);
492   return NULL;
493 }
494 
print_gens(BIO * out,STACK_OF (GENERAL_NAME)* gens,int indent)495 static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) {
496   size_t i;
497   for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
498     BIO_printf(out, "%*s", indent + 2, "");
499     GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
500     BIO_puts(out, "\n");
501   }
502   return 1;
503 }
504 
print_distpoint(BIO * out,DIST_POINT_NAME * dpn,int indent)505 static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) {
506   if (dpn->type == 0) {
507     BIO_printf(out, "%*sFull Name:\n", indent, "");
508     print_gens(out, dpn->name.fullname, indent);
509   } else {
510     X509_NAME ntmp;
511     ntmp.entries = dpn->name.relativename;
512     BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, "");
513     X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
514     BIO_puts(out, "\n");
515   }
516   return 1;
517 }
518 
i2r_idp(const X509V3_EXT_METHOD * method,void * pidp,BIO * out,int indent)519 static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
520                    int indent) {
521   ISSUING_DIST_POINT *idp = pidp;
522   if (idp->distpoint) {
523     print_distpoint(out, idp->distpoint, indent);
524   }
525   if (idp->onlyuser > 0) {
526     BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
527   }
528   if (idp->onlyCA > 0) {
529     BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
530   }
531   if (idp->indirectCRL > 0) {
532     BIO_printf(out, "%*sIndirect CRL\n", indent, "");
533   }
534   if (idp->onlysomereasons) {
535     print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent);
536   }
537   if (idp->onlyattr > 0) {
538     BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
539   }
540   if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) &&
541       (idp->indirectCRL <= 0) && !idp->onlysomereasons &&
542       (idp->onlyattr <= 0)) {
543     BIO_printf(out, "%*s<EMPTY>\n", indent, "");
544   }
545 
546   return 1;
547 }
548 
i2r_crldp(const X509V3_EXT_METHOD * method,void * pcrldp,BIO * out,int indent)549 static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
550                      int indent) {
551   STACK_OF(DIST_POINT) *crld = pcrldp;
552   DIST_POINT *point;
553   size_t i;
554   for (i = 0; i < sk_DIST_POINT_num(crld); i++) {
555     BIO_puts(out, "\n");
556     point = sk_DIST_POINT_value(crld, i);
557     if (point->distpoint) {
558       print_distpoint(out, point->distpoint, indent);
559     }
560     if (point->reasons) {
561       print_reasons(out, "Reasons", point->reasons, indent);
562     }
563     if (point->CRLissuer) {
564       BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
565       print_gens(out, point->CRLissuer, indent);
566     }
567   }
568   return 1;
569 }
570 
DIST_POINT_set_dpname(DIST_POINT_NAME * dpn,X509_NAME * iname)571 int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) {
572   size_t i;
573   STACK_OF(X509_NAME_ENTRY) *frag;
574   X509_NAME_ENTRY *ne;
575   if (!dpn || (dpn->type != 1)) {
576     return 1;
577   }
578   frag = dpn->name.relativename;
579   dpn->dpname = X509_NAME_dup(iname);
580   if (!dpn->dpname) {
581     return 0;
582   }
583   for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
584     ne = sk_X509_NAME_ENTRY_value(frag, i);
585     if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
586       X509_NAME_free(dpn->dpname);
587       dpn->dpname = NULL;
588       return 0;
589     }
590   }
591   // generate cached encoding of name
592   if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
593     X509_NAME_free(dpn->dpname);
594     dpn->dpname = NULL;
595     return 0;
596   }
597   return 1;
598 }
599