X509_EXTENSION *ext = NULL;
static X509_EXTENSION *do_ext_conf(LHASH *conf, X509V3_CTX *ctx, int ext_nid,	     int crit, char *value){	X509_EXTENSION *ext = NULL;	X509V3_EXT_METHOD *method;	STACK *nval;	char *ext_struc;	unsigned char *ext_der, *p;	int ext_len;	ASN1_OCTET_STRING *ext_oct;	if(ext_nid == NID_undef) {		X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION_NAME);		return NULL;	}	if(!(method = X509V3_EXT_get_nid(ext_nid))) {		X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION);		return NULL;	}	/* Now get internal extension representation based on type */	if(method->v2i) {		if(*value == '@') nval = CONF_get_section(conf, value + 1);		else nval = X509V3_parse_list(value);		if(!nval) {			X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_INVALID_EXTENSION_STRING);			ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);			return NULL;		}		ext_struc = method->v2i(method, ctx, nval);		if(*value != '@') sk_pop_free(nval, X509V3_conf_free);		if(!ext_struc) return NULL;	} else if(method->s2i) {		if(!(ext_struc = method->s2i(method, ctx, value))) return NULL;	} else if(method->r2i) {		if(!ctx->db) {			X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_NO_CONFIG_DATABASE);			return NULL;		}		if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;	} else {		X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);		ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));		return NULL;	}	/* We've now got the internal representation: convert to DER */	ext_len = method->i2d(ext_struc, NULL);	ext_der = Malloc(ext_len);	p = ext_der;	method->i2d(ext_struc, &p);	method->ext_free(ext_struc);	ext_oct = ASN1_OCTET_STRING_new();	ext_oct->data = ext_der;	ext_oct->length = ext_len;		ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);	ASN1_OCTET_STRING_free(ext_oct);	return ext;}