2009/8/28 Andrew John Hughes <[email protected]>: > 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
