GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/x509v3/v3_cpols.c Lines: 0 234 0.0 %
Date: 2016-12-06 Branches: 0 133 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: v3_cpols.c,v 1.23 2015/09/30 18:21:50 jsing Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project 1999.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 1999-2004 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
 */
58
59
#include <stdio.h>
60
#include <string.h>
61
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>
67
68
#include "pcy_int.h"
69
70
/* Certificate policies extension support: this one is a bit complex... */
71
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,
77
    int indent);
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);
84
85
const X509V3_EXT_METHOD v3_cpols = {
86
	.ext_nid = NID_certificate_policies,
87
	.ext_flags = 0,
88
	.it = ASN1_ITEM_ref(CERTIFICATEPOLICIES),
89
	.ext_new = NULL,
90
	.ext_free = NULL,
91
	.d2i = NULL,
92
	.i2d = NULL,
93
	.i2s = NULL,
94
	.s2i = NULL,
95
	.i2v = NULL,
96
	.v2i = NULL,
97
	.i2r = (X509V3_EXT_I2R)i2r_certpol,
98
	.r2i = (X509V3_EXT_R2I)r2i_certpol,
99
	.usr_data = NULL,
100
};
101
102
static const ASN1_TEMPLATE CERTIFICATEPOLICIES_item_tt = {
103
	.flags = ASN1_TFLG_SEQUENCE_OF,
104
	.tag = 0,
105
	.offset = 0,
106
	.field_name = "CERTIFICATEPOLICIES",
107
	.item = &POLICYINFO_it,
108
};
109
110
const ASN1_ITEM CERTIFICATEPOLICIES_it = {
111
	.itype = ASN1_ITYPE_PRIMITIVE,
112
	.utype = -1,
113
	.templates = &CERTIFICATEPOLICIES_item_tt,
114
	.tcount = 0,
115
	.funcs = NULL,
116
	.size = 0,
117
	.sname = "CERTIFICATEPOLICIES",
118
};
119
120
121
CERTIFICATEPOLICIES *
122
d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len)
123
{
124
	return (CERTIFICATEPOLICIES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
125
	    &CERTIFICATEPOLICIES_it);
126
}
127
128
int
129
i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out)
130
{
131
	return ASN1_item_i2d((ASN1_VALUE *)a, out, &CERTIFICATEPOLICIES_it);
132
}
133
134
CERTIFICATEPOLICIES *
135
CERTIFICATEPOLICIES_new(void)
136
{
137
	return (CERTIFICATEPOLICIES *)ASN1_item_new(&CERTIFICATEPOLICIES_it);
138
}
139
140
void
141
CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a)
142
{
143
	ASN1_item_free((ASN1_VALUE *)a, &CERTIFICATEPOLICIES_it);
144
}
145
146
static const ASN1_TEMPLATE POLICYINFO_seq_tt[] = {
147
	{
148
		.flags = 0,
149
		.tag = 0,
150
		.offset = offsetof(POLICYINFO, policyid),
151
		.field_name = "policyid",
152
		.item = &ASN1_OBJECT_it,
153
	},
154
	{
155
		.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
156
		.tag = 0,
157
		.offset = offsetof(POLICYINFO, qualifiers),
158
		.field_name = "qualifiers",
159
		.item = &POLICYQUALINFO_it,
160
	},
161
};
162
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),
168
	.funcs = NULL,
169
	.size = sizeof(POLICYINFO),
170
	.sname = "POLICYINFO",
171
};
172
173
174
POLICYINFO *
175
d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len)
176
{
177
	return (POLICYINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
178
	    &POLICYINFO_it);
179
}
180
181
int
182
i2d_POLICYINFO(POLICYINFO *a, unsigned char **out)
183
{
184
	return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYINFO_it);
185
}
186
187
POLICYINFO *
188
POLICYINFO_new(void)
189
{
190
	return (POLICYINFO *)ASN1_item_new(&POLICYINFO_it);
191
}
192
193
void
194
POLICYINFO_free(POLICYINFO *a)
195
{
196
	ASN1_item_free((ASN1_VALUE *)a, &POLICYINFO_it);
197
}
198
199
static const ASN1_TEMPLATE policydefault_tt = {
200
	.flags = 0,
201
	.tag = 0,
202
	.offset = offsetof(POLICYQUALINFO, d.other),
203
	.field_name = "d.other",
204
	.item = &ASN1_ANY_it,
205
};
206
207
static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl[] = {
208
	{
209
		.value = NID_id_qt_cps,
210
		.tt = {
211
			.flags = 0,
212
			.tag = 0,
213
			.offset = offsetof(POLICYQUALINFO, d.cpsuri),
214
			.field_name = "d.cpsuri",
215
			.item = &ASN1_IA5STRING_it,
216
		},
217
218
	},
219
	{
220
		.value = NID_id_qt_unotice,
221
		.tt = {
222
			.flags = 0,
223
			.tag = 0,
224
			.offset = offsetof(POLICYQUALINFO, d.usernotice),
225
			.field_name = "d.usernotice",
226
			.item = &USERNOTICE_it,
227
		},
228
229
	},
230
};
231
232
static const ASN1_ADB POLICYQUALINFO_adb = {
233
	.flags = 0,
234
	.offset = offsetof(POLICYQUALINFO, pqualid),
235
	.app_items = 0,
236
	.tbl = POLICYQUALINFO_adbtbl,
237
	.tblcount = sizeof(POLICYQUALINFO_adbtbl) / sizeof(ASN1_ADB_TABLE),
238
	.default_tt = &policydefault_tt,
239
	.null_tt = NULL,
240
};
241
242
static const ASN1_TEMPLATE POLICYQUALINFO_seq_tt[] = {
243
	{
244
		.flags = 0,
245
		.tag = 0,
246
		.offset = offsetof(POLICYQUALINFO, pqualid),
247
		.field_name = "pqualid",
248
		.item = &ASN1_OBJECT_it,
249
	},
250
	{
251
		.flags = ASN1_TFLG_ADB_OID,
252
		.tag = -1,
253
		.offset = 0,
254
		.field_name = "POLICYQUALINFO",
255
		.item = (const ASN1_ITEM *)&POLICYQUALINFO_adb,
256
	},
257
};
258
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),
264
	.funcs = NULL,
265
	.size = sizeof(POLICYQUALINFO),
266
	.sname = "POLICYQUALINFO",
267
};
268
269
270
POLICYQUALINFO *
271
d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len)
272
{
273
	return (POLICYQUALINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
274
	    &POLICYQUALINFO_it);
275
}
276
277
int
278
i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out)
279
{
280
	return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYQUALINFO_it);
281
}
282
283
POLICYQUALINFO *
284
POLICYQUALINFO_new(void)
285
{
286
	return (POLICYQUALINFO *)ASN1_item_new(&POLICYQUALINFO_it);
287
}
288
289
void
290
POLICYQUALINFO_free(POLICYQUALINFO *a)
291
{
292
	ASN1_item_free((ASN1_VALUE *)a, &POLICYQUALINFO_it);
293
}
294
295
static const ASN1_TEMPLATE USERNOTICE_seq_tt[] = {
296
	{
297
		.flags = ASN1_TFLG_OPTIONAL,
298
		.tag = 0,
299
		.offset = offsetof(USERNOTICE, noticeref),
300
		.field_name = "noticeref",
301
		.item = &NOTICEREF_it,
302
	},
303
	{
304
		.flags = ASN1_TFLG_OPTIONAL,
305
		.tag = 0,
306
		.offset = offsetof(USERNOTICE, exptext),
307
		.field_name = "exptext",
308
		.item = &DISPLAYTEXT_it,
309
	},
310
};
311
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),
317
	.funcs = NULL,
318
	.size = sizeof(USERNOTICE),
319
	.sname = "USERNOTICE",
320
};
321
322
323
USERNOTICE *
324
d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len)
325
{
326
	return (USERNOTICE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
327
	    &USERNOTICE_it);
328
}
329
330
int
331
i2d_USERNOTICE(USERNOTICE *a, unsigned char **out)
332
{
333
	return ASN1_item_i2d((ASN1_VALUE *)a, out, &USERNOTICE_it);
334
}
335
336
USERNOTICE *
337
USERNOTICE_new(void)
338
{
339
	return (USERNOTICE *)ASN1_item_new(&USERNOTICE_it);
340
}
341
342
void
343
USERNOTICE_free(USERNOTICE *a)
344
{
345
	ASN1_item_free((ASN1_VALUE *)a, &USERNOTICE_it);
346
}
347
348
static const ASN1_TEMPLATE NOTICEREF_seq_tt[] = {
349
	{
350
		.flags = 0,
351
		.tag = 0,
352
		.offset = offsetof(NOTICEREF, organization),
353
		.field_name = "organization",
354
		.item = &DISPLAYTEXT_it,
355
	},
356
	{
357
		.flags = ASN1_TFLG_SEQUENCE_OF,
358
		.tag = 0,
359
		.offset = offsetof(NOTICEREF, noticenos),
360
		.field_name = "noticenos",
361
		.item = &ASN1_INTEGER_it,
362
	},
363
};
364
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),
370
	.funcs = NULL,
371
	.size = sizeof(NOTICEREF),
372
	.sname = "NOTICEREF",
373
};
374
375
376
NOTICEREF *
377
d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len)
378
{
379
	return (NOTICEREF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
380
	    &NOTICEREF_it);
381
}
382
383
int
384
i2d_NOTICEREF(NOTICEREF *a, unsigned char **out)
385
{
386
	return ASN1_item_i2d((ASN1_VALUE *)a, out, &NOTICEREF_it);
387
}
388
389
NOTICEREF *
390
NOTICEREF_new(void)
391
{
392
	return (NOTICEREF *)ASN1_item_new(&NOTICEREF_it);
393
}
394
395
void
396
NOTICEREF_free(NOTICEREF *a)
397
{
398
	ASN1_item_free((ASN1_VALUE *)a, &NOTICEREF_it);
399
}
400
401
static
402
STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
403
    char *value)
404
{
405
	STACK_OF(POLICYINFO) *pols = NULL;
406
	char *pstr;
407
	POLICYINFO *pol;
408
	ASN1_OBJECT *pobj;
409
	STACK_OF(CONF_VALUE) *vals;
410
	CONF_VALUE *cnf;
411
	int i, ia5org;
412
413
	pols = sk_POLICYINFO_new_null();
414
	if (pols == NULL) {
415
		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
416
		return NULL;
417
	}
418
	vals = X509V3_parse_list(value);
419
	if (vals == NULL) {
420
		X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
421
		goto err;
422
	}
423
	ia5org = 0;
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);
430
			goto err;
431
		}
432
		pstr = cnf->name;
433
		if (!strcmp(pstr, "ia5org")) {
434
			ia5org = 1;
435
			continue;
436
		} else if (*pstr == '@') {
437
			STACK_OF(CONF_VALUE) *polsect;
438
			polsect = X509V3_get_section(ctx, pstr + 1);
439
			if (!polsect) {
440
				X509V3err(X509V3_F_R2I_CERTPOL,
441
				    X509V3_R_INVALID_SECTION);
442
				X509V3_conf_err(cnf);
443
				goto err;
444
			}
445
			pol = policy_section(ctx, polsect, ia5org);
446
			X509V3_section_free(ctx, polsect);
447
			if (!pol)
448
				goto err;
449
		} else {
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);
454
				goto err;
455
			}
456
			pol = POLICYINFO_new();
457
			pol->policyid = pobj;
458
		}
459
		if (!sk_POLICYINFO_push(pols, pol)){
460
			POLICYINFO_free(pol);
461
			X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
462
			goto err;
463
		}
464
	}
465
	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
466
	return pols;
467
468
err:
469
	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
470
	sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
471
	return NULL;
472
}
473
474
static POLICYINFO *
475
policy_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *polstrs, int ia5org)
476
{
477
	int i;
478
	CONF_VALUE *cnf;
479
	POLICYINFO *pol;
480
	POLICYQUALINFO *nqual = NULL;
481
482
	if ((pol = POLICYINFO_new()) == NULL)
483
		goto merr;
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) {
487
			ASN1_OBJECT *pobj;
488
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);
493
				goto err;
494
			}
495
			pol->policyid = pobj;
496
		} else if (name_cmp(cnf->name, "CPS") == 0) {
497
			if ((nqual = POLICYQUALINFO_new()) == NULL)
498
				goto merr;
499
			nqual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
500
			nqual->d.cpsuri = ASN1_IA5STRING_new();
501
			if (nqual->d.cpsuri == NULL)
502
				goto merr;
503
			if (ASN1_STRING_set(nqual->d.cpsuri, cnf->value,
504
			    strlen(cnf->value)) == 0)
505
				goto merr;
506
507
			if (pol->qualifiers == NULL) {
508
				pol->qualifiers = sk_POLICYQUALINFO_new_null();
509
				if (pol->qualifiers == NULL)
510
					goto merr;
511
			}
512
			if (sk_POLICYQUALINFO_push(pol->qualifiers, nqual) == 0)
513
				goto merr;
514
			nqual = NULL;
515
		} else if (name_cmp(cnf->name, "userNotice") == 0) {
516
			STACK_OF(CONF_VALUE) *unot;
517
			POLICYQUALINFO *qual;
518
519
			if (*cnf->value != '@') {
520
				X509V3err(X509V3_F_POLICY_SECTION,
521
				    X509V3_R_EXPECTED_A_SECTION_NAME);
522
				X509V3_conf_err(cnf);
523
				goto err;
524
			}
525
			unot = X509V3_get_section(ctx, cnf->value + 1);
526
			if (unot == NULL) {
527
				X509V3err(X509V3_F_POLICY_SECTION,
528
				    X509V3_R_INVALID_SECTION);
529
				X509V3_conf_err(cnf);
530
				goto err;
531
			}
532
			qual = notice_section(ctx, unot, ia5org);
533
			X509V3_section_free(ctx, unot);
534
			if (qual == NULL)
535
				goto err;
536
537
			if (pol->qualifiers == NULL) {
538
				pol->qualifiers = sk_POLICYQUALINFO_new_null();
539
				if (pol->qualifiers == NULL)
540
					goto merr;
541
			}
542
			if (sk_POLICYQUALINFO_push(pol->qualifiers, qual) == 0)
543
				goto merr;
544
		} else {
545
			X509V3err(X509V3_F_POLICY_SECTION,
546
			    X509V3_R_INVALID_OPTION);
547
			X509V3_conf_err(cnf);
548
			goto err;
549
		}
550
	}
551
	if (pol->policyid == NULL) {
552
		X509V3err(X509V3_F_POLICY_SECTION,
553
		    X509V3_R_NO_POLICY_IDENTIFIER);
554
		goto err;
555
	}
556
557
	return pol;
558
559
merr:
560
	X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE);
561
562
err:
563
	POLICYQUALINFO_free(nqual);
564
	POLICYINFO_free(pol);
565
	return NULL;
566
}
567
568
static POLICYQUALINFO *
569
notice_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *unot, int ia5org)
570
{
571
	int i, ret;
572
	CONF_VALUE *cnf;
573
	USERNOTICE *not;
574
	POLICYQUALINFO *qual;
575
576
	if (!(qual = POLICYQUALINFO_new()))
577
		goto merr;
578
	qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
579
	if (!(not = USERNOTICE_new()))
580
		goto merr;
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)
588
					goto merr;
589
			}
590
			if (!ASN1_STRING_set(not->exptext, cnf->value,
591
			    strlen(cnf->value)))
592
				goto merr;
593
		} else if (!strcmp(cnf->name, "organization")) {
594
			NOTICEREF *nref;
595
			if (!not->noticeref) {
596
				if (!(nref = NOTICEREF_new()))
597
					goto merr;
598
				not->noticeref = nref;
599
			} else
600
				nref = not->noticeref;
601
			if (ia5org)
602
				nref->organization->type = V_ASN1_IA5STRING;
603
			else
604
				nref->organization->type = V_ASN1_VISIBLESTRING;
605
			if (!ASN1_STRING_set(nref->organization, cnf->value,
606
			    strlen(cnf->value)))
607
				goto merr;
608
		} else if (!strcmp(cnf->name, "noticeNumbers")) {
609
			NOTICEREF *nref;
610
			STACK_OF(CONF_VALUE) *nos;
611
			if (!not->noticeref) {
612
				if (!(nref = NOTICEREF_new()))
613
					goto merr;
614
				not->noticeref = nref;
615
			} else
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);
622
				if (nos != NULL)
623
					sk_CONF_VALUE_pop_free(nos,
624
					    X509V3_conf_free);
625
				goto err;
626
			}
627
			ret = nref_nos(nref->noticenos, nos);
628
			sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
629
			if (!ret)
630
				goto err;
631
		} else {
632
			X509V3err(X509V3_F_NOTICE_SECTION,
633
			    X509V3_R_INVALID_OPTION);
634
			X509V3_conf_err(cnf);
635
			goto err;
636
		}
637
	}
638
639
	if (not->noticeref &&
640
	    (!not->noticeref->noticenos || !not->noticeref->organization)) {
641
		X509V3err(X509V3_F_NOTICE_SECTION,
642
		    X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
643
		goto err;
644
	}
645
646
	return qual;
647
648
merr:
649
	X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE);
650
651
err:
652
	POLICYQUALINFO_free(qual);
653
	return NULL;
654
}
655
656
static int
657
nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
658
{
659
	CONF_VALUE *cnf;
660
	ASN1_INTEGER *aint;
661
	int i;
662
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);
667
			goto err;
668
		}
669
		if (!sk_ASN1_INTEGER_push(nnums, aint))
670
			goto merr;
671
	}
672
	return 1;
673
674
merr:
675
	X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE);
676
677
err:
678
	sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
679
	return 0;
680
}
681
682
static int
683
i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out,
684
    int indent)
685
{
686
	int i;
687
	POLICYINFO *pinfo;
688
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);
694
		BIO_puts(out, "\n");
695
		if (pinfo->qualifiers)
696
			print_qualifiers(out, pinfo->qualifiers, indent + 2);
697
	}
698
	return 1;
699
}
700
701
static void
702
print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent)
703
{
704
	POLICYQUALINFO *qualinfo;
705
	int i;
706
707
	for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
708
		qualinfo = sk_POLICYQUALINFO_value(quals, i);
709
		switch (OBJ_obj2nid(qualinfo->pqualid)) {
710
		case NID_id_qt_cps:
711
			BIO_printf(out, "%*sCPS: %s\n", indent, "",
712
			    qualinfo->d.cpsuri->data);
713
			break;
714
715
		case NID_id_qt_unotice:
716
			BIO_printf(out, "%*sUser Notice:\n", indent, "");
717
			print_notice(out, qualinfo->d.usernotice, indent + 2);
718
			break;
719
720
		default:
721
			BIO_printf(out, "%*sUnknown Qualifier: ",
722
			    indent + 2, "");
723
724
			i2a_ASN1_OBJECT(out, qualinfo->pqualid);
725
			BIO_puts(out, "\n");
726
			break;
727
		}
728
	}
729
}
730
731
static void
732
print_notice(BIO *out, USERNOTICE *notice, int indent)
733
{
734
	int i;
735
736
	if (notice->noticeref) {
737
		NOTICEREF *ref;
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++) {
744
			ASN1_INTEGER *num;
745
			char *tmp;
746
			num = sk_ASN1_INTEGER_value(ref->noticenos, i);
747
			if (i)
748
				BIO_puts(out, ", ");
749
			tmp = i2s_ASN1_INTEGER(NULL, num);
750
			BIO_puts(out, tmp);
751
			free(tmp);
752
		}
753
		BIO_puts(out, "\n");
754
	}
755
	if (notice->exptext)
756
		BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
757
		    notice->exptext->data);
758
}
759
760
void
761
X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
762
{
763
	const X509_POLICY_DATA *dat = node->data;
764
765
	BIO_printf(out, "%*sPolicy: ", indent, "");
766
767
	i2a_ASN1_OBJECT(out, dat->valid_policy);
768
	BIO_puts(out, "\n");
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);
773
	else
774
		BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
775
}