1 /* $OpenBSD: v3_cpols.c,v 1.22 2015/07/29 16:13:48 jsing Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
5 /* ====================================================================
6 * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
34 * 6. Redistributions of any form whatsoever must retain the following
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
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 * ====================================================================
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).
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>
70 /* Certificate policies extension support: this one is a bit complex... */
72 static int i2r_certpol(X509V3_EXT_METHOD
*method
, STACK_OF(POLICYINFO
) *pol
,
73 BIO
*out
, int indent
);
74 static STACK_OF(POLICYINFO
) *r2i_certpol(X509V3_EXT_METHOD
*method
,
75 X509V3_CTX
*ctx
, char *value
);
76 static void print_qualifiers(BIO
*out
, STACK_OF(POLICYQUALINFO
) *quals
,
78 static void print_notice(BIO
*out
, USERNOTICE
*notice
, int indent
);
79 static POLICYINFO
*policy_section(X509V3_CTX
*ctx
,
80 STACK_OF(CONF_VALUE
) *polstrs
, int ia5org
);
81 static POLICYQUALINFO
*notice_section(X509V3_CTX
*ctx
,
82 STACK_OF(CONF_VALUE
) *unot
, int ia5org
);
83 static int nref_nos(STACK_OF(ASN1_INTEGER
) *nnums
, STACK_OF(CONF_VALUE
) *nos
);
85 const X509V3_EXT_METHOD v3_cpols
= {
86 .ext_nid
= NID_certificate_policies
,
88 .it
= ASN1_ITEM_ref(CERTIFICATEPOLICIES
),
97 .i2r
= (X509V3_EXT_I2R
)i2r_certpol
,
98 .r2i
= (X509V3_EXT_R2I
)r2i_certpol
,
102 static const ASN1_TEMPLATE CERTIFICATEPOLICIES_item_tt
= {
103 .flags
= ASN1_TFLG_SEQUENCE_OF
,
106 .field_name
= "CERTIFICATEPOLICIES",
107 .item
= &POLICYINFO_it
,
110 const ASN1_ITEM CERTIFICATEPOLICIES_it
= {
111 .itype
= ASN1_ITYPE_PRIMITIVE
,
113 .templates
= &CERTIFICATEPOLICIES_item_tt
,
117 .sname
= "CERTIFICATEPOLICIES",
121 CERTIFICATEPOLICIES
*
122 d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES
**a
, const unsigned char **in
, long len
)
124 return (CERTIFICATEPOLICIES
*)ASN1_item_d2i((ASN1_VALUE
**)a
, in
, len
,
125 &CERTIFICATEPOLICIES_it
);
129 i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES
*a
, unsigned char **out
)
131 return ASN1_item_i2d((ASN1_VALUE
*)a
, out
, &CERTIFICATEPOLICIES_it
);
134 CERTIFICATEPOLICIES
*
135 CERTIFICATEPOLICIES_new(void)
137 return (CERTIFICATEPOLICIES
*)ASN1_item_new(&CERTIFICATEPOLICIES_it
);
141 CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES
*a
)
143 ASN1_item_free((ASN1_VALUE
*)a
, &CERTIFICATEPOLICIES_it
);
146 static const ASN1_TEMPLATE POLICYINFO_seq_tt
[] = {
150 .offset
= offsetof(POLICYINFO
, policyid
),
151 .field_name
= "policyid",
152 .item
= &ASN1_OBJECT_it
,
155 .flags
= ASN1_TFLG_SEQUENCE_OF
| ASN1_TFLG_OPTIONAL
,
157 .offset
= offsetof(POLICYINFO
, qualifiers
),
158 .field_name
= "qualifiers",
159 .item
= &POLICYQUALINFO_it
,
163 const ASN1_ITEM POLICYINFO_it
= {
164 .itype
= ASN1_ITYPE_SEQUENCE
,
165 .utype
= V_ASN1_SEQUENCE
,
166 .templates
= POLICYINFO_seq_tt
,
167 .tcount
= sizeof(POLICYINFO_seq_tt
) / sizeof(ASN1_TEMPLATE
),
169 .size
= sizeof(POLICYINFO
),
170 .sname
= "POLICYINFO",
175 d2i_POLICYINFO(POLICYINFO
**a
, const unsigned char **in
, long len
)
177 return (POLICYINFO
*)ASN1_item_d2i((ASN1_VALUE
**)a
, in
, len
,
182 i2d_POLICYINFO(POLICYINFO
*a
, unsigned char **out
)
184 return ASN1_item_i2d((ASN1_VALUE
*)a
, out
, &POLICYINFO_it
);
190 return (POLICYINFO
*)ASN1_item_new(&POLICYINFO_it
);
194 POLICYINFO_free(POLICYINFO
*a
)
196 ASN1_item_free((ASN1_VALUE
*)a
, &POLICYINFO_it
);
199 static const ASN1_TEMPLATE policydefault_tt
= {
202 .offset
= offsetof(POLICYQUALINFO
, d
.other
),
203 .field_name
= "d.other",
204 .item
= &ASN1_ANY_it
,
207 static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl
[] = {
209 .value
= NID_id_qt_cps
,
213 .offset
= offsetof(POLICYQUALINFO
, d
.cpsuri
),
214 .field_name
= "d.cpsuri",
215 .item
= &ASN1_IA5STRING_it
,
220 .value
= NID_id_qt_unotice
,
224 .offset
= offsetof(POLICYQUALINFO
, d
.usernotice
),
225 .field_name
= "d.usernotice",
226 .item
= &USERNOTICE_it
,
232 static const ASN1_ADB POLICYQUALINFO_adb
= {
234 .offset
= offsetof(POLICYQUALINFO
, pqualid
),
236 .tbl
= POLICYQUALINFO_adbtbl
,
237 .tblcount
= sizeof(POLICYQUALINFO_adbtbl
) / sizeof(ASN1_ADB_TABLE
),
238 .default_tt
= &policydefault_tt
,
242 static const ASN1_TEMPLATE POLICYQUALINFO_seq_tt
[] = {
246 .offset
= offsetof(POLICYQUALINFO
, pqualid
),
247 .field_name
= "pqualid",
248 .item
= &ASN1_OBJECT_it
,
251 .flags
= ASN1_TFLG_ADB_OID
,
254 .field_name
= "POLICYQUALINFO",
255 .item
= (const ASN1_ITEM
*)&POLICYQUALINFO_adb
,
259 const ASN1_ITEM POLICYQUALINFO_it
= {
260 .itype
= ASN1_ITYPE_SEQUENCE
,
261 .utype
= V_ASN1_SEQUENCE
,
262 .templates
= POLICYQUALINFO_seq_tt
,
263 .tcount
= sizeof(POLICYQUALINFO_seq_tt
) / sizeof(ASN1_TEMPLATE
),
265 .size
= sizeof(POLICYQUALINFO
),
266 .sname
= "POLICYQUALINFO",
271 d2i_POLICYQUALINFO(POLICYQUALINFO
**a
, const unsigned char **in
, long len
)
273 return (POLICYQUALINFO
*)ASN1_item_d2i((ASN1_VALUE
**)a
, in
, len
,
278 i2d_POLICYQUALINFO(POLICYQUALINFO
*a
, unsigned char **out
)
280 return ASN1_item_i2d((ASN1_VALUE
*)a
, out
, &POLICYQUALINFO_it
);
284 POLICYQUALINFO_new(void)
286 return (POLICYQUALINFO
*)ASN1_item_new(&POLICYQUALINFO_it
);
290 POLICYQUALINFO_free(POLICYQUALINFO
*a
)
292 ASN1_item_free((ASN1_VALUE
*)a
, &POLICYQUALINFO_it
);
295 static const ASN1_TEMPLATE USERNOTICE_seq_tt
[] = {
297 .flags
= ASN1_TFLG_OPTIONAL
,
299 .offset
= offsetof(USERNOTICE
, noticeref
),
300 .field_name
= "noticeref",
301 .item
= &NOTICEREF_it
,
304 .flags
= ASN1_TFLG_OPTIONAL
,
306 .offset
= offsetof(USERNOTICE
, exptext
),
307 .field_name
= "exptext",
308 .item
= &DISPLAYTEXT_it
,
312 const ASN1_ITEM USERNOTICE_it
= {
313 .itype
= ASN1_ITYPE_SEQUENCE
,
314 .utype
= V_ASN1_SEQUENCE
,
315 .templates
= USERNOTICE_seq_tt
,
316 .tcount
= sizeof(USERNOTICE_seq_tt
) / sizeof(ASN1_TEMPLATE
),
318 .size
= sizeof(USERNOTICE
),
319 .sname
= "USERNOTICE",
324 d2i_USERNOTICE(USERNOTICE
**a
, const unsigned char **in
, long len
)
326 return (USERNOTICE
*)ASN1_item_d2i((ASN1_VALUE
**)a
, in
, len
,
331 i2d_USERNOTICE(USERNOTICE
*a
, unsigned char **out
)
333 return ASN1_item_i2d((ASN1_VALUE
*)a
, out
, &USERNOTICE_it
);
339 return (USERNOTICE
*)ASN1_item_new(&USERNOTICE_it
);
343 USERNOTICE_free(USERNOTICE
*a
)
345 ASN1_item_free((ASN1_VALUE
*)a
, &USERNOTICE_it
);
348 static const ASN1_TEMPLATE NOTICEREF_seq_tt
[] = {
352 .offset
= offsetof(NOTICEREF
, organization
),
353 .field_name
= "organization",
354 .item
= &DISPLAYTEXT_it
,
357 .flags
= ASN1_TFLG_SEQUENCE_OF
,
359 .offset
= offsetof(NOTICEREF
, noticenos
),
360 .field_name
= "noticenos",
361 .item
= &ASN1_INTEGER_it
,
365 const ASN1_ITEM NOTICEREF_it
= {
366 .itype
= ASN1_ITYPE_SEQUENCE
,
367 .utype
= V_ASN1_SEQUENCE
,
368 .templates
= NOTICEREF_seq_tt
,
369 .tcount
= sizeof(NOTICEREF_seq_tt
) / sizeof(ASN1_TEMPLATE
),
371 .size
= sizeof(NOTICEREF
),
372 .sname
= "NOTICEREF",
377 d2i_NOTICEREF(NOTICEREF
**a
, const unsigned char **in
, long len
)
379 return (NOTICEREF
*)ASN1_item_d2i((ASN1_VALUE
**)a
, in
, len
,
384 i2d_NOTICEREF(NOTICEREF
*a
, unsigned char **out
)
386 return ASN1_item_i2d((ASN1_VALUE
*)a
, out
, &NOTICEREF_it
);
392 return (NOTICEREF
*)ASN1_item_new(&NOTICEREF_it
);
396 NOTICEREF_free(NOTICEREF
*a
)
398 ASN1_item_free((ASN1_VALUE
*)a
, &NOTICEREF_it
);
402 STACK_OF(POLICYINFO
) *r2i_certpol(X509V3_EXT_METHOD
*method
, X509V3_CTX
*ctx
,
405 STACK_OF(POLICYINFO
) *pols
= NULL
;
409 STACK_OF(CONF_VALUE
) *vals
;
413 pols
= sk_POLICYINFO_new_null();
415 X509V3err(X509V3_F_R2I_CERTPOL
, ERR_R_MALLOC_FAILURE
);
418 vals
= X509V3_parse_list(value
);
420 X509V3err(X509V3_F_R2I_CERTPOL
, ERR_R_X509V3_LIB
);
424 for (i
= 0; i
< sk_CONF_VALUE_num(vals
); i
++) {
425 cnf
= sk_CONF_VALUE_value(vals
, i
);
426 if (cnf
->value
|| !cnf
->name
) {
427 X509V3err(X509V3_F_R2I_CERTPOL
,
428 X509V3_R_INVALID_POLICY_IDENTIFIER
);
429 X509V3_conf_err(cnf
);
433 if (!strcmp(pstr
, "ia5org")) {
436 } else if (*pstr
== '@') {
437 STACK_OF(CONF_VALUE
) *polsect
;
438 polsect
= X509V3_get_section(ctx
, pstr
+ 1);
440 X509V3err(X509V3_F_R2I_CERTPOL
,
441 X509V3_R_INVALID_SECTION
);
442 X509V3_conf_err(cnf
);
445 pol
= policy_section(ctx
, polsect
, ia5org
);
446 X509V3_section_free(ctx
, polsect
);
450 if (!(pobj
= OBJ_txt2obj(cnf
->name
, 0))) {
451 X509V3err(X509V3_F_R2I_CERTPOL
,
452 X509V3_R_INVALID_OBJECT_IDENTIFIER
);
453 X509V3_conf_err(cnf
);
456 pol
= POLICYINFO_new();
457 pol
->policyid
= pobj
;
459 if (!sk_POLICYINFO_push(pols
, pol
)){
460 POLICYINFO_free(pol
);
461 X509V3err(X509V3_F_R2I_CERTPOL
, ERR_R_MALLOC_FAILURE
);
465 sk_CONF_VALUE_pop_free(vals
, X509V3_conf_free
);
469 sk_CONF_VALUE_pop_free(vals
, X509V3_conf_free
);
470 sk_POLICYINFO_pop_free(pols
, POLICYINFO_free
);
475 policy_section(X509V3_CTX
*ctx
, STACK_OF(CONF_VALUE
) *polstrs
, int ia5org
)
480 POLICYQUALINFO
*nqual
= NULL
;
482 if ((pol
= POLICYINFO_new()) == NULL
)
484 for (i
= 0; i
< sk_CONF_VALUE_num(polstrs
); i
++) {
485 cnf
= sk_CONF_VALUE_value(polstrs
, i
);
486 if (strcmp(cnf
->name
, "policyIdentifier") == 0) {
489 if ((pobj
= OBJ_txt2obj(cnf
->value
, 0)) == NULL
) {
490 X509V3err(X509V3_F_POLICY_SECTION
,
491 X509V3_R_INVALID_OBJECT_IDENTIFIER
);
492 X509V3_conf_err(cnf
);
495 pol
->policyid
= pobj
;
496 } else if (name_cmp(cnf
->name
, "CPS") == 0) {
497 if ((nqual
= POLICYQUALINFO_new()) == NULL
)
499 nqual
->pqualid
= OBJ_nid2obj(NID_id_qt_cps
);
500 nqual
->d
.cpsuri
= ASN1_IA5STRING_new();
501 if (nqual
->d
.cpsuri
== NULL
)
503 if (ASN1_STRING_set(nqual
->d
.cpsuri
, cnf
->value
,
504 strlen(cnf
->value
)) == 0)
507 if (pol
->qualifiers
== NULL
) {
508 pol
->qualifiers
= sk_POLICYQUALINFO_new_null();
509 if (pol
->qualifiers
== NULL
)
512 if (sk_POLICYQUALINFO_push(pol
->qualifiers
, nqual
) == 0)
515 } else if (name_cmp(cnf
->name
, "userNotice") == 0) {
516 STACK_OF(CONF_VALUE
) *unot
;
517 POLICYQUALINFO
*qual
;
519 if (*cnf
->value
!= '@') {
520 X509V3err(X509V3_F_POLICY_SECTION
,
521 X509V3_R_EXPECTED_A_SECTION_NAME
);
522 X509V3_conf_err(cnf
);
525 unot
= X509V3_get_section(ctx
, cnf
->value
+ 1);
527 X509V3err(X509V3_F_POLICY_SECTION
,
528 X509V3_R_INVALID_SECTION
);
529 X509V3_conf_err(cnf
);
532 qual
= notice_section(ctx
, unot
, ia5org
);
533 X509V3_section_free(ctx
, unot
);
537 if (pol
->qualifiers
== NULL
) {
538 pol
->qualifiers
= sk_POLICYQUALINFO_new_null();
539 if (pol
->qualifiers
== NULL
)
542 if (sk_POLICYQUALINFO_push(pol
->qualifiers
, qual
) == 0)
545 X509V3err(X509V3_F_POLICY_SECTION
,
546 X509V3_R_INVALID_OPTION
);
547 X509V3_conf_err(cnf
);
551 if (pol
->policyid
== NULL
) {
552 X509V3err(X509V3_F_POLICY_SECTION
,
553 X509V3_R_NO_POLICY_IDENTIFIER
);
560 X509V3err(X509V3_F_POLICY_SECTION
, ERR_R_MALLOC_FAILURE
);
563 POLICYQUALINFO_free(nqual
);
564 POLICYINFO_free(pol
);
568 static POLICYQUALINFO
*
569 notice_section(X509V3_CTX
*ctx
, STACK_OF(CONF_VALUE
) *unot
, int ia5org
)
574 POLICYQUALINFO
*qual
;
576 if (!(qual
= POLICYQUALINFO_new()))
578 qual
->pqualid
= OBJ_nid2obj(NID_id_qt_unotice
);
579 if (!(not = USERNOTICE_new()))
581 qual
->d
.usernotice
= not;
582 for (i
= 0; i
< sk_CONF_VALUE_num(unot
); i
++) {
583 cnf
= sk_CONF_VALUE_value(unot
, i
);
584 if (!strcmp(cnf
->name
, "explicitText")) {
585 if (not->exptext
== NULL
) {
586 not->exptext
= ASN1_VISIBLESTRING_new();
587 if (not->exptext
== NULL
)
590 if (!ASN1_STRING_set(not->exptext
, cnf
->value
,
593 } else if (!strcmp(cnf
->name
, "organization")) {
595 if (!not->noticeref
) {
596 if (!(nref
= NOTICEREF_new()))
598 not->noticeref
= nref
;
600 nref
= not->noticeref
;
602 nref
->organization
->type
= V_ASN1_IA5STRING
;
604 nref
->organization
->type
= V_ASN1_VISIBLESTRING
;
605 if (!ASN1_STRING_set(nref
->organization
, cnf
->value
,
608 } else if (!strcmp(cnf
->name
, "noticeNumbers")) {
610 STACK_OF(CONF_VALUE
) *nos
;
611 if (!not->noticeref
) {
612 if (!(nref
= NOTICEREF_new()))
614 not->noticeref
= nref
;
616 nref
= not->noticeref
;
617 nos
= X509V3_parse_list(cnf
->value
);
618 if (!nos
|| !sk_CONF_VALUE_num(nos
)) {
619 X509V3err(X509V3_F_NOTICE_SECTION
,
620 X509V3_R_INVALID_NUMBERS
);
621 X509V3_conf_err(cnf
);
623 sk_CONF_VALUE_pop_free(nos
,
627 ret
= nref_nos(nref
->noticenos
, nos
);
628 sk_CONF_VALUE_pop_free(nos
, X509V3_conf_free
);
632 X509V3err(X509V3_F_NOTICE_SECTION
,
633 X509V3_R_INVALID_OPTION
);
634 X509V3_conf_err(cnf
);
639 if (not->noticeref
&&
640 (!not->noticeref
->noticenos
|| !not->noticeref
->organization
)) {
641 X509V3err(X509V3_F_NOTICE_SECTION
,
642 X509V3_R_NEED_ORGANIZATION_AND_NUMBERS
);
649 X509V3err(X509V3_F_NOTICE_SECTION
, ERR_R_MALLOC_FAILURE
);
652 POLICYQUALINFO_free(qual
);
657 nref_nos(STACK_OF(ASN1_INTEGER
) *nnums
, STACK_OF(CONF_VALUE
) *nos
)
663 for (i
= 0; i
< sk_CONF_VALUE_num(nos
); i
++) {
664 cnf
= sk_CONF_VALUE_value(nos
, i
);
665 if (!(aint
= s2i_ASN1_INTEGER(NULL
, cnf
->name
))) {
666 X509V3err(X509V3_F_NREF_NOS
, X509V3_R_INVALID_NUMBER
);
669 if (!sk_ASN1_INTEGER_push(nnums
, aint
))
675 X509V3err(X509V3_F_NREF_NOS
, ERR_R_MALLOC_FAILURE
);
678 sk_ASN1_INTEGER_pop_free(nnums
, ASN1_STRING_free
);
683 i2r_certpol(X509V3_EXT_METHOD
*method
, STACK_OF(POLICYINFO
) *pol
, BIO
*out
,
689 /* First print out the policy OIDs */
690 for (i
= 0; i
< sk_POLICYINFO_num(pol
); i
++) {
691 pinfo
= sk_POLICYINFO_value(pol
, i
);
692 BIO_printf(out
, "%*sPolicy: ", indent
, "");
693 i2a_ASN1_OBJECT(out
, pinfo
->policyid
);
695 if (pinfo
->qualifiers
)
696 print_qualifiers(out
, pinfo
->qualifiers
, indent
+ 2);
702 print_qualifiers(BIO
*out
, STACK_OF(POLICYQUALINFO
) *quals
, int indent
)
704 POLICYQUALINFO
*qualinfo
;
707 for (i
= 0; i
< sk_POLICYQUALINFO_num(quals
); i
++) {
708 qualinfo
= sk_POLICYQUALINFO_value(quals
, i
);
709 switch (OBJ_obj2nid(qualinfo
->pqualid
)) {
711 BIO_printf(out
, "%*sCPS: %s\n", indent
, "",
712 qualinfo
->d
.cpsuri
->data
);
715 case NID_id_qt_unotice
:
716 BIO_printf(out
, "%*sUser Notice:\n", indent
, "");
717 print_notice(out
, qualinfo
->d
.usernotice
, indent
+ 2);
721 BIO_printf(out
, "%*sUnknown Qualifier: ",
724 i2a_ASN1_OBJECT(out
, qualinfo
->pqualid
);
732 print_notice(BIO
*out
, USERNOTICE
*notice
, int indent
)
736 if (notice
->noticeref
) {
738 ref
= notice
->noticeref
;
739 BIO_printf(out
, "%*sOrganization: %s\n", indent
, "",
740 ref
->organization
->data
);
741 BIO_printf(out
, "%*sNumber%s: ", indent
, "",
742 sk_ASN1_INTEGER_num(ref
->noticenos
) > 1 ? "s" : "");
743 for (i
= 0; i
< sk_ASN1_INTEGER_num(ref
->noticenos
); i
++) {
746 num
= sk_ASN1_INTEGER_value(ref
->noticenos
, i
);
749 tmp
= i2s_ASN1_INTEGER(NULL
, num
);
756 BIO_printf(out
, "%*sExplicit Text: %s\n", indent
, "",
757 notice
->exptext
->data
);
761 X509_POLICY_NODE_print(BIO
*out
, X509_POLICY_NODE
*node
, int indent
)
763 const X509_POLICY_DATA
*dat
= node
->data
;
765 BIO_printf(out
, "%*sPolicy: ", indent
, "");
767 i2a_ASN1_OBJECT(out
, dat
->valid_policy
);
769 BIO_printf(out
, "%*s%s\n", indent
+ 2, "",
770 node_data_critical(dat
) ? "Critical" : "Non Critical");
771 if (dat
->qualifier_set
)
772 print_qualifiers(out
, dat
->qualifier_set
, indent
+ 2);
774 BIO_printf(out
, "%*sNo Qualifiers\n", indent
+ 2, "");