diff options
Diffstat (limited to 'openssl/crypto/ec/ec_asn1.c')
-rw-r--r-- | openssl/crypto/ec/ec_asn1.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/openssl/crypto/ec/ec_asn1.c b/openssl/crypto/ec/ec_asn1.c index b4b0e9f3b..4ad849498 100644 --- a/openssl/crypto/ec/ec_asn1.c +++ b/openssl/crypto/ec/ec_asn1.c @@ -1114,7 +1114,7 @@ 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; + size_t buf_len = 0, tmp_len, bn_len; EC_PRIVATEKEY *priv_key = NULL; if (a == NULL || a->group == NULL || a->priv_key == NULL || @@ -1130,18 +1130,32 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) priv_key->version = a->version; - buf_len = (size_t)BN_num_bytes(a->priv_key); + bn_len = (size_t)BN_num_bytes(a->priv_key); + + /* Octetstring may need leading zeros if BN is to short */ + + buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8; + + if (bn_len > buf_len) { + ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); + goto err; + } + 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)) { + if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) { ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); goto err; } + if (buf_len - bn_len > 0) { + memset(buffer, 0, buf_len - bn_len); + } + if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); goto err; |