xref: /onnv-gate/usr/src/common/openssl/crypto/x509v3/v3_pci.c (revision 2139:6243c3338933)
1*2139Sjp161948 /* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
2*2139Sjp161948 /* Contributed to the OpenSSL Project 2004
3*2139Sjp161948  * by Richard Levitte (richard@levitte.org)
4*2139Sjp161948  */
5*2139Sjp161948 /* Copyright (c) 2004 Kungliga Tekniska H�gskolan
6*2139Sjp161948  * (Royal Institute of Technology, Stockholm, Sweden).
7*2139Sjp161948  * All rights reserved.
8*2139Sjp161948  *
9*2139Sjp161948  * Redistribution and use in source and binary forms, with or without
10*2139Sjp161948  * modification, are permitted provided that the following conditions
11*2139Sjp161948  * are met:
12*2139Sjp161948  *
13*2139Sjp161948  * 1. Redistributions of source code must retain the above copyright
14*2139Sjp161948  *    notice, this list of conditions and the following disclaimer.
15*2139Sjp161948  *
16*2139Sjp161948  * 2. Redistributions in binary form must reproduce the above copyright
17*2139Sjp161948  *    notice, this list of conditions and the following disclaimer in the
18*2139Sjp161948  *    documentation and/or other materials provided with the distribution.
19*2139Sjp161948  *
20*2139Sjp161948  * 3. Neither the name of the Institute nor the names of its contributors
21*2139Sjp161948  *    may be used to endorse or promote products derived from this software
22*2139Sjp161948  *    without specific prior written permission.
23*2139Sjp161948  *
24*2139Sjp161948  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
25*2139Sjp161948  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*2139Sjp161948  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27*2139Sjp161948  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
28*2139Sjp161948  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29*2139Sjp161948  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30*2139Sjp161948  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31*2139Sjp161948  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32*2139Sjp161948  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33*2139Sjp161948  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34*2139Sjp161948  * SUCH DAMAGE.
35*2139Sjp161948  */
36*2139Sjp161948 
37*2139Sjp161948 #include <stdio.h>
38*2139Sjp161948 #include "cryptlib.h"
39*2139Sjp161948 #include <openssl/conf.h>
40*2139Sjp161948 #include <openssl/x509v3.h>
41*2139Sjp161948 
42*2139Sjp161948 static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
43*2139Sjp161948 	BIO *out, int indent);
44*2139Sjp161948 static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
45*2139Sjp161948 	X509V3_CTX *ctx, char *str);
46*2139Sjp161948 
47*2139Sjp161948 X509V3_EXT_METHOD v3_pci =
48*2139Sjp161948 	{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
49*2139Sjp161948 	  0,0,0,0,
50*2139Sjp161948 	  0,0,
51*2139Sjp161948 	  NULL, NULL,
52*2139Sjp161948 	  (X509V3_EXT_I2R)i2r_pci,
53*2139Sjp161948 	  (X509V3_EXT_R2I)r2i_pci,
54*2139Sjp161948 	  NULL,
55*2139Sjp161948 	};
56*2139Sjp161948 
i2r_pci(X509V3_EXT_METHOD * method,PROXY_CERT_INFO_EXTENSION * pci,BIO * out,int indent)57*2139Sjp161948 static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
58*2139Sjp161948 	BIO *out, int indent)
59*2139Sjp161948 	{
60*2139Sjp161948 	BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
61*2139Sjp161948 	if (pci->pcPathLengthConstraint)
62*2139Sjp161948 	  i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
63*2139Sjp161948 	else
64*2139Sjp161948 	  BIO_printf(out, "infinite");
65*2139Sjp161948 	BIO_puts(out, "\n");
66*2139Sjp161948 	BIO_printf(out, "%*sPolicy Language: ", indent, "");
67*2139Sjp161948 	i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
68*2139Sjp161948 	BIO_puts(out, "\n");
69*2139Sjp161948 	if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
70*2139Sjp161948 	  BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
71*2139Sjp161948 		     pci->proxyPolicy->policy->data);
72*2139Sjp161948 	return 1;
73*2139Sjp161948 	}
74*2139Sjp161948 
process_pci_value(CONF_VALUE * val,ASN1_OBJECT ** language,ASN1_INTEGER ** pathlen,ASN1_OCTET_STRING ** policy)75*2139Sjp161948 static int process_pci_value(CONF_VALUE *val,
76*2139Sjp161948 	ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
77*2139Sjp161948 	ASN1_OCTET_STRING **policy)
78*2139Sjp161948 	{
79*2139Sjp161948 	int free_policy = 0;
80*2139Sjp161948 
81*2139Sjp161948 	if (strcmp(val->name, "language") == 0)
82*2139Sjp161948 		{
83*2139Sjp161948 		if (*language)
84*2139Sjp161948 			{
85*2139Sjp161948 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED);
86*2139Sjp161948 			X509V3_conf_err(val);
87*2139Sjp161948 			return 0;
88*2139Sjp161948 			}
89*2139Sjp161948 		if (!(*language = OBJ_txt2obj(val->value, 0)))
90*2139Sjp161948 			{
91*2139Sjp161948 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
92*2139Sjp161948 			X509V3_conf_err(val);
93*2139Sjp161948 			return 0;
94*2139Sjp161948 			}
95*2139Sjp161948 		}
96*2139Sjp161948 	else if (strcmp(val->name, "pathlen") == 0)
97*2139Sjp161948 		{
98*2139Sjp161948 		if (*pathlen)
99*2139Sjp161948 			{
100*2139Sjp161948 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED);
101*2139Sjp161948 			X509V3_conf_err(val);
102*2139Sjp161948 			return 0;
103*2139Sjp161948 			}
104*2139Sjp161948 		if (!X509V3_get_value_int(val, pathlen))
105*2139Sjp161948 			{
106*2139Sjp161948 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH);
107*2139Sjp161948 			X509V3_conf_err(val);
108*2139Sjp161948 			return 0;
109*2139Sjp161948 			}
110*2139Sjp161948 		}
111*2139Sjp161948 	else if (strcmp(val->name, "policy") == 0)
112*2139Sjp161948 		{
113*2139Sjp161948 		unsigned char *tmp_data = NULL;
114*2139Sjp161948 		long val_len;
115*2139Sjp161948 		if (!*policy)
116*2139Sjp161948 			{
117*2139Sjp161948 			*policy = ASN1_OCTET_STRING_new();
118*2139Sjp161948 			if (!*policy)
119*2139Sjp161948 				{
120*2139Sjp161948 				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
121*2139Sjp161948 				X509V3_conf_err(val);
122*2139Sjp161948 				return 0;
123*2139Sjp161948 				}
124*2139Sjp161948 			free_policy = 1;
125*2139Sjp161948 			}
126*2139Sjp161948 		if (strncmp(val->value, "hex:", 4) == 0)
127*2139Sjp161948 			{
128*2139Sjp161948 			unsigned char *tmp_data2 =
129*2139Sjp161948 				string_to_hex(val->value + 4, &val_len);
130*2139Sjp161948 
131*2139Sjp161948 			if (!tmp_data2) goto err;
132*2139Sjp161948 
133*2139Sjp161948 			tmp_data = OPENSSL_realloc((*policy)->data,
134*2139Sjp161948 				(*policy)->length + val_len + 1);
135*2139Sjp161948 			if (tmp_data)
136*2139Sjp161948 				{
137*2139Sjp161948 				(*policy)->data = tmp_data;
138*2139Sjp161948 				memcpy(&(*policy)->data[(*policy)->length],
139*2139Sjp161948 					tmp_data2, val_len);
140*2139Sjp161948 				(*policy)->length += val_len;
141*2139Sjp161948 				(*policy)->data[(*policy)->length] = '\0';
142*2139Sjp161948 				}
143*2139Sjp161948 			}
144*2139Sjp161948 		else if (strncmp(val->value, "file:", 5) == 0)
145*2139Sjp161948 			{
146*2139Sjp161948 			unsigned char buf[2048];
147*2139Sjp161948 			int n;
148*2139Sjp161948 			BIO *b = BIO_new_file(val->value + 5, "r");
149*2139Sjp161948 			if (!b)
150*2139Sjp161948 				{
151*2139Sjp161948 				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
152*2139Sjp161948 				X509V3_conf_err(val);
153*2139Sjp161948 				goto err;
154*2139Sjp161948 				}
155*2139Sjp161948 			while((n = BIO_read(b, buf, sizeof(buf))) > 0
156*2139Sjp161948 				|| (n == 0 && BIO_should_retry(b)))
157*2139Sjp161948 				{
158*2139Sjp161948 				if (!n) continue;
159*2139Sjp161948 
160*2139Sjp161948 				tmp_data = OPENSSL_realloc((*policy)->data,
161*2139Sjp161948 					(*policy)->length + n + 1);
162*2139Sjp161948 
163*2139Sjp161948 				if (!tmp_data)
164*2139Sjp161948 					break;
165*2139Sjp161948 
166*2139Sjp161948 				(*policy)->data = tmp_data;
167*2139Sjp161948 				memcpy(&(*policy)->data[(*policy)->length],
168*2139Sjp161948 					buf, n);
169*2139Sjp161948 				(*policy)->length += n;
170*2139Sjp161948 				(*policy)->data[(*policy)->length] = '\0';
171*2139Sjp161948 				}
172*2139Sjp161948 
173*2139Sjp161948 			if (n < 0)
174*2139Sjp161948 				{
175*2139Sjp161948 				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
176*2139Sjp161948 				X509V3_conf_err(val);
177*2139Sjp161948 				goto err;
178*2139Sjp161948 				}
179*2139Sjp161948 			}
180*2139Sjp161948 		else if (strncmp(val->value, "text:", 5) == 0)
181*2139Sjp161948 			{
182*2139Sjp161948 			val_len = strlen(val->value + 5);
183*2139Sjp161948 			tmp_data = OPENSSL_realloc((*policy)->data,
184*2139Sjp161948 				(*policy)->length + val_len + 1);
185*2139Sjp161948 			if (tmp_data)
186*2139Sjp161948 				{
187*2139Sjp161948 				(*policy)->data = tmp_data;
188*2139Sjp161948 				memcpy(&(*policy)->data[(*policy)->length],
189*2139Sjp161948 					val->value + 5, val_len);
190*2139Sjp161948 				(*policy)->length += val_len;
191*2139Sjp161948 				(*policy)->data[(*policy)->length] = '\0';
192*2139Sjp161948 				}
193*2139Sjp161948 			}
194*2139Sjp161948 		else
195*2139Sjp161948 			{
196*2139Sjp161948 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
197*2139Sjp161948 			X509V3_conf_err(val);
198*2139Sjp161948 			goto err;
199*2139Sjp161948 			}
200*2139Sjp161948 		if (!tmp_data)
201*2139Sjp161948 			{
202*2139Sjp161948 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
203*2139Sjp161948 			X509V3_conf_err(val);
204*2139Sjp161948 			goto err;
205*2139Sjp161948 			}
206*2139Sjp161948 		}
207*2139Sjp161948 	return 1;
208*2139Sjp161948 err:
209*2139Sjp161948 	if (free_policy)
210*2139Sjp161948 		{
211*2139Sjp161948 		ASN1_OCTET_STRING_free(*policy);
212*2139Sjp161948 		*policy = NULL;
213*2139Sjp161948 		}
214*2139Sjp161948 	return 0;
215*2139Sjp161948 	}
216*2139Sjp161948 
r2i_pci(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,char * value)217*2139Sjp161948 static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
218*2139Sjp161948 	X509V3_CTX *ctx, char *value)
219*2139Sjp161948 	{
220*2139Sjp161948 	PROXY_CERT_INFO_EXTENSION *pci = NULL;
221*2139Sjp161948 	STACK_OF(CONF_VALUE) *vals;
222*2139Sjp161948 	ASN1_OBJECT *language = NULL;
223*2139Sjp161948 	ASN1_INTEGER *pathlen = NULL;
224*2139Sjp161948 	ASN1_OCTET_STRING *policy = NULL;
225*2139Sjp161948 	int i, j;
226*2139Sjp161948 
227*2139Sjp161948 	vals = X509V3_parse_list(value);
228*2139Sjp161948 	for (i = 0; i < sk_CONF_VALUE_num(vals); i++)
229*2139Sjp161948 		{
230*2139Sjp161948 		CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
231*2139Sjp161948 		if (!cnf->name || (*cnf->name != '@' && !cnf->value))
232*2139Sjp161948 			{
233*2139Sjp161948 			X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_PROXY_POLICY_SETTING);
234*2139Sjp161948 			X509V3_conf_err(cnf);
235*2139Sjp161948 			goto err;
236*2139Sjp161948 			}
237*2139Sjp161948 		if (*cnf->name == '@')
238*2139Sjp161948 			{
239*2139Sjp161948 			STACK_OF(CONF_VALUE) *sect;
240*2139Sjp161948 			int success_p = 1;
241*2139Sjp161948 
242*2139Sjp161948 			sect = X509V3_get_section(ctx, cnf->name + 1);
243*2139Sjp161948 			if (!sect)
244*2139Sjp161948 				{
245*2139Sjp161948 				X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_SECTION);
246*2139Sjp161948 				X509V3_conf_err(cnf);
247*2139Sjp161948 				goto err;
248*2139Sjp161948 				}
249*2139Sjp161948 			for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++)
250*2139Sjp161948 				{
251*2139Sjp161948 				success_p =
252*2139Sjp161948 					process_pci_value(sk_CONF_VALUE_value(sect, j),
253*2139Sjp161948 						&language, &pathlen, &policy);
254*2139Sjp161948 				}
255*2139Sjp161948 			X509V3_section_free(ctx, sect);
256*2139Sjp161948 			if (!success_p)
257*2139Sjp161948 				goto err;
258*2139Sjp161948 			}
259*2139Sjp161948 		else
260*2139Sjp161948 			{
261*2139Sjp161948 			if (!process_pci_value(cnf,
262*2139Sjp161948 					&language, &pathlen, &policy))
263*2139Sjp161948 				{
264*2139Sjp161948 				X509V3_conf_err(cnf);
265*2139Sjp161948 				goto err;
266*2139Sjp161948 				}
267*2139Sjp161948 			}
268*2139Sjp161948 		}
269*2139Sjp161948 
270*2139Sjp161948 	/* Language is mandatory */
271*2139Sjp161948 	if (!language)
272*2139Sjp161948 		{
273*2139Sjp161948 		X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
274*2139Sjp161948 		goto err;
275*2139Sjp161948 		}
276*2139Sjp161948 	i = OBJ_obj2nid(language);
277*2139Sjp161948 	if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy)
278*2139Sjp161948 		{
279*2139Sjp161948 		X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
280*2139Sjp161948 		goto err;
281*2139Sjp161948 		}
282*2139Sjp161948 
283*2139Sjp161948 	pci = PROXY_CERT_INFO_EXTENSION_new();
284*2139Sjp161948 	if (!pci)
285*2139Sjp161948 		{
286*2139Sjp161948 		X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
287*2139Sjp161948 		goto err;
288*2139Sjp161948 		}
289*2139Sjp161948 	pci->proxyPolicy = PROXY_POLICY_new();
290*2139Sjp161948 	if (!pci->proxyPolicy)
291*2139Sjp161948 		{
292*2139Sjp161948 		X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
293*2139Sjp161948 		goto err;
294*2139Sjp161948 		}
295*2139Sjp161948 
296*2139Sjp161948 	pci->proxyPolicy->policyLanguage = language; language = NULL;
297*2139Sjp161948 	pci->proxyPolicy->policy = policy; policy = NULL;
298*2139Sjp161948 	pci->pcPathLengthConstraint = pathlen; pathlen = NULL;
299*2139Sjp161948 	goto end;
300*2139Sjp161948 err:
301*2139Sjp161948 	if (language) { ASN1_OBJECT_free(language); language = NULL; }
302*2139Sjp161948 	if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
303*2139Sjp161948 	if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
304*2139Sjp161948 	if (pci && pci->proxyPolicy)
305*2139Sjp161948 		{
306*2139Sjp161948 		PROXY_POLICY_free(pci->proxyPolicy);
307*2139Sjp161948 		pci->proxyPolicy = NULL;
308*2139Sjp161948 		}
309*2139Sjp161948 	if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
310*2139Sjp161948 end:
311*2139Sjp161948 	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
312*2139Sjp161948 	return pci;
313*2139Sjp161948 	}
314