New EC functions.

New functions EC_POINT_point2buf and EC_KEY_key2buf which encode
a point and allocate a buffer in one call.

New function EC_KEY_oct2key() which sets public key in an EC_KEY
structure from an encoded point.

Reviewed-by: Richard Levitte <levitte@openssl.org>
This commit is contained in:
Dr. Stephen Henson 2015-12-12 01:04:25 +00:00
parent 19a86b0301
commit 981bd8a2f2
5 changed files with 84 additions and 28 deletions

View file

@ -578,19 +578,11 @@ static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
form = EC_GROUP_get_point_conversion_form(group);
len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
len = EC_POINT_point2buf(group, point, form, &buffer, 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;

View file

@ -575,3 +575,23 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags)
{
key->flags &= ~flags;
}
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
unsigned char **pbuf, BN_CTX *ctx)
{
if (key == NULL || key->pub_key == NULL || key->group == NULL)
return 0;
return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
}
int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
BN_CTX *ctx)
{
if (key == NULL || key->group == NULL)
return 0;
if (key->pub_key == NULL)
key->pub_key = EC_POINT_new(key->group);
if (key->pub_key == NULL)
return 0;
return EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx);
}

View file

@ -190,3 +190,24 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
}
return group->meth->oct2point(group, point, buf, len, ctx);
}
size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form,
unsigned char **pbuf, BN_CTX *ctx)
{
size_t len;
unsigned char *buf;
len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL);
if (len == 0)
return 0;
buf = OPENSSL_malloc(len);
if (buf == NULL)
return 0;
len = EC_POINT_point2oct(group, point, form, buf, len, ctx);
if (len == 0) {
OPENSSL_free(buf);
return 0;
}
*pbuf = buf;
return len;
}

View file

@ -64,18 +64,11 @@ BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
size_t buf_len = 0;
unsigned char *buf;
buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
if (buf_len == 0)
return NULL;
if ((buf = OPENSSL_malloc(buf_len)) == NULL)
return NULL;
if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
OPENSSL_free(buf);
return NULL;
}
ret = BN_bin2bn(buf, buf_len, ret);
OPENSSL_free(buf);
@ -129,20 +122,13 @@ char *EC_POINT_point2hex(const EC_GROUP *group,
{
char *ret, *p;
size_t buf_len = 0, i;
unsigned char *buf, *pbuf;
unsigned char *buf = NULL, *pbuf;
buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
if (buf_len == 0)
return NULL;
if ((buf = OPENSSL_malloc(buf_len)) == NULL)
return NULL;
if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
OPENSSL_free(buf);
return NULL;
}
ret = OPENSSL_malloc(buf_len * 2 + 2);
if (ret == NULL) {
OPENSSL_free(buf);

View file

@ -589,6 +589,20 @@ size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
const unsigned char *buf, size_t len, BN_CTX *ctx);
/** Encodes an EC_POINT object to an allocated octet string
* \param group underlying EC_GROUP object
* \param point EC_POINT object
* \param form point conversion form
* \param pbuf returns pointer to allocated buffer
* \param len length of the memory buffer
* \param ctx BN_CTX object (optional)
* \return the length of the encoded octet string or 0 if an error occurred
*/
size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form,
unsigned char **pbuf, BN_CTX *ctx);
/* other interfaces to point2oct/oct2point: */
BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
point_conversion_form_t form, BIGNUM *, BN_CTX *);
@ -887,6 +901,29 @@ int EC_KEY_check_key(const EC_KEY *key);
int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
BIGNUM *y);
/** Encodes an EC_KEY public key to an allocated octet string
* \param key key to encode
* \param form point conversion form
* \param pbuf returns pointer to allocated buffer
* \param len length of the memory buffer
* \param ctx BN_CTX object (optional)
* \return the length of the encoded octet string or 0 if an error occurred
*/
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
unsigned char **pbuf, BN_CTX *ctx);
/** Decodes a EC_KEY public key from a octet string
* \param key key to decode
* \param buf memory buffer with the encoded ec point
* \param len length of the encoded ec point
* \param ctx BN_CTX object (optional)
* \return 1 on success and 0 if an error occurred
*/
int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
BN_CTX *ctx);
/********************************************************************/
/* de- and encoding functions for SEC1 ECPrivateKey */
/********************************************************************/