On 3/24/2015 6:10 AM, Annie Yousar wrote:
Dear all, this should not have happened:
The private key may have leading zero bytes, and the size of the BIGNUM is used for the length of the octetstring rather then the field_len. The length of the BIGNUM does not include any leading zeros. Try the attached diff.
$ for i in `seq 1 1000` ; do if [ "x`openssl ecparam -genkey -name prime256v1 -noout > key.pem; ls -l key.pem | sed '/ 227 /d'`" != " x" ]; then echo; cat key.pem;else echo -n "."; fi; done .................................................................................... -----BEGIN EC PRIVATE KEY----- MHYCAQEEH9gjg1X/Gn9X/2VTustsXS/OuWV9LU4ivfp5oewxbACgCgYIKoZIzj0D AQehRANCAARlO6sLkCzJl7khaT8Nj6z3WpcDnMALQ4nI8Toc4/oYHtgUopeSMEj8 fgHw9Ym3/2GgClzweJXYLuTYRB7oR/MY -----END EC PRIVATE KEY----- ............................................................................ ... Conforming to the standards the EC private key has always a fixed length, defined by the group order. Regards, Ann. _______________________________________________ openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
-- Douglas E. Engert <deeng...@gmail.com>
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 90de23b..b6aa7a5 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -1113,7 +1113,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 || @@ -1129,18 +1129,33 @@ 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, ERR_R_BN_LIB); + goto err; + /* to get old behavior, set buf_len = bn_len */ + } + 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 (!ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); goto err;
_______________________________________________ openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev