Weird error in SSL negociation when using Unlimited Crypto in Java 7 :
Sample Java Test program :
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.ConsoleHandler;
import java.util.logging.SimpleFormatter;
import java.util.logging.Logger;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.logging.Level;
public class TestSSL extends Formatter {
public static void main(String[] args) throws Exception {
System.setProperty("java.net.preferIPv4Stack" , "true");
Logger theLogger = Logger.getLogger(TestSSL.class.getName());
theLogger.setUseParentHandlers(false);
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new TestSSL());
theLogger.addHandler(handler);
try {
if (args.length != 1 && args.length != 2) {
theLogger.warning("Usage: java Test <https://address.server.edu> [timeout]");
return;
}
theLogger.info("Received host address " + args[0]);
URL constructedUrl = new URL(args[0]);
URLConnection conn = constructedUrl.openConnection();
if (args.length == 2) {
conn.setConnectTimeout(Integer.valueOf(args[1]) * 1000);
} else {
conn.setConnectTimeout(5000);
}
theLogger.info("Setting connection timeout to " + conn.getConnectTimeout() / 1000 + " second(s).");
theLogger.info("Trying to connect to " + args[0]);
InputStreamReader reader = new InputStreamReader(conn.getInputStream(), "UTF-8");
BufferedReader in = new BufferedReader(reader);
in.readLine();
in.close();
reader.close();
theLogger.info("Great! It worked.");
} catch (Exception e) {
theLogger.info("Could not connect to the host address " + args[0]);
theLogger.info("The error is: " + e.getMessage());
theLogger.info("Here are the details:");
theLogger.log(Level.SEVERE, e.getMessage(), e);
throw new RuntimeException(e);
}
}
public String format(LogRecord record) {
StringBuffer sb = new StringBuffer();
sb.append("[");
sb.append(record.getLevel().getName());
sb.append("]\t");
sb.append(formatMessage(record));
sb.append("\n");
return sb.toString();
}
}
When running stock Java 7u67 on Linux 64bits, no problem.
When using 7u67 with local_policy.jar and US_export_policy.jar from UnlimitedJCEPolicyJDK7.zip replacing original in jre/lib/security :
java TestSSL https://projects.itemis.de/nexus/content/repositories/releases/
[INFO] Received host address https://projects.itemis.de/nexus/content/repositories/releases/
[INFO] Setting connection timeout to 5 second(s).
[INFO] Trying to connect to https://projects.itemis.de/nexus/content/repositories/releases/
[INFO] Could not connect to the host address https://projects.itemis.de/nexus/content/repositories/releases/
[INFO] The error is: java.lang.RuntimeException: Could not generate DH keypair
[INFO] Here are the details:
[SEVERE] java.lang.RuntimeException: Could not generate DH keypair
Exception in thread "main" java.lang.RuntimeException: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at TestSSL.main(TestSSL.java:64)
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1842)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1825)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1346)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at TestSSL.main(TestSSL.java:48)
Caused by: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.DHCrypt.<init>(DHCrypt.java:136)
at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:621)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:205)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
... 6 more
Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120)
at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:658)
at sun.security.ssl.DHCrypt.<init>(DHCrypt.java:127)
... 13 more
FTR, relevant links:
http://stackoverflow.com/questions/6851461/java-why-does-ssl-handshake-give-could-not-generate-dh-keypair-exception
and
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6521495
I confirmed this problem on OSX / Java 1.7.0_65 too (so, it's not only Linux)