I have a java test app that makes a Restful SSL connection/call to a remote server but same code run from servlet under Tomcat returns Bad_Certificate error.
Test app version successfully connects to remote after referencing my keyStore and trustStore that I specify through System.setProperty("javax.net.ssl....? statements for file locations and passwords. This test program is a stand-alone simple class with a main method that successfully establishes connection and gets a response. However, if I move this same code to my servlet that runs on Tomcat I get a "SSLHandshakeException" Bad_Certificate error. And ssl:all:verbose debug trace doesn't provide any help because it appears that it's not getting to the handshake stage. I can recreate this error on my test app only if I don't set the System Properties pointing to the certificates. It appears that setting System.setProperty is being overridden when running from Tomcat. I also tried putting locations in web.xml but that didn't have any affect either.
My code is not readily available because it is exists behind a firewall that won't allow me to copy anything. But I'll fat-finger anything in that you want to verify.
OS: Redhat 7.4 Tomcat: 7.0.76 Java: JDK 10.0.2
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java 198)
java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java 159)
java.base/sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2046)
java.base/sun.security.ssl.SSLSocketImpl.processInputRecord(SSLSocketImpl.java:1207)
java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1074)
java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
java.base/sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1402)
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1429)
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1581)
java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:329)
Since adding debug to JAVA_OPTS in Tomcat configuration file, I'm getting more detail. Prior to the stacktrace that I provided yesterday I'm seeing the handshake now. And the last part of the handshake looks as follows:
update handshake state: finished
upcoming handshake states: server change_cipher_spec[-1]
upcoming handshake states: server finished [20]
ajp-bio-8009-exec-1, WRITE TLSv1.2 Handshake, length = 32
ajp-bio-8009-exec-1, READ TLSv1.2 Alert, length = 2
ajp-bio-8009-exec-1, RECV TLSv1.2 ALERT: fatal, bad certificate
%%invalidated: [Session-3 TLS_RSA_WITH_AES_128_CBC_SHA]
ajp-bio-8009-exec-1, call closeSocket()
But I'm not sure what to do about this.