Skip to content

Commit 6984ce2

Browse files
committed
add some error message hints when DH key pair fails on Open/Oracle JDK
1 parent a38ec5c commit 6984ce2

3 files changed

Lines changed: 53 additions & 10 deletions

File tree

src/main/java/org/jruby/ext/openssl/OpenSSL.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,22 @@ static boolean javaVersion8(final boolean atLeast) {
239239
return atLeast ? gt <= 0 : gt == 0;
240240
}
241241

242+
private static String javaName(final String def) {
243+
// Sun Java 6 or Oracle Java 7/8
244+
// "Java HotSpot(TM) Server VM" or "Java HotSpot(TM) 64-Bit Server VM"
245+
// OpenJDK :
246+
// "OpenJDK 64-Bit Server VM"
247+
return SafePropertyAccessor.getProperty("java.vm.name", def);
248+
}
249+
250+
static boolean javaHotSpot() {
251+
return javaName("").contains("HotSpot(TM)");
252+
}
253+
254+
static boolean javaOpenJDK() {
255+
return javaName("").contains("OpenJDK");
256+
}
257+
242258
//
243259

244260
static IRubyObject to_der_if_possible(final ThreadContext context, IRubyObject obj) {

src/main/java/org/jruby/ext/openssl/SSL.java

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,35 +65,51 @@ public class SSL {
6565
public static final long OP_NETSCAPE_CA_DN_BUG = 0x20000000L;
6666
public static final long OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 0x40000000L;
6767

68+
private static final String JSSE_TLS_ephemeralDHKeySize = "jdk.tls.ephemeralDHKeySize" ;
69+
private static final String JSSE_TLS_ephemeralDHKeySize_default = "matched" ;
70+
private static final String JSSE_TLS_disabledAlgorithms = "jdk.tls.disabledAlgorithms" ;
71+
private static final String JSSE_TLS_disabledAlgorithms_default = "SSLv3, DHE" ;
72+
6873
static { configureJSSE(); }
6974

7075
private static void configureJSSE() {
7176
if ( OpenSSL.javaVersion8(true) ) { // >= 1.8
72-
final String ephemeralDHKeySize = "jdk.tls.ephemeralDHKeySize";
7377
try {
74-
if ( System.getProperty(ephemeralDHKeySize) == null ) {
78+
if ( System.getProperty(JSSE_TLS_ephemeralDHKeySize) == null ) {
7579
// The key size is the same as the authentication certificate,
7680
// but must be between 1024 bits and 2048 bits, inclusively.
7781
// However, the SunJCE provider only supports 2048-bit DH keys larger
7882
// than 1024 bits. Consequently, you may use the values 1024 or 2048 only.
79-
System.setProperty(ephemeralDHKeySize, "matched"); // only on Java 8
83+
System.setProperty(JSSE_TLS_ephemeralDHKeySize, JSSE_TLS_ephemeralDHKeySize_default);
8084
}
8185
}
8286
catch (SecurityException ex) {
83-
OpenSSL.debug("setting " + ephemeralDHKeySize + " failed: " + ex);
87+
OpenSSL.debug("setting " + JSSE_TLS_ephemeralDHKeySize + " failed: " + ex);
8488
}
8589
}
8690
else { // on JDK 7 DHE is weak - disable completely (unless user-set)
87-
final String disabledAlgorithms = "jdk.tls.disabledAlgorithms";
8891
try {
89-
if ( System.getProperty(disabledAlgorithms) == null ) {
90-
System.setProperty(disabledAlgorithms, "SSLv3, DHE");
92+
if ( System.getProperty(JSSE_TLS_disabledAlgorithms) == null ) {
93+
System.setProperty(JSSE_TLS_disabledAlgorithms, JSSE_TLS_disabledAlgorithms_default);
9194
}
9295
}
9396
catch (SecurityException se) {
94-
OpenSSL.debug("setting " + disabledAlgorithms + " failed: " + se);
97+
OpenSSL.debug("setting " + JSSE_TLS_disabledAlgorithms + " failed: " + se);
98+
}
99+
}
100+
}
101+
102+
static RaiseException handleCouldNotGenerateDHKeyPairError(final Ruby runtime, final RuntimeException ex) {
103+
String message = ex.getMessage();
104+
if ( OpenSSL.javaHotSpot() || OpenSSL.javaOpenJDK() ) {
105+
if ( OpenSSL.javaVersion8(false) ) { // == 1.8
106+
message += " (try disabling DHE using -D"+ JSSE_TLS_disabledAlgorithms +" as only keys of size 1024/2048 are supported in Java 8)";
107+
}
108+
else if ( ! OpenSSL.javaVersion8(true) ) { // < 1.8
109+
message += " (try disabling DHE using -D"+ JSSE_TLS_disabledAlgorithms +" as prior to Java 8 only keys of size < 1024 are supported)";
95110
}
96111
}
112+
return newSSLError(runtime, message, ex);
97113
}
98114

99115
public static void createSSL(final Ruby runtime, final RubyModule OpenSSL) {
@@ -141,14 +157,18 @@ public static void createSSL(final Ruby runtime, final RubyModule OpenSSL) {
141157
createNonblock(SSL);
142158
}
143159

144-
public static RaiseException newSSLError(Ruby runtime, Exception exception) {
145-
return Utils.newError(runtime, _SSL(runtime).getClass("SSLError"), exception);
160+
public static RaiseException newSSLError(Ruby runtime, Exception ex) {
161+
return Utils.newError(runtime, _SSL(runtime).getClass("SSLError"), ex);
146162
}
147163

148164
public static RaiseException newSSLError(Ruby runtime, String message) {
149165
return Utils.newError(runtime, _SSL(runtime).getClass("SSLError"), message, false);
150166
}
151167

168+
private static RaiseException newSSLError(Ruby runtime, String message, Exception ex) {
169+
return Utils.newError(runtime, _SSL(runtime).getClass("SSLError"), message, ex);
170+
}
171+
152172
public static RaiseException newSSLErrorWaitReadable(Ruby runtime, String message) {
153173
return newCustomSSLError(runtime, "SSLErrorWaitReadable", message);
154174
}

src/main/java/org/jruby/ext/openssl/SSLSocket.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,13 @@ private SSLSocket acceptImpl(final ThreadContext context, final boolean blocking
328328
debugStackTrace(runtime, e);
329329
throw newSSLError(runtime, e);
330330
}
331+
catch (RuntimeException e) {
332+
debugStackTrace(runtime, e);
333+
if ( "Could not generate DH keypair".equals( e.getMessage() ) ) {
334+
throw SSL.handleCouldNotGenerateDHKeyPairError(runtime, e);
335+
}
336+
throw newSSLError(runtime, e);
337+
}
331338
return this;
332339
}
333340

0 commit comments

Comments
 (0)