JDK-6779460 : sun.security.ec.ECParameters.decodePoint expects a plain byte array, can't handle DER octet string.
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.crypto
  • Affected Version: 7
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2008-12-03
  • Updated: 2010-11-11
  • Resolved: 2010-11-11
Related Reports
Duplicate :  
Description
From OpenJDK's security-dev, Lars wrote:

    http://mail.openjdk.java.net/pipermail/security-dev/2008-September/000299.html

I have found a bug in the PKCS#11 ECC implementation.

When I try to read the public part of a newly created EC key I get the following exception:

java.lang.RuntimeException: Could not parse key values
	at sun.security.pkcs11.P11Key$P11ECPublicKey.fetchValues(P11Key.java:1022)
	at sun.security.pkcs11.P11Key$P11ECPublicKey.getW(P11Key.java:1043)
	at org.ejbca.util.keystore.KeyStoreContainerBase.getSelfCertificate(KeyStoreContainerBase.java:136)
	at org.ejbca.util.keystore.KeyStoreContainerBase.generate(KeyStoreContainerBase.java:198)
	at org.ejbca.util.keystore.KeyStoreContainerBase.generateEC(KeyStoreContainerBase.java:156)
	at org.ejbca.util.keystore.KeyStoreContainerBase.generate(KeyStoreContainerBase.java:182)
	at org.ejbca.ui.cli.HSMKeyTool.execute(HSMKeyTool.java:126)
	at org.ejbca.ui.cli.PKCS11HSMKeyTool.execute(PKCS11HSMKeyTool.java:46)
	at org.ejbca.ui.cli.ClientToolBox.executeIfSelected(ClientToolBox.java:38)
	at org.ejbca.ui.cli.ClientToolBox.main(ClientToolBox.java:51)
Caused by: java.io.IOException: Point does not match field size
	at sun.security.ec.ECParameters.decodePoint(ECParameters.java:92)
	at sun.security.pkcs11.P11ECKeyFactory.decodePoint(P11ECKeyFactory.java:78)
	at sun.security.pkcs11.P11Key$P11ECPublicKey.fetchValues(P11Key.java:1019)
	... 9 more

When running the code in the debugger I found out that P11 is returning an DER encoded OCTET STRING but sun.security.ec.ECParameters.decodePoint expects a plain byte array.

I first turned to the Utimaco that has created the P11 that I'm using. ###@###.### gives the following explanation of the issue:

<citation>
the PKCS#11 specification defines the value of a CKA_EC_POINT value as "DER-encoding of the ANSI X9.62 ECPoint value".
ANSI X9.62 defines: ECPoint ::= OCETET STRING;
DER-encoding implies the TLV format (04 is the tag of an OCTET STRING).

We compared this definition with other implementations:
1) A competition HSM also returns the CKA_EC_POINT in TLV format.
2) The IAIK P11 Provider expects the TLV coded EC_POINT and works fine with the CryptoServer.
</citation>

I have created a patch that is fixing the problem:

diff -Naur ./sun/security/ec/ECParameters.java ../src/sun/security/ec/ECParameters.java
--- ./sun/security/ec/ECParameters.java	2008-07-10 21:57:44.000000000 +0200
+++ ../src/sun/security/ec/ECParameters.java	2008-09-11 14:15:44.000000000 +0200
@@ -84,17 +84,24 @@
     // Used by SunPKCS11 and SunJSSE.
     public static ECPoint decodePoint(byte[] data, EllipticCurve curve)
             throws IOException {
-        if ((data.length == 0) || (data[0] != 4)) {
+        final int offset;
+      	if ( data.length>2 && data[0]==4 && data[1]+2==data.length )
+            offset = 2;
+        else if ( data.length>3 && data[0]==4 && (0xff&data[1])==0x81 && (0xff&data[2])+3==data.length )
+            offset = 3;
+        else
+            offset = 0;
+        if ((data.length <= offset) || (data[offset] != 4)) {
             throw new IOException("Only uncompressed point format supported");
         }
         int n = (curve.getField().getFieldSize() + 7 ) >> 3;
-        if (data.length != (n * 2) + 1) {
+        if (data.length != (n * 2) + 1+offset) {
             throw new IOException("Point does not match field size");
         }
         byte[] xb = new byte[n];
         byte[] yb = new byte[n];
-        System.arraycopy(data, 1, xb, 0, n);
-        System.arraycopy(data, n + 1, yb, 0, n);
+        System.arraycopy(data, offset+1, xb, 0, n);
+        System.arraycopy(data, offset+n + 1, yb, 0, n);
         return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
     }

This patch is tested successfully with the Utimaco p11 and HSM emulator.
It will even work with p11s that is just return a plain byte array not encoded as an OCTET STRING.

We will be very pleased if you could fix this to the next release of OpenJDK 6 and if possible also in the next release of Sun java 6.

Best Regards,
Lars Silv��n

===followed by===
    http://mail.openjdk.java.net/pipermail/security-dev/2008-September/000303.html

I have written a simple application that illustrates the problem: http://bunny.primekey.se/~lars/sunP11Bug/src/test/Main.java

But you need a p11 module with ECC capability to run it. Do you have one? If not I could investigate if one of our HSM vendors could send you one.
Also to verify that the public key actually is usable a JCA provider with ECC is needed. But for that you could use BouncyCastle.

Start running the application without parameters and then you get a description of needed parameters.

Lars

Comments
EVALUATION I'm pretty sure this is a duplicate of 6763530.
2008-12-03