The attached patch against https://github.com/openssl/openssl
makes sure the EC private key in an OCTETSTRING retains leading zeros
when converting from BIGNUM to OCTETSTRING.

http://www.secg.org/sec1-v2.pdf

   2.3.7 Integer-to-Octet-String Conversion
   Says: "Output: An octet string M of length mlen octets."

https://tools.ietf.org/html/rfc5915

   Says: "It is an octet string of length ceiling (log2(n)/8)"

https://tools.ietf.org/html/rfc3447

   4.1 I2OSP
   Says: " X corresponding octet string of length xLen"
   and also says: "(note that one or more leading digits will be
   zero if x is less than 256^(xLen-1))."

On 3/25/2015 4:34 PM, Annie wrote:
Am 24.03.2015 um 19:42 schrieb Douglas E Engert:

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.


Exactly.

Try the attached diff.

The diff solves the issue.
One remark: Please remove the line

        /* to get old behavior, set buf_len = bn_len */

from the diff. There is no need to keep it. OpenSSL handles gently the leading 
zero bytes in the encoded private key.
Your diff changes the ASN.1 encoding only and no bits on the wire. So the old 
buggy behavior is obsolete.

Kind regards,
Ann.



$ 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-----
............................................................................

...


The correct encoded key from above is:

-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIADYI4NV/xp/V/9lU7rLbF0vzrllfS1OIr36eaHsMWwAoAoGCCqGSM49
AwEHoUQDQgAEZTurC5AsyZe5IWk/DY+s91qXA5zAC0OJyPE6HOP6GB7YFKKXkjBI
/H4B8PWJt/9hoApc8HiV2C7k2EQe6EfzGA==
-----END EC PRIVATE KEY-----

Thanks again.

_______________________________________________
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..2b9ae8c 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,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 (!ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
         goto err;
diff --git a/engines/Makefile b/engines/Makefile
old mode 100644
new mode 100755
diff --git a/engines/alpha.opt b/engines/alpha.opt
old mode 100644
new mode 100755
diff --git a/engines/axp.opt b/engines/axp.opt
old mode 100644
new mode 100755
diff --git a/engines/capierr.bat b/engines/capierr.bat
old mode 100644
new mode 100755
diff --git a/engines/e_4758cca.c b/engines/e_4758cca.c
old mode 100644
new mode 100755
diff --git a/engines/e_4758cca.ec b/engines/e_4758cca.ec
old mode 100644
new mode 100755
diff --git a/engines/e_4758cca_err.c b/engines/e_4758cca_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_4758cca_err.h b/engines/e_4758cca_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_aep.c b/engines/e_aep.c
old mode 100644
new mode 100755
diff --git a/engines/e_aep.ec b/engines/e_aep.ec
old mode 100644
new mode 100755
diff --git a/engines/e_aep_err.c b/engines/e_aep_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_aep_err.h b/engines/e_aep_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_atalla.c b/engines/e_atalla.c
old mode 100644
new mode 100755
diff --git a/engines/e_atalla.ec b/engines/e_atalla.ec
old mode 100644
new mode 100755
diff --git a/engines/e_atalla_err.c b/engines/e_atalla_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_atalla_err.h b/engines/e_atalla_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_capi.c b/engines/e_capi.c
old mode 100644
new mode 100755
diff --git a/engines/e_capi.ec b/engines/e_capi.ec
old mode 100644
new mode 100755
diff --git a/engines/e_capi_err.c b/engines/e_capi_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_capi_err.h b/engines/e_capi_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_chil.c b/engines/e_chil.c
old mode 100644
new mode 100755
diff --git a/engines/e_chil.ec b/engines/e_chil.ec
old mode 100644
new mode 100755
diff --git a/engines/e_chil_err.c b/engines/e_chil_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_chil_err.h b/engines/e_chil_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_cswift.c b/engines/e_cswift.c
old mode 100644
new mode 100755
diff --git a/engines/e_cswift.ec b/engines/e_cswift.ec
old mode 100644
new mode 100755
diff --git a/engines/e_cswift_err.c b/engines/e_cswift_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_cswift_err.h b/engines/e_cswift_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_gmp.c b/engines/e_gmp.c
old mode 100644
new mode 100755
diff --git a/engines/e_gmp.ec b/engines/e_gmp.ec
old mode 100644
new mode 100755
diff --git a/engines/e_gmp_err.c b/engines/e_gmp_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_gmp_err.h b/engines/e_gmp_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_nuron.c b/engines/e_nuron.c
old mode 100644
new mode 100755
diff --git a/engines/e_nuron.ec b/engines/e_nuron.ec
old mode 100644
new mode 100755
diff --git a/engines/e_nuron_err.c b/engines/e_nuron_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_nuron_err.h b/engines/e_nuron_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_padlock.c b/engines/e_padlock.c
old mode 100644
new mode 100755
diff --git a/engines/e_padlock.ec b/engines/e_padlock.ec
old mode 100644
new mode 100755
diff --git a/engines/e_sureware.c b/engines/e_sureware.c
old mode 100644
new mode 100755
diff --git a/engines/e_sureware.ec b/engines/e_sureware.ec
old mode 100644
new mode 100755
diff --git a/engines/e_sureware_err.c b/engines/e_sureware_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_sureware_err.h b/engines/e_sureware_err.h
old mode 100644
new mode 100755
diff --git a/engines/e_ubsec.c b/engines/e_ubsec.c
old mode 100644
new mode 100755
diff --git a/engines/e_ubsec.ec b/engines/e_ubsec.ec
old mode 100644
new mode 100755
diff --git a/engines/e_ubsec_err.c b/engines/e_ubsec_err.c
old mode 100644
new mode 100755
diff --git a/engines/e_ubsec_err.h b/engines/e_ubsec_err.h
old mode 100644
new mode 100755
diff --git a/engines/engine_vector.mar b/engines/engine_vector.mar
old mode 100644
new mode 100755
diff --git a/engines/ia64.opt b/engines/ia64.opt
old mode 100644
new mode 100755
diff --git a/engines/makeengines.com b/engines/makeengines.com
old mode 100644
new mode 100755
diff --git a/engines/vax.opt b/engines/vax.opt
old mode 100644
new mode 100755
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

Reply via email to