/* v3_conf.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project 1999.
 */
/* ====================================================================
 * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com). */

/* extension creation utilities */

#include <stdio.h>
#include <ctype.h>

#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>


static int v3_check_critical(char **value);
static int v3_check_generic(char **value);
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value);
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
				  int crit, void *ext_struc);
static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
/* CONF *conf:  Config file    */
/* char *name:  Name    */
/* char *value:  Value    */
X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
				 char *value)
	{
	int crit;
	int ext_type;
	X509_EXTENSION *ret;
	crit = v3_check_critical(&value);
	if ((ext_type = v3_check_generic(&value))) 
		return v3_generic_extension(name, value, crit, ext_type, ctx);
	ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
	if (!ret)
		{
		OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_nconf, X509V3_R_ERROR_IN_EXTENSION);
		ERR_add_error_data(4,"name=", name, ", value=", value);
		}
	return ret;
	}

/* CONF *conf:  Config file    */
/* char *value:  Value    */
X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
				     char *value)
	{
	int crit;
	int ext_type;
	crit = v3_check_critical(&value);
	if ((ext_type = v3_check_generic(&value))) 
		return v3_generic_extension(OBJ_nid2sn(ext_nid),
						 value, crit, ext_type, ctx);
	return do_ext_nconf(conf, ctx, ext_nid, crit, value);
	}

/* CONF *conf:  Config file    */
/* char *value:  Value    */
static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
				    int crit, char *value)
	{
	const X509V3_EXT_METHOD *method;
	X509_EXTENSION *ext;
	STACK_OF(CONF_VALUE) *nval;
	void *ext_struc;
	if (ext_nid == NID_undef)
		{
		OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_UNKNOWN_EXTENSION_NAME);
		return NULL;
		}
	if (!(method = X509V3_EXT_get_nid(ext_nid)))
		{
		OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_UNKNOWN_EXTENSION);
		return NULL;
		}
	/* Now get internal extension representation based on type */
	if (method->v2i)
		{
		if(*value == '@') nval = NCONF_get_section(conf, value + 1);
		else nval = X509V3_parse_list(value);
		if(sk_CONF_VALUE_num(nval) <= 0)
			{
			OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, 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_CONF_VALUE_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 || !ctx->db_meth)
			{
			OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_NO_CONFIG_DATABASE);
			return NULL;
			}
		if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
		}
	else
		{
		OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
		ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
		return NULL;
		}

	ext  = do_ext_i2d(method, ext_nid, crit, ext_struc);
	if(method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
	else method->ext_free(ext_struc);
	return ext;

	}

static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
				  int crit, void *ext_struc)
	{
	unsigned char *ext_der;
	int ext_len;
	ASN1_OCTET_STRING *ext_oct;
	X509_EXTENSION *ext;
	/* Convert internal representation to DER */
	if (method->it)
		{
		ext_der = NULL;
		ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
		if (ext_len < 0) goto merr;
		}
	 else
		{
		unsigned char *p;
		ext_len = method->i2d(ext_struc, NULL);
		if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
		p = ext_der;
		method->i2d(ext_struc, &p);
		}
	if (!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
	ext_oct->data = ext_der;
	ext_oct->length = ext_len;

	ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
	if (!ext) goto merr;
	M_ASN1_OCTET_STRING_free(ext_oct);

	return ext;

	merr:
	OPENSSL_PUT_ERROR(X509V3, do_ext_i2d, ERR_R_MALLOC_FAILURE);
	return NULL;

	}

/* Given an internal structure, nid and critical flag create an extension */

X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
	{
	const X509V3_EXT_METHOD *method;
	if (!(method = X509V3_EXT_get_nid(ext_nid))) {
		OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_i2d, X509V3_R_UNKNOWN_EXTENSION);
		return NULL;
	}
	return do_ext_i2d(method, ext_nid, crit, ext_struc);
}

/* Check the extension string for critical flag */
static int v3_check_critical(char **value)
{
	char *p = *value;
	if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0;
	p+=9;
	while(isspace((unsigned char)*p)) p++;
	*value = p;
	return 1;
}

/* Check extension string for generic extension and return the type */
static int v3_check_generic(char **value)
{
	int gen_type = 0;
	char *p = *value;
	if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4))
		{
		p+=4;
		gen_type = 1;
		}
	else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5))
		{
		p+=5;
		gen_type = 2;
		}
	else
		return 0;

	while (isspace((unsigned char)*p)) p++;
	*value = p;
	return gen_type;
}

/* Create a generic extension: for now just handle DER type */
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
					    int crit, int gen_type,
					    X509V3_CTX *ctx)
	{
	unsigned char *ext_der=NULL;
	long ext_len;
	ASN1_OBJECT *obj=NULL;
	ASN1_OCTET_STRING *oct=NULL;
	X509_EXTENSION *extension=NULL;
	if (!(obj = OBJ_txt2obj(ext, 0)))
		{
		OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, X509V3_R_EXTENSION_NAME_ERROR);
		ERR_add_error_data(2, "name=", ext);
		goto err;
		}

	if (gen_type == 1)
		ext_der = string_to_hex(value, &ext_len);
	else if (gen_type == 2)
		ext_der = generic_asn1(value, ctx, &ext_len);

	if (ext_der == NULL)
		{
		OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, X509V3_R_EXTENSION_VALUE_ERROR);
		ERR_add_error_data(2, "value=", value);
		goto err;
		}

	if (!(oct = M_ASN1_OCTET_STRING_new()))
		{
		OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	oct->data = ext_der;
	oct->length = ext_len;
	ext_der = NULL;

	extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);

	err:
	ASN1_OBJECT_free(obj);
	M_ASN1_OCTET_STRING_free(oct);
	if(ext_der) OPENSSL_free(ext_der);
	return extension;

	}

static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
	{
	ASN1_TYPE *typ;
	unsigned char *ext_der = NULL;
	typ = ASN1_generate_v3(value, ctx);
	if (typ == NULL)
		return NULL;
	*ext_len = i2d_ASN1_TYPE(typ, &ext_der);
	ASN1_TYPE_free(typ);
	return ext_der;
	}

/* This is the main function: add a bunch of extensions based on a config file
 * section to an extension STACK.
 */


int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
			    STACK_OF(X509_EXTENSION) **sk)
	{
	X509_EXTENSION *ext;
	STACK_OF(CONF_VALUE) *nval;
	CONF_VALUE *val;	
	size_t i;
	if (!(nval = NCONF_get_section(conf, section))) return 0;
	for (i = 0; i < sk_CONF_VALUE_num(nval); i++)
		{
		val = sk_CONF_VALUE_value(nval, i);
		if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
								return 0;
		if (sk) X509v3_add_ext(sk, ext, -1);
		X509_EXTENSION_free(ext);
		}
	return 1;
	}

/* Convenience functions to add extensions to a certificate, CRL and request */

int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
			 X509 *cert)
	{
	STACK_OF(X509_EXTENSION) **sk = NULL;
	if (cert)
		sk = &cert->cert_info->extensions;
	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
	}

/* Same as above but for a CRL */

int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
			     X509_CRL *crl)
	{
	STACK_OF(X509_EXTENSION) **sk = NULL;
	if (crl)
		sk = &crl->crl->extensions;
	return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
	}

/* Add extensions to certificate request */

int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
	     X509_REQ *req)
	{
	STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
	int i;
	if (req)
		sk = &extlist;
	i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
	if (!i || !sk)
		return i;
	i = X509_REQ_add_extensions(req, extlist);
	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
	return i;
	}

/* Config database functions */

char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
	{
	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
		{
		OPENSSL_PUT_ERROR(X509V3, X509V3_get_string, X509V3_R_OPERATION_NOT_DEFINED);
		return NULL;
		}
	if (ctx->db_meth->get_string)
			return ctx->db_meth->get_string(ctx->db, name, section);
	return NULL;
	}

STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
	{
	if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
		{
		OPENSSL_PUT_ERROR(X509V3, X509V3_get_section, X509V3_R_OPERATION_NOT_DEFINED);
		return NULL;
		}
	if (ctx->db_meth->get_section)
			return ctx->db_meth->get_section(ctx->db, section);
	return NULL;
	}

void X509V3_string_free(X509V3_CTX *ctx, char *str)
	{
	if (!str) return;
	if (ctx->db_meth->free_string)
			ctx->db_meth->free_string(ctx->db, str);
	}

void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
	{
	if (!section) return;
	if (ctx->db_meth->free_section)
			ctx->db_meth->free_section(ctx->db, section);
	}

static char *nconf_get_string(void *db, char *section, char *value)
	{
        /* TODO(fork): this should return a const value. */
	return (char *) NCONF_get_string(db, section, value);
	}

static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
	{
	return NCONF_get_section(db, section);
	}

static X509V3_CONF_METHOD nconf_method = {
nconf_get_string,
nconf_get_section,
NULL,
NULL
};

void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
	{
	ctx->db_meth = &nconf_method;
	ctx->db = conf;
	}

void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
		    X509_CRL *crl, int flags)
	{
	ctx->issuer_cert = issuer;
	ctx->subject_cert = subj;
	ctx->crl = crl;
	ctx->subject_req = req;
	ctx->flags = flags;
	}

/* TODO(fork): remove */
#if 0
/* Old conf compatibility functions */

X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
				char *name, char *value)
	{
	CONF ctmp;
	CONF_set_nconf(&ctmp, conf);
	return X509V3_EXT_nconf(&ctmp, ctx, name, value);
	}

/* LHASH *conf:  Config file    */
/* char *value:  Value    */
X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
				    int ext_nid, char *value)
	{
	CONF ctmp;
	CONF_set_nconf(&ctmp, conf);
	return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
	}

static char *conf_lhash_get_string(void *db, char *section, char *value)
	{
	return CONF_get_string(db, section, value);
	}

static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section)
	{
	return CONF_get_section(db, section);
	}

static X509V3_CONF_METHOD conf_lhash_method = {
conf_lhash_get_string,
conf_lhash_get_section,
NULL,
NULL
};

void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
	{
	ctx->db_meth = &conf_lhash_method;
	ctx->db = lhash;
	}

int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
			char *section, X509 *cert)
	{
	CONF ctmp;
	CONF_set_nconf(&ctmp, conf);
	return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
	}

/* Same as above but for a CRL */

int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
			    char *section, X509_CRL *crl)
	{
	CONF ctmp;
	CONF_set_nconf(&ctmp, conf);
	return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
	}

/* Add extensions to certificate request */

int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
			    char *section, X509_REQ *req)
	{
	CONF ctmp;
	CONF_set_nconf(&ctmp, conf);
	return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
	}
#endif
