Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly filter out TLSv1.3 ciphers if TLSv1.3 is not enabled #10919

Merged
merged 7 commits into from
Jan 28, 2021

Conversation

normanmaurer
Copy link
Member

Motivation:

We didnt correctly filter out TLSv1.3 ciphers when TLSv1.3 is not enabled.

Modifications:

  • Filter out ciphers that are not supported due the selected TLS version
  • Add unit test

Result:

Fixes #10911

Co-authored-by: Bryce Anderson banderson@twitter.com

Motivation:

We didnt correctly filter out TLSv1.3 ciphers when TLSv1.3 is not enabled.

Modifications:

- Filter out ciphers that are not supported due the selected TLS version
- Add unit test

Result:

Fixes #10911

Co-authored-by: Bryce Anderson <banderson@twitter.com>
@normanmaurer
Copy link
Member Author

@bryce-anderson PTAL again

@bryce-anderson
Copy link
Contributor

For some reason when I pull this and run the tests, I get failures to throw the expected expected SSLHandshakeException in testIncompatibleCiphers.

@bryce-anderson
Copy link
Contributor

For some reason when I pull this and run the tests, I get failures to throw the expected expected SSLHandshakeException in testIncompatibleCiphers.

It looks like I'm getting TLSv1.1 with the TLS_RSA_WITH_AES_128_CBC_SHA suite negotiated. It seems that the client, since it had no TLSv1.(not 3) ciphers set enabled all of the tlsv1.(not 3) suites.

@normanmaurer
Copy link
Member Author

@bryce-anderson you have a unit test that shows this ?

@bryce-anderson
Copy link
Contributor

bryce-anderson commented Jan 21, 2021

@bryce-anderson you have a unit test that shows this ?

@normanmaurer, yes, see here: bryce-anderson@117607c

@normanmaurer
Copy link
Member Author

@bryce-anderson what java version / netty-tcnative version ? Also is this with BoringSSL or not ?

@bryce-anderson
Copy link
Contributor

@bryce-anderson what java version / netty-tcnative version ? Also is this with BoringSSL or not ?

I have used both what is in the maven project description by default and switch to boringssl-static

io.netty:netty-tcnative:jar:osx-x86_64:2.0.35.Final
// or
io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64:2.0.35.Final:compile

and they give the same result. Same with jdk8 and jdk11:

openjdk version "11.0.7.0.5" 2020-04-14
// or
openjdk version "1.8.0_242"

Fwiw, this is the behavior I'd expect: we didn't implicitly disable the TLSv1.(x<3) ciphers if the set is empty which I believe then defaults to all ciphers being available.
If you apply this patch I get the tests to pass but I'm not sure it's correct and maybe we need to disable SSLv[2|3] as well:

--- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java
+++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java
@@ -1549,7 +1549,12 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
             if (!isDestroyed()) {
                 try {
                     // Set non TLSv1.3 ciphers.
-                    SSL.setCipherSuites(ssl, cipherSuiteSpec, false);
+                    if (cipherSuiteSpec.isEmpty()) {
+                        SSL.setOptions(ssl, SSL.getOptions(ssl) | SSL.SSL_OP_NO_TLSv1_2 |
+                            SSL.SSL_OP_NO_TLSv1_1 | SSL.SSL_OP_NO_TLSv1);
+                    } else {
+                        SSL.setCipherSuites(ssl, cipherSuiteSpec, false);
+                    }

                     if (OpenSsl.isTlsv13Supported()) {
                         if (cipherSuiteSpecTLSv13.isEmpty()) {

@normanmaurer
Copy link
Member Author

super strange the it passes here without your change... hmmm.

@bryce-anderson
Copy link
Contributor

super strange the it passes here without your change... hmmm.

Agreed.

@bryce-anderson
Copy link
Contributor

@normanmaurer, let me know if there is anything you need from me on this.

@normanmaurer
Copy link
Member Author

@bryce-anderson will do... I just didn't have time yet to check

@normanmaurer
Copy link
Member Author

@bryce-anderson PTAL and verify :)

Copy link
Contributor

@bryce-anderson bryce-anderson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @normanmaurer!

@normanmaurer
Copy link
Member Author

@bryce-anderson so all work now on your side ?

@bryce-anderson
Copy link
Contributor

@normanmaurer, I haven't deployed and tested it but as far as I can tell it should fix our problem. If something else comes up I'll file another ticket.

@normanmaurer
Copy link
Member Author

@slandelle @chrisvest thoughts ?

@normanmaurer normanmaurer merged commit df10dfb into 4.1 Jan 28, 2021
@normanmaurer normanmaurer deleted the ciphers branch January 28, 2021 10:00
normanmaurer added a commit that referenced this pull request Jan 28, 2021
Motivation:

We didnt correctly filter out TLSv1.3 ciphers when TLSv1.3 is not enabled.

Modifications:

- Filter out ciphers that are not supported due the selected TLS version
- Add unit test

Result:

Fixes #10911

Co-authored-by: Bryce Anderson <banderson@twitter.com>
Copy link
Member

@idelpivnitskiy idelpivnitskiy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change LGTM, one nit related to intermediate collections size, but I'm not sure if it really matters because it's not on the hot path:

if (OpenSsl.isTlsv13Supported()) {
// Set TLSv1.3 ciphers.
SSL.setCipherSuites(ssl, cipherSuiteSpecTLSv13, true);
}

// We also need to update the enabled protocols to ensure we disable the protocol if there are
// no compatible ciphers left.
Set<String> protocols = new HashSet<String>(explicitlyEnabledProtocols.length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default load factor for HashSet is 0.75. Using explicitlyEnabledProtocols.length will cause resize of the internal hash table when the next line adds all explicitlyEnabledProtocols.
The following formula should be used: (int) (c.size()/.75f) + 1. Or use new HasSet(Arrays.asList(explicitlyEnabledProtocols)).

The similar situation may happen for line 1522:

Set<String> enabledSet = new LinkedHashSet<String>(enabled.length + extraCiphers.length);

If all ciphers will be added, it will cause resize of the internal hash table.

raidyue pushed a commit to raidyue/netty that referenced this pull request Jul 8, 2022
…#10919)


Motivation:

We didnt correctly filter out TLSv1.3 ciphers when TLSv1.3 is not enabled.

Modifications:

- Filter out ciphers that are not supported due the selected TLS version
- Add unit test

Result:

Fixes netty#10911

Co-authored-by: Bryce Anderson <banderson@twitter.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Broken SslEngine [set|get]EnabledCipherSuites behavior
4 participants