Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

chrisvest
Copy link
Member

@chrisvest chrisvest commented Sep 21, 2024

Motivation:
Some trust manager implementations produce custom user principals and store them in the SSLSession. Resumed TLS sessions, however, don't always recover the stored contents. For instance, with TLSv1.3 stateless session resumption, our TLS implementations only store the peer certificate chain (or even just the leaf cert) in the session ticket. In such a case, the trust manager would like to be notified of the resumption, so that the peer principal can be recreated and stored in the session once again.

Modification:
Add a ResumableX509ExtendedTrustManager interface, with callbacks for resumed client and server sessions. Add infrastructure (the ResumptionController) to detect session resumption in an SSLEngine implementation agnostic way; if a TLS handshake completed without any calls to the TrustManager, then we've made a "stateless resumption" (hand-wave details) and should call the appropriate resume method. The JDK APIs don't provide a method to reliably discern if a session has been resumed, so we instead detect if the trust manager was called during the handshake. We do this by wrapping user-supplied trust managers that implement the ResumableX509ExtendedTrustManager interface. The wrapper will monitor calls to the trust manager and register the relevant SSLEngine in the controller — the engine is the object that the trust manager and the SslHandler both have access to, which reliably identifies the specific TLS session. Before finished the handshake, the SslHandler queries the ResumptionController to see if the trust manager has already been called, or if it needs to be notified of resumption. Since it's possible that the peer certificates have expired since the initial session, the trust manager gets another change to throw CertificateException.

Result:
Handlers that expect to find user principals in the authenticated SSLSessions no longer find empty sessions, provided they use a trust manager that correctly implements ResumableX509ExtendedTrustManager.

This is a draft to gage if the general approach is sane. There's still a few things that need to be done:

  • Javadocs.
  • Tests where the resume* methods throw CertificateException.
  • Tests for different transports.
  • Tests that use TCP FastOpen.
  • Tests that use startTls.

@chrisvest chrisvest force-pushed the 4.1-resumable-tm branch 2 times, most recently from 7265063 to 0321af9 Compare September 21, 2024 16:30
@chrisvest chrisvest force-pushed the 4.1-resumable-tm branch 2 times, most recently from 0e7cd81 to 46c8336 Compare September 21, 2024 17:57
@chrisvest chrisvest force-pushed the 4.1-resumable-tm branch 3 times, most recently from cd3b1fb to 44e1c7d Compare September 22, 2024 01:05
@chrisvest
Copy link
Member Author

Looks like Conscrypt on Windows is broken somehow.

Copy link
Member

@normanmaurer normanmaurer left a comment

Choose a reason for hiding this comment

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

Great idea!

@chrisvest chrisvest force-pushed the 4.1-resumable-tm branch 3 times, most recently from 5cfbf40 to 6343606 Compare September 23, 2024 22:01
@chrisvest chrisvest force-pushed the 4.1-resumable-tm branch 2 times, most recently from 0200c43 to bff04aa Compare September 24, 2024 23:32
@chrisvest chrisvest marked this pull request as ready for review September 24, 2024 23:33
Motivation:
Some trust manager implementations produce custom user principals and store them in the SSLSession.
Resumed TLS sessions, however, don't always recover the stored contents.
For instance, with TLSv1.3 stateless session resumption, our TLS implementations only store the peer certificate chain (or even just the leaf cert) in the session ticket.
In such a case, the trust manager would like to be notified of the resumption, so that the peer principal can be recreated and stored in the session once again.

Modification:
Add a `ResumableX509ExtendedTrustManager` interface, with callbacks for resumed client and server sessions.
Add infrastructure (the `ResumptionController`) to detect session resumption in an SSLEngine implementation agnostic way; if a TLS handshake completed without any calls to the TrustManager, then we've made a "stateless resumption" (hand-wave details) and should call the appropriate resume method.
The JDK APIs don't provide a method to reliably discern if a session has been resumed, so we instead detect if the trust manager was called during the handshake.
We do this by wrapping user-supplied trust managers that implement the `ResumableX509ExtendedTrustManager` interface.
The wrapper will monitor calls to the trust manager and register the relevant `SSLEngine` in the controller — the engine is the object that the trust manager and the `SslHandler` both have access to, which reliably identifies the specific TLS session.
Before finished the handshake, the `SslHandler` queries the `ResumptionController` to see if the trust manager has already been called, or if it needs to be notified of resumption.
Since it's possible that the peer certificates have expired since the initial session, the trust manager gets another change to throw CertificateException.

Result:
Handlers that expect to find user principals in the authenticated SSLSessions no longer find empty sessions, provided they use a trust manager that correctly implements ResumableX509ExtendedTrustManager.
@chrisvest
Copy link
Member Author

@normanmaurer I think this is good to go, assuming the tests are no longer flaky.

…ionReuseTest.testSslSessionTrustManagerResumption
Copy link
Member

@normanmaurer normanmaurer left a comment

Choose a reason for hiding this comment

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

Almost there...

@normanmaurer
Copy link
Member

Great work... Ship it!

@chrisvest chrisvest added this to the 4.1.114.Final milestone Sep 26, 2024
@chrisvest
Copy link
Member Author

The Java 11 Graal build failure is caused by #14375.

The Java 11 BoringSSL build fails with an OOME in the HTTP/2 module at io.netty.handler.codec.http2.HpackDynamicTable.setCapacity(HpackDynamicTable.java:182), and I'm not immediately convinced it's related to these changes.

@chrisvest chrisvest merged commit 3f66dd2 into netty:4.1 Sep 27, 2024
15 of 17 checks passed
@chrisvest chrisvest deleted the 4.1-resumable-tm branch September 27, 2024 02:33
@chrisvest
Copy link
Member Author

Will do the forward merge tomorrow

chrisvest added a commit to chrisvest/netty that referenced this pull request Oct 18, 2024
chrisvest added a commit that referenced this pull request Oct 23, 2024
Motivation:
Some trust manager implementations produce custom user principals and
store them in the SSLSession. Resumed TLS sessions, however, don't
always recover the stored contents. For instance, with TLSv1.3 stateless
session resumption, our TLS implementations only store the peer
certificate chain (or even just the leaf cert) in the session ticket. In
such a case, the trust manager would like to be notified of the
resumption, so that the peer principal can be recreated and stored in
the session once again.

Modification:
Add a ResumableX509ExtendedTrustManager interface, with callbacks for
resumed client and server sessions. Add infrastructure (the
ResumptionController) to detect session resumption in an SSLEngine
implementation agnostic way; if a TLS handshake completed without any
calls to the TrustManager, then we've made a "stateless resumption"
(hand-wave details) and should call the appropriate resume method. The
JDK APIs don't provide a method to reliably discern if a session has
been resumed, so we instead detect if the trust manager was called
during the handshake. We do this by wrapping user-supplied trust
managers that implement the ResumableX509ExtendedTrustManager interface.
The wrapper will monitor calls to the trust manager and register the
relevant SSLEngine in the controller — the engine is the object that the
trust manager and the SslHandler both have access to, which reliably
identifies the specific TLS session. Before finished the handshake, the
SslHandler queries the ResumptionController to see if the trust manager
has already been called, or if it needs to be notified of resumption.
Since it's possible that the peer certificates have expired since the
initial session, the trust manager gets another change to throw
CertificateException.

Result:
Handlers that expect to find user principals in the authenticated
SSLSessions no longer find empty sessions, provided they use a trust
manager that correctly implements ResumableX509ExtendedTrustManager.

This is a forward port of #14358,
#14404, and
#14411
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.

2 participants