Skip to content

Conversation

@kares
Copy link
Contributor

@kares kares commented Jun 23, 2022

Description

This PR is JRuby specific and follows up on TLS 1.3 support.
To control protocol selection Puma only has no_tlsv1 and no_tlsv1_1, these are insufficient when fine grained control is needed (e.g. only enable 1.3).

I've decided to add MiniSSL::Context#protocols which accepts an array or a "," delimited string (a similar logic existed for setting the cipher suites and has been moved to .rb from the native Java bits).
Setting Context#protocols explicitly takes precedence over the previously existing no_tlsv1_1 ways.

The MiniSSL::Context properties all follow the underlying Java conventions thus also went ahead and "renamed" ssl_cipher_list to cipher_suites in a non-breaking way.

Your checklist for this pull request

  • I have reviewed the guidelines for contributing to this repository.
  • I have added (or updated) appropriate tests if this PR fixes a bug or adds a feature.
  • My pull request is 100 lines added/removed or less so that it can be easily reviewed.
  • If this PR doesn't need tests (docs change), I added [ci skip] to the title of the PR.
  • If this closes any issues, I have added "Closes #issue" to the PR description or my commit messages.
  • I have updated the documentation accordingly.
  • All new and existing tests passed, including Rubocop.

kares added 2 commits June 22, 2022 18:02
follow Java naming as we already do with keystore/truststore ...

Context now does the string split and accepts an Array
@kares kares marked this pull request as ready for review June 23, 2022 06:55
@MSP-Greg
Copy link
Member

@kares

Thanks for the PR. Not sure about JRuby's OpenSSL implementation, but with MRI OpenSSL, there are two cipher functions, one to set ciphers for TLSv1.2 and below (SSL_CTX_set_cipher_list), and one specific to TLSv1.3 (SSL_CTX_set_ciphersuites).

Re TLSv1.3, are there systems that are only allowing it as a protocol? I assumed that TLSv1.2 would be considered an 'allowed' protocol for at least a few years. Maybe an incorrect assumption...

@kares
Copy link
Contributor Author

kares commented Jun 24, 2022

Thanks Greg for the review 💜

Not sure about JRuby's OpenSSL implementation, but with MRI OpenSSL, there are two cipher functions, one to set ciphers for TLSv1.2 and below (SSL_CTX_set_cipher_list), and one specific to TLSv1.3 (SSL_CTX_set_ciphersuites).

as noted in the description Puma is already using Java specific concepts to setup MiniSSL on JRuby (keystore, truststore) simply because that is what we have in JDK - using PEM files would need additional work. in that regard I was about to add protocols so I thought about having ssl_cipher_list option aligned with the Java naming.

the 2 functions in OpenSSL are a bit unfortunate esp. the fact that there are 2 also leaked into Ruby OpenSSL APIs. with Java there's one way to set ciphers for both 1.2 and 1.3 - the API has been named setEnabledCipherSuites even before TLSv1.3 existed.

Re TLSv1.3, are there systems that are only allowing it as a protocol? I assumed that TLSv1.2 would be considered an 'allowed' protocol for at least a few years. Maybe an incorrect assumption...

the protocols option is about giving users a choice to configure which TLS versions their server supports, there's a way to do that with OpenSSL as well just the exposed API is less explicit (min_version, max_version, what specific version NOT to enable).

@MSP-Greg
Copy link
Member

@kares

To control protocol selection Puma only has no_tlsv1 and no_tlsv1_1

Long story. no_tlsv1 was added 11-May-2018. Re OpenSSL 1.0.2, the last release was 1.0.2u, on 20-Dec-2019, and it's been out of public support since at least 21-April-2020.

So, I think it's time to add something like tls_min_version and tls_max_version, which will only work with OpenSSL 1.1.1 or later. I've got much of the code done on the MRI side, then realized it would have merge conflicts here.

So, any thoughts re adding that, and might it be an option to using protocols for JRuby?

Note that I'm using the same strings to reference TLS versions as the code here, and it would be easy to assemble a string (or array) like TLSv1.2,TLSv1.3 from the code I have. IOW, use tls_min_version and tls_max_version in the bind string and the DSL code, but use them to set ctx.protocols when using JRuby? I.think.that.made.sense...

@kares
Copy link
Contributor Author

kares commented Jun 28, 2022

So, any thoughts re adding that, and might it be an option to using protocols for JRuby?

I'm fine with protocols as well as having tls_min_version and tls_max_version.
we're exposing the Java engine specifics already e.g. we do not have the same enabled ciphers setting and even those settings use different cipher naming. thus I went with being "aligned" and added protocols. having min/max version setting would be fine as well -> if that is something you guys would prefer to start with it's a start.

One (very edgy) downside of the tls_min_version and tls_max_version approach is that selecting non intervals gets verbose/impossible e.g. you want 1.1 and 1.3 one would need to set OP_NO_TLSv1_2
while with protocols = [ 'TLSv1.1', 'TLSv1.3' ] it's simple.

@MSP-Greg MSP-Greg merged commit e9f09ba into puma:master Jul 4, 2022
JuanitoFatas pushed a commit to JuanitoFatas/puma that referenced this pull request Sep 9, 2022
…2899)

* [jruby] support setting TLS protocols + rename ssl_cipher_list

follow Java naming as we already do with keystore/truststore ...

Context now does the string split and accepts an Array

* [test] cipher_suites and protocols behavior

* [jruby] support new TLS settings in DSL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants