v3_cpols.c revision 194206
155714Skris/* v3_cpols.c */ 2194206Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 355714Skris * project 1999. 455714Skris */ 555714Skris/* ==================================================================== 6160814Ssimon * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. 755714Skris * 855714Skris * Redistribution and use in source and binary forms, with or without 955714Skris * modification, are permitted provided that the following conditions 1055714Skris * are met: 1155714Skris * 1255714Skris * 1. Redistributions of source code must retain the above copyright 1355714Skris * notice, this list of conditions and the following disclaimer. 1455714Skris * 1555714Skris * 2. Redistributions in binary form must reproduce the above copyright 1655714Skris * notice, this list of conditions and the following disclaimer in 1755714Skris * the documentation and/or other materials provided with the 1855714Skris * distribution. 1955714Skris * 2055714Skris * 3. All advertising materials mentioning features or use of this 2155714Skris * software must display the following acknowledgment: 2255714Skris * "This product includes software developed by the OpenSSL Project 2355714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2455714Skris * 2555714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2655714Skris * endorse or promote products derived from this software without 2755714Skris * prior written permission. For written permission, please contact 2855714Skris * licensing@OpenSSL.org. 2955714Skris * 3055714Skris * 5. Products derived from this software may not be called "OpenSSL" 3155714Skris * nor may "OpenSSL" appear in their names without prior written 3255714Skris * permission of the OpenSSL Project. 3355714Skris * 3455714Skris * 6. Redistributions of any form whatsoever must retain the following 3555714Skris * acknowledgment: 3655714Skris * "This product includes software developed by the OpenSSL Project 3755714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3855714Skris * 3955714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4055714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4155714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4255714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4355714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4455714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4555714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4655714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4755714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4855714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4955714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5055714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5155714Skris * ==================================================================== 5255714Skris * 5355714Skris * This product includes cryptographic software written by Eric Young 5455714Skris * (eay@cryptsoft.com). This product includes software written by Tim 5555714Skris * Hudson (tjh@cryptsoft.com). 5655714Skris * 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include "cryptlib.h" 6155714Skris#include <openssl/conf.h> 6255714Skris#include <openssl/asn1.h> 63109998Smarkm#include <openssl/asn1t.h> 6455714Skris#include <openssl/x509v3.h> 6555714Skris 66160814Ssimon#include "pcy_int.h" 67160814Ssimon 6855714Skris/* Certificate policies extension support: this one is a bit complex... */ 6955714Skris 7055714Skrisstatic int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent); 7155714Skrisstatic STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value); 7255714Skrisstatic void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent); 7355714Skrisstatic void print_notice(BIO *out, USERNOTICE *notice, int indent); 7455714Skrisstatic POLICYINFO *policy_section(X509V3_CTX *ctx, 7555714Skris STACK_OF(CONF_VALUE) *polstrs, int ia5org); 7655714Skrisstatic POLICYQUALINFO *notice_section(X509V3_CTX *ctx, 7755714Skris STACK_OF(CONF_VALUE) *unot, int ia5org); 78120631Snectarstatic int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); 7955714Skris 80167612Ssimonconst X509V3_EXT_METHOD v3_cpols = { 81109998SmarkmNID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES), 82109998Smarkm0,0,0,0, 83109998Smarkm0,0, 84109998Smarkm0,0, 8555714Skris(X509V3_EXT_I2R)i2r_certpol, 8655714Skris(X509V3_EXT_R2I)r2i_certpol, 8755714SkrisNULL 8855714Skris}; 8955714Skris 90109998SmarkmASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = 91109998Smarkm ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO) 92109998SmarkmASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES) 9355714Skris 94109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) 95109998Smarkm 96109998SmarkmASN1_SEQUENCE(POLICYINFO) = { 97109998Smarkm ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), 98109998Smarkm ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO) 99109998Smarkm} ASN1_SEQUENCE_END(POLICYINFO) 100109998Smarkm 101109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(POLICYINFO) 102109998Smarkm 103109998SmarkmASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY); 104109998Smarkm 105109998SmarkmASN1_ADB(POLICYQUALINFO) = { 106109998Smarkm ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)), 107109998Smarkm ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)) 108109998Smarkm} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL); 109109998Smarkm 110109998SmarkmASN1_SEQUENCE(POLICYQUALINFO) = { 111109998Smarkm ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), 112109998Smarkm ASN1_ADB_OBJECT(POLICYQUALINFO) 113109998Smarkm} ASN1_SEQUENCE_END(POLICYQUALINFO) 114109998Smarkm 115109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO) 116109998Smarkm 117109998SmarkmASN1_SEQUENCE(USERNOTICE) = { 118109998Smarkm ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), 119109998Smarkm ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT) 120109998Smarkm} ASN1_SEQUENCE_END(USERNOTICE) 121109998Smarkm 122109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(USERNOTICE) 123109998Smarkm 124109998SmarkmASN1_SEQUENCE(NOTICEREF) = { 125109998Smarkm ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), 126109998Smarkm ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER) 127109998Smarkm} ASN1_SEQUENCE_END(NOTICEREF) 128109998Smarkm 129109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(NOTICEREF) 130109998Smarkm 13155714Skrisstatic STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, 13255714Skris X509V3_CTX *ctx, char *value) 13355714Skris{ 13455714Skris STACK_OF(POLICYINFO) *pols = NULL; 13555714Skris char *pstr; 13655714Skris POLICYINFO *pol; 13755714Skris ASN1_OBJECT *pobj; 13855714Skris STACK_OF(CONF_VALUE) *vals; 13955714Skris CONF_VALUE *cnf; 14055714Skris int i, ia5org; 14155714Skris pols = sk_POLICYINFO_new_null(); 142160814Ssimon if (pols == NULL) { 143160814Ssimon X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); 144160814Ssimon return NULL; 145160814Ssimon } 14655714Skris vals = X509V3_parse_list(value); 147160814Ssimon if (vals == NULL) { 148160814Ssimon X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB); 149160814Ssimon goto err; 150160814Ssimon } 15155714Skris ia5org = 0; 15255714Skris for(i = 0; i < sk_CONF_VALUE_num(vals); i++) { 15355714Skris cnf = sk_CONF_VALUE_value(vals, i); 15455714Skris if(cnf->value || !cnf->name ) { 15555714Skris X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_POLICY_IDENTIFIER); 15655714Skris X509V3_conf_err(cnf); 15755714Skris goto err; 15855714Skris } 15955714Skris pstr = cnf->name; 16055714Skris if(!strcmp(pstr,"ia5org")) { 16155714Skris ia5org = 1; 16255714Skris continue; 16355714Skris } else if(*pstr == '@') { 16455714Skris STACK_OF(CONF_VALUE) *polsect; 16555714Skris polsect = X509V3_get_section(ctx, pstr + 1); 16655714Skris if(!polsect) { 16755714Skris X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_SECTION); 16855714Skris 16955714Skris X509V3_conf_err(cnf); 17055714Skris goto err; 17155714Skris } 17255714Skris pol = policy_section(ctx, polsect, ia5org); 17355714Skris X509V3_section_free(ctx, polsect); 17455714Skris if(!pol) goto err; 17555714Skris } else { 17655714Skris if(!(pobj = OBJ_txt2obj(cnf->name, 0))) { 17755714Skris X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER); 17855714Skris X509V3_conf_err(cnf); 17955714Skris goto err; 18055714Skris } 18155714Skris pol = POLICYINFO_new(); 18255714Skris pol->policyid = pobj; 18355714Skris } 184194206Ssimon if (!sk_POLICYINFO_push(pols, pol)){ 185194206Ssimon POLICYINFO_free(pol); 186194206Ssimon X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); 187194206Ssimon goto err; 188194206Ssimon } 18955714Skris } 19055714Skris sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 19155714Skris return pols; 19255714Skris err: 193160814Ssimon sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 19455714Skris sk_POLICYINFO_pop_free(pols, POLICYINFO_free); 19555714Skris return NULL; 19655714Skris} 19755714Skris 19855714Skrisstatic POLICYINFO *policy_section(X509V3_CTX *ctx, 19955714Skris STACK_OF(CONF_VALUE) *polstrs, int ia5org) 20055714Skris{ 20155714Skris int i; 20255714Skris CONF_VALUE *cnf; 20355714Skris POLICYINFO *pol; 20455714Skris POLICYQUALINFO *qual; 20555714Skris if(!(pol = POLICYINFO_new())) goto merr; 20655714Skris for(i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { 20755714Skris cnf = sk_CONF_VALUE_value(polstrs, i); 20855714Skris if(!strcmp(cnf->name, "policyIdentifier")) { 20955714Skris ASN1_OBJECT *pobj; 21055714Skris if(!(pobj = OBJ_txt2obj(cnf->value, 0))) { 21155714Skris X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OBJECT_IDENTIFIER); 21255714Skris X509V3_conf_err(cnf); 21355714Skris goto err; 21455714Skris } 21555714Skris pol->policyid = pobj; 21655714Skris 21755714Skris } else if(!name_cmp(cnf->name, "CPS")) { 21855714Skris if(!pol->qualifiers) pol->qualifiers = 21955714Skris sk_POLICYQUALINFO_new_null(); 22055714Skris if(!(qual = POLICYQUALINFO_new())) goto merr; 22155714Skris if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) 22255714Skris goto merr; 22355714Skris qual->pqualid = OBJ_nid2obj(NID_id_qt_cps); 22459191Skris qual->d.cpsuri = M_ASN1_IA5STRING_new(); 22555714Skris if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value, 22655714Skris strlen(cnf->value))) goto merr; 22755714Skris } else if(!name_cmp(cnf->name, "userNotice")) { 22855714Skris STACK_OF(CONF_VALUE) *unot; 22955714Skris if(*cnf->value != '@') { 23055714Skris X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_EXPECTED_A_SECTION_NAME); 23155714Skris X509V3_conf_err(cnf); 23255714Skris goto err; 23355714Skris } 23455714Skris unot = X509V3_get_section(ctx, cnf->value + 1); 23555714Skris if(!unot) { 23655714Skris X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_SECTION); 23755714Skris 23855714Skris X509V3_conf_err(cnf); 23955714Skris goto err; 24055714Skris } 24155714Skris qual = notice_section(ctx, unot, ia5org); 24255714Skris X509V3_section_free(ctx, unot); 24355714Skris if(!qual) goto err; 244120631Snectar if(!pol->qualifiers) pol->qualifiers = 245120631Snectar sk_POLICYQUALINFO_new_null(); 24655714Skris if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) 24755714Skris goto merr; 24855714Skris } else { 24955714Skris X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OPTION); 25055714Skris 25155714Skris X509V3_conf_err(cnf); 25255714Skris goto err; 25355714Skris } 25455714Skris } 25555714Skris if(!pol->policyid) { 25655714Skris X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_NO_POLICY_IDENTIFIER); 25755714Skris goto err; 25855714Skris } 25955714Skris 26055714Skris return pol; 26155714Skris 26255714Skris merr: 26355714Skris X509V3err(X509V3_F_POLICY_SECTION,ERR_R_MALLOC_FAILURE); 26455714Skris 26555714Skris err: 26655714Skris POLICYINFO_free(pol); 26755714Skris return NULL; 26855714Skris 26955714Skris 27055714Skris} 27155714Skris 27255714Skrisstatic POLICYQUALINFO *notice_section(X509V3_CTX *ctx, 27355714Skris STACK_OF(CONF_VALUE) *unot, int ia5org) 27455714Skris{ 275120631Snectar int i, ret; 27655714Skris CONF_VALUE *cnf; 27755714Skris USERNOTICE *not; 27855714Skris POLICYQUALINFO *qual; 27955714Skris if(!(qual = POLICYQUALINFO_new())) goto merr; 28055714Skris qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice); 28155714Skris if(!(not = USERNOTICE_new())) goto merr; 28255714Skris qual->d.usernotice = not; 28355714Skris for(i = 0; i < sk_CONF_VALUE_num(unot); i++) { 28455714Skris cnf = sk_CONF_VALUE_value(unot, i); 28555714Skris if(!strcmp(cnf->name, "explicitText")) { 28659191Skris not->exptext = M_ASN1_VISIBLESTRING_new(); 28755714Skris if(!ASN1_STRING_set(not->exptext, cnf->value, 28855714Skris strlen(cnf->value))) goto merr; 28955714Skris } else if(!strcmp(cnf->name, "organization")) { 29055714Skris NOTICEREF *nref; 29155714Skris if(!not->noticeref) { 29255714Skris if(!(nref = NOTICEREF_new())) goto merr; 29355714Skris not->noticeref = nref; 29455714Skris } else nref = not->noticeref; 295120631Snectar if(ia5org) nref->organization->type = V_ASN1_IA5STRING; 296120631Snectar else nref->organization->type = V_ASN1_VISIBLESTRING; 29755714Skris if(!ASN1_STRING_set(nref->organization, cnf->value, 29855714Skris strlen(cnf->value))) goto merr; 29955714Skris } else if(!strcmp(cnf->name, "noticeNumbers")) { 30055714Skris NOTICEREF *nref; 30155714Skris STACK_OF(CONF_VALUE) *nos; 30255714Skris if(!not->noticeref) { 30355714Skris if(!(nref = NOTICEREF_new())) goto merr; 30455714Skris not->noticeref = nref; 30555714Skris } else nref = not->noticeref; 30655714Skris nos = X509V3_parse_list(cnf->value); 30755714Skris if(!nos || !sk_CONF_VALUE_num(nos)) { 30855714Skris X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_NUMBERS); 30955714Skris X509V3_conf_err(cnf); 31055714Skris goto err; 31155714Skris } 312120631Snectar ret = nref_nos(nref->noticenos, nos); 31355714Skris sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); 314120631Snectar if (!ret) 315120631Snectar goto err; 31655714Skris } else { 31755714Skris X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_OPTION); 31855714Skris X509V3_conf_err(cnf); 31955714Skris goto err; 32055714Skris } 32155714Skris } 32255714Skris 32355714Skris if(not->noticeref && 32455714Skris (!not->noticeref->noticenos || !not->noticeref->organization)) { 32555714Skris X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); 32655714Skris goto err; 32755714Skris } 32855714Skris 32955714Skris return qual; 33055714Skris 33155714Skris merr: 33255714Skris X509V3err(X509V3_F_NOTICE_SECTION,ERR_R_MALLOC_FAILURE); 33355714Skris 33455714Skris err: 33555714Skris POLICYQUALINFO_free(qual); 33655714Skris return NULL; 33755714Skris} 33855714Skris 339120631Snectarstatic int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) 34055714Skris{ 34155714Skris CONF_VALUE *cnf; 34255714Skris ASN1_INTEGER *aint; 34368651Skris 34455714Skris int i; 34568651Skris 34655714Skris for(i = 0; i < sk_CONF_VALUE_num(nos); i++) { 34755714Skris cnf = sk_CONF_VALUE_value(nos, i); 34855714Skris if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { 34955714Skris X509V3err(X509V3_F_NREF_NOS,X509V3_R_INVALID_NUMBER); 35055714Skris goto err; 35155714Skris } 35268651Skris if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr; 35355714Skris } 354120631Snectar return 1; 35555714Skris 35655714Skris merr: 357160814Ssimon X509V3err(X509V3_F_NREF_NOS,ERR_R_MALLOC_FAILURE); 35855714Skris 35955714Skris err: 36068651Skris sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free); 361120631Snectar return 0; 36255714Skris} 36355714Skris 36455714Skris 36555714Skrisstatic int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, 36655714Skris BIO *out, int indent) 36755714Skris{ 36855714Skris int i; 36955714Skris POLICYINFO *pinfo; 37055714Skris /* First print out the policy OIDs */ 37155714Skris for(i = 0; i < sk_POLICYINFO_num(pol); i++) { 37255714Skris pinfo = sk_POLICYINFO_value(pol, i); 37355714Skris BIO_printf(out, "%*sPolicy: ", indent, ""); 37455714Skris i2a_ASN1_OBJECT(out, pinfo->policyid); 37555714Skris BIO_puts(out, "\n"); 37655714Skris if(pinfo->qualifiers) 37755714Skris print_qualifiers(out, pinfo->qualifiers, indent + 2); 37855714Skris } 37955714Skris return 1; 38055714Skris} 38155714Skris 38255714Skrisstatic void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, 38355714Skris int indent) 38455714Skris{ 38555714Skris POLICYQUALINFO *qualinfo; 38655714Skris int i; 38755714Skris for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { 38855714Skris qualinfo = sk_POLICYQUALINFO_value(quals, i); 38955714Skris switch(OBJ_obj2nid(qualinfo->pqualid)) 39055714Skris { 39155714Skris case NID_id_qt_cps: 39255714Skris BIO_printf(out, "%*sCPS: %s\n", indent, "", 39355714Skris qualinfo->d.cpsuri->data); 39455714Skris break; 39555714Skris 39655714Skris case NID_id_qt_unotice: 39755714Skris BIO_printf(out, "%*sUser Notice:\n", indent, ""); 39855714Skris print_notice(out, qualinfo->d.usernotice, indent + 2); 39955714Skris break; 40055714Skris 40155714Skris default: 40255714Skris BIO_printf(out, "%*sUnknown Qualifier: ", 40355714Skris indent + 2, ""); 40455714Skris 40555714Skris i2a_ASN1_OBJECT(out, qualinfo->pqualid); 40655714Skris BIO_puts(out, "\n"); 40755714Skris break; 40855714Skris } 40955714Skris } 41055714Skris} 41155714Skris 41255714Skrisstatic void print_notice(BIO *out, USERNOTICE *notice, int indent) 41355714Skris{ 41455714Skris int i; 41555714Skris if(notice->noticeref) { 41655714Skris NOTICEREF *ref; 41755714Skris ref = notice->noticeref; 41855714Skris BIO_printf(out, "%*sOrganization: %s\n", indent, "", 41955714Skris ref->organization->data); 42055714Skris BIO_printf(out, "%*sNumber%s: ", indent, "", 42168651Skris sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); 42268651Skris for(i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { 42355714Skris ASN1_INTEGER *num; 42455714Skris char *tmp; 42568651Skris num = sk_ASN1_INTEGER_value(ref->noticenos, i); 42655714Skris if(i) BIO_puts(out, ", "); 42755714Skris tmp = i2s_ASN1_INTEGER(NULL, num); 42855714Skris BIO_puts(out, tmp); 42968651Skris OPENSSL_free(tmp); 43055714Skris } 43155714Skris BIO_puts(out, "\n"); 43255714Skris } 43355714Skris if(notice->exptext) 43455714Skris BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", 43555714Skris notice->exptext->data); 43655714Skris} 43755714Skris 438160814Ssimonvoid X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) 439160814Ssimon { 440160814Ssimon const X509_POLICY_DATA *dat = node->data; 441160814Ssimon 442160814Ssimon BIO_printf(out, "%*sPolicy: ", indent, ""); 443160814Ssimon 444160814Ssimon i2a_ASN1_OBJECT(out, dat->valid_policy); 445160814Ssimon BIO_puts(out, "\n"); 446160814Ssimon BIO_printf(out, "%*s%s\n", indent + 2, "", 447160814Ssimon node_data_critical(dat) ? "Critical" : "Non Critical"); 448160814Ssimon if (dat->qualifier_set) 449160814Ssimon print_qualifiers(out, dat->qualifier_set, indent + 2); 450160814Ssimon else 451160814Ssimon BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); 452160814Ssimon } 453160814Ssimon 454194206SsimonIMPLEMENT_STACK_OF(X509_POLICY_NODE) 455