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

feat(binding): add key update request api #4469

Merged
merged 10 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bindings/rust/s2n-tls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ license = "Apache-2.0"
[features]
default = []
unstable-fingerprint = ["s2n-tls-sys/unstable-fingerprint"]
unstable-ktls = ["s2n-tls-sys/unstable-ktls"]
quic = ["s2n-tls-sys/quic"]
pq = ["s2n-tls-sys/pq"]
testing = ["bytes"]
Expand Down
49 changes: 49 additions & 0 deletions bindings/rust/s2n-tls/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ macro_rules! static_const_str {
};
}

#[non_exhaustive]
#[derive(Debug, PartialEq)]
/// s2n-tls only tracks up to u8::MAX (255) key updates. If any of the fields show
/// 255 updates, then more than 255 updates may have occurred.
pub struct KeyUpdateCount {
pub send_key_updates: u8,
pub recv_key_updates: u8,
}

pub struct Connection {
connection: NonNull<s2n_connection>,
}
Expand Down Expand Up @@ -267,6 +276,46 @@ impl Connection {
Ok(self)
}

/// Signals the connection to do a key_update at the next possible opportunity.
/// Note that the resulting key update message will not be sent until `send` is
/// called on the connection.
///
/// `peer_request` indicates if a key update should also be requested
/// of the peer. When set to `KeyUpdateNotRequested`, then only the sending
/// key of the connection will be updated. If set to `KeyUpdateRequested`, then
/// the sending key of conn will be updated AND the peer will be requested to
/// update their sending key. Note that s2n-tls currently only supports
/// `peer_request` being set to `KeyUpdateNotRequested` and will return an error
/// if any other value is used.
pub fn request_key_update(&mut self, peer_request: PeerKeyUpdate) -> Result<(), Error> {
unsafe {
s2n_connection_request_key_update(self.connection.as_ptr(), peer_request.into())
.into_result()
}?;
Ok(())
}

/// Reports the number of times sending and receiving keys have been updated.
///
/// This only applies to TLS1.3. Earlier versions do not support key updates.
#[cfg(feature = "unstable-ktls")]
pub fn key_update_counts(&self) -> Result<KeyUpdateCount, Error> {
let mut send_key_updates = 0;
let mut recv_key_updates = 0;
unsafe {
s2n_connection_get_key_update_counts(
self.connection.as_ptr(),
&mut send_key_updates,
&mut recv_key_updates,
)
.into_result()?;
}
Ok(KeyUpdateCount {
send_key_updates,
recv_key_updates,
})
}

/// sets the application protocol preferences on an s2n_connection object.
///
/// protocols is a list in order of preference, with most preferred protocol first, and of
Expand Down
16 changes: 16 additions & 0 deletions bindings/rust/s2n-tls/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,19 @@ impl TryFrom<s2n_tls_hash_algorithm::Type> for HashAlgorithm {
Ok(version)
}
}

#[non_exhaustive]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum PeerKeyUpdate {
KeyUpdateNotRequested,
KeyUpdatedRequested,
}

impl From<PeerKeyUpdate> for s2n_peer_key_update::Type {
fn from(input: PeerKeyUpdate) -> s2n_peer_key_update::Type {
match input {
PeerKeyUpdate::KeyUpdateNotRequested => s2n_peer_key_update::KEY_UPDATE_NOT_REQUESTED,
PeerKeyUpdate::KeyUpdatedRequested => s2n_peer_key_update::KEY_UPDATE_REQUESTED,
}
}
}
36 changes: 36 additions & 0 deletions bindings/rust/s2n-tls/src/testing/s2n_tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,4 +892,40 @@ mod tests {

Ok(())
}

#[cfg(feature = "unstable-ktls")]
#[test]
fn key_updates() -> Result<(), Error> {
use crate::{connection::KeyUpdateCount, enums::PeerKeyUpdate};

let empty_key_updates = KeyUpdateCount {
recv_key_updates: 0,
send_key_updates: 0,
};

let pair = tls_pair(build_config(&security::DEFAULT_TLS13)?);
let mut pair = poll_tls_pair(pair);

// there haven't been any key updates at the start of the connection
let client_updates = pair.client.0.connection.as_ref().key_update_counts()?;
assert_eq!(client_updates, empty_key_updates);
let server_updates = pair.server.0.connection.as_ref().key_update_counts()?;
assert_eq!(server_updates, empty_key_updates);

pair.server
.0
.connection
.as_mut()
.request_key_update(PeerKeyUpdate::KeyUpdateNotRequested)?;
assert!(pair.poll_send(Mode::Server, &[0]).is_ready());

// the server send key has been updated
let client_updates = pair.client.0.connection.as_ref().key_update_counts()?;
assert_eq!(client_updates, empty_key_updates);
let server_updates = pair.server.0.connection.as_ref().key_update_counts()?;
assert_eq!(server_updates.recv_key_updates, 0);
assert_eq!(server_updates.send_key_updates, 1);

Ok(())
}
}
Loading