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

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/x509.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
#ifndef OPENSSL_NO_CMS
#include <openssl/cms.h>
#endif
#include <openssl/asn1t.h>
#include "asn1_locl.h"

static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);

static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
	{
	const EC_GROUP  *group;
	int nid;
	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) 
	{
		ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
		return 0;
	}
	if (EC_GROUP_get_asn1_flag(group)
                     && (nid = EC_GROUP_get_curve_name(group)))
		/* we have a 'named curve' => just set the OID */
		{
		*ppval = OBJ_nid2obj(nid);
		*pptype = V_ASN1_OBJECT;
		}
	else	/* explicit parameters */
		{
		ASN1_STRING *pstr = NULL;
		pstr = ASN1_STRING_new();
		if (!pstr)
			return 0;
		pstr->length = i2d_ECParameters(ec_key, &pstr->data);
		if (pstr->length <= 0)
			{
			ASN1_STRING_free(pstr);
			ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
			return 0;
			}
		*ppval = pstr;
		*pptype = V_ASN1_SEQUENCE;
		}
	return 1;
	}

static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
	{
	EC_KEY *ec_key = pkey->pkey.ec;
	void *pval = NULL;
	int ptype;
	unsigned char *penc = NULL, *p;
	int penclen;

	if (!eckey_param2type(&ptype, &pval, ec_key))
		{
		ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
		return 0;
		}
	penclen = i2o_ECPublicKey(ec_key, NULL);
	if (penclen <= 0)
		goto err;
	penc = OPENSSL_malloc(penclen);
	if (!penc)
		goto err;
	p = penc;
	penclen = i2o_ECPublicKey(ec_key, &p);
	if (penclen <= 0)
		goto err;
	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
				ptype, pval, penc, penclen))
		return 1;
	err:
	if (ptype == V_ASN1_OBJECT)
		ASN1_OBJECT_free(pval);
	else
		ASN1_STRING_free(pval);
	if (penc)
		OPENSSL_free(penc);
	return 0;
	}

static EC_KEY *eckey_type2param(int ptype, void *pval)
	{
	EC_KEY *eckey = NULL;
	if (ptype == V_ASN1_SEQUENCE)
		{
		ASN1_STRING *pstr = pval;
		const unsigned char *pm = NULL;
		int pmlen;
		pm = pstr->data;
		pmlen = pstr->length;
		if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
			{
			ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
			goto ecerr;
			}
		}
	else if (ptype == V_ASN1_OBJECT)
		{
		ASN1_OBJECT *poid = pval;
		EC_GROUP *group;

		/* type == V_ASN1_OBJECT => the parameters are given
		 * by an asn1 OID
		 */
		if ((eckey = EC_KEY_new()) == NULL)
			{
			ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
			goto ecerr;
			}
		group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
		if (group == NULL)
			goto ecerr;
		EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
		if (EC_KEY_set_group(eckey, group) == 0)
			goto ecerr;
		EC_GROUP_free(group);
		}
	else
		{
		ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
		goto ecerr;
		}

	return eckey;

	ecerr:
	if (eckey)
		EC_KEY_free(eckey);
	return NULL;
	}

static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
	{
	const unsigned char *p = NULL;
	void *pval;
	int ptype, pklen;
	EC_KEY *eckey = NULL;
	X509_ALGOR *palg;

	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
		return 0;
	X509_ALGOR_get0(NULL, &ptype, &pval, palg);

	eckey = eckey_type2param(ptype, pval);

	if (!eckey)
		{
		ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
		return 0;
		}

	/* We have parameters now set public key */
	if (!o2i_ECPublicKey(&eckey, &p, pklen))
		{
		ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
		goto ecerr;
		}

	EVP_PKEY_assign_EC_KEY(pkey, eckey);
	return 1;

	ecerr:
	if (eckey)
		EC_KEY_free(eckey);
	return 0;
	}

static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
	{
	int  r;
	const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
	const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
	               *pb = EC_KEY_get0_public_key(b->pkey.ec);
	r = EC_POINT_cmp(group, pa, pb, NULL);
	if (r == 0)
		return 1;
	if (r == 1)
		return 0;
	return -2;
	}

static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
	{
	const unsigned char *p = NULL;
	void *pval;
	int ptype, pklen;
	EC_KEY *eckey = NULL;
	X509_ALGOR *palg;

	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
		return 0;
	X509_ALGOR_get0(NULL, &ptype, &pval, palg);

	eckey = eckey_type2param(ptype, pval);

	if (!eckey)
		goto ecliberr;

	/* We have parameters now set private key */
	if (!d2i_ECPrivateKey(&eckey, &p, pklen))
		{
		ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
		goto ecerr;
		}

	/* calculate public key (if necessary) */
	if (EC_KEY_get0_public_key(eckey) == NULL)
		{
		const BIGNUM *priv_key;
		const EC_GROUP *group;
		EC_POINT *pub_key;
		/* the public key was not included in the SEC1 private
		 * key => calculate the public key */
		group   = EC_KEY_get0_group(eckey);
		pub_key = EC_POINT_new(group);
		if (pub_key == NULL)
			{
			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
			goto ecliberr;
			}
		if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
			{
			EC_POINT_free(pub_key);
			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
			goto ecliberr;
			}
		priv_key = EC_KEY_get0_private_key(eckey);
		if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
			{
			EC_POINT_free(pub_key);
			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
			goto ecliberr;
			}
		if (EC_KEY_set_public_key(eckey, pub_key) == 0)
			{
			EC_POINT_free(pub_key);
			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
			goto ecliberr;
			}
		EC_POINT_free(pub_key);
		}

	EVP_PKEY_assign_EC_KEY(pkey, eckey);
	return 1;

	ecliberr:
	ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
	ecerr:
	if (eckey)
		EC_KEY_free(eckey);
	return 0;
	}

static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{
	EC_KEY		*ec_key;
	unsigned char	*ep, *p;
	int 		eplen, ptype;
	void		*pval;
	unsigned int    tmp_flags, old_flags;

	ec_key = pkey->pkey.ec;

	if (!eckey_param2type(&ptype, &pval, ec_key))
		{
		ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
		return 0;
		}

	/* set the private key */

	/* do not include the parameters in the SEC1 private key
	 * see PKCS#11 12.11 */
	old_flags = EC_KEY_get_enc_flags(ec_key);
	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
	EC_KEY_set_enc_flags(ec_key, tmp_flags);
	eplen = i2d_ECPrivateKey(ec_key, NULL);
	if (!eplen)
	{
		EC_KEY_set_enc_flags(ec_key, old_flags);
		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
		return 0;
	}
	ep = (unsigned char *) OPENSSL_malloc(eplen);
	if (!ep)
	{
		EC_KEY_set_enc_flags(ec_key, old_flags);
		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
		return 0;
	}
	p = ep;
	if (!i2d_ECPrivateKey(ec_key, &p))
	{
		EC_KEY_set_enc_flags(ec_key, old_flags);
		OPENSSL_free(ep);
		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
		return 0;
	}
	/* restore old encoding flags */
	EC_KEY_set_enc_flags(ec_key, old_flags);

	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
				ptype, pval, ep, eplen))
		return 0;

	return 1;
}

static int int_ec_size(const EVP_PKEY *pkey)
	{
	return ECDSA_size(pkey->pkey.ec);
	}

static int ec_bits(const EVP_PKEY *pkey)
	{
	BIGNUM *order = BN_new();
	const EC_GROUP *group;
	int ret;

	if (!order)
		{
		ERR_clear_error();
		return 0;
		}
	group = EC_KEY_get0_group(pkey->pkey.ec);
	if (!EC_GROUP_get_order(group, order, NULL))
		{
		ERR_clear_error();
		return 0;
		}

	ret = BN_num_bits(order);
	BN_free(order);
	return ret;
	}

static int ec_security_bits(const EVP_PKEY *pkey)
	{
	int ecbits = ec_bits(pkey);
	if (ecbits >= 512)
		return 256;
	if (ecbits >= 384)
		return 192;
	if (ecbits >= 256)
		return 128;
	if (ecbits >= 224)
		return 112;
	if (ecbits >= 160)
		return 80;
	return ecbits / 2;
	}

static int ec_missing_parameters(const EVP_PKEY *pkey)
	{
	if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
		return 1;
	return 0;
	}

static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
	{
	EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
	if (group == NULL)
		return 0;
	if (EC_KEY_set_group(to->pkey.ec, group) == 0)
		return 0;
	EC_GROUP_free(group);
	return 1;
	}

static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
	{
	const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
	               *group_b = EC_KEY_get0_group(b->pkey.ec);
	if (EC_GROUP_cmp(group_a, group_b, NULL))
		return 0;
	else
		return 1;
	}

static void int_ec_free(EVP_PKEY *pkey)
	{
	EC_KEY_free(pkey->pkey.ec);
	}

static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
	{
	unsigned char *buffer=NULL;
	const char *ecstr;
	size_t	buf_len=0, i;
	int     ret=0, reason=ERR_R_BIO_LIB;
	BIGNUM  *pub_key=NULL, *order=NULL;
	BN_CTX  *ctx=NULL;
	const EC_GROUP *group;
	const EC_POINT *public_key;
	const BIGNUM *priv_key;
 
	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
		{
		reason = ERR_R_PASSED_NULL_PARAMETER;
		goto err;
		}

	ctx = BN_CTX_new();
	if (ctx == NULL)
		{
		reason = ERR_R_MALLOC_FAILURE;
		goto err;
		}

	if (ktype > 0)
		{
		public_key = EC_KEY_get0_public_key(x);
		if (public_key != NULL)
			{
			if ((pub_key = EC_POINT_point2bn(group, public_key,
				EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
				{
				reason = ERR_R_EC_LIB;
				goto err;
				}
			buf_len = (size_t)BN_num_bytes(pub_key);
			}
		}

	if (ktype == 2)
		{
		priv_key = EC_KEY_get0_private_key(x);
		if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
			buf_len = i;
		}
	else
		priv_key = NULL;

	if (ktype > 0)
		{
		buf_len += 10;
		if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
			{
			reason = ERR_R_MALLOC_FAILURE;
			goto err;
			}
		}
	if (ktype == 2)
		ecstr = "Private-Key";
	else if (ktype == 1)
		ecstr = "Public-Key";
	else
		ecstr = "ECDSA-Parameters";

	if (!BIO_indent(bp, off, 128))
		goto err;
	if ((order = BN_new()) == NULL)
		goto err;
	if (!EC_GROUP_get_order(group, order, NULL))
		goto err;
	if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
		BN_num_bits(order)) <= 0) goto err;
  
	if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 
		buffer, off))
		goto err;
	if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
		buffer, off))
		goto err;
	if (!ECPKParameters_print(bp, group, off))
		goto err;
	ret=1;
err:
	if (!ret)
 		ECerr(EC_F_DO_EC_KEY_PRINT, reason);
	if (pub_key) 
		BN_free(pub_key);
	if (order)
		BN_free(order);
	if (ctx)
		BN_CTX_free(ctx);
	if (buffer != NULL)
		OPENSSL_free(buffer);
	return(ret);
	}

static int eckey_param_decode(EVP_PKEY *pkey,
					const unsigned char **pder, int derlen)
	{
	EC_KEY *eckey;
	if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
		{
		ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
		return 0;
		}
	EVP_PKEY_assign_EC_KEY(pkey, eckey);
	return 1;
	}

static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
	{
	return i2d_ECParameters(pkey->pkey.ec, pder);
	}

static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
							ASN1_PCTX *ctx)
	{
	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
	}

static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
							ASN1_PCTX *ctx)
	{
	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
	}


static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
							ASN1_PCTX *ctx)
	{
	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
	}

static int old_ec_priv_decode(EVP_PKEY *pkey,
					const unsigned char **pder, int derlen)
	{
	EC_KEY *ec;
	if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
		{
		ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
		return 0;
		}
	EVP_PKEY_assign_EC_KEY(pkey, ec);
	return 1;
	}

static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
	{
	return i2d_ECPrivateKey(pkey->pkey.ec, pder);
	}

static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
	{
	switch (op)
		{
		case ASN1_PKEY_CTRL_PKCS7_SIGN:
		if (arg1 == 0)
			{
			int snid, hnid;
			X509_ALGOR *alg1, *alg2;
			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
			if (alg1 == NULL || alg1->algorithm == NULL)
				return -1;
			hnid = OBJ_obj2nid(alg1->algorithm);
			if (hnid == NID_undef)
				return -1;
			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
				return -1; 
			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
			}
		return 1;
#ifndef OPENSSL_NO_CMS
		case ASN1_PKEY_CTRL_CMS_SIGN:
		if (arg1 == 0)
			{
			int snid, hnid;
			X509_ALGOR *alg1, *alg2;
			CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
								&alg1, &alg2);
			if (alg1 == NULL || alg1->algorithm == NULL)
				return -1;
			hnid = OBJ_obj2nid(alg1->algorithm);
			if (hnid == NID_undef)
				return -1;
			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
				return -1; 
			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
			}
		return 1;

		case ASN1_PKEY_CTRL_CMS_ENVELOPE:
		if (arg1 == 1)
			return ecdh_cms_decrypt(arg2);
		else if (arg1 == 0)
			return ecdh_cms_encrypt(arg2);
		return -2;

		case ASN1_PKEY_CTRL_CMS_RI_TYPE:
		*(int *)arg2 = CMS_RECIPINFO_AGREE;
		return 1;
#endif

		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
		*(int *)arg2 = NID_sha256;
		return 2;

		default:
		return -2;

		}

	}

const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = 
	{
	EVP_PKEY_EC,
	EVP_PKEY_EC,
	0,
	"EC",
	"OpenSSL EC algorithm",

	eckey_pub_decode,
	eckey_pub_encode,
	eckey_pub_cmp,
	eckey_pub_print,

	eckey_priv_decode,
	eckey_priv_encode,
	eckey_priv_print,

	int_ec_size,
	ec_bits,
	ec_security_bits,

	eckey_param_decode,
	eckey_param_encode,
	ec_missing_parameters,
	ec_copy_parameters,
	ec_cmp_parameters,
	eckey_param_print,
	0,

	int_ec_free,
	ec_pkey_ctrl,
	old_ec_priv_decode,
	old_ec_priv_encode
	};

#ifndef OPENSSL_NO_CMS

static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
				X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
	{
	ASN1_OBJECT *aoid;
	int atype;
	void *aval;
	int rv = 0;
	EVP_PKEY *pkpeer = NULL;
	EC_KEY *ecpeer = NULL;
	const unsigned char *p;
	int plen;
	X509_ALGOR_get0(&aoid, &atype, &aval, alg);
	if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
		goto err;
	/* If absent parameters get group from main key */
	if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL)
		{
		const EC_GROUP *grp;
		EVP_PKEY *pk;
		pk = EVP_PKEY_CTX_get0_pkey(pctx);
		if (!pk)
			goto err;
		grp = EC_KEY_get0_group(pk->pkey.ec);
		ecpeer = EC_KEY_new();
		if (!ecpeer)
			goto err;
		if (!EC_KEY_set_group(ecpeer, grp))
			goto err;
		}
	else
		{
		ecpeer = eckey_type2param(atype, aval);
		if (!ecpeer)
			goto err;
		}
	/* We have parameters now set public key */
	plen = ASN1_STRING_length(pubkey);
	p = ASN1_STRING_data(pubkey);
	if (!p || !plen)
		goto err;
	if (!o2i_ECPublicKey(&ecpeer, &p, plen))
		goto err;
	pkpeer = EVP_PKEY_new();
	if (!pkpeer)
		goto err;
	EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
	if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
		rv = 1;
	err:
	if (ecpeer)
		EC_KEY_free(ecpeer);
	if (pkpeer)
		EVP_PKEY_free(pkpeer);
	return rv;
	}
/* Set KDF parameters based on KDF NID */
static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
	{
	int kdf_nid, kdfmd_nid, cofactor;
	const EVP_MD *kdf_md;
	if (eckdf_nid == NID_undef)
		return 0;

	/* Lookup KDF type, cofactor mode and digest */
	if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
		return 0;

	if (kdf_nid == NID_dh_std_kdf)
		cofactor = 0;
	else if (kdf_nid == NID_dh_cofactor_kdf)
		cofactor = 1;
	else return 0;

	if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
		return 0;

	if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0)
		return 0;

	kdf_md = EVP_get_digestbynid(kdfmd_nid);
	if (!kdf_md)
		return 0;

	if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
		return 0;
	return 1;
	}

static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
	{
	int rv = 0;

	X509_ALGOR *alg, *kekalg = NULL;
	ASN1_OCTET_STRING *ukm;
	const unsigned char *p;
	unsigned char *der = NULL;
	int plen, keylen;
	const EVP_CIPHER *kekcipher;
	EVP_CIPHER_CTX *kekctx;

	if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
		return 0;

	if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm)))
		{
		ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
		return 0;
		}

	if (alg->parameter->type != V_ASN1_SEQUENCE)
		return 0;

	p = alg->parameter->value.sequence->data;
	plen = alg->parameter->value.sequence->length;
	kekalg = d2i_X509_ALGOR(NULL, &p, plen);
	if (!kekalg)
		goto err;
	kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
	if (!kekctx)
		goto err;
	kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
	if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
		goto err;
	if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
		goto err;
	if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
		goto err;

	keylen = EVP_CIPHER_CTX_key_length(kekctx);
	if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
		goto err;

	plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);

	if (!plen)
		goto err;

	if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
		goto err;
	der = NULL;

	rv = 1;
	err:
	if (kekalg)
		X509_ALGOR_free(kekalg);
	if (der)
		OPENSSL_free(der);
	return rv;
	}

static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
	{
	EVP_PKEY_CTX *pctx;
	pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
	if (!pctx)
		return 0;
	/* See if we need to set peer key */
	if (!EVP_PKEY_CTX_get0_peerkey(pctx))
		{
		X509_ALGOR *alg;
		ASN1_BIT_STRING *pubkey;
		if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
							NULL, NULL, NULL))
			return 0;
		if (!alg || !pubkey)
			return 0;
		if (!ecdh_cms_set_peerkey(pctx, alg, pubkey))
			{
			ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
			return 0;
			}
		}
	/* Set ECDH derivation parameters and initialise unwrap context */
	if (!ecdh_cms_set_shared_info(pctx, ri))
		{
		ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
		return 0;
		}
	return 1;
	}

static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
	{
	EVP_PKEY_CTX *pctx;
	EVP_PKEY *pkey;
	EVP_CIPHER_CTX *ctx;
	int keylen;
	X509_ALGOR *talg, *wrap_alg = NULL;
	ASN1_OBJECT *aoid;
	ASN1_BIT_STRING *pubkey;
	ASN1_STRING *wrap_str;
	ASN1_OCTET_STRING *ukm;
	unsigned char *penc = NULL;
	int penclen;
	int rv = 0;
	int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
	const EVP_MD *kdf_md;
	pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
	if (!pctx)
		return 0;
	/* Get ephemeral key */
	pkey = EVP_PKEY_CTX_get0_pkey(pctx);
	if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
							NULL, NULL, NULL))
		goto err;
	X509_ALGOR_get0(&aoid, NULL, NULL, talg);
	/* Is everything uninitialised? */
	if (aoid == OBJ_nid2obj(NID_undef))
		{

		EC_KEY *eckey = pkey->pkey.ec;
		/* Set the key */
		unsigned char *p;

		penclen = i2o_ECPublicKey(eckey, NULL);
		if (penclen <= 0)
			goto err;
		penc = OPENSSL_malloc(penclen);
		if (!penc)
			goto err;
		p = penc;
		penclen = i2o_ECPublicKey(eckey, &p);
		if (penclen <= 0)
			goto err;
		ASN1_STRING_set0(pubkey, penc, penclen);
		pubkey->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
		pubkey->flags|=ASN1_STRING_FLAG_BITS_LEFT;

		penc = NULL;
		X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
							V_ASN1_UNDEF, NULL);
		}

	/* See if custom paraneters set */
	kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
	if (kdf_type <= 0)
		goto err;
	if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
		goto err;
	ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
	if (ecdh_nid < 0)
		goto err;
	else if (ecdh_nid == 0)
		ecdh_nid = NID_dh_std_kdf;
	else if (ecdh_nid == 1)
		ecdh_nid = NID_dh_cofactor_kdf;

	if (kdf_type == EVP_PKEY_ECDH_KDF_NONE)
		{
		kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
		if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
			goto err;
		}
	else
		/* Uknown KDF */
		goto err;
	if (kdf_md == NULL)
		{
		/* Fixme later for better MD */
		kdf_md = EVP_sha1();
		if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
			goto err;
		}

	if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
		goto err;

	/* Lookup NID for KDF+cofactor+digest */

	if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
		goto err;
	/* Get wrap NID */
	ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
	wrap_nid = EVP_CIPHER_CTX_type(ctx);
	keylen = EVP_CIPHER_CTX_key_length(ctx);

	/* Package wrap algorithm in an AlgorithmIdentifier */

	wrap_alg = X509_ALGOR_new();
	if (!wrap_alg)
		goto err;
	wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
	wrap_alg->parameter = ASN1_TYPE_new();
	if (!wrap_alg->parameter)
		goto err;
	if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
		goto err;
	if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef)
		{
		ASN1_TYPE_free(wrap_alg->parameter);
		wrap_alg->parameter = NULL;
		}

	if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
		goto err;

	penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);

	if (!penclen)
		goto err;

	if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
		goto err;
	penc = NULL;

	/* Now need to wrap encoding of wrap AlgorithmIdentifier into
	 * parameter of another AlgorithmIdentifier.
	 */
	penclen = i2d_X509_ALGOR(wrap_alg, &penc);
	if (!penc || !penclen)
		goto err;
	wrap_str = ASN1_STRING_new();
	if (!wrap_str)
		goto err;
	ASN1_STRING_set0(wrap_str, penc, penclen);
	penc = NULL;
	X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);

	rv = 1;

	err:
	if (penc)
		OPENSSL_free(penc);
	if (wrap_alg)
		X509_ALGOR_free(wrap_alg);
	return rv;
	}

#endif
