1

I am trying to call a 2-way-auth thirdparty POST api using a certificate and its working in a basic java project, below is the code to create the socket factory instance before using that in the POST call. Now the problem is as soon as I move the code in the java web application (tomcat 8.5) it does not work and give 401, exact same code, is there anything specific need to be setup in the tomcat ? Any pointer will help. Thank you !

private static SSLContext getSSLSocketFactory() throws Exception {
        SSLContext context = null;
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        InputStream keyInput = new FileInputStream(new File("certificate-1.pfx"));
        keyStore.load(keyInput, PFX_Password.toCharArray());
        keyInput.close();
        
        keyManagerFactory.init(keyStore, PFX_Password.toCharArray());
        context = SSLContext.getInstance("TLSv1.3");

        context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
        return context;
    }
A Paul
  • 8,113
  • 3
  • 31
  • 61
  • Are there any errors or warnings in Tomcat logs? – Forketyfork Jul 18 '22 at 05:21
  • @Sergie, no error. After further checking to code I think I have to update new FileInputStream(new File("certificate-1.pfx")) this line to something that will read from classpath, I think its not reading the certificate maybe. I will add update if I figure it out, but if this is something tomcat specific, any pointer will be helpful ! – A Paul Jul 18 '22 at 05:48

1 Answers1

1

Most likely the issue is in how you load the file. However, if that's the case, you should normally get an IOException during the keyStore.load() call, but as you said you don't observe any errors in the logs. You could double-check if your code swallows this exception somewhere up the call stack, or if you write your application logs to some specific location.

Assuming you bundle your application as a WAR file, your certificate-1.pfx file should end up in the WEB-INF/classes folder. The way to ensure this depends on your build system, but if you use Maven, you just need to put the file into the src/main/resources folder of your sources.

Then you can get this file as a stream as follows:

InputStream keyInput = Thread.currentThread().getContextClassLoader().getResourceAsStream("certificate-1.pfx");
Forketyfork
  • 7,416
  • 1
  • 26
  • 33
  • Hi @Sergei, Thank you ! I just tried your suggestion and I can see its the "keyInput" Inputstream is reading the file, but still getting 401 Unauthorized – A Paul Jul 18 '22 at 16:41
  • Interesting, maybe you could share the code where you use the result of this `getSSLSocketFactory()` method in the Tomcat environment? – Forketyfork Jul 18 '22 at 16:50
  • 1
    I figured it out, they require a timestamp in the POST request, which we were missing, totally separate issue than the certificate. But I will give you a up vote for your help ! Thank you ! – A Paul Jul 18 '22 at 17:17