提交 7fc7d1a7 编写于 作者: D Dr. Stephen Henson

Add EC_KEY_priv2buf()

Add new function EC_KEY_priv2buf() to allocated and encode private
key octet in one call. Update and simplify ASN.1 and print routines.
Reviewed-by: NViktor Dukhovni <viktor@openssl.org>
上级 ac3e3665
......@@ -387,51 +387,29 @@ typedef enum {
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
{
unsigned char *buffer = NULL;
const char *ecstr;
size_t priv_len = 0, pub_len = 0, buf_len = 0;
int ret = 0, reason = ERR_R_BIO_LIB;
BIGNUM *pub_key = NULL;
BN_CTX *ctx = NULL;
unsigned char *priv = NULL, *pub = NULL;
size_t privlen = 0, publen = 0;
int ret = 0;
const EC_GROUP *group;
const EC_POINT *public_key = NULL;
if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (ktype != EC_KEY_PRINT_PARAM) {
public_key = EC_KEY_get0_public_key(x);
if (public_key != NULL) {
pub_len = EC_POINT_point2oct(group, public_key,
EC_KEY_get_conv_form(x),
NULL, 0, NULL);
if (pub_len == 0) {
reason = ERR_R_EC_LIB;
publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
if (publen == 0)
goto err;
}
buf_len = pub_len;
}
}
if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
priv_len = EC_KEY_priv2oct(x, NULL, 0);
if (priv_len == 0) {
reason = ERR_R_EC_LIB;
privlen = EC_KEY_priv2buf(x, &priv);
if (privlen == 0)
goto err;
}
if (priv_len > buf_len)
buf_len = priv_len;
}
if (buf_len != 0) {
buffer = OPENSSL_malloc(buf_len);
if (buffer == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
}
if (ktype == EC_KEY_PRINT_PRIVATE)
ecstr = "Private-Key";
else if (ktype == EC_KEY_PRINT_PUBLIC)
......@@ -445,23 +423,17 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
EC_GROUP_order_bits(group)) <= 0)
goto err;
if (priv_len != 0) {
if (privlen != 0) {
if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
goto err;
if (EC_KEY_priv2oct(x, buffer, priv_len) == 0)
goto err;
if (ASN1_buf_print(bp, buffer, priv_len, off + 4) == 0)
if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
goto err;
}
if (pub_len != 0) {
if (publen != 0) {
if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
goto err;
if (EC_POINT_point2oct(group, public_key,
EC_KEY_get_conv_form(x),
buffer, pub_len, NULL) == 0)
goto err;
if (ASN1_buf_print(bp, buffer, pub_len, off + 4) == 0)
if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
goto err;
}
......@@ -470,10 +442,9 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
ret = 1;
err:
if (!ret)
ECerr(EC_F_DO_EC_KEY_PRINT, reason);
BN_free(pub_key);
BN_CTX_free(ctx);
OPENSSL_clear_free(buffer, buf_len);
ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
OPENSSL_clear_free(priv, privlen);
OPENSSL_free(pub);
return ret;
}
......
......@@ -1075,8 +1075,9 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
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;
unsigned char *priv= NULL, *pub= NULL;
size_t privlen, publen;
EC_PRIVATEKEY *priv_key = NULL;
if (a == NULL || a->group == NULL ||
......@@ -1092,28 +1093,15 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
priv_key->version = a->version;
buf_len = EC_KEY_priv2oct(a, NULL, 0);
privlen = EC_KEY_priv2buf(a, &priv);
if (buf_len == 0) {
if (privlen == 0) {
ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
goto err;
}
buffer = OPENSSL_malloc(buf_len);
if (buffer == NULL) {
ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
goto err;
}
if (EC_KEY_priv2oct(a, buffer, buf_len) == 0) {
ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
goto err;
}
if (!ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
goto err;
}
ASN1_STRING_set0(priv_key->privateKey, priv, privlen);
priv = NULL;
if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
if ((priv_key->parameters =
......@@ -1131,31 +1119,17 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
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;
}
publen = EC_KEY_key2buf(a, a->conv_form, &pub, NULL);
if (!EC_POINT_point2oct(a->group, a->pub_key,
a->conv_form, buffer, buf_len, NULL)) {
if (publen == 0) {
ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
goto err;
}
priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
if (!ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
goto err;
}
ASN1_STRING_set0(priv_key->publicKey, pub, publen);
pub = NULL;
}
if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
......@@ -1164,7 +1138,8 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
}
ok = 1;
err:
OPENSSL_free(buffer);
OPENSSL_clear_free(priv, privlen);
OPENSSL_free(pub);
EC_PRIVATEKEY_free(priv_key);
return (ok ? ret : 0);
}
......
......@@ -591,3 +591,22 @@ int EC_KEY_oct2priv(EC_KEY *eckey, unsigned char *buf, size_t len)
}
return 1;
}
size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
{
size_t len;
unsigned char *buf;
len = EC_KEY_priv2oct(eckey, NULL, 0);
if (len == 0)
return 0;
buf = OPENSSL_malloc(len);
if (buf == NULL)
return 0;
len = EC_KEY_priv2oct(eckey, buf, len);
if (len == 0) {
OPENSSL_free(buf);
return 0;
}
*pbuf = buf;
return len;
}
......@@ -953,6 +953,13 @@ int EC_KEY_oct2priv(EC_KEY *key, unsigned char *buf, size_t len);
size_t EC_KEY_priv2oct(const EC_KEY *key, unsigned char *buf, size_t len);
/** Encodes an EC_KEY private key to an allocated octet string
* \param key key to encode
* \param pbuf returns pointer to allocated buffer
* \return the length of the encoded octet string or 0 if an error occurred
*/
size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf);
/********************************************************************/
/* de- and encoding functions for SEC1 ECPrivateKey */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册