0

my problem i following: I have two jars build by maven. One jar contains a logic which wraps some classes from jave.net.ssl to make https requests when scheme in URL is https: After obtaining HttpsUrlConnection I'm obtaining SSLSocketFactory as follows:

private SSLSocketFactory prepareSSLSocketFactory(SecurityConfig secConfig) throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, KeyManagementException
{
    if (secConfig == null) throw new IllegalArgumentException("secConfig");
    if (sslSocketFactory!=null)
        return sslSocketFactory;

    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());      
    trustStore.load(secConfig.getSslTrustStore()/*ClassLoader.getSystemClassLoader().getResourceAsStream("jclienttruststore.jks")*/, secConfig.getSslTrustStorePassword().toCharArray());

    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(trustStore);
    SSLContext ctx = SSLContext.getInstance(secConfig.getSslAlgorithm());
    ctx.init(null, tmf.getTrustManagers(), null);
    sslSocketFactory = ctx.getSocketFactory();
    return sslSocketFactory;
}

Note the part secConfig.getSslTrustStore() as this contains InputStream passed into this method, after obtaining it in the class from jar which is parent for the one containing above code. Obtaining InputStream is as Follows:

protected InputStream obtainTrustStore() 
{                
    //InputStream stream = this.getClass().getClassLoader().getParent().getResourceAsStream("trustcert/jclienttruststore.jks");
    //InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream("trustcert/jclienttruststore.jks");

    InputStream stream = this.getClass().getClassLoader().getResourceAsStream("trustcert/jclienttruststore.jks");
    return stream;
}       

the resource is successfully located, and InputStream is obtained. but when it comes to execute trustStore.load() on the first snippet I'm getting strange exceptions saying that KeyStoreFormat is invalid. The KeyStoreFormat is valid - this is for sure - because when I execute test method from jar containing this prepareSSLSocketFactory and load the same keystore file but located in resources for current jar,there is no exception at all, and client successfully comunicates over ssl.

So, my observation is following: If I load trustore giving InputStream from keystore resource located in the jar which executed method prepareSSLSocketFactory it works, but If another jar is responsible for providing InputStream (with keystore) to the dependent jar containing prepareSSLSocketFactory() - it throws exception. Do not know how to deal with it.

Note that I've checked if class providing resource and class containing prepareSSLSocketFacory are loaded by the same ClassLoader by calling :

this.getClass().getClassLoader().equals(HttpConnector.class.getClassLoader()) - its ok.

from class which provides keystore InputStream to the underlying https request making class.

However I do not know if there is possibility, that the ClassLoader returned by HttpConnector.class.getClassLoader() is not the one which loads the HttpConnector which is used at last at runtime.

voytech
  • 380
  • 3
  • 13

1 Answers1

0

The problem is now solved... and what is more - the answer is not real. The problem wasn't connected with different classloader loading the same keystore resources, in fact one of resources (by resource i mean keystore file generated by keytool) was simply corrupted at runtime (So the exception "Keystore format invalid" was ok). This was quite dificult to figure it out, because the keystore was generated only once and then the file was copied to resources folders. So I've assumed that it cannot be corrupted - and it was not - since I rebuild project - In my maven build I had a resource plugin which has filtering enabled for all resources - this was making keystore file corrupted each time I was building project :)

voytech
  • 380
  • 3
  • 13