1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* v3_crld.c */
2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * project 1999.
4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ====================================================================
6480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without
9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions
10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met:
11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright
13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer.
14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer in
17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    the documentation and/or other materials provided with the
18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    distribution.
19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this
21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    software must display the following acknowledgment:
22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software developed by the OpenSSL Project
23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    endorse or promote products derived from this software without
27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    prior written permission. For written permission, please contact
28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    licensing@OpenSSL.org.
29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL"
31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    nor may "OpenSSL" appear in their names without prior written
32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    permission of the OpenSSL Project.
33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following
35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    acknowledgment:
36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software developed by the OpenSSL Project
37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE.
51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ====================================================================
52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young
54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com).  This product includes software written by Tim
55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com).
56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h>
60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h"
61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/conf.h>
62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/asn1.h>
63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/asn1t.h>
64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/x509v3.h>
65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
66480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void *v2i_crld(const X509V3_EXT_METHOD *method,
67480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
69480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     int indent);
70480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
71480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgconst X509V3_EXT_METHOD v3_crld =
72480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
73480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
74480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,0,0,0,
75480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,0,
76480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,
77480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	v2i_crld,
78480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	i2r_crldp,0,
79480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	NULL
80480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	};
81480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
82480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgconst X509V3_EXT_METHOD v3_freshest_crl =
83480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
84480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
85480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,0,0,0,
86480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,0,
87480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,
88480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	v2i_crld,
89480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	i2r_crldp,0,
90480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	NULL
91480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	};
92480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
93480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
94480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
95480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	STACK_OF(CONF_VALUE) *gnsect;
96480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	STACK_OF(GENERAL_NAME) *gens;
97480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (*sect == '@')
98480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		gnsect = X509V3_get_section(ctx, sect + 1);
99480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
100480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		gnsect = X509V3_parse_list(sect);
101480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!gnsect)
102480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
103480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509V3err(X509V3_F_GNAMES_FROM_SECTNAME,
104480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org						X509V3_R_SECTION_NOT_FOUND);
105480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return NULL;
106480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
107480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
108480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (*sect == '@')
109480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509V3_section_free(ctx, gnsect);
110480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
111480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
112480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return gens;
113480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
114480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
115480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
116480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org							CONF_VALUE *cnf)
117480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
118480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	STACK_OF(GENERAL_NAME) *fnm = NULL;
119480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!strncmp(cnf->name, "fullname", 9))
121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		fnm = gnames_from_sectname(ctx, cnf->value);
123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!fnm)
124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else if (!strcmp(cnf->name, "relativename"))
127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
128480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		int ret;
129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		STACK_OF(CONF_VALUE) *dnsect;
130480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509_NAME *nm;
131480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		nm = X509_NAME_new();
132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!nm)
133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return -1;
134480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		dnsect = X509V3_get_section(ctx, cnf->value);
135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!dnsect)
136480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
137480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509V3err(X509V3_F_SET_DIST_POINT_NAME,
138480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org						X509V3_R_SECTION_NOT_FOUND);
139480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return -1;
140480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
141480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
142480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509V3_section_free(ctx, dnsect);
143480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		rnm = nm->entries;
144480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		nm->entries = NULL;
145480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509_NAME_free(nm);
146480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
147480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
148480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Since its a name fragment can't have more than one
149480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 * RDNSequence
150480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 */
151480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (sk_X509_NAME_ENTRY_value(rnm,
152480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
153480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
154480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509V3err(X509V3_F_SET_DIST_POINT_NAME,
155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org						X509V3_R_INVALID_MULTIPLE_RDNS);
156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
161480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
162480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (*pdp)
163480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
164480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509V3err(X509V3_F_SET_DIST_POINT_NAME,
165480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org						X509V3_R_DISTPOINT_ALREADY_SET);
166480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
167480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
168480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
169480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	*pdp = DIST_POINT_NAME_new();
170480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!*pdp)
171480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
172480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (fnm)
173480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
174480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		(*pdp)->type = 0;
175480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		(*pdp)->name.fullname = fnm;
176480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
177480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
178480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
179480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		(*pdp)->type = 1;
180480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		(*pdp)->name.relativename = rnm;
181480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
182480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
183480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
184480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
185480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	err:
186480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (fnm)
187480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
188480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (rnm)
189480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
190480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return -1;
191480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
192480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
193480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic const BIT_STRING_BITNAME reason_flags[] = {
194480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{0, "Unused", "unused"},
195480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{1, "Key Compromise", "keyCompromise"},
196480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{2, "CA Compromise", "CACompromise"},
197480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{3, "Affiliation Changed", "affiliationChanged"},
198480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{4, "Superseded", "superseded"},
199480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{5, "Cessation Of Operation", "cessationOfOperation"},
200480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{6, "Certificate Hold", "certificateHold"},
201480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{7, "Privilege Withdrawn", "privilegeWithdrawn"},
202480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{8, "AA Compromise", "AACompromise"},
203480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org{-1, NULL, NULL}
204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org};
205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
206480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int set_reasons(ASN1_BIT_STRING **preas, char *value)
207480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
208480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	STACK_OF(CONF_VALUE) *rsk = NULL;
209480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const BIT_STRING_BITNAME *pbn;
210480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const char *bnam;
211480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i, ret = 0;
212480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	rsk = X509V3_parse_list(value);
213480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!rsk)
214480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
215480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (*preas)
216480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
217480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
218480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
219480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		bnam = sk_CONF_VALUE_value(rsk, i)->name;
220480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!*preas)
221480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
222480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*preas = ASN1_BIT_STRING_new();
223480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!*preas)
224480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
225480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
226480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		for (pbn = reason_flags; pbn->lname; pbn++)
227480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
228480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!strcmp(pbn->sname, bnam))
229480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
230480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				if (!ASN1_BIT_STRING_set_bit(*preas,
231480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org							pbn->bitnum, 1))
232480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					goto err;
233480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				break;
234480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
235480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!pbn->lname)
237480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
238480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
239480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ret = 1;
240480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
241480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	err:
242480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
243480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ret;
244480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
245480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
246480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int print_reasons(BIO *out, const char *rname,
247480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ASN1_BIT_STRING *rflags, int indent)
248480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
249480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int first = 1;
250480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const BIT_STRING_BITNAME *pbn;
251480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
252480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (pbn = reason_flags; pbn->lname; pbn++)
253480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
254480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
255480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
256480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (first)
257480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				first = 0;
258480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			else
259480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				BIO_puts(out, ", ");
260480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			BIO_puts(out, pbn->lname);
261480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
262480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
263480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (first)
264480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_puts(out, "<EMPTY>\n");
265480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
266480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_puts(out, "\n");
267480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
268480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
269480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
270480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
271480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org						STACK_OF(CONF_VALUE) *nval)
272480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i;
274480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	CONF_VALUE *cnf;
275480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	DIST_POINT *point = NULL;
276480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	point = DIST_POINT_new();
277480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!point)
278480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
279480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
280480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
281480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		int ret;
282480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		cnf = sk_CONF_VALUE_value(nval, i);
283480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ret = set_dist_point_name(&point->distpoint, ctx, cnf);
284480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ret > 0)
285480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			continue;
286480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ret < 0)
287480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
288480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!strcmp(cnf->name, "reasons"))
289480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
290480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!set_reasons(&point->reasons, cnf->value))
291480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
292480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
293480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else if (!strcmp(cnf->name, "CRLissuer"))
294480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
295480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			point->CRLissuer =
296480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				gnames_from_sectname(ctx, cnf->value);
297480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!point->CRLissuer)
298480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
299480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
301480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
302480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return point;
303480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
304480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
305480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	err:
306480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (point)
307480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		DIST_POINT_free(point);
308480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return NULL;
309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
311480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void *v2i_crld(const X509V3_EXT_METHOD *method,
312480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
313480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	STACK_OF(DIST_POINT) *crld = NULL;
315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	GENERAL_NAMES *gens = NULL;
316c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	GENERAL_NAME *gen = NULL;
317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	CONF_VALUE *cnf;
318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i;
319c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if(!(crld = sk_DIST_POINT_new_null())) goto merr;
320c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
321c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		DIST_POINT *point;
322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		cnf = sk_CONF_VALUE_value(nval, i);
323480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!cnf->value)
324480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
325480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			STACK_OF(CONF_VALUE) *dpsect;
326480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			dpsect = X509V3_get_section(ctx, cnf->name);
327480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!dpsect)
328480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
329480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			point = crldp_from_section(ctx, dpsect);
330480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509V3_section_free(ctx, dpsect);
331480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!point)
332480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
333480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if(!sk_DIST_POINT_push(crld, point))
334480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
335480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				DIST_POINT_free(point);
336480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto merr;
337480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
338480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
339480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else
340480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
341480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
342480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
343480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if(!(gens = GENERAL_NAMES_new()))
344480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto merr;
345480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if(!sk_GENERAL_NAME_push(gens, gen))
346480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto merr;
347480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			gen = NULL;
348480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if(!(point = DIST_POINT_new()))
349480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto merr;
350480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if(!sk_DIST_POINT_push(crld, point))
351480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
352480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				DIST_POINT_free(point);
353480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto merr;
354480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
355480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if(!(point->distpoint = DIST_POINT_NAME_new()))
356480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto merr;
357480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			point->distpoint->name.fullname = gens;
358480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			point->distpoint->type = 0;
359480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			gens = NULL;
360480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
361c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return crld;
363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	merr:
365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509V3err(X509V3_F_V2I_CRLD,ERR_R_MALLOC_FAILURE);
366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	err:
367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	GENERAL_NAME_free(gen);
368c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	GENERAL_NAMES_free(gens);
369c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return NULL;
371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
373c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_STACK_OF(DIST_POINT)
374c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_ASN1_SET_OF(DIST_POINT)
375c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
376480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
377480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org								void *exarg)
378480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
379480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
380480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
381480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	switch(operation)
382480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
383480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		case ASN1_OP_NEW_POST:
384480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		dpn->dpname = NULL;
385480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		break;
386480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
387480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		case ASN1_OP_FREE_POST:
388480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (dpn->dpname)
389480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_NAME_free(dpn->dpname);
390480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		break;
391480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
392480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
393480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
394480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
395c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
396480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
397c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
398c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
399480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
400480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
401c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
402c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
403c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
404c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgASN1_SEQUENCE(DIST_POINT) = {
405c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
406c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
407c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
408c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org} ASN1_SEQUENCE_END(DIST_POINT)
409c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
410c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
411c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
412c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
413c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
414c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
415c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
416c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
417480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
418480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgASN1_SEQUENCE(ISSUING_DIST_POINT) = {
419480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
420480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
421480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
422480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
423480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
424480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
425480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
426480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
427480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgIMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
428480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
429480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
430480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		   int indent);
431480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
432480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     STACK_OF(CONF_VALUE) *nval);
433480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
434480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgconst X509V3_EXT_METHOD v3_idp =
435480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
436480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
437480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ASN1_ITEM_ref(ISSUING_DIST_POINT),
438480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,0,0,0,
439480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,0,
440480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	0,
441480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	v2i_idp,
442480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	i2r_idp,0,
443480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	NULL
444480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	};
445480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
446480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
447480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     STACK_OF(CONF_VALUE) *nval)
448480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
449480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ISSUING_DIST_POINT *idp = NULL;
450480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	CONF_VALUE *cnf;
451480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	char *name, *val;
452480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i, ret;
453480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	idp = ISSUING_DIST_POINT_new();
454480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!idp)
455480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto merr;
456480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
457480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
458480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		cnf = sk_CONF_VALUE_value(nval, i);
459480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		name = cnf->name;
460480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		val = cnf->value;
461480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
462480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ret > 0)
463480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			continue;
464480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ret < 0)
465480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
466480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!strcmp(name, "onlyuser"))
467480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
468480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
469480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
470480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
471480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else if (!strcmp(name, "onlyCA"))
472480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
473480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
474480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
475480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
476480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else if (!strcmp(name, "onlyAA"))
477480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
478480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
479480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
480480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
481480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else if (!strcmp(name, "indirectCRL"))
482480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
483480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
484480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
485480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
486480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else if (!strcmp(name, "onlysomereasons"))
487480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
488480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!set_reasons(&idp->onlysomereasons, val))
489480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
490480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
491480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else
492480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
493480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org                        X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
494480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org                        X509V3_conf_err(cnf);
495480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org                        goto err;
496480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
497480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
498480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return idp;
499480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
500480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	merr:
501480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE);
502480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	err:
503480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ISSUING_DIST_POINT_free(idp);
504480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return NULL;
505480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
506480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
507480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
508480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
509480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
510480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
511480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
512480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_printf(out, "%*s", indent + 2, "");
513480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
514480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_puts(out, "\n");
515480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
516480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
517480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
518480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
519480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
520480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
521480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (dpn->type == 0)
522480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
523480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_printf(out, "%*sFull Name:\n", indent, "");
524480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		print_gens(out, dpn->name.fullname, indent);
525480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
526480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
527480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
528480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509_NAME ntmp;
529480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ntmp.entries = dpn->name.relativename;
530480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_printf(out, "%*sRelative Name:\n%*s",
531480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org						indent, "", indent + 2, "");
532480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
533480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_puts(out, "\n");
534480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
535480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
536480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
537480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
538480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
539480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		   int indent)
540480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
541480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ISSUING_DIST_POINT *idp = pidp;
542480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (idp->distpoint)
543480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		print_distpoint(out, idp->distpoint, indent);
544480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (idp->onlyuser > 0)
545480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
546480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (idp->onlyCA > 0)
547480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
548480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (idp->indirectCRL > 0)
549480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_printf(out, "%*sIndirect CRL\n", indent, "");
550480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (idp->onlysomereasons)
551480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		print_reasons(out, "Only Some Reasons",
552480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				idp->onlysomereasons, indent);
553480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (idp->onlyattr > 0)
554480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
555480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
556480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		&& (idp->indirectCRL <= 0) && !idp->onlysomereasons
557480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		&& (idp->onlyattr <= 0))
558480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_printf(out, "%*s<EMPTY>\n", indent, "");
559480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
560480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
561480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
562480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
563480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
564480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     int indent)
565480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
566480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	STACK_OF(DIST_POINT) *crld = pcrldp;
567480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	DIST_POINT *point;
568480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
569480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for(i = 0; i < sk_DIST_POINT_num(crld); i++)
570480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
571480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		BIO_puts(out, "\n");
572480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		point = sk_DIST_POINT_value(crld, i);
573480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if(point->distpoint)
574480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			print_distpoint(out, point->distpoint, indent);
575480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if(point->reasons)
576480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			print_reasons(out, "Reasons", point->reasons,
577480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org								indent);
578480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if(point->CRLissuer)
579480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
580480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
581480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			print_gens(out, point->CRLissuer, indent);
582480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
583480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
584480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
585480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
586480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
587480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
588480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
589480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
590480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	STACK_OF(X509_NAME_ENTRY) *frag;
591480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_NAME_ENTRY *ne;
592480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!dpn || (dpn->type != 1))
593480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 1;
594480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	frag = dpn->name.relativename;
595480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	dpn->dpname = X509_NAME_dup(iname);
596480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!dpn->dpname)
597480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
598480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
599480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
600480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ne = sk_X509_NAME_ENTRY_value(frag, i);
601480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
602480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
603480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_NAME_free(dpn->dpname);
604480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			dpn->dpname = NULL;
605480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
606480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
607480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
608480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* generate cached encoding of name */
609480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
610480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
611480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509_NAME_free(dpn->dpname);
612480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		dpn->dpname = NULL;
613480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
614480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
615480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
616480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
617