155714Skris/* v3_conf.c */
2194206Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
355714Skris * project 1999.
455714Skris */
555714Skris/* ====================================================================
6160814Ssimon * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
755714Skris *
855714Skris * Redistribution and use in source and binary forms, with or without
955714Skris * modification, are permitted provided that the following conditions
1055714Skris * are met:
1155714Skris *
1255714Skris * 1. Redistributions of source code must retain the above copyright
1355714Skris *    notice, this list of conditions and the following disclaimer.
1455714Skris *
1555714Skris * 2. Redistributions in binary form must reproduce the above copyright
1655714Skris *    notice, this list of conditions and the following disclaimer in
1755714Skris *    the documentation and/or other materials provided with the
1855714Skris *    distribution.
1955714Skris *
2055714Skris * 3. All advertising materials mentioning features or use of this
2155714Skris *    software must display the following acknowledgment:
2255714Skris *    "This product includes software developed by the OpenSSL Project
2355714Skris *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2455714Skris *
2555714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2655714Skris *    endorse or promote products derived from this software without
2755714Skris *    prior written permission. For written permission, please contact
2855714Skris *    licensing@OpenSSL.org.
2955714Skris *
3055714Skris * 5. Products derived from this software may not be called "OpenSSL"
3155714Skris *    nor may "OpenSSL" appear in their names without prior written
3255714Skris *    permission of the OpenSSL Project.
3355714Skris *
3455714Skris * 6. Redistributions of any form whatsoever must retain the following
3555714Skris *    acknowledgment:
3655714Skris *    "This product includes software developed by the OpenSSL Project
3755714Skris *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3855714Skris *
3955714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4055714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4155714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4255714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4355714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4455714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4555714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4655714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4755714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4855714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4955714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5055714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
5155714Skris * ====================================================================
5255714Skris *
5355714Skris * This product includes cryptographic software written by Eric Young
5455714Skris * (eay@cryptsoft.com).  This product includes software written by Tim
5555714Skris * Hudson (tjh@cryptsoft.com).
5655714Skris *
5755714Skris */
5855714Skris/* extension creation utilities */
5955714Skris
6055714Skris
6155714Skris
6255714Skris#include <stdio.h>
6355714Skris#include <ctype.h>
6455714Skris#include "cryptlib.h"
6555714Skris#include <openssl/conf.h>
6655714Skris#include <openssl/x509.h>
6755714Skris#include <openssl/x509v3.h>
6855714Skris
6955714Skrisstatic int v3_check_critical(char **value);
7055714Skrisstatic int v3_check_generic(char **value);
71109998Smarkmstatic X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
72160814Ssimonstatic X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
7355714Skrisstatic char *conf_lhash_get_string(void *db, char *section, char *value);
7455714Skrisstatic STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
75238405Sjkimstatic X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
76238405Sjkim				  int crit, void *ext_struc);
77160814Ssimonstatic unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
78109998Smarkm/* CONF *conf:  Config file    */
7955714Skris/* char *name:  Name    */
8055714Skris/* char *value:  Value    */
81109998SmarkmX509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
82238405Sjkim				 char *value)
83109998Smarkm	{
8455714Skris	int crit;
8555714Skris	int ext_type;
8655714Skris	X509_EXTENSION *ret;
8755714Skris	crit = v3_check_critical(&value);
88109998Smarkm	if ((ext_type = v3_check_generic(&value)))
89160814Ssimon		return v3_generic_extension(name, value, crit, ext_type, ctx);
90109998Smarkm	ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
91109998Smarkm	if (!ret)
92109998Smarkm		{
93160814Ssimon		X509V3err(X509V3_F_X509V3_EXT_NCONF,X509V3_R_ERROR_IN_EXTENSION);
9455714Skris		ERR_add_error_data(4,"name=", name, ", value=", value);
95109998Smarkm		}
96109998Smarkm	return ret;
9755714Skris	}
9855714Skris
99109998Smarkm/* CONF *conf:  Config file    */
10055714Skris/* char *value:  Value    */
101109998SmarkmX509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
102238405Sjkim				     char *value)
103109998Smarkm	{
10455714Skris	int crit;
10555714Skris	int ext_type;
10655714Skris	crit = v3_check_critical(&value);
107109998Smarkm	if ((ext_type = v3_check_generic(&value)))
10855714Skris		return v3_generic_extension(OBJ_nid2sn(ext_nid),
109160814Ssimon						 value, crit, ext_type, ctx);
110109998Smarkm	return do_ext_nconf(conf, ctx, ext_nid, crit, value);
111109998Smarkm	}
11255714Skris
113109998Smarkm/* CONF *conf:  Config file    */
11455714Skris/* char *value:  Value    */
115109998Smarkmstatic X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
116238405Sjkim				    int crit, char *value)
117109998Smarkm	{
118238405Sjkim	const X509V3_EXT_METHOD *method;
11955714Skris	X509_EXTENSION *ext;
12055714Skris	STACK_OF(CONF_VALUE) *nval;
12155714Skris	void *ext_struc;
122109998Smarkm	if (ext_nid == NID_undef)
123109998Smarkm		{
124160814Ssimon		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
12555714Skris		return NULL;
126109998Smarkm		}
127109998Smarkm	if (!(method = X509V3_EXT_get_nid(ext_nid)))
128109998Smarkm		{
129160814Ssimon		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION);
13055714Skris		return NULL;
131109998Smarkm		}
13255714Skris	/* Now get internal extension representation based on type */
133109998Smarkm	if (method->v2i)
134109998Smarkm		{
135109998Smarkm		if(*value == '@') nval = NCONF_get_section(conf, value + 1);
13655714Skris		else nval = X509V3_parse_list(value);
137160814Ssimon		if(sk_CONF_VALUE_num(nval) <= 0)
138109998Smarkm			{
139160814Ssimon			X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_INVALID_EXTENSION_STRING);
14055714Skris			ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
14155714Skris			return NULL;
142109998Smarkm			}
14355714Skris		ext_struc = method->v2i(method, ctx, nval);
14455714Skris		if(*value != '@') sk_CONF_VALUE_pop_free(nval,
14555714Skris							 X509V3_conf_free);
14655714Skris		if(!ext_struc) return NULL;
147109998Smarkm		}
148109998Smarkm	else if(method->s2i)
149109998Smarkm		{
15055714Skris		if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
151109998Smarkm		}
152109998Smarkm	else if(method->r2i)
153109998Smarkm		{
154160814Ssimon		if(!ctx->db || !ctx->db_meth)
155109998Smarkm			{
156160814Ssimon			X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_NO_CONFIG_DATABASE);
15755714Skris			return NULL;
158109998Smarkm			}
159109998Smarkm		if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
16055714Skris		}
161109998Smarkm	else
162109998Smarkm		{
163160814Ssimon		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
16455714Skris		ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
16555714Skris		return NULL;
166109998Smarkm		}
16755714Skris
16855714Skris	ext  = do_ext_i2d(method, ext_nid, crit, ext_struc);
169109998Smarkm	if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
170109998Smarkm	else method->ext_free(ext_struc);
17155714Skris	return ext;
17255714Skris
173109998Smarkm	}
17455714Skris
175238405Sjkimstatic X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
176238405Sjkim				  int crit, void *ext_struc)
177109998Smarkm	{
178109998Smarkm	unsigned char *ext_der;
17955714Skris	int ext_len;
18055714Skris	ASN1_OCTET_STRING *ext_oct;
18155714Skris	X509_EXTENSION *ext;
18255714Skris	/* Convert internal representation to DER */
183109998Smarkm	if (method->it)
184109998Smarkm		{
185109998Smarkm		ext_der = NULL;
186109998Smarkm		ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
187109998Smarkm		if (ext_len < 0) goto merr;
188109998Smarkm		}
189109998Smarkm	 else
190109998Smarkm		{
191109998Smarkm		unsigned char *p;
192109998Smarkm		ext_len = method->i2d(ext_struc, NULL);
193109998Smarkm		if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
194109998Smarkm		p = ext_der;
195109998Smarkm		method->i2d(ext_struc, &p);
196109998Smarkm		}
197109998Smarkm	if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
19855714Skris	ext_oct->data = ext_der;
19955714Skris	ext_oct->length = ext_len;
200109998Smarkm
20155714Skris	ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
202109998Smarkm	if (!ext) goto merr;
20359191Skris	M_ASN1_OCTET_STRING_free(ext_oct);
20455714Skris
20555714Skris	return ext;
20655714Skris
20755714Skris	merr:
20855714Skris	X509V3err(X509V3_F_DO_EXT_I2D,ERR_R_MALLOC_FAILURE);
20955714Skris	return NULL;
21055714Skris
211109998Smarkm	}
21255714Skris
21355714Skris/* Given an internal structure, nid and critical flag create an extension */
21455714Skris
21555714SkrisX509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
216109998Smarkm	{
217238405Sjkim	const X509V3_EXT_METHOD *method;
218109998Smarkm	if (!(method = X509V3_EXT_get_nid(ext_nid))) {
21955714Skris		X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
22055714Skris		return NULL;
22155714Skris	}
22255714Skris	return do_ext_i2d(method, ext_nid, crit, ext_struc);
22355714Skris}
22455714Skris
22555714Skris/* Check the extension string for critical flag */
22655714Skrisstatic int v3_check_critical(char **value)
22755714Skris{
22855714Skris	char *p = *value;
229109998Smarkm	if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
23055714Skris	p+=9;
23155714Skris	while(isspace((unsigned char)*p)) p++;
23255714Skris	*value = p;
23355714Skris	return 1;
23455714Skris}
23555714Skris
23655714Skris/* Check extension string for generic extension and return the type */
23755714Skrisstatic int v3_check_generic(char **value)
23855714Skris{
239160814Ssimon	int gen_type = 0;
24055714Skris	char *p = *value;
241160814Ssimon	if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
242160814Ssimon		{
243160814Ssimon		p+=4;
244160814Ssimon		gen_type = 1;
245160814Ssimon		}
246160814Ssimon	else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
247160814Ssimon		{
248160814Ssimon		p+=5;
249160814Ssimon		gen_type = 2;
250160814Ssimon		}
251160814Ssimon	else
252160814Ssimon		return 0;
253160814Ssimon
254109998Smarkm	while (isspace((unsigned char)*p)) p++;
25555714Skris	*value = p;
256160814Ssimon	return gen_type;
25755714Skris}
25855714Skris
25959191Skris/* Create a generic extension: for now just handle DER type */
26055714Skrisstatic X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
261238405Sjkim					    int crit, int gen_type,
262238405Sjkim					    X509V3_CTX *ctx)
263109998Smarkm	{
264109998Smarkm	unsigned char *ext_der=NULL;
265109998Smarkm	long ext_len;
266109998Smarkm	ASN1_OBJECT *obj=NULL;
267109998Smarkm	ASN1_OCTET_STRING *oct=NULL;
268109998Smarkm	X509_EXTENSION *extension=NULL;
269109998Smarkm	if (!(obj = OBJ_txt2obj(ext, 0)))
270109998Smarkm		{
271109998Smarkm		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR);
272109998Smarkm		ERR_add_error_data(2, "name=", ext);
273109998Smarkm		goto err;
274109998Smarkm		}
27555714Skris
276160814Ssimon	if (gen_type == 1)
277160814Ssimon		ext_der = string_to_hex(value, &ext_len);
278160814Ssimon	else if (gen_type == 2)
279160814Ssimon		ext_der = generic_asn1(value, ctx, &ext_len);
280160814Ssimon
281160814Ssimon	if (ext_der == NULL)
282109998Smarkm		{
283109998Smarkm		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR);
284109998Smarkm		ERR_add_error_data(2, "value=", value);
285109998Smarkm		goto err;
286109998Smarkm		}
28755714Skris
288109998Smarkm	if (!(oct = M_ASN1_OCTET_STRING_new()))
289109998Smarkm		{
290109998Smarkm		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE);
291109998Smarkm		goto err;
292109998Smarkm		}
29355714Skris
294109998Smarkm	oct->data = ext_der;
295109998Smarkm	oct->length = ext_len;
296109998Smarkm	ext_der = NULL;
29755714Skris
298109998Smarkm	extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
29955714Skris
300109998Smarkm	err:
301109998Smarkm	ASN1_OBJECT_free(obj);
302109998Smarkm	M_ASN1_OCTET_STRING_free(oct);
303109998Smarkm	if(ext_der) OPENSSL_free(ext_der);
304109998Smarkm	return extension;
30555714Skris
306109998Smarkm	}
30755714Skris
308160814Ssimonstatic unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
309160814Ssimon	{
310160814Ssimon	ASN1_TYPE *typ;
311160814Ssimon	unsigned char *ext_der = NULL;
312160814Ssimon	typ = ASN1_generate_v3(value, ctx);
313160814Ssimon	if (typ == NULL)
314160814Ssimon		return NULL;
315160814Ssimon	*ext_len = i2d_ASN1_TYPE(typ, &ext_der);
316160814Ssimon	ASN1_TYPE_free(typ);
317160814Ssimon	return ext_der;
318160814Ssimon	}
319109998Smarkm
32055714Skris/* This is the main function: add a bunch of extensions based on a config file
321109998Smarkm * section to an extension STACK.
32255714Skris */
32355714Skris
324109998Smarkm
325109998Smarkmint X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
326238405Sjkim			    STACK_OF(X509_EXTENSION) **sk)
327109998Smarkm	{
32855714Skris	X509_EXTENSION *ext;
32955714Skris	STACK_OF(CONF_VALUE) *nval;
33055714Skris	CONF_VALUE *val;
33155714Skris	int i;
332109998Smarkm	if (!(nval = NCONF_get_section(conf, section))) return 0;
333109998Smarkm	for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
334109998Smarkm		{
33555714Skris		val = sk_CONF_VALUE_value(nval, i);
336109998Smarkm		if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
33755714Skris								return 0;
338109998Smarkm		if (sk) X509v3_add_ext(sk, ext, -1);
33955714Skris		X509_EXTENSION_free(ext);
340109998Smarkm		}
341109998Smarkm	return 1;
34255714Skris	}
34355714Skris
344109998Smarkm/* Convenience functions to add extensions to a certificate, CRL and request */
345109998Smarkm
346109998Smarkmint X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
347238405Sjkim			 X509 *cert)
348109998Smarkm	{
349109998Smarkm	STACK_OF(X509_EXTENSION) **sk = NULL;
350109998Smarkm	if (cert)
351109998Smarkm		sk = &cert->cert_info->extensions;
352109998Smarkm	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
353109998Smarkm	}
354109998Smarkm
35555714Skris/* Same as above but for a CRL */
35655714Skris
357109998Smarkmint X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
358238405Sjkim			     X509_CRL *crl)
359109998Smarkm	{
360109998Smarkm	STACK_OF(X509_EXTENSION) **sk = NULL;
361109998Smarkm	if (crl)
362109998Smarkm		sk = &crl->crl->extensions;
363109998Smarkm	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
36455714Skris	}
36555714Skris
36659191Skris/* Add extensions to certificate request */
36759191Skris
368109998Smarkmint X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
36959191Skris	     X509_REQ *req)
370109998Smarkm	{
371109998Smarkm	STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
37259191Skris	int i;
373109998Smarkm	if (req)
374109998Smarkm		sk = &extlist;
375109998Smarkm	i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
376109998Smarkm	if (!i || !sk)
377109998Smarkm		return i;
378109998Smarkm	i = X509_REQ_add_extensions(req, extlist);
37959191Skris	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
38059191Skris	return i;
381109998Smarkm	}
38259191Skris
38355714Skris/* Config database functions */
38455714Skris
38555714Skrischar * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
386109998Smarkm	{
387160814Ssimon	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
388160814Ssimon		{
389160814Ssimon		X509V3err(X509V3_F_X509V3_GET_STRING,X509V3_R_OPERATION_NOT_DEFINED);
390160814Ssimon		return NULL;
391160814Ssimon		}
392109998Smarkm	if (ctx->db_meth->get_string)
39355714Skris			return ctx->db_meth->get_string(ctx->db, name, section);
39455714Skris	return NULL;
395109998Smarkm	}
39655714Skris
39755714SkrisSTACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
398109998Smarkm	{
399160814Ssimon	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
400160814Ssimon		{
401160814Ssimon		X509V3err(X509V3_F_X509V3_GET_SECTION,X509V3_R_OPERATION_NOT_DEFINED);
402160814Ssimon		return NULL;
403160814Ssimon		}
404109998Smarkm	if (ctx->db_meth->get_section)
40555714Skris			return ctx->db_meth->get_section(ctx->db, section);
40655714Skris	return NULL;
407109998Smarkm	}
40855714Skris
40955714Skrisvoid X509V3_string_free(X509V3_CTX *ctx, char *str)
410109998Smarkm	{
411109998Smarkm	if (!str) return;
412109998Smarkm	if (ctx->db_meth->free_string)
41355714Skris			ctx->db_meth->free_string(ctx->db, str);
414109998Smarkm	}
41555714Skris
41655714Skrisvoid X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
417109998Smarkm	{
418109998Smarkm	if (!section) return;
419109998Smarkm	if (ctx->db_meth->free_section)
42055714Skris			ctx->db_meth->free_section(ctx->db, section);
421109998Smarkm	}
42255714Skris
423109998Smarkmstatic char *nconf_get_string(void *db, char *section, char *value)
424109998Smarkm	{
425109998Smarkm	return NCONF_get_string(db, section, value);
426109998Smarkm	}
427109998Smarkm
428109998Smarkmstatic STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
429109998Smarkm	{
430109998Smarkm	return NCONF_get_section(db, section);
431109998Smarkm	}
432109998Smarkm
433109998Smarkmstatic X509V3_CONF_METHOD nconf_method = {
434109998Smarkmnconf_get_string,
435109998Smarkmnconf_get_section,
436109998SmarkmNULL,
437109998SmarkmNULL
438109998Smarkm};
439109998Smarkm
440109998Smarkmvoid X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
441109998Smarkm	{
442109998Smarkm	ctx->db_meth = &nconf_method;
443109998Smarkm	ctx->db = conf;
444109998Smarkm	}
445109998Smarkm
446109998Smarkmvoid X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
447238405Sjkim		    X509_CRL *crl, int flags)
448109998Smarkm	{
449109998Smarkm	ctx->issuer_cert = issuer;
450109998Smarkm	ctx->subject_cert = subj;
451109998Smarkm	ctx->crl = crl;
452109998Smarkm	ctx->subject_req = req;
453109998Smarkm	ctx->flags = flags;
454109998Smarkm	}
455109998Smarkm
456109998Smarkm/* Old conf compatibility functions */
457109998Smarkm
458238405SjkimX509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
459238405Sjkim				char *name, char *value)
460109998Smarkm	{
461109998Smarkm	CONF ctmp;
462109998Smarkm	CONF_set_nconf(&ctmp, conf);
463109998Smarkm	return X509V3_EXT_nconf(&ctmp, ctx, name, value);
464109998Smarkm	}
465109998Smarkm
466109998Smarkm/* LHASH *conf:  Config file    */
467109998Smarkm/* char *value:  Value    */
468238405SjkimX509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
469238405Sjkim				    int ext_nid, char *value)
470109998Smarkm	{
471109998Smarkm	CONF ctmp;
472109998Smarkm	CONF_set_nconf(&ctmp, conf);
473109998Smarkm	return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
474109998Smarkm	}
475109998Smarkm
47655714Skrisstatic char *conf_lhash_get_string(void *db, char *section, char *value)
477109998Smarkm	{
47855714Skris	return CONF_get_string(db, section, value);
479109998Smarkm	}
48055714Skris
48155714Skrisstatic STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section)
482109998Smarkm	{
48355714Skris	return CONF_get_section(db, section);
484109998Smarkm	}
48555714Skris
48655714Skrisstatic X509V3_CONF_METHOD conf_lhash_method = {
48755714Skrisconf_lhash_get_string,
48855714Skrisconf_lhash_get_section,
48955714SkrisNULL,
49055714SkrisNULL
49155714Skris};
49255714Skris
493238405Sjkimvoid X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
494109998Smarkm	{
49555714Skris	ctx->db_meth = &conf_lhash_method;
49655714Skris	ctx->db = lhash;
497109998Smarkm	}
49855714Skris
499238405Sjkimint X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
500238405Sjkim			char *section, X509 *cert)
501109998Smarkm	{
502109998Smarkm	CONF ctmp;
503109998Smarkm	CONF_set_nconf(&ctmp, conf);
504109998Smarkm	return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
505109998Smarkm	}
506109998Smarkm
507109998Smarkm/* Same as above but for a CRL */
508109998Smarkm
509238405Sjkimint X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
510238405Sjkim			    char *section, X509_CRL *crl)
511109998Smarkm	{
512109998Smarkm	CONF ctmp;
513109998Smarkm	CONF_set_nconf(&ctmp, conf);
514109998Smarkm	return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
515109998Smarkm	}
516109998Smarkm
517109998Smarkm/* Add extensions to certificate request */
518109998Smarkm
519238405Sjkimint X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
520238405Sjkim			    char *section, X509_REQ *req)
521109998Smarkm	{
522109998Smarkm	CONF ctmp;
523109998Smarkm	CONF_set_nconf(&ctmp, conf);
524109998Smarkm	return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
525109998Smarkm	}
526