I'm using a Java SE Jersey client to connect to a HTTPS resource which uses two-way SSL.
My SSLContext
looks like this:
private SSLContext getSSLContext() {
SslConfigurator sslConfig = SslConfigurator.newInstance()
.keyStoreFile("src/main/certificates/testcert.p12")
.keyPassword("mypassword");
return sslConfig.createSSLContext();
}
The problem is that the client certificate is never sent.
I get error "Warning: no suitable certificate found - continuing without client authentication" and I've tracked the reason to the fact that the client certificate isn't issued to one of the Cert Authorities listed in the server's CertificateRequest message to the client. I know from testing with cURL
that the server will accept the certificate regardless. The endpoint is a public test system.
My question: How do I force-send my client certificate? (i.e. my Java SE client should ignore the fact that the testcert.p12
certificate's issuer is not the list of issuers that the server has said it would accept)
Please, don't point me to answers that are about disabling check of the server's certificate or about using self-signed certificates. The server's certificate is just fine.
UPDATE
It turned out my problem was another one. I debug by setting system property javax.net.debug=all
. After examining the resulting output it looked to me as if the keystore was empty, even after doing the above. So no wonder why "no suitable certificate found".
Jersey has this 'clever' SslConfigurator
class which is there to help you set up an SSLContext
. Perhaps just too clever for me, because I couldn't make it work with the above code. So instead, I now configure my SSLContext
like below:
KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream("src/main/certificates/testcert.p12");
ks.load(fis, "mypassword".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "mypassword".toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
// now use 'sc' in Jersey
This works for me where Jersey's helper class didn't. I fully sympathize with Jersey's idea of a helper class for SSLContext, because JSSE seems overly complex here for such a simple use case. Well, well.