summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDouglas E Engert <deengert@gmail.com>2015-03-25 23:52:28 +0000
committerMatt Caswell <matt@openssl.org>2015-03-31 16:41:33 +0100
commita63d3ac012f4a1c3e7440dc9d419d8bc6041ee46 (patch)
tree0cf9bb6f9c4bafadebc44049e8d4fbb2fe89252f /crypto
parent8a46e51ed83300e16eb6daebf664f141f6c313df (diff)
Ensure EC private keys retain leading zeros
RFC5915 requires the use of the I2OSP primitive as defined in RFC3447 for storing an EC Private Key. This converts the private key into an OCTETSTRING and retains any leading zeros. This commit ensures that those leading zeros are present if required. Reviewed-by: Andy Polyakov <appro@openssl.org> (cherry picked from commit 30cd4ff294252c4b6a4b69cbef6a5b4117705d22) Conflicts: crypto/ec/ec_asn1.c
Diffstat (limited to 'crypto')
-rw-r--r--crypto/ec/ec_asn1.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index b4b0e9f3b8..4ad8494981 100644
--- a/crypto/ec/ec_asn1.c
+++ b/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;