-
-
Notifications
You must be signed in to change notification settings - Fork 203
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
Support RFC 5077 TLS session ticket reuse #166
base: master
Are you sure you want to change the base?
Conversation
See https://github.com/sfackler/hyper-openssl/blob/master/src/lib.rs for how to have a more robust cache with OpenSSL. |
Using the domain provided for hostname verification seems like it's not a fully accurate identifier - it doesn't account for multiple servers running on the same host, for example. |
RFC 5077 presents an approach to stateless resumption though, so it should be possible to resume a TLS session initiated on a different server as long as both machines have access to the same session key used to encrypt the session. Thanks for the pointer for OpenSSL. I'll take a look and make some changes. |
Not sure what's going on here with the Windows CI, it works for me locally on Windows 10. Maybe the OS version is too old? According to the Appveyor docs on the build environment,
Which should correspond to Microsoft docs indicate that RFC 5077 was implemented starting in Windows 8, which should include Windows Server 2012 R2 as well. |
I am talking about the standard case where the servers would not share a cache. |
RFC 5077 only requires that servers share a secret that they can all use to encrypt/decrypt the tickets. For example, Cloudflare wrote up how they do this in a portion of this tangentially related blog post. Arguably, implementations of RFC 5077 that do not share a secret across servers are incorrect, as they would not satisfy the usecases described in that RFC:
|
Yes, I am aware that is is possible for servers to share cached sessions. I am saying that if |
I agree that that is a possible failure case, but it seems relatively unlikely in standard usage, and IMO, the failure mode would be rather harmless:
Given that this is a bit of an edge case and the failure mode is reasonable, I think it should be fine to leave the behavior as is. Open to suggestions on how to resolve it as well, but AFAIK we don't have the relevant information at this abstraction level, since port is only really relevant at TCP connection time. |
8245c59
to
1fd8a7c
Compare
Updated the OpenSSL implementation (mostly just inlining the logic from Also pinned the Appveyor image used to Not sure why it's failing still. I'll try to run the tests on Windows 8.1 locally and see if that can repro. EDIT: Tests also pass for me on Windows 8.1 locally. I don't have any Windows Server installations around to test there, but I don't know why it would produce different results. |
src/imp/security_framework.rs
Outdated
@@ -7,6 +7,7 @@ use self::security_framework::base; | |||
use self::security_framework::certificate::SecCertificate; | |||
use self::security_framework::identity::SecIdentity; | |||
use self::security_framework::import_export::{ImportedIdentity, Pkcs12ImportOptions}; | |||
use self::security_framework::os::macos::import_export::Pkcs12ImportOptionsExt; | |||
use self::security_framework::secure_transport::{ | |||
self, ClientBuilder, SslConnectionType, SslContext, SslProtocol, SslProtocolSide, | |||
}; |
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.
Doesn't set_peer_id need to be called here?
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.
It's called internally in https://github.com/kornelski/rust-security-framework/pull/95/files#diff-0c189053dd842cb8ae78ca32925584a8R1359, since we're using the ClientBuilder
rather than manually building an SslContext
(which is the one that has a set_peer_id
method).
I think I'd be more comfortable if we separated the domain used for hostname verification from the ID used to cache sessions. I'm imagining a new API that let you configure individual connection attempts like the SslConnector::configure method in rust-openssl: https://docs.rs/openssl/0.10.29/openssl/ssl/struct.SslConnector.html#method.configure. For now it would just have |
Also, I'm not sure the naming here should specifically refer to "tickets", since that would refer specifically to one of the two methods TLS provides for session resumption. |
That's fair. I believe Security Framework's
The changes here are only meant to support client-side stateless TLS resumption. I haven't looked into server-side TLS resumption much, but I had thought that it was implicitly taken care of by each TLS implementation. |
At least in OpenSSL, the mode of session resumption doesn't affect the API in any significant way. In both cases, the client needs to send something it has saved to the server in the ClientHello. |
Rebased onto current master. Also added a fix for caching the session on Windows, where the session wasn't properly stored if there were underlying async connection abstractions being used. What can I do to get this across the finish line? For your comment about |
Adds an option to enable RFC 5077 TLS session ticket reuse, and implementations for all backends.
set_session_cache_mode
,set_new_session_callback
,set_remove_session_callback
, andset_session
to store just the previous session that was negotiated. It doesn't look like there's a way to store any more than that, as OpenSSL doesn't pass any information about domain/host to the callbacks.SchannelCred
, with an expiration of 10 minutes.Also added implementation-specific unit tests for OpenSSL and Schannel. A platform-agnostic one isn't really possible because macOS doesn't expose any way of determining of the stream was successfully resumed, and we're not at a low enough abstraction level to look at the handshake process itself.