Skip to content

add TLS 1.3 PSK support #2424

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

Closed
wants to merge 45 commits into from

Conversation

elagergren-spideroak
Copy link
Contributor

@elagergren-spideroak elagergren-spideroak commented Apr 10, 2025

This PR adds TLS 1.3 PSK support.

Fixes #174

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
x
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
x
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
x
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
x
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
x
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
x
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
x
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
@djc
Copy link
Member

djc commented Apr 11, 2025

Can you fix up CI? Let's drop the separate examples for now.

@elagergren-spideroak
Copy link
Contributor Author

Can you fix up CI?

Sure thing. I fixed bogo locally, just haven't pushed it yet. For semver should I bump the version in the cargo manifest?

Let's drop the separate examples for now.

👍

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
@elagergren-spideroak
Copy link
Contributor Author

elagergren-spideroak commented Apr 14, 2025

@djc okay, I've verified that bogo passes locally. For some reason runme exits with 0 (on my machine) even when tests fail.

@djc
Copy link
Member

djc commented Apr 16, 2025

I don't think we're in a state where we want to merge semver-incompatible changes. As such:

  • We can't add a HandshakeKind variant right now
  • We can't remove a PeerMisbehaved variant right now (but we can #[deprecate] it and stop emitting it)

Copy link
Member

@djc djc left a comment

Choose a reason for hiding this comment

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

Okay, that is a lot of stuff...

I think this needs a bunch of work to clean it up. There should be a clean commit history (potentially as separate PRs so we can merge some of it sooner). I also think there should be a bunch of refactoring here so that the PSK/resumption code is more isolated from the rest of the handshake.

Comment on lines +170 to +171
preshared_keys: Arc::new(handy::NoPresharedKeys),
psk_kex_modes: vec![PskKexMode::PskWithDhe],
Copy link
Member

Choose a reason for hiding this comment

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

Suggest grouping these in a struct together. Aren't there any interactions between these values in terms of expected behavior?

Comment on lines +117 to +120
/// To help prevent adversaries from discovering identities
/// supported by the server, identity comparisons should be
/// performed in constant time.
fn load_psk(&self, identity: &[u8]) -> Option<Arc<PresharedKey>>;
Copy link
Member

Choose a reason for hiding this comment

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

If we need constant-time here, suggest we change the API so that rustls itself handles the identity comparison.

Copy link
Contributor Author

@elagergren-spideroak elagergren-spideroak Apr 16, 2025

Choose a reason for hiding this comment

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

PSK identities are not secret (they're in the unencrypted portion of the handshake), so a constant time comparison isn't an absolute necessity. However, constant time comparisons help prevent clients from enumerating the identities that the server supports. I originally wanted rustls to handle the identity comparison, but I couldn't come up with a suitable API that still allowed users to implement their own PSK database.

@elagergren-spideroak
Copy link
Contributor Author

I don't think we're in a state where we want to merge semver-incompatible changes. As such:

  • We can't add a HandshakeKind variant right now

This is probably fine since rustls doesn't make any important decisions with HandshakeKind, but if we don't add a new variant then it's unclear which variant we should return when external PSKs are used. HandshakeKind::Resumed is the closest, but external PSKs are different from session resumption. Specifically, you can use an external PSK without ever having previously performed a handshake.

@elagergren-spideroak
Copy link
Contributor Author

Okay, that is a lot of stuff...

I think this needs a bunch of work to clean it up. There should be a clean commit history (potentially as separate PRs so we can merge some of it sooner). I also think there should be a bunch of refactoring here so that the PSK/resumption code is more isolated from the rest of the handshake.

Let me know if you'd like me to roll up the commit history. I typically wait to squash commits before committing so it doesn't disrupt code review.

Let me know which parts you'd like moved to separate PRs, if any. I tried to make this PR as minimal as possible, but some refactoring (particularly of resumption handling) was necessary, otherwise the code would've been terribly difficult to follow, which is unacceptable for security critical code.

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
elagergren-spideroak added a commit to elagergren-spideroak/rustls that referenced this pull request Apr 16, 2025
For rustls#2424

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Copy link

codecov bot commented Apr 16, 2025

Codecov Report

Attention: Patch coverage is 90.00876% with 114 lines in your changes missing coverage. Please review.

Project coverage is 95.62%. Comparing base (47ed0c6) to head (648a025).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
rustls/src/client/tls13.rs 87.68% 49 Missing ⚠️
rustls/src/server/tls13.rs 92.02% 28 Missing ⚠️
rustls/src/crypto/mod.rs 84.76% 16 Missing ⚠️
rustls/src/client/hs.rs 92.89% 12 Missing ⚠️
rustls/src/msgs/base.rs 0.00% 3 Missing ⚠️
rustls/src/client/client_conn.rs 87.50% 2 Missing ⚠️
rustls/src/enums.rs 83.33% 1 Missing ⚠️
rustls/src/error.rs 0.00% 1 Missing ⚠️
rustls/src/msgs/handshake.rs 95.65% 1 Missing ⚠️
rustls/src/tls13/key_schedule.rs 96.29% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2424      +/-   ##
==========================================
- Coverage   95.96%   95.62%   -0.34%     
==========================================
  Files          94       94              
  Lines       22634    23349     +715     
==========================================
+ Hits        21721    22328     +607     
- Misses        913     1021     +108     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

elagergren-spideroak added a commit to elagergren-spideroak/rustls that referenced this pull request Apr 16, 2025
For rustls#2424

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
elagergren-spideroak added a commit to elagergren-spideroak/rustls that referenced this pull request Apr 21, 2025
For rustls#2424

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
elagergren-spideroak added a commit to elagergren-spideroak/rustls that referenced this pull request Apr 21, 2025
For rustls#2424

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
github-merge-queue bot pushed a commit that referenced this pull request Apr 22, 2025
For #2424

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
github-merge-queue bot pushed a commit that referenced this pull request Apr 22, 2025
For #2424

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
@djc
Copy link
Member

djc commented May 5, 2025

I don't think we're in a state where we want to merge semver-incompatible changes. As such:

  • We can't add a HandshakeKind variant right now

This is probably fine since rustls doesn't make any important decisions with HandshakeKind, but if we don't add a new variant then it's unclear which variant we should return when external PSKs are used. HandshakeKind::Resumed is the closest, but external PSKs are different from session resumption. Specifically, you can use an external PSK without ever having previously performed a handshake.

I think using Resumed is probably fine, if you add documentation on the variant that it can be used this way -- and file an issue to make HandshakeKind #[non_exhaustive] in the future.

Let me know if you'd like me to roll up the commit history. I typically wait to squash commits before committing so it doesn't disrupt code review.

Let me know which parts you'd like moved to separate PRs, if any. I tried to make this PR as minimal as possible, but some refactoring (particularly of resumption handling) was necessary, otherwise the code would've been terribly difficult to follow, which is unacceptable for security critical code.

We typically work with smallish commits that each compile and can pass CI (though we don't usually test whether exactly each commit does). I suggest you break this up into smaller pieces, especially by (1) splitting refactoring into separate commits, (2) splitting client from server. Also try to minimize unrelated changes (like renaming secret to psk). We don't usually incrementally review, so keeping all WIP commits around just makes things harder.

This is a pretty large amount of code to review. Maybe your organization could consider sponsoring the integration effort?

@mooreoak
Copy link

mooreoak commented May 5, 2025

This is a pretty large amount of code to review. Maybe your organization could consider sponsoring the integration effort?

What would this cost/involve?

@djc
Copy link
Member

djc commented May 5, 2025

This is a pretty large amount of code to review. Maybe your organization could consider sponsoring the integration effort?

What would this cost/involve?

Send me an email? You can trivially find my address from my homepage. Feel free to include a proposal for what you would consider reasonable.

Signed-off-by: Eric Lagergren <elagergren@spideroak.com>
djohnson-spideroak added a commit to aranya-project/aranya that referenced this pull request May 28, 2025
Initial AQC implementation

- Binds QUIC server to a network address
- Binds QUIC client to 0.0.0.0:0 (this should be configurable in the
future)
- Fetches the AQC PSK from the daemon via the encrypted tarpc IPC
- Integrates with rustls w/ PSK support based on this PR
(rustls/rustls#2424)
- Initializes the QUIC server with a PSK keystore
- Adds AQC PSKs to the key store when AQC channels are created or
received.
- Creates bidirectional and unidirectional AQC channels.
- Supports creating new QUIC streams on existing AQC channels.
- Supports sending/receiving data via AQC QUIC data streams.
- Adds AQC example to Rust example application.

TODO:
- Removal of test certs once rustls is updated to no longer require the
server to be initialized with a cert when using PSKs.
- Make QUIC client address configurable
- More robust testing (e.g. multiple peers creating/deleting channels
and sending/receiving in parallel)
- And additional cleanup, see #214 (comment) 

---------

Co-authored-by: Nikki <npoelma@spideroak.com>
Co-authored-by: gknopf <gknopf@spideroak.com>
Co-authored-by: Declan Johnson <102169329+djohnson-spideroak@users.noreply.github.com>
Co-authored-by: Jonathan Dygert <jdygert@spideroak.com>
@ctz
Copy link
Member

ctz commented Jun 13, 2025

Going to close this for now, pending future work on PSK support.

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.

Status of PSK Support?
4 participants