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

Reply via email to