/*	$NetBSD: crypto_openssl.c,v 1.11.6.5 2009/04/20 13:33:30 tteras Exp $	*/

/* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */

/*
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS 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 PROJECT OR 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.
 */

#include "config.h"

#include <sys/types.h>
#include <sys/param.h>

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>

/* get openssl/ssleay version number */
#include <openssl/opensslv.h>

#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090602fL)
#error OpenSSL version 0.9.6 or later required.
#endif

#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/des.h>
#include <openssl/crypto.h>
#ifdef HAVE_OPENSSL_ENGINE_H
#include <openssl/engine.h>
#endif
#ifndef ANDROID_CHANGES
#include <openssl/blowfish.h>
#include <openssl/cast.h>
#else
#define EVP_bf_cbc()    NULL
#define EVP_cast5_cbc() NULL
#include "keystore_get.h"
#endif
#include <openssl/err.h>
#ifdef HAVE_OPENSSL_RC5_H
#include <openssl/rc5.h>
#endif
#ifdef HAVE_OPENSSL_IDEA_H
#include <openssl/idea.h>
#endif
#if defined(HAVE_OPENSSL_AES_H)
#include <openssl/aes.h>
#elif defined(HAVE_OPENSSL_RIJNDAEL_H)
#include <openssl/rijndael.h>
#else
#include "crypto/rijndael/rijndael-api-fst.h"
#endif
#if defined(HAVE_OPENSSL_CAMELLIA_H)
#include <openssl/camellia.h>
#endif
#ifdef WITH_SHA2
#ifdef HAVE_OPENSSL_SHA2_H
#include <openssl/sha2.h>
#else
#include "crypto/sha2/sha2.h"
#endif
#endif
#include "plog.h"

/* 0.9.7 stuff? */
#if OPENSSL_VERSION_NUMBER < 0x0090700fL
typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
#else
#define USE_NEW_DES_API
#endif

#define OpenSSL_BUG()	do { plog(LLV_ERROR, LOCATION, NULL, "OpenSSL function failed\n"); } while(0)

#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "crypto_openssl.h"
#include "debug.h"
#include "gcmalloc.h"

/*
 * I hate to cast every parameter to des_xx into void *, but it is
 * necessary for SSLeay/OpenSSL portability.  It sucks.
 */

static int cb_check_cert_local __P((int, X509_STORE_CTX *));
static int cb_check_cert_remote __P((int, X509_STORE_CTX *));
static X509 *mem2x509 __P((vchar_t *));

static caddr_t eay_hmac_init __P((vchar_t *, const EVP_MD *));

/* X509 Certificate */
/*
 * convert the string of the subject name into DER
 * e.g. str = "C=JP, ST=Kanagawa";
 */
vchar_t *
eay_str2asn1dn(str, len)
	const char *str;
	int len;
{
	X509_NAME *name;
	char *buf;
	char *field, *value;
	int i, j;
	vchar_t *ret = NULL;
	caddr_t p;

	if (len == -1)
		len = strlen(str);

	buf = racoon_malloc(len + 1);
	if (!buf) {
		plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
		return NULL;
	}
	memcpy(buf, str, len);

	name = X509_NAME_new();

	field = &buf[0];
	value = NULL;
	for (i = 0; i < len; i++) {
		if (!value && buf[i] == '=') {
			buf[i] = '\0';
			value = &buf[i + 1];
			continue;
		} else if (buf[i] == ',' || buf[i] == '/') {
			buf[i] = '\0';

			plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
			     field, value);

			if (!value) goto err;
			if (!X509_NAME_add_entry_by_txt(name, field,
					(value[0] == '*' && value[1] == 0) ? 
						V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
					(unsigned char *) value, -1, -1, 0)) {
				plog(LLV_ERROR, LOCATION, NULL, 
				     "Invalid DN field: %s=%s\n",
				     field, value);
				plog(LLV_ERROR, LOCATION, NULL, 
				     "%s\n", eay_strerror());
				goto err;
			}
			for (j = i + 1; j < len; j++) {
				if (buf[j] != ' ')
					break;
			}
			field = &buf[j];
			value = NULL;
			continue;
		}
	}
	buf[len] = '\0';

	plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
	     field, value);

	if (!value) goto err;
	if (!X509_NAME_add_entry_by_txt(name, field,
			(value[0] == '*' && value[1] == 0) ? 
				V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
			(unsigned char *) value, -1, -1, 0)) {
		plog(LLV_ERROR, LOCATION, NULL, 
		     "Invalid DN field: %s=%s\n",
		     field, value);
		plog(LLV_ERROR, LOCATION, NULL, 
		     "%s\n", eay_strerror());
		goto err;
	}

	i = i2d_X509_NAME(name, NULL);
	if (!i)
		goto err;
	ret = vmalloc(i);
	if (!ret)
		goto err;
	p = ret->v;
	i = i2d_X509_NAME(name, (void *)&p);
	if (!i)
		goto err;

	return ret;

    err:
	if (buf)
		racoon_free(buf);
	if (name)
		X509_NAME_free(name);
	if (ret)
		vfree(ret);
	return NULL;
}

/*
 * convert the hex string of the subject name into DER
 */
vchar_t *
eay_hex2asn1dn(const char *hex, int len)
{
	BIGNUM *bn = BN_new();
	char *binbuf;
	size_t binlen;
	vchar_t *ret = NULL;
	
	if (len == -1)
		len = strlen(hex);

	if (BN_hex2bn(&bn, hex) != len) {
		plog(LLV_ERROR, LOCATION, NULL, 
		     "conversion of Hex-encoded ASN1 string to binary failed: %s\n",
		     eay_strerror());
		goto out;
	}
	
	binlen = BN_num_bytes(bn);
	ret = vmalloc(binlen);
	if (!ret) {
		plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
		return NULL;
	}
	binbuf = ret->v;

	BN_bn2bin(bn, (unsigned char *) binbuf);

out:
	BN_free(bn);

	return ret;
}

/*
 * The following are derived from code in crypto/x509/x509_cmp.c
 * in OpenSSL0.9.7c:
 * X509_NAME_wildcmp() adds wildcard matching to the original
 * X509_NAME_cmp(), nocase_cmp() and nocase_spacenorm_cmp() are as is.
 */
#include <ctype.h>
/* Case insensitive string comparision */
static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
	int i;

	if (a->length != b->length)
		return (a->length - b->length);

	for (i=0; i<a->length; i++)
	{
		int ca, cb;

		ca = tolower(a->data[i]);
		cb = tolower(b->data[i]);

		if (ca != cb)
			return(ca-cb);
	}
	return 0;
}

/* Case insensitive string comparision with space normalization 
 * Space normalization - ignore leading, trailing spaces, 
 *       multiple spaces between characters are replaced by single space  
 */
static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
	unsigned char *pa = NULL, *pb = NULL;
	int la, lb;
	
	la = a->length;
	lb = b->length;
	pa = a->data;
	pb = b->data;

	/* skip leading spaces */
	while (la > 0 && isspace(*pa))
	{
		la--;
		pa++;
	}
	while (lb > 0 && isspace(*pb))
	{
		lb--;
		pb++;
	}

	/* skip trailing spaces */
	while (la > 0 && isspace(pa[la-1]))
		la--;
	while (lb > 0 && isspace(pb[lb-1]))
		lb--;

	/* compare strings with space normalization */
	while (la > 0 && lb > 0)
	{
		int ca, cb;

		/* compare character */
		ca = tolower(*pa);
		cb = tolower(*pb);
		if (ca != cb)
			return (ca - cb);

		pa++; pb++;
		la--; lb--;

		if (la <= 0 || lb <= 0)
			break;

		/* is white space next character ? */
		if (isspace(*pa) && isspace(*pb))
		{
			/* skip remaining white spaces */
			while (la > 0 && isspace(*pa))
			{
				la--;
				pa++;
			}
			while (lb > 0 && isspace(*pb))
			{
				lb--;
				pb++;
			}
		}
	}
	if (la > 0 || lb > 0)
		return la - lb;

	return 0;
}

static int X509_NAME_wildcmp(const X509_NAME *a, const X509_NAME *b)
{
    int i,j;
    X509_NAME_ENTRY *na,*nb;

    if (sk_X509_NAME_ENTRY_num(a->entries)
	!= sk_X509_NAME_ENTRY_num(b->entries))
	    return sk_X509_NAME_ENTRY_num(a->entries)
	      -sk_X509_NAME_ENTRY_num(b->entries);
    for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
    {
	    na=sk_X509_NAME_ENTRY_value(a->entries,i);
	    nb=sk_X509_NAME_ENTRY_value(b->entries,i);
	    j=OBJ_cmp(na->object,nb->object);
	    if (j) return(j);
	    if ((na->value->length == 1 && na->value->data[0] == '*')
	     || (nb->value->length == 1 && nb->value->data[0] == '*'))
		    continue;
	    j=na->value->type-nb->value->type;
	    if (j) return(j);
	    if (na->value->type == V_ASN1_PRINTABLESTRING)
		    j=nocase_spacenorm_cmp(na->value, nb->value);
	    else if (na->value->type == V_ASN1_IA5STRING
		    && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
		    j=nocase_cmp(na->value, nb->value);
	    else
		    {
		    j=na->value->length-nb->value->length;
		    if (j) return(j);
		    j=memcmp(na->value->data,nb->value->data,
			    na->value->length);
		    }
	    if (j) return(j);
	    j=na->set-nb->set;
	    if (j) return(j);
    }

    return(0);
}

/*
 * compare two subjectNames.
 * OUT:        0: equal
 *	positive:
 *	      -1: other error.
 */
int
eay_cmp_asn1dn(n1, n2)
	vchar_t *n1, *n2;
{
	X509_NAME *a = NULL, *b = NULL;
	caddr_t p;
	int i = -1;

	p = n1->v;
	if (!d2i_X509_NAME(&a, (void *)&p, n1->l))
		goto end;
	p = n2->v;
	if (!d2i_X509_NAME(&b, (void *)&p, n2->l))
		goto end;

	i = X509_NAME_wildcmp(a, b);

    end:
	if (a)
		X509_NAME_free(a);
	if (b)
		X509_NAME_free(b);
	return i;
}

#ifdef ANDROID_CHANGES
static BIO *BIO_from_keystore(char *key)
{
	BIO *bio = NULL;
	char *value;
	int size;

	value = keystore_get(key, &size);
	if (value) {
		bio = BIO_new(BIO_s_mem());
		if (bio) {
			BIO_write(bio, value, size);
		}
		free(value);
	}
	return bio;
}
#endif


/*
 * this functions is derived from apps/verify.c in OpenSSL0.9.5
 */
int
eay_check_x509cert(cert, CApath, CAfile, local)
	vchar_t *cert;
	char *CApath;
	char *CAfile;
	int local;
{
	X509_STORE *cert_ctx = NULL;
	X509_LOOKUP *lookup = NULL;
	X509 *x509 = NULL;
	X509_STORE_CTX *csc;
	int error = -1;

	cert_ctx = X509_STORE_new();
	if (cert_ctx == NULL)
		goto end;

	if (local)
		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_local);
	else 
		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_remote);

#ifndef ANDROID_CHANGES
	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
	if (lookup == NULL)
		goto end;

	X509_LOOKUP_load_file(lookup, CAfile, 
	    (CAfile == NULL) ? X509_FILETYPE_DEFAULT : X509_FILETYPE_PEM);

	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
	if (lookup == NULL)
		goto end;
	error = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
	if(!error) {
		error = -1;
		goto end;
	}
	error = -1;	/* initialized */
#else
	if (CAfile) {
		BIO *bio = BIO_from_keystore(CAfile);
		STACK_OF(X509_INFO) *stack;
		X509_INFO *info;
		int i;

		if (!bio) {
			goto end;
		}
		stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
		BIO_free(bio);
		if (!stack) {
			goto end;
		}
		for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
			info = sk_X509_INFO_value(stack, i);
			if (info->x509) {
				X509_STORE_add_cert(cert_ctx, info->x509);
			}
			if (info->crl) {
				X509_STORE_add_crl(cert_ctx, info->crl);
			}
		}
		sk_X509_INFO_pop_free(stack, X509_INFO_free);
	}
#endif

	/* read the certificate to be verified */
	x509 = mem2x509(cert);
	if (x509 == NULL)
		goto end;

	csc = X509_STORE_CTX_new();
	if (csc == NULL)
		goto end;
	X509_STORE_CTX_init(csc, cert_ctx, x509, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
	X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK);
	X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK_ALL);
#endif
	error = X509_verify_cert(csc);
	X509_STORE_CTX_cleanup(csc);

	/*
	 * if x509_verify_cert() is successful then the value of error is
	 * set non-zero.
	 */
	error = error ? 0 : -1;

end:
	if (error)
		plog(LLV_WARNING, LOCATION, NULL,"%s\n", eay_strerror());
	if (cert_ctx != NULL)
		X509_STORE_free(cert_ctx);
	if (x509 != NULL)
		X509_free(x509);

	return(error);
}

/*
 * callback function for verifing certificate.
 * this function is derived from cb() in openssl/apps/s_server.c
 */
static int
cb_check_cert_local(ok, ctx)
	int ok;
	X509_STORE_CTX *ctx;
{
	char buf[256];
	int log_tag;

	if (!ok) {
		X509_NAME_oneline(
				X509_get_subject_name(ctx->current_cert),
				buf,
				256);
		/*
		 * since we are just checking the certificates, it is
		 * ok if they are self signed. But we should still warn
		 * the user.
 		 */
		switch (ctx->error) {
		case X509_V_ERR_CERT_HAS_EXPIRED:
		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
		case X509_V_ERR_INVALID_CA:
		case X509_V_ERR_PATH_LENGTH_EXCEEDED:
		case X509_V_ERR_INVALID_PURPOSE:
		case X509_V_ERR_UNABLE_TO_GET_CRL:
			ok = 1;
			log_tag = LLV_WARNING;
			break;
		default:
			log_tag = LLV_ERROR;
		}
		plog(log_tag, LOCATION, NULL,
			"%s(%d) at depth:%d SubjectName:%s\n",
			X509_verify_cert_error_string(ctx->error),
			ctx->error,
			ctx->error_depth,
			buf);
	}
	ERR_clear_error();

	return ok;
}

/*
 * callback function for verifing remote certificates.
 * this function is derived from cb() in openssl/apps/s_server.c
 */
static int
cb_check_cert_remote(ok, ctx)
	int ok;
	X509_STORE_CTX *ctx;
{
	char buf[256];
	int log_tag;

	if (!ok) {
		X509_NAME_oneline(
				X509_get_subject_name(ctx->current_cert),
				buf,
				256);
		switch (ctx->error) {
		case X509_V_ERR_UNABLE_TO_GET_CRL:
			ok = 1;
			log_tag = LLV_WARNING;
			break;
		default:
			log_tag = LLV_ERROR;
		}
		plog(log_tag, LOCATION, NULL,
			"%s(%d) at depth:%d SubjectName:%s\n",
			X509_verify_cert_error_string(ctx->error),
			ctx->error,
			ctx->error_depth,
			buf);
	}
	ERR_clear_error();

	return ok;
}

/*
 * get a subjectAltName from X509 certificate.
 */
vchar_t *
eay_get_x509asn1subjectname(cert)
	vchar_t *cert;
{
	X509 *x509 = NULL;
	u_char *bp;
	vchar_t *name = NULL;
	int len;

	bp = (unsigned char *) cert->v;

	x509 = mem2x509(cert);
	if (x509 == NULL)
		goto error;

	/* get the length of the name */
	len = i2d_X509_NAME(x509->cert_info->subject, NULL);
	name = vmalloc(len);
	if (!name)
		goto error;
	/* get the name */
	bp = (unsigned char *) name->v;
	len = i2d_X509_NAME(x509->cert_info->subject, &bp);

	X509_free(x509);

	return name;

error:
	plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());

	if (name != NULL) 
		vfree(name);

	if (x509 != NULL)
		X509_free(x509);

	return NULL;
}

/*
 * get the subjectAltName from X509 certificate.
 * the name must be terminated by '\0'.
 */
int
eay_get_x509subjectaltname(cert, altname, type, pos)
	vchar_t *cert;
	char **altname;
	int *type;
	int pos;
{
	X509 *x509 = NULL;
	GENERAL_NAMES *gens = NULL;
	GENERAL_NAME *gen;
	int len;
	int error = -1;

	*altname = NULL;
	*type = GENT_OTHERNAME;

	x509 = mem2x509(cert);
	if (x509 == NULL)
		goto end;

	gens = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
	if (gens == NULL)
		goto end;

	/* there is no data at "pos" */
	if (pos > sk_GENERAL_NAME_num(gens))
		goto end;

	gen = sk_GENERAL_NAME_value(gens, pos - 1);

	/* read DNSName / Email */
	if (gen->type == GEN_DNS	||
		gen->type == GEN_EMAIL	||
		gen->type == GEN_URI )
	{
		/* make sure if the data is terminated by '\0'. */
		if (gen->d.ia5->data[gen->d.ia5->length] != '\0')
		{
			plog(LLV_ERROR, LOCATION, NULL,
				 "data is not terminated by NUL.");
			racoon_hexdump(gen->d.ia5->data, gen->d.ia5->length + 1);
			goto end;
		}
		
		len = gen->d.ia5->length + 1;
		*altname = racoon_malloc(len);
		if (!*altname)
			goto end;
		
		strlcpy(*altname, (char *) gen->d.ia5->data, len);
		*type = gen->type;
		error = 0;
	}
	/* read IP address */
	else if (gen->type == GEN_IPADD)
	{
		unsigned char p[5], *ip;
		ip = p;
		
		/* only support IPv4 */
		if (gen->d.ip->length != 4)
			goto end;
		
		/* convert Octet String to String
		 * XXX ???????
		 */
		/*i2d_ASN1_OCTET_STRING(gen->d.ip,&ip);*/
		ip = gen->d.ip->data;

		/* XXX Magic, enough for an IPv4 address
		 */
		*altname = racoon_malloc(20);
		if (!*altname)
			goto end;
		
		sprintf(*altname, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
		*type = gen->type;
		error = 0;
	}
	/* XXX other possible types ?
	 * For now, error will be -1 if unsupported type
	 */

end:
	if (error) {
		if (*altname) {
			racoon_free(*altname);
			*altname = NULL;
		}
		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
	}
	if (x509)
		X509_free(x509);
	if (gens)
		/* free the whole stack. */
		sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);

	return error;
}


/*
 * decode a X509 certificate and make a readable text terminated '\n'.
 * return the buffer allocated, so must free it later.
 */
char *
eay_get_x509text(cert)
	vchar_t *cert;
{
	X509 *x509 = NULL;
	BIO *bio = NULL;
	char *text = NULL;
	u_char *bp = NULL;
	int len = 0;
	int error = -1;

	x509 = mem2x509(cert);
	if (x509 == NULL)
		goto end;

	bio = BIO_new(BIO_s_mem());
	if (bio == NULL)
		goto end;

	error = X509_print(bio, x509);
	if (error != 1) {
		error = -1;
		goto end;
	}

	len = BIO_get_mem_data(bio, &bp);
	text = racoon_malloc(len + 1);
	if (text == NULL)
		goto end;
	memcpy(text, bp, len);
	text[len] = '\0';

	error = 0;

    end:
	if (error) {
		if (text) {
			racoon_free(text);
			text = NULL;
		}
		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
	}
	if (bio)
		BIO_free(bio);
	if (x509)
		X509_free(x509);

	return text;
}

/* get X509 structure from buffer. */
static X509 *
mem2x509(cert)
	vchar_t *cert;
{
	X509 *x509;

#ifndef EAYDEBUG
    {
	u_char *bp;

	bp = (unsigned char *) cert->v;

	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
    }
#else
    {
	BIO *bio;
	int len;

	bio = BIO_new(BIO_s_mem());
	if (bio == NULL)
		return NULL;
	len = BIO_write(bio, cert->v, cert->l);
	if (len == -1)
		return NULL;
	x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
	BIO_free(bio);
    }
#endif
	return x509;
}

/*
 * get a X509 certificate from local file.
 * a certificate must be PEM format.
 * Input:
 *	path to a certificate.
 * Output:
 *	NULL if error occured
 *	other is the cert.
 */
vchar_t *
eay_get_x509cert(path)
	char *path;
{
	FILE *fp;
	X509 *x509;
	vchar_t *cert;
	u_char *bp;
	int len;
	int error;

#ifdef ANDROID_CHANGES
	BIO *bio = BIO_from_keystore(path);
	x509 = NULL;
	if (bio) {
		x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
		BIO_free(bio);
	}
#else
	/* Read private key */
	fp = fopen(path, "r");
	if (fp == NULL)
		return NULL;
	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
	fclose (fp);
#endif

	if (x509 == NULL)
		return NULL;

	len = i2d_X509(x509, NULL);
	cert = vmalloc(len);
	if (cert == NULL) {
		X509_free(x509);
		return NULL;
	}
	bp = (unsigned char *) cert->v;
	error = i2d_X509(x509, &bp);
	X509_free(x509);

	if (error == 0) {
		vfree(cert);
		return NULL;
	}

	return cert;
}

/*
 * check a X509 signature
 *	XXX: to be get hash type from my cert ?
 *		to be handled EVP_dss().
 * OUT: return -1 when error.
 *	0
 */
int
eay_check_x509sign(source, sig, cert)
	vchar_t *source;
	vchar_t *sig;
	vchar_t *cert;
{
	X509 *x509;
	u_char *bp;
	EVP_PKEY *evp;
	int res;

	bp = (unsigned char *) cert->v;

	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
	if (x509 == NULL) {
		plog(LLV_ERROR, LOCATION, NULL, "d2i_X509(): %s\n", eay_strerror());
		return -1;
	}

	evp = X509_get_pubkey(x509);
	if (! evp) {
		plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror());
		X509_free(x509);
		return -1;
	}

	res = eay_rsa_verify(source, sig, evp->pkey.rsa);

	EVP_PKEY_free(evp);
	X509_free(x509);

	return res;
}

/*
 * check RSA signature
 * OUT: return -1 when error.
 *	0 on success
 */
int
eay_check_rsasign(source, sig, rsa)
	vchar_t *source;
	vchar_t *sig;
	RSA *rsa;
{
	return eay_rsa_verify(source, sig, rsa);
}

/*
 * get PKCS#1 Private Key of PEM format from local file.
 */
vchar_t *
eay_get_pkcs1privkey(path)
	char *path;
{
	FILE *fp;
	EVP_PKEY *evp = NULL;
	vchar_t *pkey = NULL;
	u_char *bp;
	int pkeylen;
	int error = -1;

#ifdef ANDROID_CHANGES
	BIO *bio = BIO_from_keystore(path);
	if (bio) {
		evp = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
		BIO_free(bio);
	}
#else
	/* Read private key */
	fp = fopen(path, "r");
	if (fp == NULL)
		return NULL;

	evp = PEM_read_PrivateKey(fp, NULL, NULL, NULL);

	fclose (fp);
#endif

	if (evp == NULL)
		return NULL;

	pkeylen = i2d_PrivateKey(evp, NULL);
	if (pkeylen == 0)
		goto end;
	pkey = vmalloc(pkeylen);
	if (pkey == NULL)
		goto end;
	bp = (unsigned char *) pkey->v;
	pkeylen = i2d_PrivateKey(evp, &bp);
	if (pkeylen == 0)
		goto end;

	error = 0;

end:
	if (evp != NULL)
		EVP_PKEY_free(evp);
	if (error != 0 && pkey != NULL) {
		vfree(pkey);
		pkey = NULL;
	}

	return pkey;
}

/*
 * get PKCS#1 Public Key of PEM format from local file.
 */
vchar_t *
eay_get_pkcs1pubkey(path)
	char *path;
{
	FILE *fp;
	EVP_PKEY *evp = NULL;
	vchar_t *pkey = NULL;
	X509 *x509 = NULL;
	u_char *bp;
	int pkeylen;
	int error = -1;

	/* Read private key */
	fp = fopen(path, "r");
	if (fp == NULL)
		return NULL;

	x509 = PEM_read_X509(fp, NULL, NULL, NULL);

	fclose (fp);

	if (x509 == NULL)
		return NULL;
  
	/* Get public key - eay */
	evp = X509_get_pubkey(x509);
	if (evp == NULL)
		return NULL;

	pkeylen = i2d_PublicKey(evp, NULL);
	if (pkeylen == 0)
		goto end;
	pkey = vmalloc(pkeylen);
	if (pkey == NULL)
		goto end;
	bp = (unsigned char *) pkey->v;
	pkeylen = i2d_PublicKey(evp, &bp);
	if (pkeylen == 0)
		goto end;

	error = 0;
end:
	if (evp != NULL)
		EVP_PKEY_free(evp);
	if (error != 0 && pkey != NULL) {
		vfree(pkey);
		pkey = NULL;
	}

	return pkey;
}

vchar_t *
eay_get_x509sign(src, privkey)
	vchar_t *src, *privkey;
{
	EVP_PKEY *evp;
	u_char *bp = (unsigned char *) privkey->v;
	vchar_t *sig = NULL;
	int len;
	int pad = RSA_PKCS1_PADDING;

	/* XXX to be handled EVP_PKEY_DSA */
	evp = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (void *)&bp, privkey->l);
	if (evp == NULL)
		return NULL;

	sig = eay_rsa_sign(src, evp->pkey.rsa);

	EVP_PKEY_free(evp);

	return sig;
}

vchar_t *
eay_get_rsasign(src, rsa)
	vchar_t *src;
	RSA *rsa;
{
	return eay_rsa_sign(src, rsa);
}

vchar_t *
eay_rsa_sign(vchar_t *src, RSA *rsa)
{
	int len;
	vchar_t *sig = NULL;
	int pad = RSA_PKCS1_PADDING;

	len = RSA_size(rsa);

	sig = vmalloc(len);
	if (sig == NULL)
		return NULL;

	len = RSA_private_encrypt(src->l, (unsigned char *) src->v, 
			(unsigned char *) sig->v, rsa, pad);

	if (len == 0 || len != sig->l) {
		vfree(sig);
		sig = NULL;
	}

	return sig;
}

int
eay_rsa_verify(src, sig, rsa)
	vchar_t *src, *sig;
	RSA *rsa;
{
	vchar_t *xbuf = NULL;
	int pad = RSA_PKCS1_PADDING;
	int len = 0;
	int error;

	len = RSA_size(rsa);
	xbuf = vmalloc(len);
	if (xbuf == NULL) {
		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
		return -1;
	}

	len = RSA_public_decrypt(sig->l, (unsigned char *) sig->v, 
			(unsigned char *) xbuf->v, rsa, pad);
	if (len == 0 || len != src->l) {
		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
		vfree(xbuf);
		return -1;
	}

	error = memcmp(src->v, xbuf->v, src->l);
	vfree(xbuf);
	if (error != 0)
		return -1;

	return 0;
}

/*
 * get error string
 * MUST load ERR_load_crypto_strings() first.
 */
char *
eay_strerror()
{
	static char ebuf[512];
	int len = 0, n;
	unsigned long l;
	char buf[200];
	const char *file, *data;
	int line, flags;
	unsigned long es;

	es = CRYPTO_thread_id();

	while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){
		n = snprintf(ebuf + len, sizeof(ebuf) - len,
				"%lu:%s:%s:%d:%s ",
				es, ERR_error_string(l, buf), file, line,
				(flags & ERR_TXT_STRING) ? data : "");
		if (n < 0 || n >= sizeof(ebuf) - len)
			break;
		len += n;
		if (sizeof(ebuf) < len)
			break;
	}

	return ebuf;
}

vchar_t *
evp_crypt(vchar_t *data, vchar_t *key, vchar_t *iv, const EVP_CIPHER *e, int enc)
{
	vchar_t *res;
	EVP_CIPHER_CTX ctx;

	if (!e)
		return NULL;

	if (data->l % EVP_CIPHER_block_size(e))
		return NULL;

	if ((res = vmalloc(data->l)) == NULL)
		return NULL;

	EVP_CIPHER_CTX_init(&ctx);

	switch(EVP_CIPHER_nid(e)){
	case NID_bf_cbc:
	case NID_bf_ecb:
	case NID_bf_cfb64:
	case NID_bf_ofb64:
	case NID_cast5_cbc:
	case NID_cast5_ecb:
	case NID_cast5_cfb64:
	case NID_cast5_ofb64:
		/* XXX: can we do that also for algos with a fixed key size ?
		 */
		/* init context without key/iv
         */
        if (!EVP_CipherInit(&ctx, e, NULL, NULL, enc))
        {
            OpenSSL_BUG();
            vfree(res);
            return NULL;
        }
		
        /* update key size
         */
        if (!EVP_CIPHER_CTX_set_key_length(&ctx, key->l))
        {
            OpenSSL_BUG();
            vfree(res);
            return NULL;
        }

        /* finalize context init with desired key size
         */
        if (!EVP_CipherInit(&ctx, NULL, (u_char *) key->v,
							(u_char *) iv->v, enc))
        {
            OpenSSL_BUG();
            vfree(res);
            return NULL;
		}
		break;
	default:
		if (!EVP_CipherInit(&ctx, e, (u_char *) key->v, 
							(u_char *) iv->v, enc)) {
			OpenSSL_BUG();
			vfree(res);
			return NULL;
		}
	}

	/* disable openssl padding */
	EVP_CIPHER_CTX_set_padding(&ctx, 0); 
	
	if (!EVP_Cipher(&ctx, (u_char *) res->v, (u_char *) data->v, data->l)) {
		OpenSSL_BUG();
		vfree(res);
		return NULL;
	}

	EVP_CIPHER_CTX_cleanup(&ctx);

	return res;
}

int
evp_weakkey(vchar_t *key, const EVP_CIPHER *e)
{
	return 0;
}

int
evp_keylen(int len, const EVP_CIPHER *e)
{
	if (!e)
		return -1;
	/* EVP functions return lengths in bytes, ipsec-tools
	 * uses lengths in bits, therefore conversion is required. --AK
	 */
	if (len != 0 && len != (EVP_CIPHER_key_length(e) << 3))
		return -1;
	
	return EVP_CIPHER_key_length(e) << 3;
}

/*
 * DES-CBC
 */
vchar_t *
eay_des_encrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, EVP_des_cbc(), 1);
}

vchar_t *
eay_des_decrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, EVP_des_cbc(), 0);
}

int
eay_des_weakkey(key)
	vchar_t *key;
{
#ifdef USE_NEW_DES_API
	return DES_is_weak_key((void *)key->v);
#else
	return des_is_weak_key((void *)key->v);
#endif
}

int
eay_des_keylen(len)
	int len;
{
	return evp_keylen(len, EVP_des_cbc());
}

#ifdef HAVE_OPENSSL_IDEA_H
/*
 * IDEA-CBC
 */
vchar_t *
eay_idea_encrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	vchar_t *res;
	IDEA_KEY_SCHEDULE ks;

	idea_set_encrypt_key((unsigned char *)key->v, &ks);

	/* allocate buffer for result */
	if ((res = vmalloc(data->l)) == NULL)
		return NULL;

	/* decryption data */
	idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
			&ks, (unsigned char *)iv->v, IDEA_ENCRYPT);

	return res;
}

vchar_t *
eay_idea_decrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	vchar_t *res;
	IDEA_KEY_SCHEDULE ks, dks;

	idea_set_encrypt_key((unsigned char *)key->v, &ks);
	idea_set_decrypt_key(&ks, &dks);

	/* allocate buffer for result */
	if ((res = vmalloc(data->l)) == NULL)
		return NULL;

	/* decryption data */
	idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
			&dks, (unsigned char *)iv->v, IDEA_DECRYPT);

	return res;
}

int
eay_idea_weakkey(key)
	vchar_t *key;
{
	return 0;       /* XXX */
}

int
eay_idea_keylen(len)
	int len;
{
	if (len != 0 && len != 128)
		return -1;
	return 128;
}
#endif

/*
 * BLOWFISH-CBC
 */
vchar_t *
eay_bf_encrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, EVP_bf_cbc(), 1);
}

vchar_t *
eay_bf_decrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, EVP_bf_cbc(), 0);
}

int
eay_bf_weakkey(key)
	vchar_t *key;
{
	return 0;	/* XXX to be done. refer to RFC 2451 */
}

int
eay_bf_keylen(len)
	int len;
{
	if (len == 0)
		return 448;
	if (len < 40 || len > 448)
		return -1;
	return len;
}

#ifdef HAVE_OPENSSL_RC5_H
/*
 * RC5-CBC
 */
vchar_t *
eay_rc5_encrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	vchar_t *res;
	RC5_32_KEY ks;

	/* in RFC 2451, there is information about the number of round. */
	RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16);

	/* allocate buffer for result */
	if ((res = vmalloc(data->l)) == NULL)
		return NULL;

	/* decryption data */
	RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
		&ks, (unsigned char *)iv->v, RC5_ENCRYPT);

	return res;
}

vchar_t *
eay_rc5_decrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	vchar_t *res;
	RC5_32_KEY ks;

	/* in RFC 2451, there is information about the number of round. */
	RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16);

	/* allocate buffer for result */
	if ((res = vmalloc(data->l)) == NULL)
		return NULL;

	/* decryption data */
	RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
		&ks, (unsigned char *)iv->v, RC5_DECRYPT);

	return res;
}

int
eay_rc5_weakkey(key)
	vchar_t *key;
{
	return 0;       /* No known weak keys when used with 16 rounds. */

}

int
eay_rc5_keylen(len)
	int len;
{
	if (len == 0)
		return 128;
	if (len < 40 || len > 2040)
		return -1;
	return len;
}
#endif

/*
 * 3DES-CBC
 */
vchar_t *
eay_3des_encrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 1);
}

vchar_t *
eay_3des_decrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 0);
}

int
eay_3des_weakkey(key)
	vchar_t *key;
{
#ifdef USE_NEW_DES_API
	return (DES_is_weak_key((void *)key->v) ||
	    DES_is_weak_key((void *)(key->v + 8)) ||
	    DES_is_weak_key((void *)(key->v + 16)));
#else
	if (key->l < 24)
		return 0;

	return (des_is_weak_key((void *)key->v) ||
	    des_is_weak_key((void *)(key->v + 8)) ||
	    des_is_weak_key((void *)(key->v + 16)));
#endif
}

int
eay_3des_keylen(len)
	int len;
{
	if (len != 0 && len != 192)
		return -1;
	return 192;
}

/*
 * CAST-CBC
 */
vchar_t *
eay_cast_encrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, EVP_cast5_cbc(), 1);
}

vchar_t *
eay_cast_decrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, EVP_cast5_cbc(), 0);
}

int
eay_cast_weakkey(key)
	vchar_t *key;
{
	return 0;	/* No known weak keys. */
}

int
eay_cast_keylen(len)
	int len;
{
	if (len == 0)
		return 128;
	if (len < 40 || len > 128)
		return -1;
	return len;
}

/*
 * AES(RIJNDAEL)-CBC
 */
#ifndef HAVE_OPENSSL_AES_H
vchar_t *
eay_aes_encrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	vchar_t *res;
	keyInstance k;
	cipherInstance c;

	memset(&k, 0, sizeof(k));
	if (rijndael_makeKey(&k, DIR_ENCRYPT, key->l << 3, key->v) < 0)
		return NULL;

	/* allocate buffer for result */
	if ((res = vmalloc(data->l)) == NULL)
		return NULL;

	/* encryption data */
	memset(&c, 0, sizeof(c));
	if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
		vfree(res);
		return NULL;
	}
	if (rijndael_blockEncrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
		vfree(res);
		return NULL;
	}

	return res;
}

vchar_t *
eay_aes_decrypt(data, key, iv)
	vchar_t *data, *key, *iv;
{
	vchar_t *res;
	keyInstance k;
	cipherInstance c;

	memset(&k, 0, sizeof(k));
	if (rijndael_makeKey(&k, DIR_DECRYPT, key->l << 3, key->v) < 0)
		return NULL;

	/* allocate buffer for result */
	if ((res = vmalloc(data->l)) == NULL)
		return NULL;

	/* decryption data */
	memset(&c, 0, sizeof(c));
	if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
		vfree(res);
		return NULL;
	}
	if (rijndael_blockDecrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
		vfree(res);
		return NULL;
	}

	return res;
}
#else
static inline const EVP_CIPHER *
aes_evp_by_keylen(int keylen)
{
	switch(keylen) {
		case 16:
		case 128:
			return EVP_aes_128_cbc();
		case 24:
		case 192:
			return EVP_aes_192_cbc();
		case 32:
		case 256:
			return EVP_aes_256_cbc();
		default:
			return NULL;
	}
}

vchar_t *
eay_aes_encrypt(data, key, iv)
       vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 1);
}

vchar_t *
eay_aes_decrypt(data, key, iv)
       vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 0);
}
#endif

int
eay_aes_weakkey(key)
	vchar_t *key;
{
	return 0;
}

int
eay_aes_keylen(len)
	int len;
{
	if (len == 0)
		return 128;
	if (len != 128 && len != 192 && len != 256)
		return -1;
	return len;
}

#if defined(HAVE_OPENSSL_CAMELLIA_H)
/*
 * CAMELLIA-CBC
 */
static inline const EVP_CIPHER *
camellia_evp_by_keylen(int keylen)
{
	switch(keylen) {
		case 16:
		case 128:
			return EVP_camellia_128_cbc();
		case 24:
		case 192:
			return EVP_camellia_192_cbc();
		case 32:
		case 256:
			return EVP_camellia_256_cbc();
		default:
			return NULL;
	}
}

vchar_t *
eay_camellia_encrypt(data, key, iv)
       vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 1);
}

vchar_t *
eay_camellia_decrypt(data, key, iv)
       vchar_t *data, *key, *iv;
{
	return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 0);
}

int
eay_camellia_weakkey(key)
	vchar_t *key;
{
	return 0;
}

int
eay_camellia_keylen(len)
	int len;
{
	if (len == 0)
		return 128;
	if (len != 128 && len != 192 && len != 256)
		return -1;
	return len;
}

#endif

/* for ipsec part */
int
eay_null_hashlen()
{
	return 0;
}

int
eay_kpdk_hashlen()
{
	return 0;
}

int
eay_twofish_keylen(len)
	int len;
{
	if (len < 0 || len > 256)
		return -1;
	return len;
}

int
eay_null_keylen(len)
	int len;
{
	return 0;
}

/*
 * HMAC functions
 */
static caddr_t
eay_hmac_init(key, md)
	vchar_t *key;
	const EVP_MD *md;
{
	HMAC_CTX *c = racoon_malloc(sizeof(*c));

	HMAC_Init(c, key->v, key->l, md);

	return (caddr_t)c;
}

#ifdef WITH_SHA2
/*
 * HMAC SHA2-512
 */
vchar_t *
eay_hmacsha2_512_one(key, data)
	vchar_t *key, *data;
{
	vchar_t *res;
	caddr_t ctx;

	ctx = eay_hmacsha2_512_init(key);
	eay_hmacsha2_512_update(ctx, data);
	res = eay_hmacsha2_512_final(ctx);

	return(res);
}

caddr_t
eay_hmacsha2_512_init(key)
	vchar_t *key;
{
	return eay_hmac_init(key, EVP_sha2_512());
}

void
eay_hmacsha2_512_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
}

vchar_t *
eay_hmacsha2_512_final(c)
	caddr_t c;
{
	vchar_t *res;
	unsigned int l;

	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
		return NULL;

	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
	res->l = l;
	HMAC_cleanup((HMAC_CTX *)c);
	(void)racoon_free(c);

	if (SHA512_DIGEST_LENGTH != res->l) {
		plog(LLV_ERROR, LOCATION, NULL,
			"hmac sha2_512 length mismatch %zd.\n", res->l);
		vfree(res);
		return NULL;
	}

	return(res);
}

/*
 * HMAC SHA2-384
 */
vchar_t *
eay_hmacsha2_384_one(key, data)
	vchar_t *key, *data;
{
	vchar_t *res;
	caddr_t ctx;

	ctx = eay_hmacsha2_384_init(key);
	eay_hmacsha2_384_update(ctx, data);
	res = eay_hmacsha2_384_final(ctx);

	return(res);
}

caddr_t
eay_hmacsha2_384_init(key)
	vchar_t *key;
{
	return eay_hmac_init(key, EVP_sha2_384());
}

void
eay_hmacsha2_384_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
}

vchar_t *
eay_hmacsha2_384_final(c)
	caddr_t c;
{
	vchar_t *res;
	unsigned int l;

	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
		return NULL;

	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
	res->l = l;
	HMAC_cleanup((HMAC_CTX *)c);
	(void)racoon_free(c);

	if (SHA384_DIGEST_LENGTH != res->l) {
		plog(LLV_ERROR, LOCATION, NULL,
			"hmac sha2_384 length mismatch %zd.\n", res->l);
		vfree(res);
		return NULL;
	}

	return(res);
}

/*
 * HMAC SHA2-256
 */
vchar_t *
eay_hmacsha2_256_one(key, data)
	vchar_t *key, *data;
{
	vchar_t *res;
	caddr_t ctx;

	ctx = eay_hmacsha2_256_init(key);
	eay_hmacsha2_256_update(ctx, data);
	res = eay_hmacsha2_256_final(ctx);

	return(res);
}

caddr_t
eay_hmacsha2_256_init(key)
	vchar_t *key;
{
	return eay_hmac_init(key, EVP_sha2_256());
}

void
eay_hmacsha2_256_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
}

vchar_t *
eay_hmacsha2_256_final(c)
	caddr_t c;
{
	vchar_t *res;
	unsigned int l;

	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
		return NULL;

	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
	res->l = l;
	HMAC_cleanup((HMAC_CTX *)c);
	(void)racoon_free(c);

	if (SHA256_DIGEST_LENGTH != res->l) {
		plog(LLV_ERROR, LOCATION, NULL,
			"hmac sha2_256 length mismatch %zd.\n", res->l);
		vfree(res);
		return NULL;
	}

	return(res);
}
#endif	/* WITH_SHA2 */

/*
 * HMAC SHA1
 */
vchar_t *
eay_hmacsha1_one(key, data)
	vchar_t *key, *data;
{
	vchar_t *res;
	caddr_t ctx;

	ctx = eay_hmacsha1_init(key);
	eay_hmacsha1_update(ctx, data);
	res = eay_hmacsha1_final(ctx);

	return(res);
}

caddr_t
eay_hmacsha1_init(key)
	vchar_t *key;
{
	return eay_hmac_init(key, EVP_sha1());
}

void
eay_hmacsha1_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
}

vchar_t *
eay_hmacsha1_final(c)
	caddr_t c;
{
	vchar_t *res;
	unsigned int l;

	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
		return NULL;

	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
	res->l = l;
	HMAC_cleanup((HMAC_CTX *)c);
	(void)racoon_free(c);

	if (SHA_DIGEST_LENGTH != res->l) {
		plog(LLV_ERROR, LOCATION, NULL,
			"hmac sha1 length mismatch %zd.\n", res->l);
		vfree(res);
		return NULL;
	}

	return(res);
}

/*
 * HMAC MD5
 */
vchar_t *
eay_hmacmd5_one(key, data)
	vchar_t *key, *data;
{
	vchar_t *res;
	caddr_t ctx;

	ctx = eay_hmacmd5_init(key);
	eay_hmacmd5_update(ctx, data);
	res = eay_hmacmd5_final(ctx);

	return(res);
}

caddr_t
eay_hmacmd5_init(key)
	vchar_t *key;
{
	return eay_hmac_init(key, EVP_md5());
}

void
eay_hmacmd5_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
}

vchar_t *
eay_hmacmd5_final(c)
	caddr_t c;
{
	vchar_t *res;
	unsigned int l;

	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
		return NULL;

	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
	res->l = l;
	HMAC_cleanup((HMAC_CTX *)c);
	(void)racoon_free(c);

	if (MD5_DIGEST_LENGTH != res->l) {
		plog(LLV_ERROR, LOCATION, NULL,
			"hmac md5 length mismatch %zd.\n", res->l);
		vfree(res);
		return NULL;
	}

	return(res);
}

#ifdef WITH_SHA2
/*
 * SHA2-512 functions
 */
caddr_t
eay_sha2_512_init()
{
	SHA512_CTX *c = racoon_malloc(sizeof(*c));

	SHA512_Init(c);

	return((caddr_t)c);
}

void
eay_sha2_512_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	SHA512_Update((SHA512_CTX *)c, (unsigned char *) data->v, data->l);

	return;
}

vchar_t *
eay_sha2_512_final(c)
	caddr_t c;
{
	vchar_t *res;

	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
		return(0);

	SHA512_Final((unsigned char *) res->v, (SHA512_CTX *)c);
	(void)racoon_free(c);

	return(res);
}

vchar_t *
eay_sha2_512_one(data)
	vchar_t *data;
{
	caddr_t ctx;
	vchar_t *res;

	ctx = eay_sha2_512_init();
	eay_sha2_512_update(ctx, data);
	res = eay_sha2_512_final(ctx);

	return(res);
}

int
eay_sha2_512_hashlen()
{
	return SHA512_DIGEST_LENGTH << 3;
}
#endif

#ifdef WITH_SHA2
/*
 * SHA2-384 functions
 */
caddr_t
eay_sha2_384_init()
{
	SHA384_CTX *c = racoon_malloc(sizeof(*c));

	SHA384_Init(c);

	return((caddr_t)c);
}

void
eay_sha2_384_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	SHA384_Update((SHA384_CTX *)c, (unsigned char *) data->v, data->l);

	return;
}

vchar_t *
eay_sha2_384_final(c)
	caddr_t c;
{
	vchar_t *res;

	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
		return(0);

	SHA384_Final((unsigned char *) res->v, (SHA384_CTX *)c);
	(void)racoon_free(c);

	return(res);
}

vchar_t *
eay_sha2_384_one(data)
	vchar_t *data;
{
	caddr_t ctx;
	vchar_t *res;

	ctx = eay_sha2_384_init();
	eay_sha2_384_update(ctx, data);
	res = eay_sha2_384_final(ctx);

	return(res);
}

int
eay_sha2_384_hashlen()
{
	return SHA384_DIGEST_LENGTH << 3;
}
#endif

#ifdef WITH_SHA2
/*
 * SHA2-256 functions
 */
caddr_t
eay_sha2_256_init()
{
	SHA256_CTX *c = racoon_malloc(sizeof(*c));

	SHA256_Init(c);

	return((caddr_t)c);
}

void
eay_sha2_256_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	SHA256_Update((SHA256_CTX *)c, (unsigned char *) data->v, data->l);

	return;
}

vchar_t *
eay_sha2_256_final(c)
	caddr_t c;
{
	vchar_t *res;

	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
		return(0);

	SHA256_Final((unsigned char *) res->v, (SHA256_CTX *)c);
	(void)racoon_free(c);

	return(res);
}

vchar_t *
eay_sha2_256_one(data)
	vchar_t *data;
{
	caddr_t ctx;
	vchar_t *res;

	ctx = eay_sha2_256_init();
	eay_sha2_256_update(ctx, data);
	res = eay_sha2_256_final(ctx);

	return(res);
}

int
eay_sha2_256_hashlen()
{
	return SHA256_DIGEST_LENGTH << 3;
}
#endif

/*
 * SHA functions
 */
caddr_t
eay_sha1_init()
{
	SHA_CTX *c = racoon_malloc(sizeof(*c));

	SHA1_Init(c);

	return((caddr_t)c);
}

void
eay_sha1_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	SHA1_Update((SHA_CTX *)c, data->v, data->l);

	return;
}

vchar_t *
eay_sha1_final(c)
	caddr_t c;
{
	vchar_t *res;

	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
		return(0);

	SHA1_Final((unsigned char *) res->v, (SHA_CTX *)c);
	(void)racoon_free(c);

	return(res);
}

vchar_t *
eay_sha1_one(data)
	vchar_t *data;
{
	caddr_t ctx;
	vchar_t *res;

	ctx = eay_sha1_init();
	eay_sha1_update(ctx, data);
	res = eay_sha1_final(ctx);

	return(res);
}

int
eay_sha1_hashlen()
{
	return SHA_DIGEST_LENGTH << 3;
}

/*
 * MD5 functions
 */
caddr_t
eay_md5_init()
{
	MD5_CTX *c = racoon_malloc(sizeof(*c));

	MD5_Init(c);

	return((caddr_t)c);
}

void
eay_md5_update(c, data)
	caddr_t c;
	vchar_t *data;
{
	MD5_Update((MD5_CTX *)c, data->v, data->l);

	return;
}

vchar_t *
eay_md5_final(c)
	caddr_t c;
{
	vchar_t *res;

	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
		return(0);

	MD5_Final((unsigned char *) res->v, (MD5_CTX *)c);
	(void)racoon_free(c);

	return(res);
}

vchar_t *
eay_md5_one(data)
	vchar_t *data;
{
	caddr_t ctx;
	vchar_t *res;

	ctx = eay_md5_init();
	eay_md5_update(ctx, data);
	res = eay_md5_final(ctx);

	return(res);
}

int
eay_md5_hashlen()
{
	return MD5_DIGEST_LENGTH << 3;
}

/*
 * eay_set_random
 *   size: number of bytes.
 */
vchar_t *
eay_set_random(size)
	u_int32_t size;
{
	BIGNUM *r = NULL;
	vchar_t *res = 0;

	if ((r = BN_new()) == NULL)
		goto end;
	BN_rand(r, size * 8, 0, 0);
	eay_bn2v(&res, r);

end:
	if (r)
		BN_free(r);
	return(res);
}

/* DH */
int
eay_dh_generate(prime, g, publen, pub, priv)
	vchar_t *prime, **pub, **priv;
	u_int publen;
	u_int32_t g;
{
	BIGNUM *p = NULL;
	DH *dh = NULL;
	int error = -1;

	/* initialize */
	/* pre-process to generate number */
	if (eay_v2bn(&p, prime) < 0)
		goto end;

	if ((dh = DH_new()) == NULL)
		goto end;
	dh->p = p;
	p = NULL;	/* p is now part of dh structure */
	dh->g = NULL;
	if ((dh->g = BN_new()) == NULL)
		goto end;
	if (!BN_set_word(dh->g, g))
		goto end;

	if (publen != 0)
		dh->length = publen;

	/* generate public and private number */
	if (!DH_generate_key(dh))
		goto end;

	/* copy results to buffers */
	if (eay_bn2v(pub, dh->pub_key) < 0)
		goto end;
	if (eay_bn2v(priv, dh->priv_key) < 0) {
		vfree(*pub);
		goto end;
	}

	error = 0;

end:
	if (dh != NULL)
		DH_free(dh);
	if (p != 0)
		BN_free(p);
	return(error);
}

int
eay_dh_compute(prime, g, pub, priv, pub2, key)
	vchar_t *prime, *pub, *priv, *pub2, **key;
	u_int32_t g;
{
	BIGNUM *dh_pub = NULL;
	DH *dh = NULL;
	int l;
	unsigned char *v = NULL;
	int error = -1;

	/* make public number to compute */
	if (eay_v2bn(&dh_pub, pub2) < 0)
		goto end;

	/* make DH structure */
	if ((dh = DH_new()) == NULL)
		goto end;
	if (eay_v2bn(&dh->p, prime) < 0)
		goto end;
	if (eay_v2bn(&dh->pub_key, pub) < 0)
		goto end;
	if (eay_v2bn(&dh->priv_key, priv) < 0)
		goto end;
	dh->length = pub2->l * 8;

	dh->g = NULL;
	if ((dh->g = BN_new()) == NULL)
		goto end;
	if (!BN_set_word(dh->g, g))
		goto end;

	if ((v = racoon_calloc(prime->l, sizeof(u_char))) == NULL)
		goto end;
	if ((l = DH_compute_key(v, dh_pub, dh)) == -1)
		goto end;
	memcpy((*key)->v + (prime->l - l), v, l);

	error = 0;

end:
	if (dh_pub != NULL)
		BN_free(dh_pub);
	if (dh != NULL)
		DH_free(dh);
	if (v != NULL)
		racoon_free(v);
	return(error);
}

/*
 * convert vchar_t <-> BIGNUM.
 *
 * vchar_t: unit is u_char, network endian, most significant byte first.
 * BIGNUM: unit is BN_ULONG, each of BN_ULONG is in host endian,
 *	least significant BN_ULONG must come first.
 *
 * hex value of "0x3ffe050104" is represented as follows:
 *	vchar_t: 3f fe 05 01 04
 *	BIGNUM (BN_ULONG = u_int8_t): 04 01 05 fe 3f
 *	BIGNUM (BN_ULONG = u_int16_t): 0x0104 0xfe05 0x003f
 *	BIGNUM (BN_ULONG = u_int32_t_t): 0xfe050104 0x0000003f
 */
int
eay_v2bn(bn, var)
	BIGNUM **bn;
	vchar_t *var;
{
	if ((*bn = BN_bin2bn((unsigned char *) var->v, var->l, NULL)) == NULL)
		return -1;

	return 0;
}

int
eay_bn2v(var, bn)
	vchar_t **var;
	BIGNUM *bn;
{
	*var = vmalloc(bn->top * BN_BYTES);
	if (*var == NULL)
		return(-1);

	(*var)->l = BN_bn2bin(bn, (unsigned char *) (*var)->v);

	return 0;
}

void
eay_init()
{
	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();
#ifdef HAVE_OPENSSL_ENGINE_H
	ENGINE_load_builtin_engines();
	ENGINE_register_all_complete();
#endif
}

vchar_t *
base64_decode(char *in, long inlen)
{
	BIO *bio=NULL, *b64=NULL;
	vchar_t *res = NULL;
	char *outb;
	long outlen;

	outb = malloc(inlen * 2);
	if (outb == NULL)
		goto out;
	bio = BIO_new_mem_buf(in, inlen);
	b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	bio = BIO_push(b64, bio);

	outlen = BIO_read(bio, outb, inlen * 2);
	if (outlen <= 0) {
		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
		goto out;
	}

	res = vmalloc(outlen);
	if (!res)
		goto out;

	memcpy(res->v, outb, outlen);

out:
	if (outb)
		free(outb);
	if (bio)
		BIO_free_all(bio);

	return res;
}

vchar_t *
base64_encode(char *in, long inlen)
{
	BIO *bio=NULL, *b64=NULL;
	char *ptr;
	long plen = -1;
	vchar_t *res = NULL;

	bio = BIO_new(BIO_s_mem());
	b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	bio = BIO_push(b64, bio);

	BIO_write(bio, in, inlen);
	BIO_flush(bio);

	plen = BIO_get_mem_data(bio, &ptr);
	res = vmalloc(plen+1);
	if (!res)
		goto out;
	
	memcpy (res->v, ptr, plen);
	res->v[plen] = '\0';

out:	
	if (bio)
		BIO_free_all(bio);

	return res;
}

static RSA *
binbuf_pubkey2rsa(vchar_t *binbuf)
{
	BIGNUM *exp, *mod;
	RSA *rsa_pub = NULL;

	if (binbuf->v[0] > binbuf->l - 1) {
		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
		goto out;
	}

	exp = BN_bin2bn((unsigned char *) (binbuf->v + 1), binbuf->v[0], NULL);
	mod = BN_bin2bn((unsigned char *) (binbuf->v + binbuf->v[0] + 1), 
			binbuf->l - binbuf->v[0] - 1, NULL);
	rsa_pub = RSA_new();

	if (!exp || !mod || !rsa_pub) {
		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey parsing error: %s\n", eay_strerror());
		if (exp)
			BN_free(exp);
		if (mod)
			BN_free(exp);
		if (rsa_pub)
			RSA_free(rsa_pub);
		rsa_pub = NULL;
		goto out;
	}
	
	rsa_pub->n = mod;
	rsa_pub->e = exp;

out:
	return rsa_pub;
}

RSA *
base64_pubkey2rsa(char *in)
{
	BIGNUM *exp, *mod;
	RSA *rsa_pub = NULL;
	vchar_t *binbuf;

	if (strncmp(in, "0s", 2) != 0) {
		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: doesn't start with '0s'\n");
		return NULL;
	}

	binbuf = base64_decode(in + 2, strlen(in + 2));
	if (!binbuf) {
		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: Base64 decoding failed.\n");
		return NULL;
	}
	
	if (binbuf->v[0] > binbuf->l - 1) {
		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
		goto out;
	}

	rsa_pub = binbuf_pubkey2rsa(binbuf);

out:
	if (binbuf)
		vfree(binbuf);

	return rsa_pub;
}

RSA *
bignum_pubkey2rsa(BIGNUM *in)
{
	RSA *rsa_pub = NULL;
	vchar_t *binbuf;

	binbuf = vmalloc(BN_num_bytes(in));
	if (!binbuf) {
		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey conversion: memory allocation failed..\n");
		return NULL;
	}
	
	BN_bn2bin(in, (unsigned char *) binbuf->v);

	rsa_pub = binbuf_pubkey2rsa(binbuf);

out:
	if (binbuf)
		vfree(binbuf);

	return rsa_pub;
}

u_int32_t
eay_random()
{
	u_int32_t result;
	vchar_t *vrand;

	vrand = eay_set_random(sizeof(result));
	memcpy(&result, vrand->v, sizeof(result));
	vfree(vrand);

	return result;
}

const char *
eay_version()
{
	return SSLeay_version(SSLEAY_VERSION);
}
