I have a Java application that first establishes an HTTPS connection with a server and performs a PUT. The connection requires client authentication. Subsequent to this, I establish a web socket connection with another server and send it a message. This is also secure and requires client authentication. I'm using the Jetty (9.x) web socket API.
The problem is specific to running via web start, but I will start by explaining what I did to make it work outside of web start. Note that at this point I cannot influence the problem, I can only work on the solution.
In my development environment (eclipse, but not relevant) I establish a valid KeyManagerFactory and then use the following snippet to establish the SSLContext prior to the HTTPS request. This is intended to be for testing only, I do not know the keystore or password in real life:
javax.net.ssl.SSLContext ctx = javax.net.ssl.SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), null, null);
javax.net.ssl.SSLContext.setDefault(ctx);
Then when I create the web socket connection I get the "default" SSLContext that was just established as follows. This is in a different class, I just happened to use the same variable name:
SSLContext ctx = SSLContext.getDefault();
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setSslContext(ctx);
client = new WebSocketClient(sslContextFactory);
And the HTTPS request and secure web socket connections both work.
The problem occurs when I run the application as a web start client. In this configuration, the first code block above is not executed. The SSLContext and certificate selection is "inherited" from the browser by web start as documented here: web start security and presumably established as the default. The second code snippet, however, is executed as is in an attempt to grab the same SSLContext that the HTTPS interface used.
In this configuration, the HTTPS PUT works as expected using the default SSLContext, but the web socket connection fails due to an SSL handshake failure. If I attempt to connect the web socket to a secure endpoint that does not implement client authentication as referenced here 27166258, it does connect successfully, so I'm confident that the problem is that the Jetty API is not getting the certificate part of the SSLContext. I ran across something in my research that indicated a problem like this, but I don't have the link.
I know that the appropriate authentication information is in the web start application at run time since the HTTPS PUT works. My struggle is figuring out how to get that information into the web socket connection request. I would rather not have to ask the user to find the certificate and enter the password, but that is a workaround that is on the table. I have determined that removing client authentication from the secure web socket endpoint is not an option.
I appreciate any assistance on this.