/* crypto/ec/ec_asn1.c */
/*
 * Written by Nils Larsch for the OpenSSL project.
 */
/* ====================================================================
 * Copyright (c) 2000-2003 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 <string.h>
#include "ec_lcl.h"
#include <openssl/err.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>


int EC_GROUP_get_basis_type(const EC_GROUP *group)
	{
	int i=0;

	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
		NID_X9_62_characteristic_two_field)
		/* everything else is currently not supported */
		return 0;

	while (group->poly[i] != 0)
		i++;

	if (i == 4)
		return NID_X9_62_ppBasis;
	else if (i == 2)
		return NID_X9_62_tpBasis;
	else
		/* everything else is currently not supported */
		return 0;
	}

int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
	{
	if (group == NULL)
		return 0;

	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
		{
		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		return 0;
		}

	if (k)
		*k = group->poly[1];

	return 1;
	}

int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
	unsigned int *k2, unsigned int *k3)
	{
	if (group == NULL)
		return 0;

	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
		{
		ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		return 0;
		}

	if (k1)
		*k1 = group->poly[3];
	if (k2)
		*k2 = group->poly[2];
	if (k3)
		*k3 = group->poly[1];

	return 1;
	}



/* some structures needed for the asn1 encoding */
typedef struct x9_62_pentanomial_st {
	long k1;
	long k2;
	long k3;
	} X9_62_PENTANOMIAL;

typedef struct x9_62_characteristic_two_st {
	long m;
	ASN1_OBJECT  *type;
	union	{
		char *ptr;
		/* NID_X9_62_onBasis */
		ASN1_NULL    *onBasis;
		/* NID_X9_62_tpBasis */
		ASN1_INTEGER *tpBasis;
		/* NID_X9_62_ppBasis */
		X9_62_PENTANOMIAL *ppBasis;
		/* anything else */
		ASN1_TYPE *other;
		} p;
	} X9_62_CHARACTERISTIC_TWO;

typedef struct x9_62_fieldid_st {
        ASN1_OBJECT *fieldType;
	union	{
		char *ptr;
		/* NID_X9_62_prime_field */
		ASN1_INTEGER *prime;
		/* NID_X9_62_characteristic_two_field */
		X9_62_CHARACTERISTIC_TWO *char_two;
		/* anything else */
		ASN1_TYPE *other;
		} p;
	} X9_62_FIELDID;

typedef struct x9_62_curve_st {
        ASN1_OCTET_STRING *a;
        ASN1_OCTET_STRING *b;
        ASN1_BIT_STRING   *seed;
        } X9_62_CURVE;

typedef struct ec_parameters_st {
        long              version;
        X9_62_FIELDID     *fieldID;
        X9_62_CURVE       *curve;
        ASN1_OCTET_STRING *base;
        ASN1_INTEGER      *order;
        ASN1_INTEGER      *cofactor;
        } ECPARAMETERS;

struct ecpk_parameters_st {
	int	type;
	union {
		ASN1_OBJECT  *named_curve;
		ECPARAMETERS *parameters;
		ASN1_NULL    *implicitlyCA;
	} value;
	}/* ECPKPARAMETERS */;

/* SEC1 ECPrivateKey */
typedef struct ec_privatekey_st {
	long              version;
	ASN1_OCTET_STRING *privateKey;
        ECPKPARAMETERS    *parameters;
	ASN1_BIT_STRING   *publicKey;
	} EC_PRIVATEKEY;

/* the OpenSSL ASN.1 definitions */
ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
	ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
	ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
	ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)

DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)

ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);

ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
	ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
	ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
	ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);

ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
	ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)

DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)

ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);

ASN1_ADB(X9_62_FIELDID) = {
	ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
	ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);

ASN1_SEQUENCE(X9_62_FIELDID) = {
	ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
	ASN1_ADB_OBJECT(X9_62_FIELDID)
} ASN1_SEQUENCE_END(X9_62_FIELDID)

ASN1_SEQUENCE(X9_62_CURVE) = {
	ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
	ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
	ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(X9_62_CURVE)

ASN1_SEQUENCE(ECPARAMETERS) = {
	ASN1_SIMPLE(ECPARAMETERS, version, LONG),
	ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
	ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
	ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
	ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
	ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
} ASN1_SEQUENCE_END(ECPARAMETERS)

DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)

ASN1_CHOICE(ECPKPARAMETERS) = {
	ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
	ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
	ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
} ASN1_CHOICE_END(ECPKPARAMETERS)

DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)

ASN1_SEQUENCE(EC_PRIVATEKEY) = {
	ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
	ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
	ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
	ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
} ASN1_SEQUENCE_END(EC_PRIVATEKEY)

DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)

/* some declarations of internal function */

/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ 
static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ 
static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
/* ec_asn1_parameters2group() creates a EC_GROUP object from a
 * ECPARAMETERS object */
static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); 
/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a 
 * EC_GROUP object */
static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *);
/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
 * ECPKPARAMETERS object */
static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); 
/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a 
 * EC_GROUP object */
static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, 
	ECPKPARAMETERS *);


/* the function definitions */

static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
	{
	int			ok=0, nid;
	BIGNUM			*tmp = NULL;
	
	if (group == NULL || field == NULL)
		return 0;

	/* clear the old values (if necessary) */
	if (field->fieldType != NULL)
		ASN1_OBJECT_free(field->fieldType);
	if (field->p.other != NULL)
		ASN1_TYPE_free(field->p.other);

	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
	/* set OID for the field */
	if ((field->fieldType = OBJ_nid2obj(nid)) == NULL)
		{
		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
		goto err;
		}

	if (nid == NID_X9_62_prime_field)
		{
		if ((tmp = BN_new()) == NULL) 
			{
			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
			goto err;
			}
		/* the parameters are specified by the prime number p */
		if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL))
			{
			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
			goto err;
			}
		/* set the prime number */
		field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL);
		if (field->p.prime == NULL)
			{
			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
			goto err;
			}
		}
	else	/* nid == NID_X9_62_characteristic_two_field */
		{
		int		field_type;
		X9_62_CHARACTERISTIC_TWO *char_two;

		field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
		char_two = field->p.char_two;

		if (char_two == NULL)
			{
			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
			goto err;
			}
	
		char_two->m = (long)EC_GROUP_get_degree(group);

		field_type = EC_GROUP_get_basis_type(group);

		if (field_type == 0)
			{
			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
			goto err;
			}
		/* set base type OID */
		if ((char_two->type = OBJ_nid2obj(field_type)) == NULL)
			{
			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
			goto err;
			}

		if (field_type == NID_X9_62_tpBasis)
			{
			unsigned int k;

			if (!EC_GROUP_get_trinomial_basis(group, &k))
				goto err;

			char_two->p.tpBasis = ASN1_INTEGER_new();
			if (!char_two->p.tpBasis)
				{
				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
				goto err;
				}
			if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k))
				{
				ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
					ERR_R_ASN1_LIB);
				goto err;
				}
			}
		else if (field_type == NID_X9_62_ppBasis)
			{
			unsigned int k1, k2, k3;

			if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
				goto err;

			char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
			if (!char_two->p.ppBasis)
				{
				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
				goto err;
				}

			/* set k? values */
			char_two->p.ppBasis->k1 = (long)k1;
			char_two->p.ppBasis->k2 = (long)k2;
			char_two->p.ppBasis->k3 = (long)k3;
			}
		else /* field_type == NID_X9_62_onBasis */
			{
			/* for ONB the parameters are (asn1) NULL */
			char_two->p.onBasis = ASN1_NULL_new();
			if (!char_two->p.onBasis)
				{
				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
				goto err;
				}
			}
		}

	ok = 1;

err :	if (tmp)
		BN_free(tmp);
	return(ok);
}

static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
	{
	int           ok=0, nid;
	BIGNUM        *tmp_1=NULL, *tmp_2=NULL;
	unsigned char *buffer_1=NULL, *buffer_2=NULL,
	              *a_buf=NULL, *b_buf=NULL;
	size_t        len_1, len_2;
	unsigned char char_zero = 0;

	if (!group || !curve || !curve->a || !curve->b)
		return 0;

	if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL)
		{
		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));

	/* get a and b */
	if (nid == NID_X9_62_prime_field)
		{
		if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL))
			{
			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
			goto err;
			}
		}
	else	/* nid == NID_X9_62_characteristic_two_field */
		{
		if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
			{
			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
			goto err;
			}
		}

	len_1 = (size_t)BN_num_bytes(tmp_1);
	len_2 = (size_t)BN_num_bytes(tmp_2);

	if (len_1 == 0)
		{
		/* len_1 == 0 => a == 0 */
		a_buf = &char_zero;
		len_1 = 1;
		}
	else
		{
		if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL)
			{
			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
			      ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0)
			{
			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
			goto err;
			}
		a_buf = buffer_1;
		}

	if (len_2 == 0)
		{
		/* len_2 == 0 => b == 0 */
		b_buf = &char_zero;
		len_2 = 1;
		}
	else
		{
		if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL)
			{
			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
			      ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0)
			{
			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
			goto err;
			}
		b_buf = buffer_2;
		}
	
	/* set a and b */
	if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
	    !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2))
		{
		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
		goto err;
		}
	
	/* set the seed (optional) */
	if (group->seed)
		{	
		if (!curve->seed)
			if ((curve->seed = ASN1_BIT_STRING_new()) == NULL)
				{
				ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
				goto err;
				}
		if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 
		                         (int)group->seed_len))
			{
			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
			goto err;
			}
		}
	else
		{
		if (curve->seed)
			{
			ASN1_BIT_STRING_free(curve->seed);
			curve->seed = NULL;
			}
		}

	ok = 1;

err:	if (buffer_1)
		OPENSSL_free(buffer_1);
	if (buffer_2)
		OPENSSL_free(buffer_2);
	if (tmp_1)
		BN_free(tmp_1);
	if (tmp_2)
		BN_free(tmp_2);
	return(ok);
	}

static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
                                              ECPARAMETERS *param)
	{
	int	ok=0;
	size_t  len=0;
	ECPARAMETERS   *ret=NULL;
	BIGNUM	       *tmp=NULL;
	unsigned char  *buffer=NULL;
	const EC_POINT *point=NULL;
	point_conversion_form_t form;

	if ((tmp = BN_new()) == NULL)
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (param == NULL)
	{
		if ((ret = ECPARAMETERS_new()) == NULL)
			{
			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, 
			      ERR_R_MALLOC_FAILURE);
			goto err;
			}
	}
	else
		ret = param;

	/* set the version (always one) */
	ret->version = (long)0x1;

	/* set the fieldID */
	if (!ec_asn1_group2fieldid(group, ret->fieldID))
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
		goto err;
		}

	/* set the curve */
	if (!ec_asn1_group2curve(group, ret->curve))
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
		goto err;
		}

	/* set the base point */
	if ((point = EC_GROUP_get0_generator(group)) == NULL)
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
		goto err;
		}

	form = EC_GROUP_get_point_conversion_form(group);

	len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
	if (len == 0)
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
		goto err;
		}
	if ((buffer = OPENSSL_malloc(len)) == NULL)
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
		goto err;
		}
	if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL))
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
		goto err;
		}
	if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL)
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
		goto err;
		}
	if (!ASN1_OCTET_STRING_set(ret->base, buffer, len))
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
		goto err;
		}

	/* set the order */
	if (!EC_GROUP_get_order(group, tmp, NULL))
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
		goto err;
		}
	ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
	if (ret->order == NULL)
		{
		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
		goto err;
		}

	/* set the cofactor (optional) */
	if (EC_GROUP_get_cofactor(group, tmp, NULL))
		{
		ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
		if (ret->cofactor == NULL)
			{
			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
			goto err;
			}
		}

	ok = 1;

err :	if(!ok)
		{
		if (ret && !param)
			ECPARAMETERS_free(ret);
		ret = NULL;
		}
	if (tmp)
		BN_free(tmp);
	if (buffer)
		OPENSSL_free(buffer);
	return(ret);
	}

ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 
                                           ECPKPARAMETERS *params)
	{
	int            ok = 1, tmp;
	ECPKPARAMETERS *ret = params;

	if (ret == NULL)
		{
		if ((ret = ECPKPARAMETERS_new()) == NULL)
			{
			ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, 
			      ERR_R_MALLOC_FAILURE);
			return NULL;
			}
		}
	else
		{
		if (ret->type == 0 && ret->value.named_curve)
			ASN1_OBJECT_free(ret->value.named_curve);
		else if (ret->type == 1 && ret->value.parameters)
			ECPARAMETERS_free(ret->value.parameters);
		}

	if (EC_GROUP_get_asn1_flag(group))
		{
		/* use the asn1 OID to describe the
		 * the elliptic curve parameters
		 */
		tmp = EC_GROUP_get_curve_name(group);
		if (tmp)
			{
			ret->type = 0;
			if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
				ok = 0;
			}
		else
			/* we don't kmow the nid => ERROR */
			ok = 0;
		}
	else
		{	
		/* use the ECPARAMETERS structure */
		ret->type = 1;
		if ((ret->value.parameters = ec_asn1_group2parameters(
		     group, NULL)) == NULL)
			ok = 0;
		}

	if (!ok)
		{
		ECPKPARAMETERS_free(ret);
		return NULL;
		}
	return ret;
	}

static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
	{
	int			ok = 0, tmp;
	EC_GROUP		*ret = NULL;
	BIGNUM			*p = NULL, *a = NULL, *b = NULL;
	EC_POINT		*point=NULL;

	if (!params->fieldID || !params->fieldID->fieldType || 
	    !params->fieldID->p.ptr)
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
		goto err;
		}

	/* now extract the curve parameters a and b */
	if (!params->curve || !params->curve->a || 
	    !params->curve->a->data || !params->curve->b ||
	    !params->curve->b->data)
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
		goto err;
		}
	a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
	if (a == NULL)
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
		goto err;
		}
	b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
	if (b == NULL)
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
		goto err;
		}

	/* get the field parameters */
	tmp = OBJ_obj2nid(params->fieldID->fieldType);

	if (tmp == NID_X9_62_characteristic_two_field)
		{
		X9_62_CHARACTERISTIC_TWO *char_two;

		char_two = params->fieldID->p.char_two;

		if ((p = BN_new()) == NULL)
			{
			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
			goto err;
			}

		/* get the base type */
		tmp = OBJ_obj2nid(char_two->type);

		if (tmp ==  NID_X9_62_tpBasis)
			{
			long tmp_long;

			if (!char_two->p.tpBasis)
				{
				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
				goto err;
				}

			tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
			/* create the polynomial */
			if (!BN_set_bit(p, (int)char_two->m))
				goto err;
			if (!BN_set_bit(p, (int)tmp_long))
				goto err;
			if (!BN_set_bit(p, 0))
				goto err;
			}
		else if (tmp == NID_X9_62_ppBasis)
			{
			X9_62_PENTANOMIAL *penta;

			penta = char_two->p.ppBasis;
			if (!penta)
				{
				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
				goto err;
				}
			/* create the polynomial */
			if (!BN_set_bit(p, (int)char_two->m)) goto err;
			if (!BN_set_bit(p, (int)penta->k1)) goto err;
			if (!BN_set_bit(p, (int)penta->k2)) goto err;
			if (!BN_set_bit(p, (int)penta->k3)) goto err;
			if (!BN_set_bit(p, 0)) goto err;
			}
		else if (tmp == NID_X9_62_onBasis)
			{
			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
			goto err;
			}
		else /* error */
			{
			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
			goto err;
			}

		/* create the EC_GROUP structure */
		ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
		}
	else if (tmp == NID_X9_62_prime_field)
		{
		/* we have a curve over a prime field */
		/* extract the prime number */
		if (!params->fieldID->p.prime)
			{
			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
			goto err;
			}
		p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
		if (p == NULL)
			{
			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
			goto err;
			}
		/* create the EC_GROUP structure */
		ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
		}
	else
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
		goto err;
		}

	if (ret == NULL)
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
		goto err;
		}

	/* extract seed (optional) */
	if (params->curve->seed != NULL)
		{
		if (ret->seed != NULL)
			OPENSSL_free(ret->seed);
		if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
			{
			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 
			      ERR_R_MALLOC_FAILURE);
			goto err;
			}
		memcpy(ret->seed, params->curve->seed->data, 
		       params->curve->seed->length);
		ret->seed_len = params->curve->seed->length;
		}

	if (!params->order || !params->base || !params->base->data)
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
		goto err;
		}

	if ((point = EC_POINT_new(ret)) == NULL) goto err;

	/* set the point conversion form */
	EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
				(params->base->data[0] & ~0x01));

	/* extract the ec point */
	if (!EC_POINT_oct2point(ret, point, params->base->data, 
		                params->base->length, NULL))
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
		goto err;
		}

	/* extract the order */
	if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
		goto err;
		}
	
	/* extract the cofactor (optional) */
	if (params->cofactor == NULL)
		{
		if (b)
			{
			BN_free(b);
			b = NULL;
			}
		}
	else
		if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
			{
			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
			goto err;
			}
	/* set the generator, order and cofactor (if present) */
	if (!EC_GROUP_set_generator(ret, point, a, b))
		{
		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
		goto err;
		}

	ok = 1;

err:	if (!ok)
		{
		if (ret) 
			EC_GROUP_clear_free(ret);
		ret = NULL;
		}

	if (p)	
		BN_free(p);
	if (a)	
		BN_free(a);
	if (b)	
		BN_free(b);
	if (point)	
		EC_POINT_free(point);
	return(ret);
}

EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
	{
	EC_GROUP *ret=NULL;
	int      tmp=0;

	if (params == NULL)
		{
		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
		      EC_R_MISSING_PARAMETERS);
		return NULL;
		}

	if (params->type == 0)
		{ /* the curve is given by an OID */
		tmp = OBJ_obj2nid(params->value.named_curve);
		if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
			{
			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 
			      EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
			return NULL;
			}
		EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
		}
	else if (params->type == 1)
		{ /* the parameters are given by a ECPARAMETERS
		   * structure */
		ret = ec_asn1_parameters2group(params->value.parameters);
		if (!ret)
			{
			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
			return NULL;
			}
		EC_GROUP_set_asn1_flag(ret, 0x0);
		}
	else if (params->type == 2)
		{ /* implicitlyCA */
		return NULL;
		}
	else
		{
		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
		return NULL;
		}

	return ret;
	}

/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */

EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
	{
	EC_GROUP	*group  = NULL;
	ECPKPARAMETERS	*params = NULL;

	if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
		{
		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
		ECPKPARAMETERS_free(params);
		return NULL;
		}
	
	if ((group = ec_asn1_pkparameters2group(params)) == NULL)
		{
		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
		return NULL; 
		}

	
	if (a && *a)
		EC_GROUP_clear_free(*a);
	if (a)
		*a = group;

	ECPKPARAMETERS_free(params);
	return(group);
	}

int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
	{
	int		ret=0;
	ECPKPARAMETERS	*tmp = ec_asn1_group2pkparameters(a, NULL);
	if (tmp == NULL)
		{
		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
		return 0;
		}
	if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
		{
		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
		ECPKPARAMETERS_free(tmp);
		return 0;
		}	
	ECPKPARAMETERS_free(tmp);
	return(ret);
	}

/* some EC_KEY functions */

EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
	{
	int             ok=0;
	EC_KEY          *ret=NULL;
	EC_PRIVATEKEY   *priv_key=NULL;

	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
		{
		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
		return NULL;
		}

	if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
		{
		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
		EC_PRIVATEKEY_free(priv_key);
		return NULL;
		}

	if (a == NULL || *a == NULL)
		{
		if ((ret = EC_KEY_new()) == NULL)	
			{
			ECerr(EC_F_D2I_ECPRIVATEKEY,
                                 ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (a)
			*a = ret;
		}
	else
		ret = *a;

	if (priv_key->parameters)
		{
		if (ret->group)
			EC_GROUP_clear_free(ret->group);
		ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
		}

	if (ret->group == NULL)
		{
		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
		goto err;
		}

	ret->version = priv_key->version;

	if (priv_key->privateKey)
		{
		ret->priv_key = BN_bin2bn(
			M_ASN1_STRING_data(priv_key->privateKey),
			M_ASN1_STRING_length(priv_key->privateKey),
			ret->priv_key);
		if (ret->priv_key == NULL)
			{
			ECerr(EC_F_D2I_ECPRIVATEKEY,
                              ERR_R_BN_LIB);
			goto err;
			}
		}
	else
		{
		ECerr(EC_F_D2I_ECPRIVATEKEY, 
                      EC_R_MISSING_PRIVATE_KEY);
		goto err;
		}

	if (priv_key->publicKey)
		{
		const unsigned char *pub_oct;
		size_t pub_oct_len;

		if (ret->pub_key)
			EC_POINT_clear_free(ret->pub_key);
		ret->pub_key = EC_POINT_new(ret->group);
		if (ret->pub_key == NULL)
			{
			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
			goto err;
			}
		pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
		pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
		/* save the point conversion form */
		ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
		if (!EC_POINT_oct2point(ret->group, ret->pub_key,
			pub_oct, pub_oct_len, NULL))
			{
			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
			goto err;
			}
		}

	ok = 1;
err:
	if (!ok)
		{
		if (ret)
			EC_KEY_free(ret);
		ret = NULL;
		}

	if (priv_key)
		EC_PRIVATEKEY_free(priv_key);

	return(ret);
	}

int	i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
	{
	int             ret=0, ok=0;
	unsigned char   *buffer=NULL;
	size_t          buf_len=0, tmp_len;
	EC_PRIVATEKEY   *priv_key=NULL;

	if (a == NULL || a->group == NULL || a->priv_key == NULL)
		{
		ECerr(EC_F_I2D_ECPRIVATEKEY,
                      ERR_R_PASSED_NULL_PARAMETER);
		goto err;
		}

	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
		{
		ECerr(EC_F_I2D_ECPRIVATEKEY,
                      ERR_R_MALLOC_FAILURE);
		goto err;
		}

	priv_key->version = a->version;

	buf_len = (size_t)BN_num_bytes(a->priv_key);
	buffer = OPENSSL_malloc(buf_len);
	if (buffer == NULL)
		{
		ECerr(EC_F_I2D_ECPRIVATEKEY,
                      ERR_R_MALLOC_FAILURE);
		goto err;
		}
	
	if (!BN_bn2bin(a->priv_key, buffer))
		{
		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
		goto err;
		}

	if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
		{
		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
		goto err;
		}	

	if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
		{
		if ((priv_key->parameters = ec_asn1_group2pkparameters(
			a->group, priv_key->parameters)) == NULL)
			{
			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
			goto err;
			}
		}

	if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
		{
		priv_key->publicKey = M_ASN1_BIT_STRING_new();
		if (priv_key->publicKey == NULL)
			{
			ECerr(EC_F_I2D_ECPRIVATEKEY,
				ERR_R_MALLOC_FAILURE);
			goto err;
			}

		tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 
				a->conv_form, NULL, 0, NULL);

		if (tmp_len > buf_len)
			{
			unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
			if (!tmp_buffer)
				{
				ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
				goto err;
				}
			buffer = tmp_buffer;
			buf_len = tmp_len;
			}

		if (!EC_POINT_point2oct(a->group, a->pub_key, 
			a->conv_form, buffer, buf_len, NULL))
			{
			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
			goto err;
			}

		if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, 
				buf_len))
			{
			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
			goto err;
			}
		}

	if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
		{
		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
		goto err;
		}
	ok=1;
err:
	if (buffer)
		OPENSSL_free(buffer);
	if (priv_key)
		EC_PRIVATEKEY_free(priv_key);
	return(ok?ret:0);
	}

int i2d_ECParameters(EC_KEY *a, unsigned char **out)
	{
	if (a == NULL)
		{
		ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}
	return i2d_ECPKParameters(a->group, out);
	}

EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
	{
	EC_KEY   *ret;

	if (in == NULL || *in == NULL)
		{
		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
		return NULL;
		}

	if (a == NULL || *a == NULL)
		{
		if ((ret = EC_KEY_new()) == NULL)
			{
			ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
			return NULL;
			}
		if (a)
			*a = ret;
		}
	else
		ret = *a;

	if (!d2i_ECPKParameters(&ret->group, in, len))
		{
		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
		return NULL;
		}

	return ret;
	}

EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
	{
	EC_KEY *ret=NULL;

	if (a == NULL || (*a) == NULL || (*a)->group == NULL)
		{
		/* sorry, but a EC_GROUP-structur is necessary
                 * to set the public key */
		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}
	ret = *a;
	if (ret->pub_key == NULL && 
		(ret->pub_key = EC_POINT_new(ret->group)) == NULL)
		{
		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
		{
		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
		return 0;
		}
	/* save the point conversion form */
	ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
	*in += len;
	return ret;
	}

int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
	{
        size_t buf_len=0;
	int new_buffer = 0;

        if (a == NULL) 
		{
		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}

        buf_len = EC_POINT_point2oct(a->group, a->pub_key, 
                              a->conv_form, NULL, 0, NULL);

	if (out == NULL || buf_len == 0)
	/* out == NULL => just return the length of the octet string */
		return buf_len;

	if (*out == NULL)
		{
		if ((*out = OPENSSL_malloc(buf_len)) == NULL)
			{
			ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
			return 0;
			}
		new_buffer = 1;
		}
        if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
				*out, buf_len, NULL))
		{
		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
		OPENSSL_free(*out);
		*out = NULL;
		return 0;
		}
	if (!new_buffer)
		*out += buf_len;
	return buf_len;
	}
