1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Contributed to the OpenSSL Project 2004
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Richard Levitte (richard@levitte.org)
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
51762a559ef393f9c15300398433598989033385fDavid 'Digit' Turner/* Copyright (c) 2004 Kungliga Tekniska Högskolan
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (Royal Institute of Technology, Stockholm, Sweden).
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. Neither the name of the Institute nor the names of its contributors
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    may be used to endorse or promote products derived from this software
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    without specific prior written permission.
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/conf.h>
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509v3.h>
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO *out, int indent);
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509V3_CTX *ctx, char *str);
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst X509V3_EXT_METHOD v3_pci =
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  0,0,0,0,
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  0,0,
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  NULL, NULL,
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  (X509V3_EXT_I2R)i2r_pci,
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  (X509V3_EXT_R2I)r2i_pci,
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  NULL,
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO *out, int indent)
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (pci->pcPathLengthConstraint)
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  BIO_printf(out, "infinite");
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_puts(out, "\n");
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(out, "%*sPolicy Language: ", indent, "");
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_puts(out, "\n");
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	  BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		     pci->proxyPolicy->policy->data);
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int process_pci_value(CONF_VALUE *val,
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OCTET_STRING **policy)
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int free_policy = 0;
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (strcmp(val->name, "language") == 0)
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (*language)
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3_conf_err(val);
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(*language = OBJ_txt2obj(val->value, 0)))
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3_conf_err(val);
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (strcmp(val->name, "pathlen") == 0)
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (*pathlen)
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3_conf_err(val);
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!X509V3_get_value_int(val, pathlen))
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH);
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3_conf_err(val);
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (strcmp(val->name, "policy") == 0)
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned char *tmp_data = NULL;
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		long val_len;
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!*policy)
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*policy = ASN1_OCTET_STRING_new();
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!*policy)
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3_conf_err(val);
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return 0;
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			free_policy = 1;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (strncmp(val->value, "hex:", 4) == 0)
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned char *tmp_data2 =
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				string_to_hex(val->value + 4, &val_len);
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1313d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			if (!tmp_data2)
1323d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				{
1333d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_ILLEGAL_HEX_DIGIT);
1343d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				X509V3_conf_err(val);
1353d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err;
1363d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				}
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			tmp_data = OPENSSL_realloc((*policy)->data,
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->length + val_len + 1);
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (tmp_data)
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->data = tmp_data;
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				memcpy(&(*policy)->data[(*policy)->length],
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					tmp_data2, val_len);
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->length += val_len;
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->data[(*policy)->length] = '\0';
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1483d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			else
1493d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				{
1503d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				OPENSSL_free(tmp_data2);
1513d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				/* realloc failure implies the original data space is b0rked too! */
1523d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				(*policy)->data = NULL;
1533d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				(*policy)->length = 0;
1543d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
1553d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				X509V3_conf_err(val);
1563d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err;
1573d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				}
1583d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			OPENSSL_free(tmp_data2);
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (strncmp(val->value, "file:", 5) == 0)
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned char buf[2048];
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			int n;
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO *b = BIO_new_file(val->value + 5, "r");
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!b)
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3_conf_err(val);
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			while((n = BIO_read(b, buf, sizeof(buf))) > 0
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				|| (n == 0 && BIO_should_retry(b)))
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (!n) continue;
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				tmp_data = OPENSSL_realloc((*policy)->data,
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					(*policy)->length + n + 1);
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (!tmp_data)
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					break;
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->data = tmp_data;
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				memcpy(&(*policy)->data[(*policy)->length],
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					buf, n);
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->length += n;
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->data[(*policy)->length] = '\0';
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1883d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			BIO_free_all(b);
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (n < 0)
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3_conf_err(val);
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (strncmp(val->value, "text:", 5) == 0)
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			val_len = strlen(val->value + 5);
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			tmp_data = OPENSSL_realloc((*policy)->data,
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->length + val_len + 1);
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (tmp_data)
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->data = tmp_data;
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				memcpy(&(*policy)->data[(*policy)->length],
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					val->value + 5, val_len);
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->length += val_len;
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(*policy)->data[(*policy)->length] = '\0';
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
2103d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			else
2113d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				{
2123d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				/* realloc failure implies the original data space is b0rked too! */
2133d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				(*policy)->data = NULL;
2143d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				(*policy)->length = 0;
2153d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
2163d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				X509V3_conf_err(val);
2173d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err;
2183d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				}
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3_conf_err(val);
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!tmp_data)
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3_conf_err(val);
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (free_policy)
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_OCTET_STRING_free(*policy);
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*policy = NULL;
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509V3_CTX *ctx, char *value)
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	PROXY_CERT_INFO_EXTENSION *pci = NULL;
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(CONF_VALUE) *vals;
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OBJECT *language = NULL;
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_INTEGER *pathlen = NULL;
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OCTET_STRING *policy = NULL;
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i, j;
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	vals = X509V3_parse_list(value);
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < sk_CONF_VALUE_num(vals); i++)
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!cnf->name || (*cnf->name != '@' && !cnf->value))
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_PROXY_POLICY_SETTING);
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3_conf_err(cnf);
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (*cnf->name == '@')
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			STACK_OF(CONF_VALUE) *sect;
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			int success_p = 1;
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			sect = X509V3_get_section(ctx, cnf->name + 1);
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!sect)
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_SECTION);
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3_conf_err(cnf);
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++)
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				success_p =
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					process_pci_value(sk_CONF_VALUE_value(sect, j),
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						&language, &pathlen, &policy);
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509V3_section_free(ctx, sect);
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!success_p)
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!process_pci_value(cnf,
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					&language, &pathlen, &policy))
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				X509V3_conf_err(cnf);
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Language is mandatory */
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!language)
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	i = OBJ_obj2nid(language);
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy)
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	pci = PROXY_CERT_INFO_EXTENSION_new();
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!pci)
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	pci->proxyPolicy->policyLanguage = language; language = NULL;
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	pci->proxyPolicy->policy = policy; policy = NULL;
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	pci->pcPathLengthConstraint = pathlen; pathlen = NULL;
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	goto end;
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (language) { ASN1_OBJECT_free(language); language = NULL; }
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectend:
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return pci;
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
329