/* 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 <ctype.h>
#include <stdio.h>
#include <string.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 const 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 const 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
