GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/x509v3/v3_cpols.c Lines: 0 222 0.0 %
Date: 2017-11-13 Branches: 0 144 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: v3_cpols.c,v 1.25 2017/01/29 17:49:23 beck 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 = &CERTIFICATEPOLICIES_it,
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
		X509V3error(ERR_R_MALLOC_FAILURE);
416
		return NULL;
417
	}
418
	vals = X509V3_parse_list(value);
419
	if (vals == NULL) {
420
		X509V3error(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
			X509V3error(X509V3_R_INVALID_POLICY_IDENTIFIER);
428
			X509V3_conf_err(cnf);
429
			goto err;
430
		}
431
		pstr = cnf->name;
432
		if (!strcmp(pstr, "ia5org")) {
433
			ia5org = 1;
434
			continue;
435
		} else if (*pstr == '@') {
436
			STACK_OF(CONF_VALUE) *polsect;
437
			polsect = X509V3_get_section(ctx, pstr + 1);
438
			if (!polsect) {
439
				X509V3error(X509V3_R_INVALID_SECTION);
440
				X509V3_conf_err(cnf);
441
				goto err;
442
			}
443
			pol = policy_section(ctx, polsect, ia5org);
444
			X509V3_section_free(ctx, polsect);
445
			if (!pol)
446
				goto err;
447
		} else {
448
			if (!(pobj = OBJ_txt2obj(cnf->name, 0))) {
449
				X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
450
				X509V3_conf_err(cnf);
451
				goto err;
452
			}
453
			pol = POLICYINFO_new();
454
			pol->policyid = pobj;
455
		}
456
		if (!sk_POLICYINFO_push(pols, pol)){
457
			POLICYINFO_free(pol);
458
			X509V3error(ERR_R_MALLOC_FAILURE);
459
			goto err;
460
		}
461
	}
462
	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
463
	return pols;
464
465
err:
466
	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
467
	sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
468
	return NULL;
469
}
470
471
static POLICYINFO *
472
policy_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *polstrs, int ia5org)
473
{
474
	int i;
475
	CONF_VALUE *cnf;
476
	POLICYINFO *pol;
477
	POLICYQUALINFO *nqual = NULL;
478
479
	if ((pol = POLICYINFO_new()) == NULL)
480
		goto merr;
481
	for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
482
		cnf = sk_CONF_VALUE_value(polstrs, i);
483
		if (strcmp(cnf->name, "policyIdentifier") == 0) {
484
			ASN1_OBJECT *pobj;
485
486
			if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) {
487
				X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
488
				X509V3_conf_err(cnf);
489
				goto err;
490
			}
491
			pol->policyid = pobj;
492
		} else if (name_cmp(cnf->name, "CPS") == 0) {
493
			if ((nqual = POLICYQUALINFO_new()) == NULL)
494
				goto merr;
495
			nqual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
496
			nqual->d.cpsuri = ASN1_IA5STRING_new();
497
			if (nqual->d.cpsuri == NULL)
498
				goto merr;
499
			if (ASN1_STRING_set(nqual->d.cpsuri, cnf->value,
500
			    strlen(cnf->value)) == 0)
501
				goto merr;
502
503
			if (pol->qualifiers == NULL) {
504
				pol->qualifiers = sk_POLICYQUALINFO_new_null();
505
				if (pol->qualifiers == NULL)
506
					goto merr;
507
			}
508
			if (sk_POLICYQUALINFO_push(pol->qualifiers, nqual) == 0)
509
				goto merr;
510
			nqual = NULL;
511
		} else if (name_cmp(cnf->name, "userNotice") == 0) {
512
			STACK_OF(CONF_VALUE) *unot;
513
			POLICYQUALINFO *qual;
514
515
			if (*cnf->value != '@') {
516
				X509V3error(X509V3_R_EXPECTED_A_SECTION_NAME);
517
				X509V3_conf_err(cnf);
518
				goto err;
519
			}
520
			unot = X509V3_get_section(ctx, cnf->value + 1);
521
			if (unot == NULL) {
522
				X509V3error(X509V3_R_INVALID_SECTION);
523
				X509V3_conf_err(cnf);
524
				goto err;
525
			}
526
			qual = notice_section(ctx, unot, ia5org);
527
			X509V3_section_free(ctx, unot);
528
			if (qual == NULL)
529
				goto err;
530
531
			if (pol->qualifiers == NULL) {
532
				pol->qualifiers = sk_POLICYQUALINFO_new_null();
533
				if (pol->qualifiers == NULL)
534
					goto merr;
535
			}
536
			if (sk_POLICYQUALINFO_push(pol->qualifiers, qual) == 0)
537
				goto merr;
538
		} else {
539
			X509V3error(X509V3_R_INVALID_OPTION);
540
			X509V3_conf_err(cnf);
541
			goto err;
542
		}
543
	}
544
	if (pol->policyid == NULL) {
545
		X509V3error(X509V3_R_NO_POLICY_IDENTIFIER);
546
		goto err;
547
	}
548
549
	return pol;
550
551
merr:
552
	X509V3error(ERR_R_MALLOC_FAILURE);
553
554
err:
555
	POLICYQUALINFO_free(nqual);
556
	POLICYINFO_free(pol);
557
	return NULL;
558
}
559
560
static POLICYQUALINFO *
561
notice_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *unot, int ia5org)
562
{
563
	int i, ret;
564
	CONF_VALUE *cnf;
565
	USERNOTICE *not;
566
	POLICYQUALINFO *qual;
567
568
	if (!(qual = POLICYQUALINFO_new()))
569
		goto merr;
570
	qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
571
	if (!(not = USERNOTICE_new()))
572
		goto merr;
573
	qual->d.usernotice = not;
574
	for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
575
		cnf = sk_CONF_VALUE_value(unot, i);
576
		if (!strcmp(cnf->name, "explicitText")) {
577
			if (not->exptext == NULL) {
578
				not->exptext = ASN1_VISIBLESTRING_new();
579
				if (not->exptext == NULL)
580
					goto merr;
581
			}
582
			if (!ASN1_STRING_set(not->exptext, cnf->value,
583
			    strlen(cnf->value)))
584
				goto merr;
585
		} else if (!strcmp(cnf->name, "organization")) {
586
			NOTICEREF *nref;
587
			if (!not->noticeref) {
588
				if (!(nref = NOTICEREF_new()))
589
					goto merr;
590
				not->noticeref = nref;
591
			} else
592
				nref = not->noticeref;
593
			if (ia5org)
594
				nref->organization->type = V_ASN1_IA5STRING;
595
			else
596
				nref->organization->type = V_ASN1_VISIBLESTRING;
597
			if (!ASN1_STRING_set(nref->organization, cnf->value,
598
			    strlen(cnf->value)))
599
				goto merr;
600
		} else if (!strcmp(cnf->name, "noticeNumbers")) {
601
			NOTICEREF *nref;
602
			STACK_OF(CONF_VALUE) *nos;
603
			if (!not->noticeref) {
604
				if (!(nref = NOTICEREF_new()))
605
					goto merr;
606
				not->noticeref = nref;
607
			} else
608
				nref = not->noticeref;
609
			nos = X509V3_parse_list(cnf->value);
610
			if (!nos || !sk_CONF_VALUE_num(nos)) {
611
				X509V3error(X509V3_R_INVALID_NUMBERS);
612
				X509V3_conf_err(cnf);
613
				if (nos != NULL)
614
					sk_CONF_VALUE_pop_free(nos,
615
					    X509V3_conf_free);
616
				goto err;
617
			}
618
			ret = nref_nos(nref->noticenos, nos);
619
			sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
620
			if (!ret)
621
				goto err;
622
		} else {
623
			X509V3error(X509V3_R_INVALID_OPTION);
624
			X509V3_conf_err(cnf);
625
			goto err;
626
		}
627
	}
628
629
	if (not->noticeref &&
630
	    (!not->noticeref->noticenos || !not->noticeref->organization)) {
631
		X509V3error(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
632
		goto err;
633
	}
634
635
	return qual;
636
637
merr:
638
	X509V3error(ERR_R_MALLOC_FAILURE);
639
640
err:
641
	POLICYQUALINFO_free(qual);
642
	return NULL;
643
}
644
645
static int
646
nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
647
{
648
	CONF_VALUE *cnf;
649
	ASN1_INTEGER *aint;
650
	int i;
651
652
	for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
653
		cnf = sk_CONF_VALUE_value(nos, i);
654
		if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
655
			X509V3error(X509V3_R_INVALID_NUMBER);
656
			goto err;
657
		}
658
		if (!sk_ASN1_INTEGER_push(nnums, aint))
659
			goto merr;
660
	}
661
	return 1;
662
663
merr:
664
	X509V3error(ERR_R_MALLOC_FAILURE);
665
666
err:
667
	sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
668
	return 0;
669
}
670
671
static int
672
i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out,
673
    int indent)
674
{
675
	int i;
676
	POLICYINFO *pinfo;
677
678
	/* First print out the policy OIDs */
679
	for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
680
		pinfo = sk_POLICYINFO_value(pol, i);
681
		BIO_printf(out, "%*sPolicy: ", indent, "");
682
		i2a_ASN1_OBJECT(out, pinfo->policyid);
683
		BIO_puts(out, "\n");
684
		if (pinfo->qualifiers)
685
			print_qualifiers(out, pinfo->qualifiers, indent + 2);
686
	}
687
	return 1;
688
}
689
690
static void
691
print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent)
692
{
693
	POLICYQUALINFO *qualinfo;
694
	int i;
695
696
	for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
697
		qualinfo = sk_POLICYQUALINFO_value(quals, i);
698
		switch (OBJ_obj2nid(qualinfo->pqualid)) {
699
		case NID_id_qt_cps:
700
			BIO_printf(out, "%*sCPS: %s\n", indent, "",
701
			    qualinfo->d.cpsuri->data);
702
			break;
703
704
		case NID_id_qt_unotice:
705
			BIO_printf(out, "%*sUser Notice:\n", indent, "");
706
			print_notice(out, qualinfo->d.usernotice, indent + 2);
707
			break;
708
709
		default:
710
			BIO_printf(out, "%*sUnknown Qualifier: ",
711
			    indent + 2, "");
712
713
			i2a_ASN1_OBJECT(out, qualinfo->pqualid);
714
			BIO_puts(out, "\n");
715
			break;
716
		}
717
	}
718
}
719
720
static void
721
print_notice(BIO *out, USERNOTICE *notice, int indent)
722
{
723
	int i;
724
725
	if (notice->noticeref) {
726
		NOTICEREF *ref;
727
		ref = notice->noticeref;
728
		BIO_printf(out, "%*sOrganization: %s\n", indent, "",
729
		    ref->organization->data);
730
		BIO_printf(out, "%*sNumber%s: ", indent, "",
731
		    sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
732
		for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
733
			ASN1_INTEGER *num;
734
			char *tmp;
735
			num = sk_ASN1_INTEGER_value(ref->noticenos, i);
736
			if (i)
737
				BIO_puts(out, ", ");
738
			tmp = i2s_ASN1_INTEGER(NULL, num);
739
			BIO_puts(out, tmp);
740
			free(tmp);
741
		}
742
		BIO_puts(out, "\n");
743
	}
744
	if (notice->exptext)
745
		BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
746
		    notice->exptext->data);
747
}
748
749
void
750
X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
751
{
752
	const X509_POLICY_DATA *dat = node->data;
753
754
	BIO_printf(out, "%*sPolicy: ", indent, "");
755
756
	i2a_ASN1_OBJECT(out, dat->valid_policy);
757
	BIO_puts(out, "\n");
758
	BIO_printf(out, "%*s%s\n", indent + 2, "",
759
	    node_data_critical(dat) ? "Critical" : "Non Critical");
760
	if (dat->qualifier_set)
761
		print_qualifiers(out, dat->qualifier_set, indent + 2);
762
	else
763
		BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
764
}