os/ossrv/ssl/libcrypto/src/crypto/x509v3/v3_cpols.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* v3_cpols.c */
sl@0
     2
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
sl@0
     3
 * project 1999.
sl@0
     4
 */
sl@0
     5
/* ====================================================================
sl@0
     6
 * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
sl@0
     7
 *
sl@0
     8
 * Redistribution and use in source and binary forms, with or without
sl@0
     9
 * modification, are permitted provided that the following conditions
sl@0
    10
 * are met:
sl@0
    11
 *
sl@0
    12
 * 1. Redistributions of source code must retain the above copyright
sl@0
    13
 *    notice, this list of conditions and the following disclaimer. 
sl@0
    14
 *
sl@0
    15
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    16
 *    notice, this list of conditions and the following disclaimer in
sl@0
    17
 *    the documentation and/or other materials provided with the
sl@0
    18
 *    distribution.
sl@0
    19
 *
sl@0
    20
 * 3. All advertising materials mentioning features or use of this
sl@0
    21
 *    software must display the following acknowledgment:
sl@0
    22
 *    "This product includes software developed by the OpenSSL Project
sl@0
    23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
sl@0
    24
 *
sl@0
    25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
sl@0
    26
 *    endorse or promote products derived from this software without
sl@0
    27
 *    prior written permission. For written permission, please contact
sl@0
    28
 *    licensing@OpenSSL.org.
sl@0
    29
 *
sl@0
    30
 * 5. Products derived from this software may not be called "OpenSSL"
sl@0
    31
 *    nor may "OpenSSL" appear in their names without prior written
sl@0
    32
 *    permission of the OpenSSL Project.
sl@0
    33
 *
sl@0
    34
 * 6. Redistributions of any form whatsoever must retain the following
sl@0
    35
 *    acknowledgment:
sl@0
    36
 *    "This product includes software developed by the OpenSSL Project
sl@0
    37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
sl@0
    38
 *
sl@0
    39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
sl@0
    40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sl@0
    42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
sl@0
    43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
sl@0
    44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
sl@0
    45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
sl@0
    46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sl@0
    48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
sl@0
    49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
sl@0
    50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
sl@0
    51
 * ====================================================================
sl@0
    52
 *
sl@0
    53
 * This product includes cryptographic software written by Eric Young
sl@0
    54
 * (eay@cryptsoft.com).  This product includes software written by Tim
sl@0
    55
 * Hudson (tjh@cryptsoft.com).
sl@0
    56
 *
sl@0
    57
 */
sl@0
    58
/*
sl@0
    59
 © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
sl@0
    60
 */
sl@0
    61
sl@0
    62
sl@0
    63
#include <stdio.h>
sl@0
    64
#include "cryptlib.h"
sl@0
    65
#include <openssl/conf.h>
sl@0
    66
#include <openssl/asn1.h>
sl@0
    67
#include <openssl/asn1t.h>
sl@0
    68
#include <openssl/x509v3.h>
sl@0
    69
sl@0
    70
#include "pcy_int.h"
sl@0
    71
#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
sl@0
    72
#include "libcrypto_wsd_macros.h"
sl@0
    73
#include "libcrypto_wsd.h"
sl@0
    74
#endif
sl@0
    75
sl@0
    76
/* Certificate policies extension support: this one is a bit complex... */
sl@0
    77
sl@0
    78
static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent);
sl@0
    79
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value);
sl@0
    80
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent);
sl@0
    81
static void print_notice(BIO *out, USERNOTICE *notice, int indent);
sl@0
    82
static POLICYINFO *policy_section(X509V3_CTX *ctx,
sl@0
    83
				 STACK_OF(CONF_VALUE) *polstrs, int ia5org);
sl@0
    84
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
sl@0
    85
					STACK_OF(CONF_VALUE) *unot, int ia5org);
sl@0
    86
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
sl@0
    87
sl@0
    88
#ifndef EMULATOR
sl@0
    89
X509V3_EXT_METHOD v3_cpols = {
sl@0
    90
NID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES),
sl@0
    91
0,0,0,0,
sl@0
    92
0,0,
sl@0
    93
0,0,
sl@0
    94
(X509V3_EXT_I2R)i2r_certpol,
sl@0
    95
(X509V3_EXT_R2I)r2i_certpol,
sl@0
    96
NULL
sl@0
    97
};
sl@0
    98
#else
sl@0
    99
const X509V3_EXT_METHOD v3_cpols = {
sl@0
   100
NID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES),
sl@0
   101
0,0,0,0,
sl@0
   102
0,0,
sl@0
   103
0,0,
sl@0
   104
(X509V3_EXT_I2R)i2r_certpol,
sl@0
   105
(X509V3_EXT_R2I)r2i_certpol,
sl@0
   106
NULL
sl@0
   107
};
sl@0
   108
#endif
sl@0
   109
ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = 
sl@0
   110
	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
sl@0
   111
ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)
sl@0
   112
sl@0
   113
IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
sl@0
   114
sl@0
   115
ASN1_SEQUENCE(POLICYINFO) = {
sl@0
   116
	ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
sl@0
   117
	ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
sl@0
   118
} ASN1_SEQUENCE_END(POLICYINFO)
sl@0
   119
sl@0
   120
IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
sl@0
   121
sl@0
   122
ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY);
sl@0
   123
sl@0
   124
ASN1_ADB(POLICYQUALINFO) = {
sl@0
   125
	ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
sl@0
   126
	ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
sl@0
   127
} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);
sl@0
   128
sl@0
   129
ASN1_SEQUENCE(POLICYQUALINFO) = {
sl@0
   130
	ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
sl@0
   131
	ASN1_ADB_OBJECT(POLICYQUALINFO)
sl@0
   132
} ASN1_SEQUENCE_END(POLICYQUALINFO)
sl@0
   133
sl@0
   134
IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)
sl@0
   135
sl@0
   136
ASN1_SEQUENCE(USERNOTICE) = {
sl@0
   137
	ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
sl@0
   138
	ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
sl@0
   139
} ASN1_SEQUENCE_END(USERNOTICE)
sl@0
   140
sl@0
   141
IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)
sl@0
   142
sl@0
   143
ASN1_SEQUENCE(NOTICEREF) = {
sl@0
   144
	ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
sl@0
   145
	ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
sl@0
   146
} ASN1_SEQUENCE_END(NOTICEREF)
sl@0
   147
sl@0
   148
IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
sl@0
   149
sl@0
   150
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
sl@0
   151
		X509V3_CTX *ctx, char *value)
sl@0
   152
{
sl@0
   153
	STACK_OF(POLICYINFO) *pols = NULL;
sl@0
   154
	char *pstr;
sl@0
   155
	POLICYINFO *pol;
sl@0
   156
	ASN1_OBJECT *pobj;
sl@0
   157
	STACK_OF(CONF_VALUE) *vals;
sl@0
   158
	CONF_VALUE *cnf;
sl@0
   159
	int i, ia5org;
sl@0
   160
	pols = sk_POLICYINFO_new_null();
sl@0
   161
	if (pols == NULL) {
sl@0
   162
		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
sl@0
   163
		return NULL;
sl@0
   164
	}
sl@0
   165
	vals =  X509V3_parse_list(value);
sl@0
   166
	if (vals == NULL) {
sl@0
   167
		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
sl@0
   168
		goto err;
sl@0
   169
	}
sl@0
   170
	ia5org = 0;
sl@0
   171
	for(i = 0; i < sk_CONF_VALUE_num(vals); i++) {
sl@0
   172
		cnf = sk_CONF_VALUE_value(vals, i);
sl@0
   173
		if(cnf->value || !cnf->name ) {
sl@0
   174
			X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_POLICY_IDENTIFIER);
sl@0
   175
			X509V3_conf_err(cnf);
sl@0
   176
			goto err;
sl@0
   177
		}
sl@0
   178
		pstr = cnf->name;
sl@0
   179
		if(!strcmp(pstr,"ia5org")) {
sl@0
   180
			ia5org = 1;
sl@0
   181
			continue;
sl@0
   182
		} else if(*pstr == '@') {
sl@0
   183
			STACK_OF(CONF_VALUE) *polsect;
sl@0
   184
			polsect = X509V3_get_section(ctx, pstr + 1);
sl@0
   185
			if(!polsect) {
sl@0
   186
				X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_SECTION);
sl@0
   187
sl@0
   188
				X509V3_conf_err(cnf);
sl@0
   189
				goto err;
sl@0
   190
			}
sl@0
   191
			pol = policy_section(ctx, polsect, ia5org);
sl@0
   192
			X509V3_section_free(ctx, polsect);
sl@0
   193
			if(!pol) goto err;
sl@0
   194
		} else {
sl@0
   195
			if(!(pobj = OBJ_txt2obj(cnf->name, 0))) {
sl@0
   196
				X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER);
sl@0
   197
				X509V3_conf_err(cnf);
sl@0
   198
				goto err;
sl@0
   199
			}
sl@0
   200
			pol = POLICYINFO_new();
sl@0
   201
			pol->policyid = pobj;
sl@0
   202
		}
sl@0
   203
		sk_POLICYINFO_push(pols, pol);
sl@0
   204
	}
sl@0
   205
	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
sl@0
   206
	return pols;
sl@0
   207
	err:
sl@0
   208
	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
sl@0
   209
	sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
sl@0
   210
	return NULL;
sl@0
   211
}
sl@0
   212
sl@0
   213
static POLICYINFO *policy_section(X509V3_CTX *ctx,
sl@0
   214
				STACK_OF(CONF_VALUE) *polstrs, int ia5org)
sl@0
   215
{
sl@0
   216
	int i;
sl@0
   217
	CONF_VALUE *cnf;
sl@0
   218
	POLICYINFO *pol;
sl@0
   219
	POLICYQUALINFO *qual;
sl@0
   220
	if(!(pol = POLICYINFO_new())) goto merr;
sl@0
   221
	for(i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
sl@0
   222
		cnf = sk_CONF_VALUE_value(polstrs, i);
sl@0
   223
		if(!strcmp(cnf->name, "policyIdentifier")) {
sl@0
   224
			ASN1_OBJECT *pobj;
sl@0
   225
			if(!(pobj = OBJ_txt2obj(cnf->value, 0))) {
sl@0
   226
				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OBJECT_IDENTIFIER);
sl@0
   227
				X509V3_conf_err(cnf);
sl@0
   228
				goto err;
sl@0
   229
			}
sl@0
   230
			pol->policyid = pobj;
sl@0
   231
sl@0
   232
		} else if(!name_cmp(cnf->name, "CPS")) {
sl@0
   233
			if(!pol->qualifiers) pol->qualifiers =
sl@0
   234
						 sk_POLICYQUALINFO_new_null();
sl@0
   235
			if(!(qual = POLICYQUALINFO_new())) goto merr;
sl@0
   236
			if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
sl@0
   237
								 goto merr;
sl@0
   238
			qual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
sl@0
   239
			qual->d.cpsuri = M_ASN1_IA5STRING_new();
sl@0
   240
			if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
sl@0
   241
						 strlen(cnf->value))) goto merr;
sl@0
   242
		} else if(!name_cmp(cnf->name, "userNotice")) {
sl@0
   243
			STACK_OF(CONF_VALUE) *unot;
sl@0
   244
			if(*cnf->value != '@') {
sl@0
   245
				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_EXPECTED_A_SECTION_NAME);
sl@0
   246
				X509V3_conf_err(cnf);
sl@0
   247
				goto err;
sl@0
   248
			}
sl@0
   249
			unot = X509V3_get_section(ctx, cnf->value + 1);
sl@0
   250
			if(!unot) {
sl@0
   251
				X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_SECTION);
sl@0
   252
sl@0
   253
				X509V3_conf_err(cnf);
sl@0
   254
				goto err;
sl@0
   255
			}
sl@0
   256
			qual = notice_section(ctx, unot, ia5org);
sl@0
   257
			X509V3_section_free(ctx, unot);
sl@0
   258
			if(!qual) goto err;
sl@0
   259
			if(!pol->qualifiers) pol->qualifiers =
sl@0
   260
						 sk_POLICYQUALINFO_new_null();
sl@0
   261
			if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
sl@0
   262
								 goto merr;
sl@0
   263
		} else {
sl@0
   264
			X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OPTION);
sl@0
   265
sl@0
   266
			X509V3_conf_err(cnf);
sl@0
   267
			goto err;
sl@0
   268
		}
sl@0
   269
	}
sl@0
   270
	if(!pol->policyid) {
sl@0
   271
		X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_NO_POLICY_IDENTIFIER);
sl@0
   272
		goto err;
sl@0
   273
	}
sl@0
   274
sl@0
   275
	return pol;
sl@0
   276
sl@0
   277
	merr:
sl@0
   278
	X509V3err(X509V3_F_POLICY_SECTION,ERR_R_MALLOC_FAILURE);
sl@0
   279
sl@0
   280
	err:
sl@0
   281
	POLICYINFO_free(pol);
sl@0
   282
	return NULL;
sl@0
   283
	
sl@0
   284
	
sl@0
   285
}
sl@0
   286
sl@0
   287
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
sl@0
   288
					STACK_OF(CONF_VALUE) *unot, int ia5org)
sl@0
   289
{
sl@0
   290
	int i, ret;
sl@0
   291
	CONF_VALUE *cnf;
sl@0
   292
	USERNOTICE *not;
sl@0
   293
	POLICYQUALINFO *qual;
sl@0
   294
	if(!(qual = POLICYQUALINFO_new())) goto merr;
sl@0
   295
	qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
sl@0
   296
	if(!(not = USERNOTICE_new())) goto merr;
sl@0
   297
	qual->d.usernotice = not;
sl@0
   298
	for(i = 0; i < sk_CONF_VALUE_num(unot); i++) {
sl@0
   299
		cnf = sk_CONF_VALUE_value(unot, i);
sl@0
   300
		if(!strcmp(cnf->name, "explicitText")) {
sl@0
   301
			not->exptext = M_ASN1_VISIBLESTRING_new();
sl@0
   302
			if(!ASN1_STRING_set(not->exptext, cnf->value,
sl@0
   303
						 strlen(cnf->value))) goto merr;
sl@0
   304
		} else if(!strcmp(cnf->name, "organization")) {
sl@0
   305
			NOTICEREF *nref;
sl@0
   306
			if(!not->noticeref) {
sl@0
   307
				if(!(nref = NOTICEREF_new())) goto merr;
sl@0
   308
				not->noticeref = nref;
sl@0
   309
			} else nref = not->noticeref;
sl@0
   310
			if(ia5org) nref->organization->type = V_ASN1_IA5STRING;
sl@0
   311
			else nref->organization->type = V_ASN1_VISIBLESTRING;
sl@0
   312
			if(!ASN1_STRING_set(nref->organization, cnf->value,
sl@0
   313
						 strlen(cnf->value))) goto merr;
sl@0
   314
		} else if(!strcmp(cnf->name, "noticeNumbers")) {
sl@0
   315
			NOTICEREF *nref;
sl@0
   316
			STACK_OF(CONF_VALUE) *nos;
sl@0
   317
			if(!not->noticeref) {
sl@0
   318
				if(!(nref = NOTICEREF_new())) goto merr;
sl@0
   319
				not->noticeref = nref;
sl@0
   320
			} else nref = not->noticeref;
sl@0
   321
			nos = X509V3_parse_list(cnf->value);
sl@0
   322
			if(!nos || !sk_CONF_VALUE_num(nos)) {
sl@0
   323
				X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_NUMBERS);
sl@0
   324
				X509V3_conf_err(cnf);
sl@0
   325
				goto err;
sl@0
   326
			}
sl@0
   327
			ret = nref_nos(nref->noticenos, nos);
sl@0
   328
			sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
sl@0
   329
			if (!ret)
sl@0
   330
				goto err;
sl@0
   331
		} else {
sl@0
   332
			X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_OPTION);
sl@0
   333
			X509V3_conf_err(cnf);
sl@0
   334
			goto err;
sl@0
   335
		}
sl@0
   336
	}
sl@0
   337
sl@0
   338
	if(not->noticeref && 
sl@0
   339
	      (!not->noticeref->noticenos || !not->noticeref->organization)) {
sl@0
   340
			X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
sl@0
   341
			goto err;
sl@0
   342
	}
sl@0
   343
sl@0
   344
	return qual;
sl@0
   345
sl@0
   346
	merr:
sl@0
   347
	X509V3err(X509V3_F_NOTICE_SECTION,ERR_R_MALLOC_FAILURE);
sl@0
   348
sl@0
   349
	err:
sl@0
   350
	POLICYQUALINFO_free(qual);
sl@0
   351
	return NULL;
sl@0
   352
}
sl@0
   353
sl@0
   354
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
sl@0
   355
{
sl@0
   356
	CONF_VALUE *cnf;
sl@0
   357
	ASN1_INTEGER *aint;
sl@0
   358
sl@0
   359
	int i;
sl@0
   360
sl@0
   361
	for(i = 0; i < sk_CONF_VALUE_num(nos); i++) {
sl@0
   362
		cnf = sk_CONF_VALUE_value(nos, i);
sl@0
   363
		if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
sl@0
   364
			X509V3err(X509V3_F_NREF_NOS,X509V3_R_INVALID_NUMBER);
sl@0
   365
			goto err;
sl@0
   366
		}
sl@0
   367
		if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
sl@0
   368
	}
sl@0
   369
	return 1;
sl@0
   370
sl@0
   371
	merr:
sl@0
   372
	X509V3err(X509V3_F_NREF_NOS,ERR_R_MALLOC_FAILURE);
sl@0
   373
sl@0
   374
	err:
sl@0
   375
	sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
sl@0
   376
	return 0;
sl@0
   377
}
sl@0
   378
sl@0
   379
sl@0
   380
static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
sl@0
   381
		BIO *out, int indent)
sl@0
   382
{
sl@0
   383
	int i;
sl@0
   384
	POLICYINFO *pinfo;
sl@0
   385
	/* First print out the policy OIDs */
sl@0
   386
	for(i = 0; i < sk_POLICYINFO_num(pol); i++) {
sl@0
   387
		pinfo = sk_POLICYINFO_value(pol, i);
sl@0
   388
		BIO_printf(out, "%*sPolicy: ", indent, "");
sl@0
   389
		i2a_ASN1_OBJECT(out, pinfo->policyid);
sl@0
   390
		BIO_puts(out, "\n");
sl@0
   391
		if(pinfo->qualifiers)
sl@0
   392
			 print_qualifiers(out, pinfo->qualifiers, indent + 2);
sl@0
   393
	}
sl@0
   394
	return 1;
sl@0
   395
}
sl@0
   396
sl@0
   397
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
sl@0
   398
		int indent)
sl@0
   399
{
sl@0
   400
	POLICYQUALINFO *qualinfo;
sl@0
   401
	int i;
sl@0
   402
	for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
sl@0
   403
		qualinfo = sk_POLICYQUALINFO_value(quals, i);
sl@0
   404
		switch(OBJ_obj2nid(qualinfo->pqualid))
sl@0
   405
		{
sl@0
   406
			case NID_id_qt_cps:
sl@0
   407
			BIO_printf(out, "%*sCPS: %s\n", indent, "",
sl@0
   408
						qualinfo->d.cpsuri->data);
sl@0
   409
			break;
sl@0
   410
		
sl@0
   411
			case NID_id_qt_unotice:
sl@0
   412
			BIO_printf(out, "%*sUser Notice:\n", indent, "");
sl@0
   413
			print_notice(out, qualinfo->d.usernotice, indent + 2);
sl@0
   414
			break;
sl@0
   415
sl@0
   416
			default:
sl@0
   417
			BIO_printf(out, "%*sUnknown Qualifier: ",
sl@0
   418
							 indent + 2, "");
sl@0
   419
			
sl@0
   420
			i2a_ASN1_OBJECT(out, qualinfo->pqualid);
sl@0
   421
			BIO_puts(out, "\n");
sl@0
   422
			break;
sl@0
   423
		}
sl@0
   424
	}
sl@0
   425
}
sl@0
   426
sl@0
   427
static void print_notice(BIO *out, USERNOTICE *notice, int indent)
sl@0
   428
{
sl@0
   429
	int i;
sl@0
   430
	if(notice->noticeref) {
sl@0
   431
		NOTICEREF *ref;
sl@0
   432
		ref = notice->noticeref;
sl@0
   433
		BIO_printf(out, "%*sOrganization: %s\n", indent, "",
sl@0
   434
						 ref->organization->data);
sl@0
   435
		BIO_printf(out, "%*sNumber%s: ", indent, "",
sl@0
   436
			   sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
sl@0
   437
		for(i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
sl@0
   438
			ASN1_INTEGER *num;
sl@0
   439
			char *tmp;
sl@0
   440
			num = sk_ASN1_INTEGER_value(ref->noticenos, i);
sl@0
   441
			if(i) BIO_puts(out, ", ");
sl@0
   442
			tmp = i2s_ASN1_INTEGER(NULL, num);
sl@0
   443
			BIO_puts(out, tmp);
sl@0
   444
			OPENSSL_free(tmp);
sl@0
   445
		}
sl@0
   446
		BIO_puts(out, "\n");
sl@0
   447
	}
sl@0
   448
	if(notice->exptext)
sl@0
   449
		BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
sl@0
   450
							 notice->exptext->data);
sl@0
   451
}
sl@0
   452
sl@0
   453
EXPORT_C void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
sl@0
   454
	{
sl@0
   455
	const X509_POLICY_DATA *dat = node->data;
sl@0
   456
sl@0
   457
	BIO_printf(out, "%*sPolicy: ", indent, "");
sl@0
   458
			
sl@0
   459
	i2a_ASN1_OBJECT(out, dat->valid_policy);
sl@0
   460
	BIO_puts(out, "\n");
sl@0
   461
	BIO_printf(out, "%*s%s\n", indent + 2, "",
sl@0
   462
		node_data_critical(dat) ? "Critical" : "Non Critical");
sl@0
   463
	if (dat->qualifier_set)
sl@0
   464
		print_qualifiers(out, dat->qualifier_set, indent + 2);
sl@0
   465
	else
sl@0
   466
		BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
sl@0
   467
	}
sl@0
   468