diff --git a/api/s2n.h b/api/s2n.h index e8354f5d4dd..6ef207e090d 100644 --- a/api/s2n.h +++ b/api/s2n.h @@ -3680,7 +3680,8 @@ S2N_API int s2n_config_get_supported_groups(struct s2n_config *config, uint16_t uint16_t *groups_count); /* Indicates which serialized connection version will be provided. The default value is - * S2N_SERIALIZED_CONN_NONE, which indicates the feature is off. */ + * S2N_SERIALIZED_CONN_NONE, which indicates the feature is off. + */ typedef enum { S2N_SERIALIZED_CONN_NONE = 0, S2N_SERIALIZED_CONN_V1 = 1 diff --git a/bindings/rust/s2n-tls/src/config.rs b/bindings/rust/s2n-tls/src/config.rs index 9c42ad2b532..e62b3500646 100644 --- a/bindings/rust/s2n-tls/src/config.rs +++ b/bindings/rust/s2n-tls/src/config.rs @@ -719,6 +719,18 @@ impl Builder { Ok(self) } + /// Sets the expected connection serialization version. Must be set + /// before serializing the connection. + pub fn set_serialization_version( + &mut self, + version: SerializationVersion, + ) -> Result<&mut Self, Error> { + unsafe { + s2n_config_set_serialization_version(self.as_mut_ptr(), version.into()).into_result() + }?; + Ok(self) + } + pub fn build(mut self) -> Result { if self.load_system_certs { unsafe { diff --git a/bindings/rust/s2n-tls/src/connection.rs b/bindings/rust/s2n-tls/src/connection.rs index dd175680281..ff0bd0a48b7 100644 --- a/bindings/rust/s2n-tls/src/connection.rs +++ b/bindings/rust/s2n-tls/src/connection.rs @@ -969,6 +969,47 @@ impl Connection { } Ok(secret) } + + /// Retrieves the size of the serialized connection + pub fn serialization_length(&self) -> Result { + unsafe { + let mut length = 0; + s2n_connection_serialization_length(self.connection.as_ptr(), &mut length) + .into_result()?; + Ok(length.try_into().unwrap()) + } + } + + /// Serializes the TLS connection into the provided buffer + pub fn serialize(&self, output: &mut [u8]) -> Result<(), Error> { + unsafe { + s2n_connection_serialize( + self.connection.as_ptr(), + output.as_mut_ptr(), + output.len().try_into().map_err(|_| Error::INVALID_INPUT)?, + ) + .into_result()?; + Ok(()) + } + } + + /// Deserializes the input buffer into a new TLS connection that can send/recv + /// data from the original peer. + pub fn deserialize(&mut self, input: &[u8]) -> Result<(), Error> { + let size = input.len(); + /* This is not ideal, we know that s2n_connection_deserialize will not mutate the + * input value, however, the mut is needed to use the stuffer functions. */ + let input = input.as_ptr() as *mut u8; + unsafe { + s2n_connection_deserialize( + self.as_ptr(), + input, + size.try_into().map_err(|_| Error::INVALID_INPUT)?, + ) + .into_result()?; + Ok(()) + } + } } struct Context { diff --git a/bindings/rust/s2n-tls/src/enums.rs b/bindings/rust/s2n-tls/src/enums.rs index 3116dfb2323..d642a7630ce 100644 --- a/bindings/rust/s2n-tls/src/enums.rs +++ b/bindings/rust/s2n-tls/src/enums.rs @@ -193,3 +193,19 @@ impl From for s2n_peer_key_update::Type { } } } + +#[non_exhaustive] +#[derive(Debug, PartialEq, Copy, Clone)] +pub enum SerializationVersion { + None, + V1, +} + +impl From for s2n_serialization_version::Type { + fn from(input: SerializationVersion) -> s2n_serialization_version::Type { + match input { + SerializationVersion::None => s2n_serialization_version::SERIALIZED_CONN_NONE, + SerializationVersion::V1 => s2n_serialization_version::SERIALIZED_CONN_V1, + } + } +}