/*	$NetBSD: crypto_openssl.c,v 1.11.6.6 2009/04/29 10:50:25 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
#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_android(char *path)
{       
	void *data;
	if (sscanf(path, pname, &data) == 1) {
		return BIO_new_mem_buf(data, -1);
	}
	return NULL;
}

#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);

#ifdef ANDROID_CHANGES
	if (pname) {
		BIO *bio = BIO_from_android(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);
	} else {
#endif
	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 */
#ifdef ANDROID_CHANGES
	}
#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_free(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
	if (pname) {
		BIO *bio = BIO_from_android(path);
		if (!bio) {
			return NULL;
		}
		x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
		BIO_free(bio);
	} else {
#endif
	/* Read private key */
	fp = fopen(path, "r");
	if (fp == NULL)
		return NULL;
	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
	fclose (fp);
#ifdef ANDROID_CHANGES
	}
#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
	if (pname) {
		BIO *bio = BIO_from_android(path);
		if (!bio) {
			return NULL;
		}
		evp = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
		BIO_free(bio);
	} else {
#endif
	/* Read private key */
	fp = fopen(path, "r");
	if (fp == NULL)
		return NULL;

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

	fclose (fp);
#ifdef ANDROID_CHANGES
	}
#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);
}
