arcy
arcy

Reputation: 13103

which cacert is in use?

I have an example command-line java application from a vendor; it depends on SSL authentication. I have the vendor's certificate(s), I can see them in my java 7 cacerts file (windows, c:\program files\java\jdk1.7.0_07\jre\lib\security\cacerts). If I open the java 8 cacerts file, they are not there (c:\program files\java\jre1.8.0_66\lib\security\cacerts)

If I set a path so that java 8 is first, the program works. If I change the path so that java 7 is first, the program fails with a certification error:

C:\project\tryCerts\Demo2>path=c:\program files\java\jdk1.7.0_07\bin;c:\program files\java\jre1.8.0_66\bin


C:\project\tryCerts\Demo2>java -jar vendorCmd.jar user1 password2 environment3
Dec 22, 2015 11:11:35 AM [com.sun.xml.ws.policy.jaxws.PolicyConfigParser]  parse
INFO: WSP5018: Loaded WSIT configuration from file: jar:file:/C:/project/tryCerts/Demo2/vendorCmd/dist/vendorCmd.jar!/META-INF/wsit-client.xml.
Unable to log in: com.sun.xml.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: sun.security.validator.Va
lidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to re
quested target

C:\project\tryCerts\Demo2>path=c:\program files\java\jre1.8.0_66\bin;c:\program files\java\jdk1.7.0_07\bin

C:\project\tryCerts\Demo2>java -jar vendorCmd.jar acc03\acc03_ws_user accwbS3rv!ceS acc03_p_production
Dec 22, 2015 11:21:34 AM [com.sun.xml.ws.policy.jaxws.PolicyConfigParser]  parse
INFO: WSP5018: Loaded WSIT configuration from file: jar:file:/C:/project/tryCerts/Demo2/vendorCmd/dist/vendorCmd.jar!/META-INF/wsit-client.xml.
logged in
Dec 22, 2015 11:21:35 AM [com.sun.xml.ws.policy.jaxws.PolicyConfigParser]  parse
INFO: WSP5018: Loaded WSIT configuration from file: jar:file:/C:/project/tryCerts/Demo2/vendorCmd/dist/vendorCmd.jar!/META-INF/wsit-client.xml.
Signed Info:org.jcp.xml.dsig.internal.dom.DOMSignedInfo@3f071328
AccountNumber: 279105/ Firstname: null/ LastName: null
AccountNumber: 1005118/ Firstname: null/ LastName: COMPANY1
AccountNumber: 2102765/ Firstname: null/ LastName: COMPANY2
AccountNumber: 2101373/ Firstname: null/ LastName: COMPANY3
AccountNumber: 2119664/ Firstname: null/ LastName: COMPANY4
AccountNumber: 2119668/ Firstname: null/ LastName: ET CETERA

C:\project\tryCerts\Demo2>dir/s cacerts
 Volume in drive C is OS
 Volume Serial Number is 9896-211D
File Not Found

C:\project\tryCerts\Demo2>

This is exactly opposite from what I was expecting -- it is the cacerts file in the java 7 folders that has the vendor certificate chain, and java 8 that does not have it. Yet running the program on Java 7 fails with a certification error, and running it with 8 succeeds.

Can anyone tell me what I should look for to explain this?

Upvotes: 8

Views: 14380

Answers (2)

Anya Shenanigans
Anya Shenanigans

Reputation: 94574

To determine the trust store that's being used, without having to resort to tools like strace (linux) and process explorer (windows), you can pass the debug flag -Djavax.net.debug=trustmanager to the java command line, which dumps all the ssl related debug information (I mentioned all in the original comment, but that adds even more noise to the output):

java -Djavax.net.debug=trustmanager -jar vendorCmd.jar user1 password2 environment3

In the first few lines of the debug output, will be a line:

trustStore is: <path to>cacerts

this indicates the trust store that's being used.

Adding the ssl option (trustmanager,ssl) , it also dumps all the trusted certs that are being added to the list of certs that are considered trusted by the JVM. This can be used to verify that the certs you think are in the trust store are actually in the trust store - in this case you should be able to see the vendor's certs in the list.

A full list of the debug options for javax.net.debug are detailed in the JSSE reference guide. You can use =help to get a relatively short usage message for the flags

Sample code & test run:

import java.net.URL;
import java.io.BufferedInputStream;

public class pull_url {
    public static void main(String args[]) throws Exception {
        for (String arg : args) {
            downloadUsingUrl(arg);
        }
    }

    public static void downloadUsingUrl(String stringurl) throws Exception {
        URL url = new URL(stringurl);
        BufferedInputStream bis = new BufferedInputStream(url.openStream());
        bis.close();
    }
}

Output from a run:

$ java -Djavax.net.debug=trustmanager pull_url https://google.com/
javax.net.ssl|DEBUG|10|main|2023-05-06 13:40:20.584 IST|TrustStoreManager.java:162|Inaccessible trust store: /Users/anysh/Library/Java/JavaVirtualMachines/jdk-19.0.1.jdk/Contents/Home/lib/security/jssecacerts
javax.net.ssl|DEBUG|10|main|2023-05-06 13:40:20.595 IST|TrustStoreManager.java:113|trustStore is: /Users/anysh/Library/Java/JavaVirtualMachines/jdk-19.0.1.jdk/Contents/Home/lib/security/cacerts
trustStore type is: pkcs12
trustStore provider is:
the last modified time is: Wed Sep 14 17:16:16 IST 2022
javax.net.ssl|DEBUG|10|main|2023-05-06 13:40:20.595 IST|TrustStoreManager.java:334|Reload the trust store
javax.net.ssl|DEBUG|10|main|2023-05-06 13:40:20.620 IST|TrustStoreManager.java:342|Reload trust certs
javax.net.ssl|DEBUG|10|main|2023-05-06 13:40:20.620 IST|TrustStoreManager.java:347|Reloaded 89 trust certs

In this case, the second line indicates the cacerts file that's being used.

Upvotes: 13

Lewis B
Lewis B

Reputation: 59

Thanks a lot for Anya Shenanigans response. Just to tell, that in my case, I had to use the

-Djavax.net.debug=all

not the ssl option (I dont know exactly why). With that option, as Anya says, the console will show:

javax.net.ssl|DEBUG|01|main|2023-02-26 11:06:43.622 CET|TrustStoreManager.java:112|trustStore is: 

Add the option when runing java command. If using IntelliJIdea , go to Run/Debug Configuration of your app, click Modify Option (it will be hidden per default) and add it "VM option"

Upvotes: 3

Related Questions