0

I have a fixed client that call a fixed server using different keystores (one keystore for company). In my java, every time I set trustStore and keyStore system properties like this:

..reading path and password from database..
System.setProperty("javax.net.ssl.trustStore", ..path..);
System.setProperty("javax.net.ssl.trustStorePassword", ..password..);
System.setProperty("javax.net.ssl.keyStore", ..path..);
System.setProperty("javax.net.ssl.keyStorePassword", ..password);

In this way, it works only the first time that I call the server (example "Company A"). When I try to call the server with another keystore (example "Company B"), the response from server is:

javax.xml.ws.soap.SOAPFaultException: IDP Rule 'Process Error' aborted processing.

This because System.setProperty not refreshing each time, so after the first time the client have always the keystore of "Company A". I tried also to put all the certified inside one keystore, but it doesn't work. In this case all the passwords have to be the same I think. Some ideas?

Update after Misantrops response

I tried with this code:

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

InputStream trustStore1 = new FileInputStream(path1);
keyStore.load(trustStore1, password1.toCharArray());
trustStore1.close();

InputStream trustStore2 = new FileInputStream(path2);
keyStore.load(trustStore2, password2.toCharArray());
trustStore2.close();

InputStream trustStore3 = new FileInputStream(path3);
keyStore.load(trustStore3, password3.toCharArray());
trustStore3.close();

TrustManagerFactory tmf =  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
SSLSocketFactory sslFactory = ctx.getSocketFactory();

It return this error:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.] with root cause

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
wikimt
  • 71
  • 2
  • 11
  • Does this answer your question? [How can I use different certificates on specific connections?](https://stackoverflow.com/questions/859111/how-can-i-use-different-certificates-on-specific-connections) – Misantorp Jan 11 '20 at 18:22
  • Hi Misantorp, thank you. It doesn't work, I put in the topic the error – wikimt Jan 11 '20 at 19:09
  • Or this https://stackoverflow.com/questions/1793979/registering-multiple-keystores-in-jvm – Andrey Lebedenko Jan 11 '20 at 19:09
  • 1
    (1) putting all (remote) certs in one file _should_ work for truststore; you don't give any details what you did or what you think failed, so I can't help with that. However, a single file _usually_ won't for for _keystore_, so if you do in fact need separate keystores it isn't much more work to do separate truststores also (2) for separate truststores, and also for separate keystores (not posted), you must use separate `KeyStore` objects. You cannot load multiple files into one `KeyStore` object; each `load` overwrites the contents and only the last one loaded remains. – dave_thompson_085 Jan 12 '20 at 01:19
  • I found the solution by using SSLContext "init" method and passing KeyManager and TrustManager. Thank you to everyone! – wikimt Jan 13 '20 at 12:08

1 Answers1

0

Finally I found the solution:

    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

    String path1 = ..absolute path of keystore..
    path1 = path1.replaceAll("%20", " ");
    InputStream trustStore1 = new FileInputStream(path1);
    keyStore.load(trustStore1, new String(..keystore password..).toCharArray());
    trustStore1.close();

    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
    keyManagerFactory.init(keyStore, new String(..keystore password..).toCharArray());

    TrustManagerFactory tmf =  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);
    SSLContext ctx = SSLContext.getInstance("SSL");
    ctx.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
    HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

It's possibile to change at runtime the keystore simply using the method "init" of object SSLContext. The parameters of this function are KeyManager and TrustManager, initialized like in the script. So, in this way it's possible to simulate System.setProperty. Thank you to everyone!

wikimt
  • 71
  • 2
  • 11