Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6779460

sun.security.ec.ECParameters.decodePoint expects a plain byte array, can't handle DER octet string.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P2 P2
    • None
    • 7
    • security-libs
    • None

      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

            vinnie Vincent Ryan
            wetmore Bradford Wetmore
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: