I have a need to use a self-signed (or unsigned) certificate as a certificate for an HTTPS listener for an inbound endpoint to one of my flows. I have tried several methods to generate certificates, but I always get an error when the listener attempts to read a request:
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
Google seems to think that the bad_certificate
message has something to do with the trust store. I continue to see the same error with or without the mule tls-server
configuration which is supposed to define the trust store.
I've used several different mechanisms to create the certificate:
- The method using keytool in the mule documentation for the HTTPS Transport
- A method described for weblogic, using keytool
- A method described for Apache, using openssl, which I then imported into a java keystore using keytool
- A variety of other mechanisms that are mostly variations of the above.
I have tried both with and without the tls-server
and tls-client
elements configured, all as described in the mule documentation.
I am at my wit's end trying to determine what key types are acceptable to Mule, and what the root cause of the issue is. Any advise is appreciated.
My configurations and error logs follow (omitting various boilerplate content)
mule-config.xml
<https:connector name="connectorName">
<!-- only one key, alias 'mule' -->
<https:tls-key-store path="/opt/mule/keys/keystore.jks" keyPassword="thePassword" storePassword="thePassword"/>
<!-- I've also tried the following, same error occurs both with or without this parameter -->
<https:tls-server path="/opt/mule/keys/keystore.jks storePassword="thePassword"/>
</https:connector>
<flow name="theFlow">
<https:inbound-endpoint host="0.0.0.0" port="8081" connector-ref="connectorName"/>
<!-- stuff: not important, works with http -->
</flow>
This configuration loads correctly, but then when I attempt to post a request using the same method that works with HTTP (but using https:// instead) I get the following error, and no response back (not a 500 error, or anything, connection is just closed). This specific run is from the key I generated using the instructions on the mulesoft documentation for HTTPS Transport, but it is not any different from the error I get using any other method.
Error Listing
[ERROR] org.mule.exception.DefaultSystemExceptionStrategy - Caught exception in Exception Strategy: Received fatal alert: bad_certificate
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1571)
at com.sun.net.ssl.internal.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:103)
at com.sun.net.ssl.internal.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:689)
at com.sun.net.ssl.internal.ssl.ServerHandshaker.sendChangeCipherAndFinish(ServerHandshaker.java:1279)
at com.sun.net.ssl.internal.ssl.ServerHandshaker.clientFinished(ServerHandshaker.java:1239)
at com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:225)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:943)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:818)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:50)
at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
at org.mule.transport.http.HttpServerConnection.readLine(HttpServerConnection.java:219)
at org.mule.transport.http.HttpServerConnection.readRequest(HttpServerConnection.java:185)
at org.mule.transport.http.HttpMessageReceiver$HttpWorker.run(HttpMessageReceiver.java:155)
at org.mule.work.WorkerContext.run(WorkerContext.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Finally, thanks for your time reading this far.
UPDATE
I've started to get a different stack trace, but the same error. The change? The key and the keystore now have different passwords.
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:820)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:50)
at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
at org.mule.transport.http.HttpServerConnection.readLine(HttpServerConnection.java:219)
at org.mule.transport.http.HttpServerConnection.readRequest(HttpServerConnection.java:185)
at org.mule.transport.http.HttpMessageReceiver$HttpWorker.run(HttpMessageReceiver.java:155)
at org.mule.work.WorkerContext.run(WorkerContext.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
UPDATE 2
I added the key to the .../jre/lib/security/cacerts file as a trusted certificate. No change.