@@ -108,6 +108,19 @@ private static RaiseException newSSLError(Ruby runtime, String message) {
108108 return SSL .newSSLError (runtime , message );
109109 }
110110
111+ private static RaiseException newSSLErrorFromHandshake (Ruby runtime , SSLHandshakeException exception ) {
112+ // SSLHandshakeException is always a wrap around another exception that
113+ // is the actual cause. In some cases the diagnostic message from the original
114+ // exception is also lost and the handshake exception reads "General SSLEngine problem"
115+ // Follow the cause chain until we get the real message and use that to ensure
116+ // we raise an exception that contains the real reason for failure
117+ Exception cause = exception ;
118+ while (cause .getCause () != null && (cause instanceof SSLHandshakeException )) {
119+ cause = (Exception ) cause .getCause ();
120+ }
121+ return SSL .newSSLError (runtime , cause );
122+ }
123+
111124 private SSLContext sslContext ;
112125 private SSLEngine engine ;
113126 private RubyIO io ;
@@ -203,11 +216,7 @@ private IRubyObject connectCommon(final ThreadContext context, boolean blocking)
203216 // unlike server side, client should close outbound channel even if
204217 // we have remaining data to be sent.
205218 forceClose ();
206- Exception cause = e ;
207- while (cause .getCause () != null && (cause instanceof SSLHandshakeException )) {
208- cause = (Exception ) cause .getCause ();
209- }
210- throw newSSLError (runtime , cause );
219+ throw newSSLErrorFromHandshake (runtime , e );
211220 }
212221 catch (NoSuchAlgorithmException e ) {
213222 forceClose ();
@@ -267,7 +276,7 @@ public SSLSocket acceptCommon(final ThreadContext context, boolean blocking) {
267276 doHandshake (blocking );
268277 }
269278 catch (SSLHandshakeException e ) {
270- throw newSSLError (runtime , e );
279+ throw newSSLErrorFromHandshake (runtime , e );
271280 }
272281 catch (NoSuchAlgorithmException e ) {
273282 throw newSSLError (runtime , e );
0 commit comments