0
votes

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:

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.

2

2 Answers

1
votes

The method for creating a self-signed certificate shown in the Mule doc works: I've used it several times. I tried it again and it works with your configuration, except that I removed https:tls-server, which is useless.

Here are the steps I followed:

  • Create the keystore with: keytool -genkey -alias mule -keyalg RSA -keystore keystore.jks (I used "thePassword" for both the keystore and the key passwords).
  • Configured Mule like this:

    <https:connector name="connectorName">
        <https:tls-key-store
            path="...path.../keystore.jks"
            keyPassword="thePassword" storePassword="thePassword" />
    </https:connector>
    
    <flow name="theFlow">
        <https:inbound-endpoint host="0.0.0.0" port="8081"
            connector-ref="connectorName" />
        <set-payload value="w00t" />
    </flow>
    
  • Tested with:

    $ curl -vk https://localhost:8081
    * About to connect() to localhost port 8081 (#0)
    *   Trying 127.0.0.1... connected
    * successfully set certificate verify locations:
    *   CAfile: none
      CApath: /etc/ssl/certs
    * SSLv3, TLS handshake, Client hello (1):
    * SSLv3, TLS handshake, Server hello (2):
    * SSLv3, TLS handshake, CERT (11):
    * SSLv3, TLS handshake, Server key exchange (12):
    * SSLv3, TLS handshake, Server finished (14):
    * SSLv3, TLS handshake, Client key exchange (16):
    * SSLv3, TLS change cipher, Client hello (1):
    * SSLv3, TLS handshake, Finished (20):
    * SSLv3, TLS change cipher, Client hello (1):
    * SSLv3, TLS handshake, Finished (20):
    * SSL connection using ECDHE-RSA-AES256-SHA
    * Server certificate:
    *    subject: C=Unknown; ST=Unknown; L=Unknown; O=Unknown; OU=Unknown; CN=Unknown
    *    start date: 2013-05-15 18:20:34 GMT
    *    expire date: 2013-08-13 18:20:34 GMT
    *    common name: Unknown (does not match 'localhost')
    *    issuer: C=Unknown; ST=Unknown; L=Unknown; O=Unknown; OU=Unknown; CN=Unknown
    *    SSL certificate verify result: self signed certificate (18), continuing anyway.
    > GET / HTTP/1.1
    > User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
    > Host: localhost:8081
    > Accept: */*
    > 
    < HTTP/1.1 200 OK
    < Date: Wed, 15 May 2013 11:24:24 -0700
    < Server: Mule Core/3.4.0
    < X-MULE_SESSION: rO0ABXNyACNvcmcubXVsZS5zZXNzaW9uLkRlZmF1bHRNdWxlU2Vzc2lvbi7rdtEW7GGKAwAEWgAFdmFsaWRMAA1mbG93Q29uc3RydWN0dAAmTG9yZy9tdWxlL2FwaS9jb25zdHJ1Y3QvRmxvd0NvbnN0cnVjdDtMAAJpZHQAEkxqYXZhL2xhbmcvU3RyaW5nO0wAD3NlY3VyaXR5Q29udGV4dHQAJ0xvcmcvbXVsZS9hcGkvc2VjdXJpdHkvU2VjdXJpdHlDb250ZXh0O3hwAXB0ACRhYjcwZTY0OS1iZDhjLTExZTItOWU5Yy1mZjdmMDIxMmE5MmZwc3IAJWphdmEudXRpbC5Db2xsZWN0aW9ucyRTeW5jaHJvbml6ZWRNYXAbc/kJS0s5ewMAAkwAAW10AA9MamF2YS91dGlsL01hcDtMAAVtdXRleHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwc3IAJG9yZy5tdWxlLnV0aWwuQ2FzZUluc2Vuc2l0aXZlSGFzaE1hcJ3R2e9nRc4AAwAAeHB3DD9AAAAAAAAQAAAAAHhxAH4ACXh4
    < X-MULE_ENCODING: UTF-8
    < LOCAL_CERTIFICATES: [Ljava.security.cert.X509Certificate;@1c5e22a
    < Content-Type: text/plain
    < Content-Length: 4
    < Connection: close
    < 
    * Closing connection #0
    * SSLv3, TLS alert, Client hello (1):
    w00t
    
0
votes

Hopefully this helps someone else. I'm running Mule EE 3.5.0 with jdk1.6.0_45. The command listed above would not generate a compatible keystore. The keystore was fine when running in studio but would not work on the standalone ESB.

I reviewed the keystore used on the mule-security-example3.5.0 application and found differences. I used KeyStore Explorer to create a keystore that had these attributes

Size: 1024 Version: 1 Alg: MD5 with RSA

Perhaps there is something off with the configuration on my instance of Mule EE; if someone could point me in the right direction I would appreciate it. Using a key with the above attributes will work with EE 3.5.0 which was downloaded from the customer portal this week.