ring-clojure/ring

Ring Jetty + ssl-context issue

Closed this issue · 6 comments

Hello,

In #412, I added support for the :ssl-context option to the ring jetty adapter. Now, I'm trying to use this option again and I cannot make TLS work.

How to reproduce

  • Create a new lein project with ring as dependency
  • Add in the core.clj file:
(defn- hello-world [request]
  {:status  200
   :headers {"Content-Type" "text/plain"}
   :body    "Hello World"})

(defn ssl-context
  []
  (less-ssl/ssl-context "/home/mathieu/prog/clojure/ring/ring-jetty-adapter/test/server.key"
                        "/home/mathieu/prog/clojure/ring/ring-jetty-adapter/test/server.crt"
                        "/home/mathieu/prog/clojure/ring/ring-jetty-adapter/test/server.crt"))

(defn config
  []
  {:client-auth :want,
   :ssl-context (ssl-context)
   :port 10102,
   :ssl? true,
   :join? false,
   :ssl-port 3001})

Then run (def s (jetty/run-jetty hello-world (config)).

This is what happens when I try to curl my endpoint:

curl --cacert server.crt --key server.key --cert server.crt https://localhost:3001
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

I see on the JVM side (with :jvm-opts ["-Djavax.net.debug=ssl"] in my project.clj):


                
javax.net.ssl|DEBUG|10|nREPL-session-62c7efc6-c3d2-40d3-85c5-8f5b90962930|2020-11-20 22:22:25.296 CET|SSLCipher.java:438|jdk.tls.keyLimits:  entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953472
2020-11-20 22:22:25.362:INFO:oejs.Server:nREPL-session-62c7efc6-c3d2-40d3-85c5-8f5b90962930: jetty-9.4.31.v20200723; built: 2020-07-23T17:57:36.812Z; git: 450ba27947e13e66baa8cd1ce7e85a4461cacc1d; jvm 11.0.8+10-post-Debian-1deb10u1
2020-11-20 22:22:25.398:INFO:oejs.AbstractConnector:nREPL-session-62c7efc6-c3d2-40d3-85c5-8f5b90962930: Started ServerConnector@6fb5f3a7{HTTP/1.1, (http/1.1)}{0.0.0.0:10102}
2020-11-20 22:22:25.470:INFO:oejs.AbstractConnector:nREPL-session-62c7efc6-c3d2-40d3-85c5-8f5b90962930: Started ServerConnector@61faad72{SSL, (ssl, http/1.1)}{0.0.0.0:3001}
2020-11-20 22:22:25.471:INFO:oejs.Server:nREPL-session-62c7efc6-c3d2-40d3-85c5-8f5b90962930: Started @26029ms
#'testing.core/sjavax.net.ssl|DEBUG|21|qtp1574150222-33|2020-11-20 22:23:21.730 CET|SSLCipher.java:1840|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|21|qtp1574150222-33|2020-11-20 22:23:21.732 CET|SSLCipher.java:1994|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.735 CET|X509Authentication.java:264|No X.509 cert selected for EC
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.735 CET|X509Authentication.java:264|No X.509 cert selected for EC
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.736 CET|X509Authentication.java:264|No X.509 cert selected for EC
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.736 CET|X509Authentication.java:264|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.736 CET|X509Authentication.java:264|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.737 CET|X509Authentication.java:264|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.738 CET|X509Authentication.java:264|No X.509 cert selected for RSA
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.739 CET|X509Authentication.java:264|No X.509 cert selected for RSA
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.739 CET|X509Authentication.java:264|No X.509 cert selected for RSA
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.739 CET|X509Authentication.java:264|No X.509 cert selected for RSA
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.740 CET|X509Authentication.java:264|No X.509 cert selected for RSA
javax.net.ssl|ALL|21|qtp1574150222-33|2020-11-20 22:23:21.740 CET|X509Authentication.java:264|No X.509 cert selected for RSA
javax.net.ssl|ERROR|21|qtp1574150222-33|2020-11-20 22:23:21.742 CET|TransportContext.java:318|Fatal (HANDSHAKE_FAILURE): No available authentication scheme (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: No available authentication scheme
  	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
  	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
  	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:313)
  	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:269)
  	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:260)
  	at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.onProduceCertificate(CertificateMessage.java:955)
  	at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.produce(CertificateMessage.java:944)
  	at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
  	at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1234)
  	at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1170)
  	at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:852)
  	at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)
  	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
  	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
  	at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1074)
  	at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)
  	at java.base/java.security.AccessController.doPrivileged(Native Method)
  	at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1008)
  	at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.fill(SslConnection.java:639)
  	at org.eclipse.jetty.server.HttpConnection.fillRequestBuffer(HttpConnection.java:336)
  	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:254)
  	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
  	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
  	at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:540)
  	at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:395)
  	at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:161)
  	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
  	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
  	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
  	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
  	at java.base/java.lang.Thread.run(Thread.java:834)}

)
javax.net.ssl|WARNING|21|qtp1574150222-33|2020-11-20 22:23:21.745 CET|SSLEngineOutputRecord.java:168|outbound has closed, ignore outbound application data
javax.net.ssl|WARNING|21|qtp1574150222-33|2020-11-20 22:23:21.746 CET|SSLEngineOutputRecord.java:168|outbound has closed, ignore outbound application data
javax.net.ssl|WARNING|21|qtp1574150222-33|2020-11-20 22:23:21.747 CET|SSLEngineOutputRecord.java:168|outbound has closed, ignore outbound application data
javax.net.ssl|WARNING|21|qtp1574150222-33|2020-11-20 22:23:21.758 CET|SSLEngineOutputRecord.java:168|outbound has closed, ignore outbound application data

it works on the ring repository

The exact same code works on the ring project. I've started a REPL in the ring-jetty-adapter project, copied the previous code in a new file, started jetty, and now curl works:

curl --cacert server.crt --key server.key --cert server.crt https://localhost:3001 --insecure
Hello World

I use insecure because the certs are expired, but at least it works.

Also, I've added in the PR I did to add the option a lot of tests and they are all passing.

What I tried

  • lein clean
  • removed all my .m2
  • reproduced with another computer
  • tried several clojure versions, tried to file dependencies issues etc...
  • tried to force TLS1.2, TLS1.3... both on the server or on the client. For example, if I add --tlsv1.2 --tls-max 1.2 to my curl request to the faulty server, I get in the logs:
javax.net.ssl|ERROR|22|qtp711777198-34|2020-11-20 22:36:31.094 CET|TransportContext.java:318|Fatal (HANDSHAKE_FAILURE): no cipher suites in common (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: no cipher suites in common
  • I also tried to force ciphers.

The issue should be somehow related to the Jetty TLS configuration (version, cipher), but it works on the ring-jetty-adapter project and I cannot understand why. Maybe I'm doing something wrong (it's probably the case) but I cannot find differences between my code and the jetty project code.

Create a new lein project with ring as dependency

Have you created your own Ring deps based off master?

Have you created your own Ring deps based off master?

Thanks, I know what is the issue now.

I thought 1.8.2 was including my commit (because it was merged before the tag) but it seems 1.8.2 only contains commit 7a3768d6f943bc7507e28bd2b0760f09ae7600f5, which is Update Jetty version to 9.4.31 (fixes #411). If I use lein install on master it indeed works.

Is it expected to only have one commit between 1.8.1 and 1.8.2 ?

1.8.2 is a patch release, which means it only contains fixes, not any new features. Ring 1.9.0 will contain your patch, but it's not released yet. There's probably enough changes now in the pipeline for a 1.9 release, so I'll see about getting it released this month.

Thank you for your answer, I'm closing this issue.

Hi, I'm also hoping to make use of this ssl-context feature--do you have any sense of when Ring 1.9.0 might be released?

Hi, I'm also hoping to make use of this ssl-context feature--do you have any sense of when Ring 1.9.0 might be released?

Ring 1.9.0 has now been released.