-
-
Notifications
You must be signed in to change notification settings - Fork 16.2k
Fix SSL session resumption with ClientAuth.OPTIONAL and add tests with session tickets #14404
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
Conversation
Motivation: It's a valid configuration to enable session tickets with TLSv1.2, and doing so makes a meaningful change to the SSLEngine behavior that we need to test for. Modification: - Collect the OpenSSL parameterization code for SSLEngineTest. - Add tickets being enabled or not as a parameter. - Fix a test that did not anticipate the session ticket behavior. Result: We now have test coverage with TLSv1.2 session tickets.
Motivation: If TLS is `OPTIONAL` then there won't always be a verified peer. This means there will be no calls on the server `TrustManager` to check if the client is trusted. That makes it look like a resumed session to the resumption controller. But there won't be any verified peer on the session, and trying to get the peer certificates will throw an exception. Modification: - Make the `ResumptionController` consider if the engine is in client mode, or if it requires client authentication, and only propagate `SSLPeerUnverifiedException` if so. - Make the `ResumptionController` swallow the `SSLPeerUnverifiedException` when client auth is OPTIONAL or NONE. - Add a test for this scenario. Result: The `ResumableX509ExtendedTrustManager` interface can now be used together with `ClientAuth.OPTIONAL`.
3c6b8bf
to
12d973b
Compare
12d973b
to
4ce9964
Compare
This reverts commit 4ce9964.
The extra testing makes the builds slower, particularly the BoringSSL builds, but that should be more than compensated for by #14405 |
|
||
SSLSession session = engine.getSession(); | ||
boolean valid = session.isValid(); | ||
if (valid && (engine.getUseClientMode() || engine.getNeedClientAuth() || engine.getWantClientAuth()) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a comment clarifying the goal of this conditional?
getUseClientMode
-> I assume this is to cover the case of "always do this on the client"
getNeedClientAuth || getWantClientAuth
-> isn't the default treated by some engines as "want"? for example iirc openssl flavors will have the server request the client's certificate but if they don't return one it will succeed. so I'm just trying to understand if client/server need to be consistent and if not, why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Scottmitch I've added comments explaining the logic. Please take a look.
…h session tickets (#14404) Motivation: If TLS is `OPTIONAL` then there won't always be a verified peer. This means there will be no calls on the server `TrustManager` to check if the client is trusted. That makes it look like a resumed session to the resumption controller. But there won't be any verified peer on the session, and trying to get the peer certificates will throw an exception. It's also a valid configuration to enable session tickets with TLSv1.2, and doing so makes a meaningful change to the `SSLEngine` behavior that we need to test for. Modification: - Collect the OpenSSL parameterization code for `SSLEngineTest`. - Add tickets being enabled or not as a parameter. - Fix a test that did not anticipate the session ticket behavior. - Make the `ResumptionController` consider if the engine is in client mode, or if it requires client authentication, and only propagate `SSLPeerUnverifiedException` if so. - Make the `ResumptionController` swallow the `SSLPeerUnverifiedException` when client auth is OPTIONAL or NONE. - Add a test for this scenario. Result: We now have test coverage with TLSv1.2 session tickets. The `ResumableX509ExtendedTrustManager` interface can now be used together with `ClientAuth.OPTIONAL`.
…h session tickets (netty#14404) Motivation: If TLS is `OPTIONAL` then there won't always be a verified peer. This means there will be no calls on the server `TrustManager` to check if the client is trusted. That makes it look like a resumed session to the resumption controller. But there won't be any verified peer on the session, and trying to get the peer certificates will throw an exception. It's also a valid configuration to enable session tickets with TLSv1.2, and doing so makes a meaningful change to the `SSLEngine` behavior that we need to test for. Modification: - Collect the OpenSSL parameterization code for `SSLEngineTest`. - Add tickets being enabled or not as a parameter. - Fix a test that did not anticipate the session ticket behavior. - Make the `ResumptionController` consider if the engine is in client mode, or if it requires client authentication, and only propagate `SSLPeerUnverifiedException` if so. - Make the `ResumptionController` swallow the `SSLPeerUnverifiedException` when client auth is OPTIONAL or NONE. - Add a test for this scenario. Result: We now have test coverage with TLSv1.2 session tickets. The `ResumableX509ExtendedTrustManager` interface can now be used together with `ClientAuth.OPTIONAL`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Late LGTM
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
Motivation:
If TLS is
OPTIONAL
then there won't always be a verified peer.This means there will be no calls on the server
TrustManager
to check if the client is trusted.That makes it look like a resumed session to the resumption controller.
But there won't be any verified peer on the session, and trying to get the peer certificates will throw an exception.
It's also a valid configuration to enable session tickets with TLSv1.2, and doing so makes a meaningful change to the
SSLEngine
behavior that we need to test for.Modification:
SSLEngineTest
.ResumptionController
consider if the engine is in client mode, or if it requires client authentication, and only propagateSSLPeerUnverifiedException
if so.ResumptionController
swallow theSSLPeerUnverifiedException
when client auth is OPTIONAL or NONE.Result:
We now have test coverage with TLSv1.2 session tickets.
The
ResumableX509ExtendedTrustManager
interface can now be used together withClientAuth.OPTIONAL
.