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