xref: /onnv-gate/usr/src/common/openssl/crypto/x509v3/v3_conf.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /* v3_conf.c */
2*0Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3*0Sstevel@tonic-gate  * project 1999.
4*0Sstevel@tonic-gate  */
5*0Sstevel@tonic-gate /* ====================================================================
6*0Sstevel@tonic-gate  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7*0Sstevel@tonic-gate  *
8*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
9*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
10*0Sstevel@tonic-gate  * are met:
11*0Sstevel@tonic-gate  *
12*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
13*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
14*0Sstevel@tonic-gate  *
15*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
16*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
17*0Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
18*0Sstevel@tonic-gate  *    distribution.
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
21*0Sstevel@tonic-gate  *    software must display the following acknowledgment:
22*0Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
23*0Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24*0Sstevel@tonic-gate  *
25*0Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26*0Sstevel@tonic-gate  *    endorse or promote products derived from this software without
27*0Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
28*0Sstevel@tonic-gate  *    licensing@OpenSSL.org.
29*0Sstevel@tonic-gate  *
30*0Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
31*0Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
32*0Sstevel@tonic-gate  *    permission of the OpenSSL Project.
33*0Sstevel@tonic-gate  *
34*0Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
35*0Sstevel@tonic-gate  *    acknowledgment:
36*0Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
37*0Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38*0Sstevel@tonic-gate  *
39*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40*0Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41*0Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42*0Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43*0Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44*0Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45*0Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46*0Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*0Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48*0Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49*0Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50*0Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
51*0Sstevel@tonic-gate  * ====================================================================
52*0Sstevel@tonic-gate  *
53*0Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
54*0Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
55*0Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
56*0Sstevel@tonic-gate  *
57*0Sstevel@tonic-gate  */
58*0Sstevel@tonic-gate /* extension creation utilities */
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate #include <stdio.h>
63*0Sstevel@tonic-gate #include <ctype.h>
64*0Sstevel@tonic-gate #include "cryptlib.h"
65*0Sstevel@tonic-gate #include <openssl/conf.h>
66*0Sstevel@tonic-gate #include <openssl/x509.h>
67*0Sstevel@tonic-gate #include <openssl/x509v3.h>
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate static int v3_check_critical(char **value);
70*0Sstevel@tonic-gate static int v3_check_generic(char **value);
71*0Sstevel@tonic-gate static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
72*0Sstevel@tonic-gate static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type);
73*0Sstevel@tonic-gate static char *conf_lhash_get_string(void *db, char *section, char *value);
74*0Sstevel@tonic-gate static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
75*0Sstevel@tonic-gate static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
76*0Sstevel@tonic-gate 						 int crit, void *ext_struc);
77*0Sstevel@tonic-gate /* CONF *conf:  Config file    */
78*0Sstevel@tonic-gate /* char *name:  Name    */
79*0Sstevel@tonic-gate /* char *value:  Value    */
80*0Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
81*0Sstevel@tonic-gate 	     char *value)
82*0Sstevel@tonic-gate 	{
83*0Sstevel@tonic-gate 	int crit;
84*0Sstevel@tonic-gate 	int ext_type;
85*0Sstevel@tonic-gate 	X509_EXTENSION *ret;
86*0Sstevel@tonic-gate 	crit = v3_check_critical(&value);
87*0Sstevel@tonic-gate 	if ((ext_type = v3_check_generic(&value)))
88*0Sstevel@tonic-gate 		return v3_generic_extension(name, value, crit, ext_type);
89*0Sstevel@tonic-gate 	ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
90*0Sstevel@tonic-gate 	if (!ret)
91*0Sstevel@tonic-gate 		{
92*0Sstevel@tonic-gate 		X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_ERROR_IN_EXTENSION);
93*0Sstevel@tonic-gate 		ERR_add_error_data(4,"name=", name, ", value=", value);
94*0Sstevel@tonic-gate 		}
95*0Sstevel@tonic-gate 	return ret;
96*0Sstevel@tonic-gate 	}
97*0Sstevel@tonic-gate 
98*0Sstevel@tonic-gate /* CONF *conf:  Config file    */
99*0Sstevel@tonic-gate /* char *value:  Value    */
100*0Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
101*0Sstevel@tonic-gate 	     char *value)
102*0Sstevel@tonic-gate 	{
103*0Sstevel@tonic-gate 	int crit;
104*0Sstevel@tonic-gate 	int ext_type;
105*0Sstevel@tonic-gate 	crit = v3_check_critical(&value);
106*0Sstevel@tonic-gate 	if ((ext_type = v3_check_generic(&value)))
107*0Sstevel@tonic-gate 		return v3_generic_extension(OBJ_nid2sn(ext_nid),
108*0Sstevel@tonic-gate 							 value, crit, ext_type);
109*0Sstevel@tonic-gate 	return do_ext_nconf(conf, ctx, ext_nid, crit, value);
110*0Sstevel@tonic-gate 	}
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate /* CONF *conf:  Config file    */
113*0Sstevel@tonic-gate /* char *value:  Value    */
114*0Sstevel@tonic-gate static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
115*0Sstevel@tonic-gate 	     int crit, char *value)
116*0Sstevel@tonic-gate 	{
117*0Sstevel@tonic-gate 	X509V3_EXT_METHOD *method;
118*0Sstevel@tonic-gate 	X509_EXTENSION *ext;
119*0Sstevel@tonic-gate 	STACK_OF(CONF_VALUE) *nval;
120*0Sstevel@tonic-gate 	void *ext_struc;
121*0Sstevel@tonic-gate 	if (ext_nid == NID_undef)
122*0Sstevel@tonic-gate 		{
123*0Sstevel@tonic-gate 		X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
124*0Sstevel@tonic-gate 		return NULL;
125*0Sstevel@tonic-gate 		}
126*0Sstevel@tonic-gate 	if (!(method = X509V3_EXT_get_nid(ext_nid)))
127*0Sstevel@tonic-gate 		{
128*0Sstevel@tonic-gate 		X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION);
129*0Sstevel@tonic-gate 		return NULL;
130*0Sstevel@tonic-gate 		}
131*0Sstevel@tonic-gate 	/* Now get internal extension representation based on type */
132*0Sstevel@tonic-gate 	if (method->v2i)
133*0Sstevel@tonic-gate 		{
134*0Sstevel@tonic-gate 		if(*value == '@') nval = NCONF_get_section(conf, value + 1);
135*0Sstevel@tonic-gate 		else nval = X509V3_parse_list(value);
136*0Sstevel@tonic-gate 		if(!nval)
137*0Sstevel@tonic-gate 			{
138*0Sstevel@tonic-gate 			X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_INVALID_EXTENSION_STRING);
139*0Sstevel@tonic-gate 			ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
140*0Sstevel@tonic-gate 			return NULL;
141*0Sstevel@tonic-gate 			}
142*0Sstevel@tonic-gate 		ext_struc = method->v2i(method, ctx, nval);
143*0Sstevel@tonic-gate 		if(*value != '@') sk_CONF_VALUE_pop_free(nval,
144*0Sstevel@tonic-gate 							 X509V3_conf_free);
145*0Sstevel@tonic-gate 		if(!ext_struc) return NULL;
146*0Sstevel@tonic-gate 		}
147*0Sstevel@tonic-gate 	else if(method->s2i)
148*0Sstevel@tonic-gate 		{
149*0Sstevel@tonic-gate 		if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
150*0Sstevel@tonic-gate 		}
151*0Sstevel@tonic-gate 	else if(method->r2i)
152*0Sstevel@tonic-gate 		{
153*0Sstevel@tonic-gate 		if(!ctx->db)
154*0Sstevel@tonic-gate 			{
155*0Sstevel@tonic-gate 			X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_NO_CONFIG_DATABASE);
156*0Sstevel@tonic-gate 			return NULL;
157*0Sstevel@tonic-gate 			}
158*0Sstevel@tonic-gate 		if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
159*0Sstevel@tonic-gate 		}
160*0Sstevel@tonic-gate 	else
161*0Sstevel@tonic-gate 		{
162*0Sstevel@tonic-gate 		X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
163*0Sstevel@tonic-gate 		ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
164*0Sstevel@tonic-gate 		return NULL;
165*0Sstevel@tonic-gate 		}
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	ext  = do_ext_i2d(method, ext_nid, crit, ext_struc);
168*0Sstevel@tonic-gate 	if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
169*0Sstevel@tonic-gate 	else method->ext_free(ext_struc);
170*0Sstevel@tonic-gate 	return ext;
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate 	}
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
175*0Sstevel@tonic-gate 						 int crit, void *ext_struc)
176*0Sstevel@tonic-gate 	{
177*0Sstevel@tonic-gate 	unsigned char *ext_der;
178*0Sstevel@tonic-gate 	int ext_len;
179*0Sstevel@tonic-gate 	ASN1_OCTET_STRING *ext_oct;
180*0Sstevel@tonic-gate 	X509_EXTENSION *ext;
181*0Sstevel@tonic-gate 	/* Convert internal representation to DER */
182*0Sstevel@tonic-gate 	if (method->it)
183*0Sstevel@tonic-gate 		{
184*0Sstevel@tonic-gate 		ext_der = NULL;
185*0Sstevel@tonic-gate 		ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
186*0Sstevel@tonic-gate 		if (ext_len < 0) goto merr;
187*0Sstevel@tonic-gate 		}
188*0Sstevel@tonic-gate 	 else
189*0Sstevel@tonic-gate 		{
190*0Sstevel@tonic-gate 		unsigned char *p;
191*0Sstevel@tonic-gate 		ext_len = method->i2d(ext_struc, NULL);
192*0Sstevel@tonic-gate 		if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
193*0Sstevel@tonic-gate 		p = ext_der;
194*0Sstevel@tonic-gate 		method->i2d(ext_struc, &p);
195*0Sstevel@tonic-gate 		}
196*0Sstevel@tonic-gate 	if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
197*0Sstevel@tonic-gate 	ext_oct->data = ext_der;
198*0Sstevel@tonic-gate 	ext_oct->length = ext_len;
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate 	ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
201*0Sstevel@tonic-gate 	if (!ext) goto merr;
202*0Sstevel@tonic-gate 	M_ASN1_OCTET_STRING_free(ext_oct);
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 	return ext;
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 	merr:
207*0Sstevel@tonic-gate 	X509V3err(X509V3_F_DO_EXT_I2D,ERR_R_MALLOC_FAILURE);
208*0Sstevel@tonic-gate 	return NULL;
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 	}
211*0Sstevel@tonic-gate 
212*0Sstevel@tonic-gate /* Given an internal structure, nid and critical flag create an extension */
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
215*0Sstevel@tonic-gate 	{
216*0Sstevel@tonic-gate 	X509V3_EXT_METHOD *method;
217*0Sstevel@tonic-gate 	if (!(method = X509V3_EXT_get_nid(ext_nid))) {
218*0Sstevel@tonic-gate 		X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
219*0Sstevel@tonic-gate 		return NULL;
220*0Sstevel@tonic-gate 	}
221*0Sstevel@tonic-gate 	return do_ext_i2d(method, ext_nid, crit, ext_struc);
222*0Sstevel@tonic-gate }
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate /* Check the extension string for critical flag */
225*0Sstevel@tonic-gate static int v3_check_critical(char **value)
226*0Sstevel@tonic-gate {
227*0Sstevel@tonic-gate 	char *p = *value;
228*0Sstevel@tonic-gate 	if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
229*0Sstevel@tonic-gate 	p+=9;
230*0Sstevel@tonic-gate 	while(isspace((unsigned char)*p)) p++;
231*0Sstevel@tonic-gate 	*value = p;
232*0Sstevel@tonic-gate 	return 1;
233*0Sstevel@tonic-gate }
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate /* Check extension string for generic extension and return the type */
236*0Sstevel@tonic-gate static int v3_check_generic(char **value)
237*0Sstevel@tonic-gate {
238*0Sstevel@tonic-gate 	char *p = *value;
239*0Sstevel@tonic-gate 	if ((strlen(p) < 4) || strncmp(p, "DER:", 4)) return 0;
240*0Sstevel@tonic-gate 	p+=4;
241*0Sstevel@tonic-gate 	while (isspace((unsigned char)*p)) p++;
242*0Sstevel@tonic-gate 	*value = p;
243*0Sstevel@tonic-gate 	return 1;
244*0Sstevel@tonic-gate }
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate /* Create a generic extension: for now just handle DER type */
247*0Sstevel@tonic-gate static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
248*0Sstevel@tonic-gate 	     int crit, int type)
249*0Sstevel@tonic-gate 	{
250*0Sstevel@tonic-gate 	unsigned char *ext_der=NULL;
251*0Sstevel@tonic-gate 	long ext_len;
252*0Sstevel@tonic-gate 	ASN1_OBJECT *obj=NULL;
253*0Sstevel@tonic-gate 	ASN1_OCTET_STRING *oct=NULL;
254*0Sstevel@tonic-gate 	X509_EXTENSION *extension=NULL;
255*0Sstevel@tonic-gate 	if (!(obj = OBJ_txt2obj(ext, 0)))
256*0Sstevel@tonic-gate 		{
257*0Sstevel@tonic-gate 		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR);
258*0Sstevel@tonic-gate 		ERR_add_error_data(2, "name=", ext);
259*0Sstevel@tonic-gate 		goto err;
260*0Sstevel@tonic-gate 		}
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 	if (!(ext_der = string_to_hex(value, &ext_len)))
263*0Sstevel@tonic-gate 		{
264*0Sstevel@tonic-gate 		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR);
265*0Sstevel@tonic-gate 		ERR_add_error_data(2, "value=", value);
266*0Sstevel@tonic-gate 		goto err;
267*0Sstevel@tonic-gate 		}
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate 	if (!(oct = M_ASN1_OCTET_STRING_new()))
270*0Sstevel@tonic-gate 		{
271*0Sstevel@tonic-gate 		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE);
272*0Sstevel@tonic-gate 		goto err;
273*0Sstevel@tonic-gate 		}
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate 	oct->data = ext_der;
276*0Sstevel@tonic-gate 	oct->length = ext_len;
277*0Sstevel@tonic-gate 	ext_der = NULL;
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate 	extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
280*0Sstevel@tonic-gate 
281*0Sstevel@tonic-gate 	err:
282*0Sstevel@tonic-gate 	ASN1_OBJECT_free(obj);
283*0Sstevel@tonic-gate 	M_ASN1_OCTET_STRING_free(oct);
284*0Sstevel@tonic-gate 	if(ext_der) OPENSSL_free(ext_der);
285*0Sstevel@tonic-gate 	return extension;
286*0Sstevel@tonic-gate 
287*0Sstevel@tonic-gate 	}
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate 
290*0Sstevel@tonic-gate /* This is the main function: add a bunch of extensions based on a config file
291*0Sstevel@tonic-gate  * section to an extension STACK.
292*0Sstevel@tonic-gate  */
293*0Sstevel@tonic-gate 
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
296*0Sstevel@tonic-gate 	     STACK_OF(X509_EXTENSION) **sk)
297*0Sstevel@tonic-gate 	{
298*0Sstevel@tonic-gate 	X509_EXTENSION *ext;
299*0Sstevel@tonic-gate 	STACK_OF(CONF_VALUE) *nval;
300*0Sstevel@tonic-gate 	CONF_VALUE *val;
301*0Sstevel@tonic-gate 	int i;
302*0Sstevel@tonic-gate 	if (!(nval = NCONF_get_section(conf, section))) return 0;
303*0Sstevel@tonic-gate 	for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
304*0Sstevel@tonic-gate 		{
305*0Sstevel@tonic-gate 		val = sk_CONF_VALUE_value(nval, i);
306*0Sstevel@tonic-gate 		if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
307*0Sstevel@tonic-gate 								return 0;
308*0Sstevel@tonic-gate 		if (sk) X509v3_add_ext(sk, ext, -1);
309*0Sstevel@tonic-gate 		X509_EXTENSION_free(ext);
310*0Sstevel@tonic-gate 		}
311*0Sstevel@tonic-gate 	return 1;
312*0Sstevel@tonic-gate 	}
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate /* Convenience functions to add extensions to a certificate, CRL and request */
315*0Sstevel@tonic-gate 
316*0Sstevel@tonic-gate int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
317*0Sstevel@tonic-gate 	     X509 *cert)
318*0Sstevel@tonic-gate 	{
319*0Sstevel@tonic-gate 	STACK_OF(X509_EXTENSION) **sk = NULL;
320*0Sstevel@tonic-gate 	if (cert)
321*0Sstevel@tonic-gate 		sk = &cert->cert_info->extensions;
322*0Sstevel@tonic-gate 	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
323*0Sstevel@tonic-gate 	}
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate /* Same as above but for a CRL */
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
328*0Sstevel@tonic-gate 	     X509_CRL *crl)
329*0Sstevel@tonic-gate 	{
330*0Sstevel@tonic-gate 	STACK_OF(X509_EXTENSION) **sk = NULL;
331*0Sstevel@tonic-gate 	if (crl)
332*0Sstevel@tonic-gate 		sk = &crl->crl->extensions;
333*0Sstevel@tonic-gate 	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
334*0Sstevel@tonic-gate 	}
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate /* Add extensions to certificate request */
337*0Sstevel@tonic-gate 
338*0Sstevel@tonic-gate int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
339*0Sstevel@tonic-gate 	     X509_REQ *req)
340*0Sstevel@tonic-gate 	{
341*0Sstevel@tonic-gate 	STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
342*0Sstevel@tonic-gate 	int i;
343*0Sstevel@tonic-gate 	if (req)
344*0Sstevel@tonic-gate 		sk = &extlist;
345*0Sstevel@tonic-gate 	i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
346*0Sstevel@tonic-gate 	if (!i || !sk)
347*0Sstevel@tonic-gate 		return i;
348*0Sstevel@tonic-gate 	i = X509_REQ_add_extensions(req, extlist);
349*0Sstevel@tonic-gate 	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
350*0Sstevel@tonic-gate 	return i;
351*0Sstevel@tonic-gate 	}
352*0Sstevel@tonic-gate 
353*0Sstevel@tonic-gate /* Config database functions */
354*0Sstevel@tonic-gate 
355*0Sstevel@tonic-gate char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
356*0Sstevel@tonic-gate 	{
357*0Sstevel@tonic-gate 	if (ctx->db_meth->get_string)
358*0Sstevel@tonic-gate 			return ctx->db_meth->get_string(ctx->db, name, section);
359*0Sstevel@tonic-gate 	return NULL;
360*0Sstevel@tonic-gate 	}
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
363*0Sstevel@tonic-gate 	{
364*0Sstevel@tonic-gate 	if (ctx->db_meth->get_section)
365*0Sstevel@tonic-gate 			return ctx->db_meth->get_section(ctx->db, section);
366*0Sstevel@tonic-gate 	return NULL;
367*0Sstevel@tonic-gate 	}
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate void X509V3_string_free(X509V3_CTX *ctx, char *str)
370*0Sstevel@tonic-gate 	{
371*0Sstevel@tonic-gate 	if (!str) return;
372*0Sstevel@tonic-gate 	if (ctx->db_meth->free_string)
373*0Sstevel@tonic-gate 			ctx->db_meth->free_string(ctx->db, str);
374*0Sstevel@tonic-gate 	}
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
377*0Sstevel@tonic-gate 	{
378*0Sstevel@tonic-gate 	if (!section) return;
379*0Sstevel@tonic-gate 	if (ctx->db_meth->free_section)
380*0Sstevel@tonic-gate 			ctx->db_meth->free_section(ctx->db, section);
381*0Sstevel@tonic-gate 	}
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate static char *nconf_get_string(void *db, char *section, char *value)
384*0Sstevel@tonic-gate 	{
385*0Sstevel@tonic-gate 	return NCONF_get_string(db, section, value);
386*0Sstevel@tonic-gate 	}
387*0Sstevel@tonic-gate 
388*0Sstevel@tonic-gate static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
389*0Sstevel@tonic-gate 	{
390*0Sstevel@tonic-gate 	return NCONF_get_section(db, section);
391*0Sstevel@tonic-gate 	}
392*0Sstevel@tonic-gate 
393*0Sstevel@tonic-gate static X509V3_CONF_METHOD nconf_method = {
394*0Sstevel@tonic-gate nconf_get_string,
395*0Sstevel@tonic-gate nconf_get_section,
396*0Sstevel@tonic-gate NULL,
397*0Sstevel@tonic-gate NULL
398*0Sstevel@tonic-gate };
399*0Sstevel@tonic-gate 
400*0Sstevel@tonic-gate void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
401*0Sstevel@tonic-gate 	{
402*0Sstevel@tonic-gate 	ctx->db_meth = &nconf_method;
403*0Sstevel@tonic-gate 	ctx->db = conf;
404*0Sstevel@tonic-gate 	}
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
407*0Sstevel@tonic-gate 	     X509_CRL *crl, int flags)
408*0Sstevel@tonic-gate 	{
409*0Sstevel@tonic-gate 	ctx->issuer_cert = issuer;
410*0Sstevel@tonic-gate 	ctx->subject_cert = subj;
411*0Sstevel@tonic-gate 	ctx->crl = crl;
412*0Sstevel@tonic-gate 	ctx->subject_req = req;
413*0Sstevel@tonic-gate 	ctx->flags = flags;
414*0Sstevel@tonic-gate 	}
415*0Sstevel@tonic-gate 
416*0Sstevel@tonic-gate /* Old conf compatibility functions */
417*0Sstevel@tonic-gate 
418*0Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name,
419*0Sstevel@tonic-gate 	     char *value)
420*0Sstevel@tonic-gate 	{
421*0Sstevel@tonic-gate 	CONF ctmp;
422*0Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
423*0Sstevel@tonic-gate 	return X509V3_EXT_nconf(&ctmp, ctx, name, value);
424*0Sstevel@tonic-gate 	}
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate /* LHASH *conf:  Config file    */
427*0Sstevel@tonic-gate /* char *value:  Value    */
428*0Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid,
429*0Sstevel@tonic-gate 	     char *value)
430*0Sstevel@tonic-gate 	{
431*0Sstevel@tonic-gate 	CONF ctmp;
432*0Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
433*0Sstevel@tonic-gate 	return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
434*0Sstevel@tonic-gate 	}
435*0Sstevel@tonic-gate 
436*0Sstevel@tonic-gate static char *conf_lhash_get_string(void *db, char *section, char *value)
437*0Sstevel@tonic-gate 	{
438*0Sstevel@tonic-gate 	return CONF_get_string(db, section, value);
439*0Sstevel@tonic-gate 	}
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section)
442*0Sstevel@tonic-gate 	{
443*0Sstevel@tonic-gate 	return CONF_get_section(db, section);
444*0Sstevel@tonic-gate 	}
445*0Sstevel@tonic-gate 
446*0Sstevel@tonic-gate static X509V3_CONF_METHOD conf_lhash_method = {
447*0Sstevel@tonic-gate conf_lhash_get_string,
448*0Sstevel@tonic-gate conf_lhash_get_section,
449*0Sstevel@tonic-gate NULL,
450*0Sstevel@tonic-gate NULL
451*0Sstevel@tonic-gate };
452*0Sstevel@tonic-gate 
453*0Sstevel@tonic-gate void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash)
454*0Sstevel@tonic-gate 	{
455*0Sstevel@tonic-gate 	ctx->db_meth = &conf_lhash_method;
456*0Sstevel@tonic-gate 	ctx->db = lhash;
457*0Sstevel@tonic-gate 	}
458*0Sstevel@tonic-gate 
459*0Sstevel@tonic-gate int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
460*0Sstevel@tonic-gate 	     X509 *cert)
461*0Sstevel@tonic-gate 	{
462*0Sstevel@tonic-gate 	CONF ctmp;
463*0Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
464*0Sstevel@tonic-gate 	return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
465*0Sstevel@tonic-gate 	}
466*0Sstevel@tonic-gate 
467*0Sstevel@tonic-gate /* Same as above but for a CRL */
468*0Sstevel@tonic-gate 
469*0Sstevel@tonic-gate int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
470*0Sstevel@tonic-gate 	     X509_CRL *crl)
471*0Sstevel@tonic-gate 	{
472*0Sstevel@tonic-gate 	CONF ctmp;
473*0Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
474*0Sstevel@tonic-gate 	return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
475*0Sstevel@tonic-gate 	}
476*0Sstevel@tonic-gate 
477*0Sstevel@tonic-gate /* Add extensions to certificate request */
478*0Sstevel@tonic-gate 
479*0Sstevel@tonic-gate int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
480*0Sstevel@tonic-gate 	     X509_REQ *req)
481*0Sstevel@tonic-gate 	{
482*0Sstevel@tonic-gate 	CONF ctmp;
483*0Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
484*0Sstevel@tonic-gate 	return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
485*0Sstevel@tonic-gate 	}
486