On 1/3/2015 6:41 AM, Annie Yousar wrote:
Dear all,
-----Facts-----
The private EC key is always encoded as an OCTET STRING in ASN.1

It depends on its context, there are a number of ways to encode it:

PKCS#15 6.3.3 Private Elliptic Curve key objects

   PrivateECKeyAttributes ::= SEQUENCE {
           value ObjectValue {ECPrivateKey},
           keyInfo KeyInfo {Parameters, PublicKeyOperations} OPTIONAL,
           ... -- For future extensions
           }

  ECPrivateKey ::= INTEGER


cf. RFC 5915 http://tools.ietf.org/html/rfc5915#page-3:
o   privateKey is the private key.  It is an octet string of length
     ceiling (log2(n)/8) (where n is the order of the curve) obtained
     from the unsigned integer via the Integer-to-Octet-String-
     Primitive (I2OSP) defined in [RFC3447].view

Therefore the length of this OCTECT STRING is fixed by the curve parameters.

In the context of RFC5915, the OCTET STRING has a fixed length and the
I2OSP routine is provided with the length.  RFC3447 is a more important 
reference,
as it says how to do a conversion.

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

This related to problem:

   http://rt.openssl.org/Ticket/Display.html?id=3465&user=guest&pass=guest

It could have been addressed if the OCTET STRING was kept at the fixed length,
as the OCTET STRING should be xLen, which can be derived from the parameters
if they are present.

In the github master src/crypto/ec/ec_lcl.h defines struct ec_key_st
BIGNUM *priv_key;

OpenSSL is losing the xLen when converting internally to a BIGNUM.
Maybe it should be storing the xLen for use when group=NULL;
to convert the BIGNUM to OCTET STRING of the correct length.




The EC private key encoding is wrong in OpenSSL from the very beginning:
If the byte length of the private key is shorter than the byte length of
the order then OpenSSL generates a shorter OCTET STRING than required.
Keep in mind that the private key is not a DER encoded integer but an
(unsigned) integer encoded in a fixed length byte string.

Check that out with, e.g. the attached script and a log that shows up by
the script.
If you compare in the script the hexdata string length against 64 you will
get more broken key encodings:

openssl asn1parse gives:
     0:d=0  hl=2 l= 117 cons: SEQUENCE
     2:d=1  hl=2 l=   1 prim:  INTEGER           :01
     5:d=1  hl=2 l=  30 prim:  OCTET STRING      [HEX DUMP]:0672D2....
    37:d=1  hl=2 l=  10 cons:  cont [ 0 ]
    39:d=2  hl=2 l=   8 prim:   OBJECT            :prime256v1
    49:d=1  hl=2 l=  68 cons:  cont [ 1 ]
    51:d=2  hl=2 l=  66 prim:   BIT STRING

openssl ec -text shows:
read EC key
Private-Key: (256 bit)
priv:
     06:72:d2:f7:54:2a:1f:f8:35:06:12:81:94:9d:68:
     84:bb:8f:f2:4d:f5:88:62:ad:a7:42:16:1f:15:30
pub:
     04:3f:ff:4b:5d:5b:4c:b5:ae:b2:1a:2e:8e:52:14:
     7d:fc:1a:56:45:76:cd:ba:45:2e:ef:ea:d1:36:59:
     9b:85:f3:c5:d5:09:bd:6c:d8:e3:f0:88:1a:37:2c:
     20:1c:21:85:54:f3:53:6c:2e:51:66:67:c1:95:58:
     a0:64:f8:fa:97
ASN1 OID: prime256v1

-----Remark-----
Note that is not required to output the encoded OCTET STRING by the text
option, which displays an integer. Look instead at the output of the
asn1parse command.
As a side effect, if the upper bit of a shorter key is set, the text
option shows an additional leading zero byte, which is in fact not in the
encoding.

-----How to proceed-----
The encoding is broken and does not conform with the Specification.
Full stop.

Because OpenSSL gently handles leading zero bytes in a private key, I'm
quite sure that a correction of the EC key encoding has no impact.

Try out as examples the following conformaing private EC keys:

-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIADurCM9Znleeiyft0Ll5fK9HLZiMsEa1prIsF/rj5ZmoAoGCCqGSM49
AwEHoUQDQgAEbf8lX1VO8rfkHQao+D3PTIq9Mtg2Z54DNlTv2Fa4SnyKyjxbm/V9
PmluypK/YofHS+Qsd4JkExbSZ0xC+G78dg==
-----END EC PRIVATE KEY-----
or
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIAAMVeMs6sJ6iKyn+3whuEo9KuAStgwyRo+KxaOCbnfKoAoGCCqGSM49
AwEHoUQDQgAERYtBxIKY6Glq7sRHpYhrJ01KKAvH9LfD4L+B7GeMDht3Sw2IbK+e
82cUTBOXXBRHCL7xfk+DamHAcl9GtoO8XQ==
-----END EC PRIVATE KEY-----

OpenSSL converts this encoding into the internal structure, where the
private key is stored as a BIGNUM, and leading zeros disappear.

Any comments on the attached diff for 1.0.2.beta3 are welcome. It works,
but I didn't check it carefully. It is applicable to the 1.0.1 branch as
well.

Regards,
Ann.



_______________________________________________
openssl-dev mailing list
openssl-dev@openssl.org
https://mta.opensslfoundation.net/mailman/listinfo/openssl-dev


--

 Douglas E. Engert  <deeng...@gmail.com>

_______________________________________________
openssl-dev mailing list
openssl-dev@openssl.org
https://mta.opensslfoundation.net/mailman/listinfo/openssl-dev

Reply via email to