Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6738532
Votes 1
Synopsis Error in Elliptic Curve NamedCurve determination. (related to PKCS11)
Category java:classes_security
Reported Against
Release Fixed
State 1-Dispatched, bug
Priority: 4-Low
Related Bugs
Submit Date 19-AUG-2008
Description
FULL PRODUCT VERSION :
java version "1.6.0_04"
Java(TM) SE Runtime Environment (build 1.6.0_04-b12)
Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
 customer  Windows XP [Version 5.1.2600]

EXTRA RELEVANT SYSTEM CONFIGURATION :
Configuration includes the org.bouncycastle crypto provider.

A DESCRIPTION OF THE PROBLEM :
This originates from trying to use the PKCS11 KeyStore implementation.  I'm trying to store a software generated elliptic curve private key and certificate in a token.  I get an error:

Params is   xxxxx@xxxxx  
Exception in thread "main" java.lang.RuntimeException: Not a known named curve:
  xxxxx@xxxxx  
        at sun.security.ec.ECParameters.encodeParameters(ECParameters.java:168)
        at sun.security.pkcs11.P11KeyStore.storePkey(P11KeyStore.java:1820)
        at sun.security.pkcs11.P11KeyStore.engineSetEntry(P11KeyStore.java:1100)

        at sun.security.pkcs11.P11KeyStore.engineSetKeyEntry(P11KeyStore.java:44
6)
        at java.security.KeyStore.setKeyEntry(KeyStore.java:880)
        at TestPKCS11.main(TestPKCS11.java:115)

Looking through the java source code, I see at least two different errors and three different solutions.

This all involves code in the sun.security.ec package.

The problem occurs in the static method getNamedCurve in ECParameterSpec - at line 140,  my generated key fails to match any of the registered curves.

It turns out that BouncyCastle is doing the right thing - my generated ECPrivateKey includes a java.security.spec.EllipticCurve with a specified seed value.  The curves registered by sun.security.ec.NamedCurve do not.  Because of that the EllipticCurve.equal method will fail.

First possible problem solution:  NamedCurve should have specified the seed values and should probably include the seed values as an argument to the add method.

Second possible problem and solution:  The equals method of Elliptic curve is probably incorrect and should probably be modified to not check the seed value.  As I understand it, the seed value is not a proper part of the curve and is not used for any crypto calculation - its ancillary information.  An alternative is to check and see if the seed values are identical if and only if both curves have them specified. The latter is probably more correct.

I'd recommend making both changes.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Generate an off-token EC key pair (using the BC provider - but should fail for any provider that includes the seed value when creating the private key's underlying EllipticCurve)
2) Bind it into a self-signed certificate
3) Create an instance of a key store on a token
4) Attempt to write a key store entry containing that key and certificate.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Success
ACTUAL -
The error message listed in the detailed description above.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
See above.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
You should be able to do this with the keystore tool - but.

// X509V3CertificateGenerator is a bouncycastle class.


    kpg.initialize (new ECGenParameterSpec("secp256r1"));

    System.out.println ("Begin generate");
    KeyPair kp = kpg.generateKeyPair();
    System.out.println ("End generate");
    X509V3CertificateGenerator cg = new X509V3CertificateGenerator();
    X509Name dummyname = new X509Name ("C=US, O=dummy org");
    cg.setIssuerDN(dummyname);
    cg.setSubjectDN(dummyname);
    cg.setPublicKey(kp.getPublic());
    cg.setNotBefore(new Date());
    cg.setNotAfter(new Date());
    cg.setSerialNumber (new BigInteger("12345"));
    cg.setSignatureAlgorithm("SHA1withECDSA");
    X509Certificate dummycert = cg.generate(kp.getPrivate());
    X509Certificate[] certs = { dummycert};
  

    ks.setKeyEntry ("TestMeFF", kp.getPrivate(), "user00".toCharArray(), certs);
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
What you can do is convert the private key from one that has the seed value to one that hasn't by doing:

  public static ECParameterSpec convertParams(ECParameterSpec inspec)
  {
    if (inspec == null)
      return null;
    

    return new ECParameterSpec( new EllipticCurve (inspec.getCurve().getField(),
						   inspec.getCurve().getA(),
						   inspec.getCurve().getB()),
				inspec.getGenerator(), inspec.getOrder(),
				inspec.getCofactor());
				
  }

  public static ECPrivateKey convertPrivateKey (ECPrivateKey inkey)
    throws NoSuchAlgorithmException, InvalidKeySpecException
  {
    ECPrivateKeySpec outkeyspec = new ECPrivateKeySpec (inkey.getS(),
							convertParams(inkey.getParams()));
    KeyFactory kf = KeyFactory.getInstance("EC");
    return (ECPrivateKey)kf.generatePrivate(outkeyspec);
  }

Store *this* key - not the original one.
Posted Date : 2008-08-19 04:16:45.0
Work Around
N/A
Evaluation
Patch by bug author submitted at:

    https://bugs.openjdk.java.net/show_bug.cgi?id=100048
Posted Date : 2009-05-05 22:31:26.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang