Problem
If you have a Jetty embedded server running on Java 5 or 6
listening on SSL and which does not explicitly enable “SSLv2Hello” protocol; then
Client having SSLv2 enabled have no issues connecting to the Server. But if you try
to run the same server program in Java 7, then you will notice that the client
will not able to communicate with Server.
The following program demonstrates the same issue:
Server Program
public class JettyServer {
public static void main(String[] args) throws Exception {
Server server = new Server();
SslSelectChannelConnector ssl_connector = new
SslSelectChannelConnector();
ssl_connector.setPort(9999);
SslContextFactory cf = ssl_connector.getSslContextFactory();
cf.setIncludeProtocols(new String[] { "TLSv1" });
String jetty_home = System.getProperty("jetty.home","c:\\Programs\\jetty-distribution-7.6.12.v20130726");
cf.setKeyStore(jetty_home + "/etc/keystore");
cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
server.setConnectors(new Connector[] { ssl_connector });
server.setHandler(new ResponseHandler());
server.start();
server.join();
}
}
class ResponseHandler extends AbstractHandler {
public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
System.out.println("message received");
}
}
Client Program
SslContextFactory cf = new SslContextFactory();
cf.setIncludeProtocols(new String[] {
"SSLv2Hello","TLSv1"});
HttpClient httpClient = new HttpClient(cf);
httpClient.start();
ContentExchange exchange = new ContentExchange(true);
exchange.setURL("https://localhost:9999");
httpClient.send(exchange);
int exchangeState = exchange.waitForDone();
if (exchangeState == HttpExchange.STATUS_COMPLETED)
System.out.println("complete");
else if (exchangeState == HttpExchange.STATUS_EXCEPTED)
System.out.println("error");
else if (exchangeState == HttpExchange.STATUS_EXPIRED)
System.out.println("expired");
httpClient.stop();
Observation
While running Server with Java 5 or 6, the client will be
able to connect to Server, and by enabling ssl debug log (via -Djavax.net.debug=all
VM argument) you can observe following log lines:
INFO:oejus.SslContextFactory:Enabled Protocols [TLSv1] of
[SSLv2Hello, SSLv3, TLSv1]
READ: SSL v2, contentType = Handshake, translated length = 73
If you run the same Server program in Java 7, the client
will fail to connect to Server; and you can notice following logs:
INFO:oejus.SslContextFactory:Enabled Protocols [TLSv1] of
[SSLv2Hello, SSLv3, TLSv1, TLSv1.1, TLSv1.2]
…..
qtp2094737972-17, fatal error: 10: General SSLEngine problem
javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled
Solution
The solution for Jetty server in Java 7 is to enable the
SSLv2Hello protocol explicitly (since it is disabled by default in Java 7 http://docs.oracle.com/javase/7/docs/technotes/guides/security/enhancements-7.html); you can do this by replacing the existing line in Server program with following line:
cf.setIncludeProtocols(new String[] { "TLSv1","SSLv2Hello"
});
Now the same client program should be able to connect to Server,
and in the logs you can notice:
INFO:oejus.SslContextFactory:Enabled
Protocols [SSLv2Hello, TLSv1] of [SSLv2Hello, SSLv3, TLSv1, TLSv1.1, TLSv1.2]
...
READ: SSL v2,
contentType = Handshake, translated length = 85
No comments:
Post a Comment