Skip to content

Commit

Permalink
Workaround for Java bailing out on TLS warning due to SNI
Browse files Browse the repository at this point in the history
Java 7 supports the SNI extension and sends the host name in the `server_name`
extension. Some misconfigured servers (Apache only?) that support SNI send an
"Unrecognized Name" warning that kills Java 7. Oracle engineers refuse[1] to
fix this error that is not as rare as it sounds[2].

According to RFC 3546 (TLS Extensions) [3], servers *should* send the
unrecognized_name alert which *may* be fatal. In practise, clients just ignore
this (tested with wget, curl, Firefox, Chromium).

This patch makes Webscarab perform a second connection attempt without a Host
header (effectively disabling SNI), when the exception message indicates that
the "unrecognized_name" alert was received.

Tested with https://redhat.com/ and https://webmail.arago.utwente.nl/.

 [1]: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7127374
 [2]: http://stackoverflow.com/q/7615645/427545
 [3]: http://www.ietf.org/rfc/rfc3546.txt
  • Loading branch information
Lekensteyn committed Feb 14, 2013
1 parent 9b25195 commit 8f2362e
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/org/owasp/webscarab/httpclient/URLFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public Response fetchResponse(Request request) throws IOException {
request.deleteHeader("Proxy-Authorization");

_response = null;
connect(url);
connect(url, true);
if (_response != null) { // there was an error opening the socket
return _response;
}
Expand Down Expand Up @@ -345,7 +345,7 @@ public Response fetchResponse(Request request) throws IOException {
return _response;
}

private void connect(HttpUrl url) throws IOException {
private void connect(HttpUrl url, boolean enableSNI) throws IOException {
if (! invalidSocket(url)) return;
_logger.fine("Opening a new connection");
_socket = new Socket();
Expand Down Expand Up @@ -420,7 +420,12 @@ private void connect(HttpUrl url) throws IOException {
// HTTPS port of the specified web server.
try {
SSLSocketFactory factory = sslContext.getSocketFactory();
SSLSocket sslsocket=(SSLSocket)factory.createSocket(_socket,_socket.getInetAddress().getHostName(),_socket.getPort(),true);
// Empty host name avoids the SNI extension from being set
String hostname = "";
if (enableSNI) {
hostname = _socket.getInetAddress().getHostName();
}
SSLSocket sslsocket = (SSLSocket) factory.createSocket(_socket, hostname, _socket.getPort(), true);
sslsocket.setEnabledProtocols(new String[] {"TLSv1"});
sslsocket.setUseClientMode(true);
_socket = sslsocket;
Expand All @@ -432,6 +437,12 @@ private void connect(HttpUrl url) throws IOException {
try {
((SSLSocket) _socket).startHandshake();
} catch (IOException ioe) {
// Workaround for Java inability to continue on ignored SNI
if (enableSNI && ioe.getMessage().equals("handshake alert: unrecognized_name")) {
_logger.fine("Server received saw wrong SNI host, retrying without SNI");
connect(url, false);
return;
}
_logger.severe("Error during SSL handshake: " + ioe);
throw ioe;
}
Expand Down

0 comments on commit 8f2362e

Please sign in to comment.