[security-dev 01160]: PING 1: [PATCH FOR REVIEW]: Elliptic Curve Cryptography in OpenJDK6 with NSS
Andrew John Hughes
gnu_andrew at member.fsf.org
Tue Sep 1 09:43:35 UTC 2009
2009/8/28 Andrew John Hughes <gnu_andrew at member.fsf.org>:
> In OpenJDK6, the elliptic curve cryptography algorithms are available
> if the PKCS11 provider is configured to point to NSS. See:
>
> http://blogs.sun.com/andreas/entry/the_java_pkcs_11_provider
>
> If NSS is configured as specified in this blog, keytool can be used to
> generate a key as follows:
>
> $ keytool -v -genkeypair -keyalg EC -keysize 256 -keystore ectest.jks
> -storepass test12 -dname "CN=ECC Test"
>
> With NSS 3.12.3 (the current version), this fails as follows:
>
> java.lang.RuntimeException: Could not parse key values
> at sun.security.pkcs11.P11Key$P11ECPublicKey.fetchValues(P11Key.java:1028)
> at sun.security.pkcs11.P11Key$P11ECPublicKey.getEncodedInternal(P11Key.java:1038)
> at sun.security.pkcs11.P11Key.getEncoded(P11Key.java:126)
> at sun.security.x509.CertificateX509Key.encode(CertificateX509Key.java:105)
> at sun.security.x509.X509CertInfo.emit(X509CertInfo.java:819)
> at sun.security.x509.X509CertInfo.encode(X509CertInfo.java:189)
> at sun.security.x509.X509CertImpl.sign(X509CertImpl.java:528)
> at sun.security.x509.X509CertImpl.sign(X509CertImpl.java:486)
> at sun.security.x509.CertAndKeyGen.getSelfCertificate(CertAndKeyGen.java:288)
> at sun.security.tools.KeyTool.doGenKeyPair(KeyTool.java:1223)
> at sun.security.tools.KeyTool.doCommands(KeyTool.java:827)
> at sun.security.tools.KeyTool.run(KeyTool.java:194)
> at sun.security.tools.KeyTool.main(KeyTool.java:188)
> Caused by: java.io.IOException: Point does not match field size
> at sun.security.ec.ECParameters.decodePoint(ECParameters.java:95)
> at sun.security.pkcs11.P11ECKeyFactory.decodePoint(P11ECKeyFactory.java:78)
> at sun.security.pkcs11.P11Key$P11ECPublicKey.fetchValues(P11Key.java:1023)
> ... 12 more
>
> I did a bit of debugging, and the exception is caused by the array
> generated by NSS being too large (for a keysize of 256, its size is 67
> rather than 65).
>
> Looking at the NSS code, it turns out that it handles a case which the
> code in ECParameters.decodePoint doesn't:
>
> /* special note: We can't just use the first byte to
> determine
> * between these 2 cases because both
> EC_POINT_FORM_UNCOMPRESSED
> * and SEC_ASN1_OCTET_STRING are 0x04 */
>
> /* handle the non-DER encoded case (UNCOMPRESSED only) */
> if (pubKey->u.ec.publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED
> && pubKey->u.ec.publicValue.len == keyLen) {
> break; /* key was not DER encoded, no need to unwrap */
> }
>
> /* if we ever support compressed, handle it here */
>
> /* handle the encoded case */
> if ((pubKey->u.ec.publicValue.data[0] == SEC_ASN1_OCTET_STRING)
> && pubKey->u.ec.publicValue.len > keyLen) {
> SECItem publicValue;
> SECStatus rv;
>
> rv = SEC_QuickDERDecodeItem(arena, &publicValue,
> SEC_ASN1_GET(SEC_OctetStringTemplate),
> &pubKey->u.ec.publicValue);
> /* nope, didn't decode correctly */
> if ((rv != SECSuccess)
> || (publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED)
> || (publicValue.len != keyLen)) {
> crv = CKR_ATTRIBUTE_VALUE_INVALID;
> break;
> }
> /* replace our previous with the decoded key */
> pubKey->u.ec.publicValue = publicValue;
> break;
> }
>
> The code in decodePoint, by comparison, assumes that a block beginning
> with 0x04 is uncompressed, then throws an exception because the array
> is too large. The fact is that the array returned by NSS is DER
> encoded, and this encoding specifies an octet string using a header of
> 0x04. Luckily enough, there is a DER encoder in sun.security.util
> which can decode this and with the following webrev:
>
> http://cr.openjdk.java.net/~andrew/ec/webrev.01/jdk.patch
>
> we can quite easily support this format.
>
> With the patch applied:
>
> $ keytool -v -genkeypair -keyalg EC -keysize 256 -keystore ectest.jks
> -storepass test12 -dname "CN=ECC Test"
> Generating 256 bit EC key pair and self-signed certificate
> (SHA1withECDSA) with a validity of 90 days
> for: CN=ECC Test
> Enter key password for <mykey>
> (RETURN if same as keystore password):
> [Storing ectest.jks]
>
> $ keytool -v -list -keystore ectest.jks -storepass test12 -dname "CN=ECC Test"
>
> Keystore type: JKS
> Keystore provider: SUN
>
> Your keystore contains 1 entry
>
> Alias name: mykey
> Creation date: 27-Aug-2009
> Entry type: PrivateKeyEntry
> Certificate chain length: 1
> Certificate[1]:
> Owner: CN=ECC Test
> Issuer: CN=ECC Test
> Serial number: 4a97068b
> Valid from: Thu Aug 27 23:19:55 BST 2009 until: Wed Nov 25 22:19:55 GMT 2009
> Certificate fingerprints:
> MD5: 10:39:9E:CA:11:50:CD:BF:61:BC:16:1F:B2:43:52:E6
> SHA1: F7:8F:80:77:48:51:C6:3B:49:89:28:A8:5E:5F:7C:ED:D1:BD:CF:BE
> Signature algorithm name: SHA1withECDSA
> Version: 3
>
>
> *******************************************
> *******************************************
>
> key creation works fine.
>
> The code has been refactored in 7 and the NSS source code included
> (ugh) so this bug isn't triggered there:
>
> keytool -v -genkeypair -keyalg EC -keysize 256 -keystore ectest.jks
> -storepass test12 -dname "CN=ECC Test"
> Generating 256 bit EC key pair and self-signed certificate
> (SHA1withECDSA) with a validity of 90 days
> for: CN=ECC Test
> Enter key password for <mykey>
> (RETURN if same as keystore password):
> New certificate (self-signed):
> [
> [
> Version: V3
> Subject: CN=ECC Test
> Signature Algorithm: SHA1withECDSA, OID = 1.2.840.10045.4.1
>
> Key: Sun EC public key, 256 bits
> public x coord:
> 111384255692518988314535813062807496116713232200028578473047050707653587930695
> public y coord:
> 64522353781112987171728292648151233343880335217175194500175071174794420240032
> parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)
> Validity: [From: Fri Aug 28 00:17:30 BST 2009,
> To: Wed Nov 25 23:17:30 GMT 2009]
> Issuer: CN=ECC Test
> SerialNumber: [ 67f1afea]
>
> Certificate Extensions: 1
> [1]: ObjectId: 2.5.29.14 Criticality=false
> SubjectKeyIdentifier [
> KeyIdentifier [
> 0000: C0 12 A6 B9 61 A7 78 C3 F9 B2 A4 E6 76 69 12 A0 ....a.x.....vi..
> 0010: 10 59 C8 90 .Y..
> ]
> ]
>
> ]
> Algorithm: [SHA1withECDSA]
> Signature:
> 0000: 30 44 02 20 2B 9A D6 8A 3E F4 37 2D D8 43 67 F6 0D. +...>.7-.Cg.
> 0010: DF 51 EC 9D DC EF 0A 88 86 F5 2F 25 84 3E E6 92 .Q......../%.>..
> 0020: 0D DA D5 51 02 20 0F 34 9D 55 E5 C2 74 14 72 DA ...Q. .4.U..t.r.
> 0030: 53 95 9B 60 01 9A 0D D0 64 89 B6 28 7F 96 22 83 S..`....d..(..".
> 0040: DC 7F EF 10 EF 21 .....!
>
> ]
> [Storing ectest.jks]
>
> However, the same block of code is still there in ECParameters.java so
> I presume the version of NSS imported from OpenSolaris is just older.
> --
> Andrew :-)
>
> Free Java Software Engineer
> Red Hat, Inc. (http://www.redhat.com)
>
> Support Free Java!
> Contribute to GNU Classpath and the OpenJDK
> http://www.gnu.org/software/classpath
> http://openjdk.java.net
>
> PGP Key: 94EFD9D8 (http://subkeys.pgp.net)
> Fingerprint: F8EF F1EA 401E 2E60 15FA 7927 142C 2591 94EF D9D8
>
Ping? Anyone home?
--
Andrew :-)
Free Java Software Engineer
Red Hat, Inc. (http://www.redhat.com)
Support Free Java!
Contribute to GNU Classpath and the OpenJDK
http://www.gnu.org/software/classpath
http://openjdk.java.net
PGP Key: 94EFD9D8 (http://subkeys.pgp.net)
Fingerprint: F8EF F1EA 401E 2E60 15FA 7927 142C 2591 94EF D9D8
More information about the security-dev
mailing list