xref: /onnv-gate/usr/src/common/openssl/crypto/x509v3/v3_conf.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* v3_conf.c */
20Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
30Sstevel@tonic-gate  * project 1999.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate /* ====================================================================
6*2139Sjp161948  * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate  * are met:
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
180Sstevel@tonic-gate  *    distribution.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate  *    software must display the following acknowledgment:
220Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate  *    endorse or promote products derived from this software without
270Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
280Sstevel@tonic-gate  *    licensing@OpenSSL.org.
290Sstevel@tonic-gate  *
300Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate  *    permission of the OpenSSL Project.
330Sstevel@tonic-gate  *
340Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate  *    acknowledgment:
360Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate  *
390Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate  * ====================================================================
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
550Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate  *
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate /* extension creation utilities */
590Sstevel@tonic-gate 
600Sstevel@tonic-gate 
610Sstevel@tonic-gate 
620Sstevel@tonic-gate #include <stdio.h>
630Sstevel@tonic-gate #include <ctype.h>
640Sstevel@tonic-gate #include "cryptlib.h"
650Sstevel@tonic-gate #include <openssl/conf.h>
660Sstevel@tonic-gate #include <openssl/x509.h>
670Sstevel@tonic-gate #include <openssl/x509v3.h>
680Sstevel@tonic-gate 
690Sstevel@tonic-gate static int v3_check_critical(char **value);
700Sstevel@tonic-gate static int v3_check_generic(char **value);
710Sstevel@tonic-gate static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
72*2139Sjp161948 static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
730Sstevel@tonic-gate static char *conf_lhash_get_string(void *db, char *section, char *value);
740Sstevel@tonic-gate static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
750Sstevel@tonic-gate static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
760Sstevel@tonic-gate 						 int crit, void *ext_struc);
77*2139Sjp161948 static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
780Sstevel@tonic-gate /* CONF *conf:  Config file    */
790Sstevel@tonic-gate /* char *name:  Name    */
800Sstevel@tonic-gate /* char *value:  Value    */
X509V3_EXT_nconf(CONF * conf,X509V3_CTX * ctx,char * name,char * value)810Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
820Sstevel@tonic-gate 	     char *value)
830Sstevel@tonic-gate 	{
840Sstevel@tonic-gate 	int crit;
850Sstevel@tonic-gate 	int ext_type;
860Sstevel@tonic-gate 	X509_EXTENSION *ret;
870Sstevel@tonic-gate 	crit = v3_check_critical(&value);
880Sstevel@tonic-gate 	if ((ext_type = v3_check_generic(&value)))
89*2139Sjp161948 		return v3_generic_extension(name, value, crit, ext_type, ctx);
900Sstevel@tonic-gate 	ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
910Sstevel@tonic-gate 	if (!ret)
920Sstevel@tonic-gate 		{
93*2139Sjp161948 		X509V3err(X509V3_F_X509V3_EXT_NCONF,X509V3_R_ERROR_IN_EXTENSION);
940Sstevel@tonic-gate 		ERR_add_error_data(4,"name=", name, ", value=", value);
950Sstevel@tonic-gate 		}
960Sstevel@tonic-gate 	return ret;
970Sstevel@tonic-gate 	}
980Sstevel@tonic-gate 
990Sstevel@tonic-gate /* CONF *conf:  Config file    */
1000Sstevel@tonic-gate /* char *value:  Value    */
X509V3_EXT_nconf_nid(CONF * conf,X509V3_CTX * ctx,int ext_nid,char * value)1010Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
1020Sstevel@tonic-gate 	     char *value)
1030Sstevel@tonic-gate 	{
1040Sstevel@tonic-gate 	int crit;
1050Sstevel@tonic-gate 	int ext_type;
1060Sstevel@tonic-gate 	crit = v3_check_critical(&value);
1070Sstevel@tonic-gate 	if ((ext_type = v3_check_generic(&value)))
1080Sstevel@tonic-gate 		return v3_generic_extension(OBJ_nid2sn(ext_nid),
109*2139Sjp161948 						 value, crit, ext_type, ctx);
1100Sstevel@tonic-gate 	return do_ext_nconf(conf, ctx, ext_nid, crit, value);
1110Sstevel@tonic-gate 	}
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate /* CONF *conf:  Config file    */
1140Sstevel@tonic-gate /* char *value:  Value    */
do_ext_nconf(CONF * conf,X509V3_CTX * ctx,int ext_nid,int crit,char * value)1150Sstevel@tonic-gate static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
1160Sstevel@tonic-gate 	     int crit, char *value)
1170Sstevel@tonic-gate 	{
1180Sstevel@tonic-gate 	X509V3_EXT_METHOD *method;
1190Sstevel@tonic-gate 	X509_EXTENSION *ext;
1200Sstevel@tonic-gate 	STACK_OF(CONF_VALUE) *nval;
1210Sstevel@tonic-gate 	void *ext_struc;
1220Sstevel@tonic-gate 	if (ext_nid == NID_undef)
1230Sstevel@tonic-gate 		{
124*2139Sjp161948 		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION_NAME);
1250Sstevel@tonic-gate 		return NULL;
1260Sstevel@tonic-gate 		}
1270Sstevel@tonic-gate 	if (!(method = X509V3_EXT_get_nid(ext_nid)))
1280Sstevel@tonic-gate 		{
129*2139Sjp161948 		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_UNKNOWN_EXTENSION);
1300Sstevel@tonic-gate 		return NULL;
1310Sstevel@tonic-gate 		}
1320Sstevel@tonic-gate 	/* Now get internal extension representation based on type */
1330Sstevel@tonic-gate 	if (method->v2i)
1340Sstevel@tonic-gate 		{
1350Sstevel@tonic-gate 		if(*value == '@') nval = NCONF_get_section(conf, value + 1);
1360Sstevel@tonic-gate 		else nval = X509V3_parse_list(value);
137*2139Sjp161948 		if(sk_CONF_VALUE_num(nval) <= 0)
1380Sstevel@tonic-gate 			{
139*2139Sjp161948 			X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_INVALID_EXTENSION_STRING);
1400Sstevel@tonic-gate 			ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
1410Sstevel@tonic-gate 			return NULL;
1420Sstevel@tonic-gate 			}
1430Sstevel@tonic-gate 		ext_struc = method->v2i(method, ctx, nval);
1440Sstevel@tonic-gate 		if(*value != '@') sk_CONF_VALUE_pop_free(nval,
1450Sstevel@tonic-gate 							 X509V3_conf_free);
1460Sstevel@tonic-gate 		if(!ext_struc) return NULL;
1470Sstevel@tonic-gate 		}
1480Sstevel@tonic-gate 	else if(method->s2i)
1490Sstevel@tonic-gate 		{
1500Sstevel@tonic-gate 		if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;
1510Sstevel@tonic-gate 		}
1520Sstevel@tonic-gate 	else if(method->r2i)
1530Sstevel@tonic-gate 		{
154*2139Sjp161948 		if(!ctx->db || !ctx->db_meth)
1550Sstevel@tonic-gate 			{
156*2139Sjp161948 			X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_NO_CONFIG_DATABASE);
1570Sstevel@tonic-gate 			return NULL;
1580Sstevel@tonic-gate 			}
1590Sstevel@tonic-gate 		if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
1600Sstevel@tonic-gate 		}
1610Sstevel@tonic-gate 	else
1620Sstevel@tonic-gate 		{
163*2139Sjp161948 		X509V3err(X509V3_F_DO_EXT_NCONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
1640Sstevel@tonic-gate 		ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
1650Sstevel@tonic-gate 		return NULL;
1660Sstevel@tonic-gate 		}
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 	ext  = do_ext_i2d(method, ext_nid, crit, ext_struc);
1690Sstevel@tonic-gate 	if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
1700Sstevel@tonic-gate 	else method->ext_free(ext_struc);
1710Sstevel@tonic-gate 	return ext;
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate 	}
1740Sstevel@tonic-gate 
do_ext_i2d(X509V3_EXT_METHOD * method,int ext_nid,int crit,void * ext_struc)1750Sstevel@tonic-gate static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
1760Sstevel@tonic-gate 						 int crit, void *ext_struc)
1770Sstevel@tonic-gate 	{
1780Sstevel@tonic-gate 	unsigned char *ext_der;
1790Sstevel@tonic-gate 	int ext_len;
1800Sstevel@tonic-gate 	ASN1_OCTET_STRING *ext_oct;
1810Sstevel@tonic-gate 	X509_EXTENSION *ext;
1820Sstevel@tonic-gate 	/* Convert internal representation to DER */
1830Sstevel@tonic-gate 	if (method->it)
1840Sstevel@tonic-gate 		{
1850Sstevel@tonic-gate 		ext_der = NULL;
1860Sstevel@tonic-gate 		ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
1870Sstevel@tonic-gate 		if (ext_len < 0) goto merr;
1880Sstevel@tonic-gate 		}
1890Sstevel@tonic-gate 	 else
1900Sstevel@tonic-gate 		{
1910Sstevel@tonic-gate 		unsigned char *p;
1920Sstevel@tonic-gate 		ext_len = method->i2d(ext_struc, NULL);
1930Sstevel@tonic-gate 		if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
1940Sstevel@tonic-gate 		p = ext_der;
1950Sstevel@tonic-gate 		method->i2d(ext_struc, &p);
1960Sstevel@tonic-gate 		}
1970Sstevel@tonic-gate 	if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
1980Sstevel@tonic-gate 	ext_oct->data = ext_der;
1990Sstevel@tonic-gate 	ext_oct->length = ext_len;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
2020Sstevel@tonic-gate 	if (!ext) goto merr;
2030Sstevel@tonic-gate 	M_ASN1_OCTET_STRING_free(ext_oct);
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 	return ext;
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 	merr:
2080Sstevel@tonic-gate 	X509V3err(X509V3_F_DO_EXT_I2D,ERR_R_MALLOC_FAILURE);
2090Sstevel@tonic-gate 	return NULL;
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	}
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate /* Given an internal structure, nid and critical flag create an extension */
2140Sstevel@tonic-gate 
X509V3_EXT_i2d(int ext_nid,int crit,void * ext_struc)2150Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
2160Sstevel@tonic-gate 	{
2170Sstevel@tonic-gate 	X509V3_EXT_METHOD *method;
2180Sstevel@tonic-gate 	if (!(method = X509V3_EXT_get_nid(ext_nid))) {
2190Sstevel@tonic-gate 		X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
2200Sstevel@tonic-gate 		return NULL;
2210Sstevel@tonic-gate 	}
2220Sstevel@tonic-gate 	return do_ext_i2d(method, ext_nid, crit, ext_struc);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate /* Check the extension string for critical flag */
v3_check_critical(char ** value)2260Sstevel@tonic-gate static int v3_check_critical(char **value)
2270Sstevel@tonic-gate {
2280Sstevel@tonic-gate 	char *p = *value;
2290Sstevel@tonic-gate 	if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
2300Sstevel@tonic-gate 	p+=9;
2310Sstevel@tonic-gate 	while(isspace((unsigned char)*p)) p++;
2320Sstevel@tonic-gate 	*value = p;
2330Sstevel@tonic-gate 	return 1;
2340Sstevel@tonic-gate }
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate /* Check extension string for generic extension and return the type */
v3_check_generic(char ** value)2370Sstevel@tonic-gate static int v3_check_generic(char **value)
2380Sstevel@tonic-gate {
239*2139Sjp161948 	int gen_type = 0;
2400Sstevel@tonic-gate 	char *p = *value;
241*2139Sjp161948 	if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
242*2139Sjp161948 		{
243*2139Sjp161948 		p+=4;
244*2139Sjp161948 		gen_type = 1;
245*2139Sjp161948 		}
246*2139Sjp161948 	else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
247*2139Sjp161948 		{
248*2139Sjp161948 		p+=5;
249*2139Sjp161948 		gen_type = 2;
250*2139Sjp161948 		}
251*2139Sjp161948 	else
252*2139Sjp161948 		return 0;
253*2139Sjp161948 
2540Sstevel@tonic-gate 	while (isspace((unsigned char)*p)) p++;
2550Sstevel@tonic-gate 	*value = p;
256*2139Sjp161948 	return gen_type;
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate /* Create a generic extension: for now just handle DER type */
v3_generic_extension(const char * ext,char * value,int crit,int gen_type,X509V3_CTX * ctx)2600Sstevel@tonic-gate static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
261*2139Sjp161948 	     int crit, int gen_type, X509V3_CTX *ctx)
2620Sstevel@tonic-gate 	{
2630Sstevel@tonic-gate 	unsigned char *ext_der=NULL;
2640Sstevel@tonic-gate 	long ext_len;
2650Sstevel@tonic-gate 	ASN1_OBJECT *obj=NULL;
2660Sstevel@tonic-gate 	ASN1_OCTET_STRING *oct=NULL;
2670Sstevel@tonic-gate 	X509_EXTENSION *extension=NULL;
2680Sstevel@tonic-gate 	if (!(obj = OBJ_txt2obj(ext, 0)))
2690Sstevel@tonic-gate 		{
2700Sstevel@tonic-gate 		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR);
2710Sstevel@tonic-gate 		ERR_add_error_data(2, "name=", ext);
2720Sstevel@tonic-gate 		goto err;
2730Sstevel@tonic-gate 		}
2740Sstevel@tonic-gate 
275*2139Sjp161948 	if (gen_type == 1)
276*2139Sjp161948 		ext_der = string_to_hex(value, &ext_len);
277*2139Sjp161948 	else if (gen_type == 2)
278*2139Sjp161948 		ext_der = generic_asn1(value, ctx, &ext_len);
279*2139Sjp161948 
280*2139Sjp161948 	if (ext_der == NULL)
2810Sstevel@tonic-gate 		{
2820Sstevel@tonic-gate 		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR);
2830Sstevel@tonic-gate 		ERR_add_error_data(2, "value=", value);
2840Sstevel@tonic-gate 		goto err;
2850Sstevel@tonic-gate 		}
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 	if (!(oct = M_ASN1_OCTET_STRING_new()))
2880Sstevel@tonic-gate 		{
2890Sstevel@tonic-gate 		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE);
2900Sstevel@tonic-gate 		goto err;
2910Sstevel@tonic-gate 		}
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate 	oct->data = ext_der;
2940Sstevel@tonic-gate 	oct->length = ext_len;
2950Sstevel@tonic-gate 	ext_der = NULL;
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 	err:
3000Sstevel@tonic-gate 	ASN1_OBJECT_free(obj);
3010Sstevel@tonic-gate 	M_ASN1_OCTET_STRING_free(oct);
3020Sstevel@tonic-gate 	if(ext_der) OPENSSL_free(ext_der);
3030Sstevel@tonic-gate 	return extension;
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate 	}
3060Sstevel@tonic-gate 
generic_asn1(char * value,X509V3_CTX * ctx,long * ext_len)307*2139Sjp161948 static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
308*2139Sjp161948 	{
309*2139Sjp161948 	ASN1_TYPE *typ;
310*2139Sjp161948 	unsigned char *ext_der = NULL;
311*2139Sjp161948 	typ = ASN1_generate_v3(value, ctx);
312*2139Sjp161948 	if (typ == NULL)
313*2139Sjp161948 		return NULL;
314*2139Sjp161948 	*ext_len = i2d_ASN1_TYPE(typ, &ext_der);
315*2139Sjp161948 	ASN1_TYPE_free(typ);
316*2139Sjp161948 	return ext_der;
317*2139Sjp161948 	}
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate /* This is the main function: add a bunch of extensions based on a config file
3200Sstevel@tonic-gate  * section to an extension STACK.
3210Sstevel@tonic-gate  */
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate 
X509V3_EXT_add_nconf_sk(CONF * conf,X509V3_CTX * ctx,char * section,STACK_OF (X509_EXTENSION)** sk)3240Sstevel@tonic-gate int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
3250Sstevel@tonic-gate 	     STACK_OF(X509_EXTENSION) **sk)
3260Sstevel@tonic-gate 	{
3270Sstevel@tonic-gate 	X509_EXTENSION *ext;
3280Sstevel@tonic-gate 	STACK_OF(CONF_VALUE) *nval;
3290Sstevel@tonic-gate 	CONF_VALUE *val;
3300Sstevel@tonic-gate 	int i;
3310Sstevel@tonic-gate 	if (!(nval = NCONF_get_section(conf, section))) return 0;
3320Sstevel@tonic-gate 	for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
3330Sstevel@tonic-gate 		{
3340Sstevel@tonic-gate 		val = sk_CONF_VALUE_value(nval, i);
3350Sstevel@tonic-gate 		if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
3360Sstevel@tonic-gate 								return 0;
3370Sstevel@tonic-gate 		if (sk) X509v3_add_ext(sk, ext, -1);
3380Sstevel@tonic-gate 		X509_EXTENSION_free(ext);
3390Sstevel@tonic-gate 		}
3400Sstevel@tonic-gate 	return 1;
3410Sstevel@tonic-gate 	}
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate /* Convenience functions to add extensions to a certificate, CRL and request */
3440Sstevel@tonic-gate 
X509V3_EXT_add_nconf(CONF * conf,X509V3_CTX * ctx,char * section,X509 * cert)3450Sstevel@tonic-gate int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
3460Sstevel@tonic-gate 	     X509 *cert)
3470Sstevel@tonic-gate 	{
3480Sstevel@tonic-gate 	STACK_OF(X509_EXTENSION) **sk = NULL;
3490Sstevel@tonic-gate 	if (cert)
3500Sstevel@tonic-gate 		sk = &cert->cert_info->extensions;
3510Sstevel@tonic-gate 	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
3520Sstevel@tonic-gate 	}
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate /* Same as above but for a CRL */
3550Sstevel@tonic-gate 
X509V3_EXT_CRL_add_nconf(CONF * conf,X509V3_CTX * ctx,char * section,X509_CRL * crl)3560Sstevel@tonic-gate int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
3570Sstevel@tonic-gate 	     X509_CRL *crl)
3580Sstevel@tonic-gate 	{
3590Sstevel@tonic-gate 	STACK_OF(X509_EXTENSION) **sk = NULL;
3600Sstevel@tonic-gate 	if (crl)
3610Sstevel@tonic-gate 		sk = &crl->crl->extensions;
3620Sstevel@tonic-gate 	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
3630Sstevel@tonic-gate 	}
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate /* Add extensions to certificate request */
3660Sstevel@tonic-gate 
X509V3_EXT_REQ_add_nconf(CONF * conf,X509V3_CTX * ctx,char * section,X509_REQ * req)3670Sstevel@tonic-gate int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
3680Sstevel@tonic-gate 	     X509_REQ *req)
3690Sstevel@tonic-gate 	{
3700Sstevel@tonic-gate 	STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
3710Sstevel@tonic-gate 	int i;
3720Sstevel@tonic-gate 	if (req)
3730Sstevel@tonic-gate 		sk = &extlist;
3740Sstevel@tonic-gate 	i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
3750Sstevel@tonic-gate 	if (!i || !sk)
3760Sstevel@tonic-gate 		return i;
3770Sstevel@tonic-gate 	i = X509_REQ_add_extensions(req, extlist);
3780Sstevel@tonic-gate 	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
3790Sstevel@tonic-gate 	return i;
3800Sstevel@tonic-gate 	}
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate /* Config database functions */
3830Sstevel@tonic-gate 
X509V3_get_string(X509V3_CTX * ctx,char * name,char * section)3840Sstevel@tonic-gate char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
3850Sstevel@tonic-gate 	{
386*2139Sjp161948 	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
387*2139Sjp161948 		{
388*2139Sjp161948 		X509V3err(X509V3_F_X509V3_GET_STRING,X509V3_R_OPERATION_NOT_DEFINED);
389*2139Sjp161948 		return NULL;
390*2139Sjp161948 		}
3910Sstevel@tonic-gate 	if (ctx->db_meth->get_string)
3920Sstevel@tonic-gate 			return ctx->db_meth->get_string(ctx->db, name, section);
3930Sstevel@tonic-gate 	return NULL;
3940Sstevel@tonic-gate 	}
3950Sstevel@tonic-gate 
STACK_OF(CONF_VALUE)3960Sstevel@tonic-gate STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
3970Sstevel@tonic-gate 	{
398*2139Sjp161948 	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
399*2139Sjp161948 		{
400*2139Sjp161948 		X509V3err(X509V3_F_X509V3_GET_SECTION,X509V3_R_OPERATION_NOT_DEFINED);
401*2139Sjp161948 		return NULL;
402*2139Sjp161948 		}
4030Sstevel@tonic-gate 	if (ctx->db_meth->get_section)
4040Sstevel@tonic-gate 			return ctx->db_meth->get_section(ctx->db, section);
4050Sstevel@tonic-gate 	return NULL;
4060Sstevel@tonic-gate 	}
4070Sstevel@tonic-gate 
X509V3_string_free(X509V3_CTX * ctx,char * str)4080Sstevel@tonic-gate void X509V3_string_free(X509V3_CTX *ctx, char *str)
4090Sstevel@tonic-gate 	{
4100Sstevel@tonic-gate 	if (!str) return;
4110Sstevel@tonic-gate 	if (ctx->db_meth->free_string)
4120Sstevel@tonic-gate 			ctx->db_meth->free_string(ctx->db, str);
4130Sstevel@tonic-gate 	}
4140Sstevel@tonic-gate 
X509V3_section_free(X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* section)4150Sstevel@tonic-gate void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
4160Sstevel@tonic-gate 	{
4170Sstevel@tonic-gate 	if (!section) return;
4180Sstevel@tonic-gate 	if (ctx->db_meth->free_section)
4190Sstevel@tonic-gate 			ctx->db_meth->free_section(ctx->db, section);
4200Sstevel@tonic-gate 	}
4210Sstevel@tonic-gate 
nconf_get_string(void * db,char * section,char * value)4220Sstevel@tonic-gate static char *nconf_get_string(void *db, char *section, char *value)
4230Sstevel@tonic-gate 	{
4240Sstevel@tonic-gate 	return NCONF_get_string(db, section, value);
4250Sstevel@tonic-gate 	}
4260Sstevel@tonic-gate 
STACK_OF(CONF_VALUE)4270Sstevel@tonic-gate static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
4280Sstevel@tonic-gate 	{
4290Sstevel@tonic-gate 	return NCONF_get_section(db, section);
4300Sstevel@tonic-gate 	}
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate static X509V3_CONF_METHOD nconf_method = {
4330Sstevel@tonic-gate nconf_get_string,
4340Sstevel@tonic-gate nconf_get_section,
4350Sstevel@tonic-gate NULL,
4360Sstevel@tonic-gate NULL
4370Sstevel@tonic-gate };
4380Sstevel@tonic-gate 
X509V3_set_nconf(X509V3_CTX * ctx,CONF * conf)4390Sstevel@tonic-gate void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
4400Sstevel@tonic-gate 	{
4410Sstevel@tonic-gate 	ctx->db_meth = &nconf_method;
4420Sstevel@tonic-gate 	ctx->db = conf;
4430Sstevel@tonic-gate 	}
4440Sstevel@tonic-gate 
X509V3_set_ctx(X509V3_CTX * ctx,X509 * issuer,X509 * subj,X509_REQ * req,X509_CRL * crl,int flags)4450Sstevel@tonic-gate void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
4460Sstevel@tonic-gate 	     X509_CRL *crl, int flags)
4470Sstevel@tonic-gate 	{
4480Sstevel@tonic-gate 	ctx->issuer_cert = issuer;
4490Sstevel@tonic-gate 	ctx->subject_cert = subj;
4500Sstevel@tonic-gate 	ctx->crl = crl;
4510Sstevel@tonic-gate 	ctx->subject_req = req;
4520Sstevel@tonic-gate 	ctx->flags = flags;
4530Sstevel@tonic-gate 	}
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate /* Old conf compatibility functions */
4560Sstevel@tonic-gate 
X509V3_EXT_conf(LHASH * conf,X509V3_CTX * ctx,char * name,char * value)4570Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name,
4580Sstevel@tonic-gate 	     char *value)
4590Sstevel@tonic-gate 	{
4600Sstevel@tonic-gate 	CONF ctmp;
4610Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
4620Sstevel@tonic-gate 	return X509V3_EXT_nconf(&ctmp, ctx, name, value);
4630Sstevel@tonic-gate 	}
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate /* LHASH *conf:  Config file    */
4660Sstevel@tonic-gate /* char *value:  Value    */
X509V3_EXT_conf_nid(LHASH * conf,X509V3_CTX * ctx,int ext_nid,char * value)4670Sstevel@tonic-gate X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid,
4680Sstevel@tonic-gate 	     char *value)
4690Sstevel@tonic-gate 	{
4700Sstevel@tonic-gate 	CONF ctmp;
4710Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
4720Sstevel@tonic-gate 	return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
4730Sstevel@tonic-gate 	}
4740Sstevel@tonic-gate 
conf_lhash_get_string(void * db,char * section,char * value)4750Sstevel@tonic-gate static char *conf_lhash_get_string(void *db, char *section, char *value)
4760Sstevel@tonic-gate 	{
4770Sstevel@tonic-gate 	return CONF_get_string(db, section, value);
4780Sstevel@tonic-gate 	}
4790Sstevel@tonic-gate 
STACK_OF(CONF_VALUE)4800Sstevel@tonic-gate static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section)
4810Sstevel@tonic-gate 	{
4820Sstevel@tonic-gate 	return CONF_get_section(db, section);
4830Sstevel@tonic-gate 	}
4840Sstevel@tonic-gate 
4850Sstevel@tonic-gate static X509V3_CONF_METHOD conf_lhash_method = {
4860Sstevel@tonic-gate conf_lhash_get_string,
4870Sstevel@tonic-gate conf_lhash_get_section,
4880Sstevel@tonic-gate NULL,
4890Sstevel@tonic-gate NULL
4900Sstevel@tonic-gate };
4910Sstevel@tonic-gate 
X509V3_set_conf_lhash(X509V3_CTX * ctx,LHASH * lhash)4920Sstevel@tonic-gate void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash)
4930Sstevel@tonic-gate 	{
4940Sstevel@tonic-gate 	ctx->db_meth = &conf_lhash_method;
4950Sstevel@tonic-gate 	ctx->db = lhash;
4960Sstevel@tonic-gate 	}
4970Sstevel@tonic-gate 
X509V3_EXT_add_conf(LHASH * conf,X509V3_CTX * ctx,char * section,X509 * cert)4980Sstevel@tonic-gate int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
4990Sstevel@tonic-gate 	     X509 *cert)
5000Sstevel@tonic-gate 	{
5010Sstevel@tonic-gate 	CONF ctmp;
5020Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
5030Sstevel@tonic-gate 	return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
5040Sstevel@tonic-gate 	}
5050Sstevel@tonic-gate 
5060Sstevel@tonic-gate /* Same as above but for a CRL */
5070Sstevel@tonic-gate 
X509V3_EXT_CRL_add_conf(LHASH * conf,X509V3_CTX * ctx,char * section,X509_CRL * crl)5080Sstevel@tonic-gate int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
5090Sstevel@tonic-gate 	     X509_CRL *crl)
5100Sstevel@tonic-gate 	{
5110Sstevel@tonic-gate 	CONF ctmp;
5120Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
5130Sstevel@tonic-gate 	return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
5140Sstevel@tonic-gate 	}
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate /* Add extensions to certificate request */
5170Sstevel@tonic-gate 
X509V3_EXT_REQ_add_conf(LHASH * conf,X509V3_CTX * ctx,char * section,X509_REQ * req)5180Sstevel@tonic-gate int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
5190Sstevel@tonic-gate 	     X509_REQ *req)
5200Sstevel@tonic-gate 	{
5210Sstevel@tonic-gate 	CONF ctmp;
5220Sstevel@tonic-gate 	CONF_set_nconf(&ctmp, conf);
5230Sstevel@tonic-gate 	return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
5240Sstevel@tonic-gate 	}
525