javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate

Java.net JIRA | gfuser9999 | 3 years ago
  1. 0

    [GLASSFISH-20841] GlassFish submits wrong Client certificate and throws bad_certificate SSL error from Webservice - Java.net JIRA

    java.net | 1 year ago
    javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
  2. 0

    h3. Background This problem happens especially in GFv3.x as the following JVM options is added -Dcom.sun.enterprise.security.httpsOutboundKeyAlias=s1as The impact of this is that it sets the default client cert to be sent is s1as. Although this option is there is GFv2, it was not enabled in the JVM options. So no issues unless one set it. Now the internals of GFv3 opensource suggest that on startup 1) GFv301 will replace the HttpsURLConnection setDefault to have a KeyManager that will sent "httpsOutboundKeyAlias"/s1as is client cert is requested. 2) Gfv312 also does this 3) Now in GFv301, it does not set the SSLContext but in GFv312x due to change GLASSFISH-15369, it seems that SSLContext.setDefault() is called to make the SSLContext have a default key manager that will submit s1as as the client cert if requested Well the behaviour is that things that work say in GFv2 may not work in GFv301 (if URLConnection to a https://... that does optional client cert request). For example ==> https://www.java.net//forum/topic/glassfish/glassfish/axis2-generated-stub-soap-webservice-call-not-working-glassfish-312?force=516 where javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate may happen in GFV312 (but may work in GFv301) due to (3). h3. Now the problem is this The issue is that a) GFv3 set the default alias to sent the client cert globally b) In GFv312, SSL artifact created from HttpsURLConnection and SSLContext will have this KeyManager that does chooseClientAlias() from X509ExtendedKeymanager and always returns s1as irregardless if the issuer matches with s1as +Look at J2EEKeyManager.java+ https://java.net/projects/glassfish/sources/svn/content/tags/3.1.2/security/core/src/main/java/com/sun/enterprise/security/ssl/J2EEKeyManager.java As you may see, from the code, the fix/issues are: a) Not setting com.sun.enterprise.security.httpsOutboundKeyAlias may help (if you do not ever use client cert) but the code may always return null for some conditions (ie: !server&!acc) b) Even if the property is explicitly set, the chooseClientAlias should still check if this alias is compatible with what the SSL server requested otherwise it should return NULL +Symptom+ For this issue even if you added all the SSL cert to the client trust store, if the remote SSL server ask for say an optional client cert (or required), the handshake will fail since the wrong client cert (self-signed s1as) is submitted which is totally different from the valid cert the server accepts. {noformat} javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077) at sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1707) at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:122) at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:972) at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1087) at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1006) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:285) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) {noformat}

    Java.net JIRA | 3 years ago | gfuser9999
    javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
  3. 0

    h3. Background This problem happens especially in GFv3.x as the following JVM options is added -Dcom.sun.enterprise.security.httpsOutboundKeyAlias=s1as The impact of this is that it sets the default client cert to be sent is s1as. Although this option is there is GFv2, it was not enabled in the JVM options. So no issues unless one set it. Now the internals of GFv3 opensource suggest that on startup 1) GFv301 will replace the HttpsURLConnection setDefault to have a KeyManager that will sent "httpsOutboundKeyAlias"/s1as is client cert is requested. 2) Gfv312 also does this 3) Now in GFv301, it does not set the SSLContext but in GFv312x due to change GLASSFISH-15369, it seems that SSLContext.setDefault() is called to make the SSLContext have a default key manager that will submit s1as as the client cert if requested Well the behaviour is that things that work say in GFv2 may not work in GFv301 (if URLConnection to a https://... that does optional client cert request). For example ==> https://www.java.net//forum/topic/glassfish/glassfish/axis2-generated-stub-soap-webservice-call-not-working-glassfish-312?force=516 where javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate may happen in GFV312 (but may work in GFv301) due to (3). h3. Now the problem is this The issue is that a) GFv3 set the default alias to sent the client cert globally b) In GFv312, SSL artifact created from HttpsURLConnection and SSLContext will have this KeyManager that does chooseClientAlias() from X509ExtendedKeymanager and always returns s1as irregardless if the issuer matches with s1as +Look at J2EEKeyManager.java+ https://java.net/projects/glassfish/sources/svn/content/tags/3.1.2/security/core/src/main/java/com/sun/enterprise/security/ssl/J2EEKeyManager.java As you may see, from the code, the fix/issues are: a) Not setting com.sun.enterprise.security.httpsOutboundKeyAlias may help (if you do not ever use client cert) but the code may always return null for some conditions (ie: !server&!acc) b) Even if the property is explicitly set, the chooseClientAlias should still check if this alias is compatible with what the SSL server requested otherwise it should return NULL +Symptom+ For this issue even if you added all the SSL cert to the client trust store, if the remote SSL server ask for say an optional client cert (or required), the handshake will fail since the wrong client cert (self-signed s1as) is submitted which is totally different from the valid cert the server accepts. {noformat} javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077) at sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1707) at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:122) at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:972) at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1087) at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1006) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:285) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) {noformat}

    Java.net JIRA | 3 years ago | gfuser9999
    javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

  5. 0

    SSL secured Jboss 7.1 Software caused connection abort: recv failed

    Stack Overflow | 2 years ago | Dan Nemes
    javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate

  1. kid 540 times, last 5 months ago
  2. poroszd 1 times, last 9 months ago
98 unregistered visitors
Not finding the right solution?
Take a tour to get the most out of Samebug.

Tired of useless tips?

Automated exception search integrated into your IDE

Root Cause Analysis

  1. javax.net.ssl.SSLHandshakeException

    Received fatal alert: bad_certificate

    at sun.security.ssl.Alerts.getSSLException()
  2. Java JSSE
    SSLSocketImpl.startHandshake
    1. sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    2. sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
    3. sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1961)
    4. sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
    5. sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1707)
    6. sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:122)
    7. sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:972)
    8. sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1087)
    9. sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1006)
    10. sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:285)
    11. sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    12. sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    13. sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
    14. sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    15. sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
    16. sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
    16 frames
  3. Java RT
    AbstractDelegateHttpsURLConnection.connect
    1. sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515)
    2. sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    2 frames