JDK-8182580 : Bug in sun.security.ec.ECParameters/jcp.xml.dsig.internal.dom.DOMKeyValue
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.xml.crypto
  • Affected Version: 8
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2017-06-10
  • Updated: 2017-07-06
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
JDK1.8.0.131 (latest current version)

A DESCRIPTION OF THE PROBLEM :

Tried to run the following code to implement EC cryptography:

XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(256);
KeyPair kp = kpg.generateKeyPair();
KeyInfoFactory kif = fac.getKeyInfoFactory();
KeyValue kv = kif.newKeyValue(kp.getPublic()); // Get error here

But I get the error in the last line of code. I found the problem in DOMKeyValue.java where it tries to get the method ECParameters.encodePoint. But the latest release of ECParameters doesn't have this method. Here is the error when I copied the code from EC.getMethod() in DOMKeyValue.java:
Source breakpoint: KeyTest.java:26
Exception breakpoint: Class.java:1786, java.lang.NoSuchMethodException, sun.security.ec.ECParameters.encodePoint(java.security.spec.ECPoint, java.security.spec.EllipticCurve)

I also checked the code in grepcode.com on both the DOMKeyValue and ECParameters class and it seems like the encodePoint disappeared from ECParameters after version 7u40-b43 whereas DOMKeyValue was not updated. So can someone please fix this? I would like to get my code for EC (secp256r1) to digitally sign my files working. Thanks.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the source code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No exceptions
ACTUAL -
Get an exception

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.security.KeyException: ECKeyValue not supported
	at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.<init>(DOMKeyValue.java:350)
	at org.jcp.xml.dsig.internal.dom.DOMKeyInfoFactory.newKeyValue(DOMKeyInfoFactory.java:71)
	at test.KeyTest.main(KeyTest.java:27)
Caused by: java.lang.ClassNotFoundException: sun/security/ec/ECParameters
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.getMethods(DOMKeyValue.java:367)
	at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC$1.run(DOMKeyValue.java:343)
	at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC$1.run(DOMKeyValue.java:339)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.<init>(DOMKeyValue.java:338)
	... 2 more


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package test;

import java.security.KeyPairGenerator;
import java.util.Collections;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.keyinfo.*;
import java.security.*;

public class KeyTest {
    


	public static void main(String[] args) throws Exception{
		XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
		KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
		kpg.initialize(256);
		KeyPair kp = kpg.generateKeyPair();
		KeyInfoFactory kif = fac.getKeyInfoFactory();
		KeyValue kv = kif.newKeyValue(kp.getPublic());
		//KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));

	}

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
I don't think there is a workaround since I am not even directly calling DOMKeyValue.


Comments
To reproduce the issue, run the attached test case. Following are the results: JDK 8 - Fail JDK 8u131 - Fail JDK 9-ea+170- Pass Following is the output on failed versions: Exception in thread "main" java.security.KeyException: ECKeyValue not supported at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.<init>(DOMKeyValue.java:350) at org.jcp.xml.dsig.internal.dom.DOMKeyInfoFactory.newKeyValue(DOMKeyInfoFactory.java:71) at JI9049510.main(JI9049510.java:19) Caused by: java.lang.ClassNotFoundException: sun/security/ec/ECParameters at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.getMethods(DOMKeyValue.java:367) at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC$1.run(DOMKeyValue.java:343) at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC$1.run(DOMKeyValue.java:339) at java.security.AccessController.doPrivileged(Native Method) at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.<init>(DOMKeyValue.java:338) ... 2 more
20-06-2017

Verified in JDK 8u-dev DOMKeyValue.java class, it does refer the encodePoint and decodePoint methods of ECParameters class which had been removed with the JDK-7194075: void getMethods() throws ClassNotFoundException, NoSuchMethodException { 367 Class c = Class.forName("sun.security.ec.ECParameters"); 368 Class[] params = new Class[] { ECPoint.class, EllipticCurve.class }; 369 encodePoint = c.getMethod("encodePoint", params); <--------------------------------referring encodePoint method of ECParameters 370 params = new Class[] { ECParameterSpec.class }; 371 getCurveName = c.getMethod("getCurveName", params); 372 params = new Class[] { byte[].class, EllipticCurve.class }; 373 decodePoint = c.getMethod("decodePoint", params); <----------------------------referring decodePoint method of ECParameters 374 c = Class.forName("sun.security.ec.NamedCurve"); 375 params = new Class[] { String.class }; 376 getECParameterSpec = c.getMethod("getECParameterSpec", params); 377 }
20-06-2017