Search code examples
javarestssljersey-client

jersey-client 2.22.2 - How to set SunPKCS11 keystore on SslConfigurator properly?


I have been attempting to have my jersey client do a ssl client authentication with my Jersey/Grizzly Rest api. Other clients are successful handshaking with this server, but I am having trouble with my java client using Jersey client. When I run the code below, the keystore is successfully loaded and when the SslConfigurator's createSSLContext() is called, the ssl debug output shows this keystore properly being accessed and my private keys found.

However, when the Client's WebTarget is used, the ssl debug output shows the handshake is happening with the default keystore JKS. Why isn't the ClientBuilder using this keystore from the SSLContext?

File tmpConfigFile = File.createTempFile("pkcs11-", "conf");
        tmpConfigFile.deleteOnExit();
        PrintWriter configWriter = new PrintWriter(new FileOutputStream(tmpConfigFile), true);
        configWriter.println("name=ActiveClient");
        configWriter.println("library=\"C:\\\\Program Files\\\\ActivIdentity\\\\ActivClient\\\\acpkcs211.dll\"");
        configWriter.println("slotListIndex=0");
        SunPKCS11 provider = new SunPKCS11(tmpConfigFile.getAbsolutePath());
        Security.addProvider(provider);
        //  KeyStore keyStore = KeyStore.getInstance("PKCS11", provider);

        KeyStore keyStore = KeyStore.getInstance("PKCS11");
        keyStore.load(null, null);

        ClientConfig config = new ClientConfig();

        SslConfigurator sslConfig = SslConfigurator.newInstance()
                .keyStore(keyStore)
                .keyStorePassword("mypin")
                .keyStoreType("PKCS11")
                .trustStoreFile(TRUSTORE_CLIENT_FILE)
                .trustStorePassword(TRUSTSTORE_CLIENT_PWD)
                .securityProtocol("TLS");



        final SSLContext sslContext = sslConfig.createSSLContext();

        Client client = ClientBuilder
                .newBuilder().hostnameVerifier(new MyHostnNameVerifier())
                .sslContext(sslContext)
                .build();
        WebTarget target = client.target("https://localhost:8443/appname/resources/employees?qparam=something");  
     Response res = target.request().accept(MediaType.APPLICATION_JSON).get();

Solution

  • This code actually worked. The problem was that my server's trust certificate wasn't available for the smart card cert that it needed to trust. I added the correct certs to the truststore on the server and then it worked. The ssl debug messages weren't very clear.