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