195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* v3_crld.c */
295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * project 1999.
495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* ====================================================================
695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without
995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions
1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met:
1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the above copyright
1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer.
1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright
1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer in
1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    the documentation and/or other materials provided with the
1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    distribution.
1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this
2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    software must display the following acknowledgment:
2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software developed by the OpenSSL Project
2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    endorse or promote products derived from this software without
2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    prior written permission. For written permission, please contact
2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    licensing@OpenSSL.org.
2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5. Products derived from this software may not be called "OpenSSL"
3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    nor may "OpenSSL" appear in their names without prior written
3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    permission of the OpenSSL Project.
3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6. Redistributions of any form whatsoever must retain the following
3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    acknowledgment:
3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software developed by the OpenSSL Project
3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF THE POSSIBILITY OF SUCH DAMAGE.
5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ====================================================================
5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This product includes cryptographic software written by Eric Young
5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (eay@cryptsoft.com).  This product includes software written by Tim
5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Hudson (tjh@cryptsoft.com). */
5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <stdio.h>
5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/asn1.h>
6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/asn1t.h>
6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/conf.h>
6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h>
6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h>
6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/obj.h>
6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/x509v3.h>
6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void *v2i_crld(const X509V3_EXT_METHOD *method,
6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		     int indent);
7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst X509V3_EXT_METHOD v3_crld =
7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,0,0,0,
7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,0,
7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,
7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	v2i_crld,
8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	i2r_crldp,0,
8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	NULL
8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	};
8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst X509V3_EXT_METHOD v3_freshest_crl =
8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,0,0,0,
8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,0,
8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,
9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	v2i_crld,
9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	i2r_crldp,0,
9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	NULL
9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	};
9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(CONF_VALUE) *gnsect;
9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(GENERAL_NAME) *gens;
9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (*sect == '@')
10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		gnsect = X509V3_get_section(ctx, sect + 1);
10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		gnsect = X509V3_parse_list(sect);
10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!gnsect)
10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(X509V3, gnames_from_sectname, X509V3_R_SECTION_NOT_FOUND);
10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return NULL;
10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (*sect == '@')
11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509V3_section_free(ctx, gnsect);
11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return gens;
11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley							CONF_VALUE *cnf)
11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(GENERAL_NAME) *fnm = NULL;
12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!strncmp(cnf->name, "fullname", 9))
12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		fnm = gnames_from_sectname(ctx, cnf->value);
12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!fnm)
12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else if (!strcmp(cnf->name, "relativename"))
12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		int ret;
13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		STACK_OF(CONF_VALUE) *dnsect;
13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_NAME *nm;
13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		nm = X509_NAME_new();
13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!nm)
13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return -1;
13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		dnsect = X509V3_get_section(ctx, cnf->value);
13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!dnsect)
13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_SECTION_NOT_FOUND);
13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return -1;
14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509V3_section_free(ctx, dnsect);
14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		rnm = nm->entries;
14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		nm->entries = NULL;
14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_NAME_free(nm);
14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		/* Since its a name fragment can't have more than one
14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 * RDNSequence
15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		 */
15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (sk_X509_NAME_ENTRY_value(rnm,
15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_INVALID_MULTIPLE_RDNS);
15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (*pdp)
16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_DISTPOINT_ALREADY_SET);
16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto err;
16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	*pdp = DIST_POINT_NAME_new();
16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!*pdp)
16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto err;
17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (fnm)
17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(*pdp)->type = 0;
17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(*pdp)->name.fullname = fnm;
17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(*pdp)->type = 1;
17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		(*pdp)->name.relativename = rnm;
17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	err:
18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (fnm)
18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (rnm)
18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return -1;
18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic const BIT_STRING_BITNAME reason_flags[] = {
19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{0, "Unused", "unused"},
19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{1, "Key Compromise", "keyCompromise"},
19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{2, "CA Compromise", "CACompromise"},
19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{3, "Affiliation Changed", "affiliationChanged"},
19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{4, "Superseded", "superseded"},
19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{5, "Cessation Of Operation", "cessationOfOperation"},
19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{6, "Certificate Hold", "certificateHold"},
19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{7, "Privilege Withdrawn", "privilegeWithdrawn"},
20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{8, "AA Compromise", "AACompromise"},
20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley{-1, NULL, NULL}
20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley};
20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int set_reasons(ASN1_BIT_STRING **preas, char *value)
20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(CONF_VALUE) *rsk = NULL;
20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	const BIT_STRING_BITNAME *pbn;
20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	const char *bnam;
20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int ret = 0;
21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	rsk = X509V3_parse_list(value);
21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!rsk)
21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (*preas)
21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		bnam = sk_CONF_VALUE_value(rsk, i)->name;
21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!*preas)
22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			*preas = ASN1_BIT_STRING_new();
22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!*preas)
22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		for (pbn = reason_flags; pbn->lname; pbn++)
22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!strcmp(pbn->sname, bnam))
22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				if (!ASN1_BIT_STRING_set_bit(*preas,
23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley							pbn->bitnum, 1))
23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley					goto err;
23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				break;
23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!pbn->lname)
23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ret = 1;
23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	err:
24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return ret;
24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int print_reasons(BIO *out, const char *rname,
24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			ASN1_BIT_STRING *rflags, int indent)
24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int first = 1;
24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	const BIT_STRING_BITNAME *pbn;
25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (pbn = reason_flags; pbn->lname; pbn++)
25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (first)
25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				first = 0;
25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			else
25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				BIO_puts(out, ", ");
25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			BIO_puts(out, pbn->lname);
26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (first)
26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_puts(out, "<EMPTY>\n");
26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_puts(out, "\n");
26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						STACK_OF(CONF_VALUE) *nval)
27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CONF_VALUE *cnf;
27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	DIST_POINT *point = NULL;
27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	point = DIST_POINT_new();
27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!point)
27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto err;
27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		int ret;
28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		cnf = sk_CONF_VALUE_value(nval, i);
28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ret = set_dist_point_name(&point->distpoint, ctx, cnf);
28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (ret > 0)
28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			continue;
28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (ret < 0)
28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!strcmp(cnf->name, "reasons"))
28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!set_reasons(&point->reasons, cnf->value))
29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (!strcmp(cnf->name, "CRLissuer"))
29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			point->CRLissuer =
29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				gnames_from_sectname(ctx, cnf->value);
29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!point->CRLissuer)
29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return point;
30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	err:
30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (point)
30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		DIST_POINT_free(point);
30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return NULL;
30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void *v2i_crld(const X509V3_EXT_METHOD *method,
31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(DIST_POINT) *crld = NULL;
31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	GENERAL_NAMES *gens = NULL;
31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	GENERAL_NAME *gen = NULL;
31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CONF_VALUE *cnf;
31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if(!(crld = sk_DIST_POINT_new_null())) goto merr;
31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		DIST_POINT *point;
32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		cnf = sk_CONF_VALUE_value(nval, i);
32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!cnf->value)
32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			STACK_OF(CONF_VALUE) *dpsect;
32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			dpsect = X509V3_get_section(ctx, cnf->name);
32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!dpsect)
32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			point = crldp_from_section(ctx, dpsect);
32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509V3_section_free(ctx, dpsect);
33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!point)
33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if(!sk_DIST_POINT_push(crld, point))
33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				DIST_POINT_free(point);
33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto merr;
33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if(!(gens = GENERAL_NAMES_new()))
34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto merr;
34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if(!sk_GENERAL_NAME_push(gens, gen))
34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto merr;
34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			gen = NULL;
34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if(!(point = DIST_POINT_new()))
34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto merr;
34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if(!sk_DIST_POINT_push(crld, point))
35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				{
35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				DIST_POINT_free(point);
35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto merr;
35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				}
35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if(!(point->distpoint = DIST_POINT_NAME_new()))
35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto merr;
35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			point->distpoint->name.fullname = gens;
35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			point->distpoint->type = 0;
35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			gens = NULL;
35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return crld;
36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	merr:
36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	OPENSSL_PUT_ERROR(X509V3, v2i_crld, ERR_R_MALLOC_FAILURE);
36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	err:
36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	GENERAL_NAME_free(gen);
36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	GENERAL_NAMES_free(gens);
36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return NULL;
37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37295c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyIMPLEMENT_ASN1_SET_OF(DIST_POINT)
37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley								void *exarg)
37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	switch(operation)
38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		case ASN1_OP_NEW_POST:
38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		dpn->dpname = NULL;
38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		break;
38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		case ASN1_OP_FREE_POST:
38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (dpn->dpname)
38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_NAME_free(dpn->dpname);
38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		break;
38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
39495c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
40095c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyIMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
40295c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyASN1_SEQUENCE(DIST_POINT) = {
40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} ASN1_SEQUENCE_END(DIST_POINT)
40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
40895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyIMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
41095c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
41295c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
41495c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyIMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
41695c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyASN1_SEQUENCE(ISSUING_DIST_POINT) = {
41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
42595c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyIMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		   int indent);
42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		     STACK_OF(CONF_VALUE) *nval);
43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst X509V3_EXT_METHOD v3_idp =
43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ASN1_ITEM_ref(ISSUING_DIST_POINT),
43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,0,0,0,
43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,0,
43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	0,
43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	v2i_idp,
44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	i2r_idp,0,
44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	NULL
44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	};
44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		     STACK_OF(CONF_VALUE) *nval)
44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ISSUING_DIST_POINT *idp = NULL;
44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	CONF_VALUE *cnf;
44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	char *name, *val;
45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	int ret;
45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	idp = ISSUING_DIST_POINT_new();
45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!idp)
45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		goto merr;
45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		cnf = sk_CONF_VALUE_value(nval, i);
45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		name = cnf->name;
45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		val = cnf->value;
46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (ret > 0)
46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			continue;
46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (ret < 0)
46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			goto err;
46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!strcmp(name, "onlyuser"))
46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (!strcmp(name, "onlyCA"))
47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (!strcmp(name, "onlyAA"))
47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (!strcmp(name, "indirectCRL"))
48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else if (!strcmp(name, "onlysomereasons"))
48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			if (!set_reasons(&idp->onlysomereasons, val))
48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				goto err;
48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		else
49195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                        OPENSSL_PUT_ERROR(X509V3, v2i_idp, X509V3_R_INVALID_NAME);
49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                        X509V3_conf_err(cnf);
49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                        goto err;
49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return idp;
49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	merr:
50095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	OPENSSL_PUT_ERROR(X509V3, v2i_idp, ERR_R_MALLOC_FAILURE);
50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	err:
50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ISSUING_DIST_POINT_free(idp);
50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return NULL;
50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
50695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
50895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
51095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
51195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_printf(out, "%*s", indent + 2, "");
51295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_puts(out, "\n");
51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
51695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
51795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
51895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
51995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
52095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (dpn->type == 0)
52195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
52295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_printf(out, "%*sFull Name:\n", indent, "");
52395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		print_gens(out, dpn->name.fullname, indent);
52495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
52595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	else
52695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
52795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_NAME ntmp;
52895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ntmp.entries = dpn->name.relativename;
52995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_printf(out, "%*sRelative Name:\n%*s",
53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley						indent, "", indent + 2, "");
53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_puts(out, "\n");
53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
53595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		   int indent)
53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	ISSUING_DIST_POINT *idp = pidp;
54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idp->distpoint)
54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		print_distpoint(out, idp->distpoint, indent);
54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idp->onlyuser > 0)
54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idp->onlyCA > 0)
54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idp->indirectCRL > 0)
54895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_printf(out, "%*sIndirect CRL\n", indent, "");
54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idp->onlysomereasons)
55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		print_reasons(out, "Only Some Reasons",
55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley				idp->onlysomereasons, indent);
55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (idp->onlyattr > 0)
55395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		&& (idp->indirectCRL <= 0) && !idp->onlysomereasons
55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		&& (idp->onlyattr <= 0))
55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_printf(out, "%*s<EMPTY>\n", indent, "");
55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		     int indent)
56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(DIST_POINT) *crld = pcrldp;
56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	DIST_POINT *point;
56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
56895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for(i = 0; i < sk_DIST_POINT_num(crld); i++)
56995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
57095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		BIO_puts(out, "\n");
57195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		point = sk_DIST_POINT_value(crld, i);
57295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if(point->distpoint)
57395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			print_distpoint(out, point->distpoint, indent);
57495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if(point->reasons)
57595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			print_reasons(out, "Reasons", point->reasons,
57695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley								indent);
57795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if(point->CRLissuer)
57895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
57995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
58095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			print_gens(out, point->CRLissuer, indent);
58195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
58295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
58395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
58495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
58595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
58695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
58795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	{
58895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	size_t i;
58995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	STACK_OF(X509_NAME_ENTRY) *frag;
59095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	X509_NAME_ENTRY *ne;
59195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!dpn || (dpn->type != 1))
59295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 1;
59395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	frag = dpn->name.relativename;
59495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	dpn->dpname = X509_NAME_dup(iname);
59595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (!dpn->dpname)
59695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
59795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
59895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
59995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		ne = sk_X509_NAME_ENTRY_value(frag, i);
60095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
60195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			{
60295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			X509_NAME_free(dpn->dpname);
60395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			dpn->dpname = NULL;
60495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			return 0;
60595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley			}
60695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
60795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	/* generate cached encoding of name */
60895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
60995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		{
61095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		X509_NAME_free(dpn->dpname);
61195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		dpn->dpname = NULL;
61295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		return 0;
61395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley		}
61495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	return 1;
61595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley	}
616