mirror of https://github.com/ctz/rustls
feat: impl safer export_keyring_material interface.
Prior to this commit the `export_keyring_material` function used a mutable out buffer for writing exported key material, and returned an empty Ok result when there was no error doing so. This commit updates the function such that the ownership of the output buffer passes through the export function and is returned as the Ok result when there is no error. Doing this makes for a safer interface for end users: the output buffer will be dropped if `export_keyring_material` errors. Callers can only access the buffer again using the OK result. All credit due to davidv1992 for the implementation idea and initial code that was extended in this commit.
This commit is contained in:
parent
861e76d599
commit
38fdd952be
|
@ -79,12 +79,12 @@ impl Connection {
|
|||
/// Derives key material from the agreed connection secrets.
|
||||
///
|
||||
/// See [`ConnectionCommon::export_keying_material()`] for more information.
|
||||
pub fn export_keying_material(
|
||||
pub fn export_keying_material<T: AsMut<[u8]>>(
|
||||
&self,
|
||||
output: &mut [u8],
|
||||
output: T,
|
||||
label: &[u8],
|
||||
context: Option<&[u8]>,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<T, Error> {
|
||||
match self {
|
||||
Self::Client(conn) => conn.export_keying_material(output, label, context),
|
||||
Self::Server(conn) => conn.export_keying_material(output, label, context),
|
||||
|
@ -738,7 +738,9 @@ impl<Data> ConnectionCommon<Data> {
|
|||
///
|
||||
/// This function fills in `output` with `output.len()` bytes of key
|
||||
/// material derived from the master session secret using `label`
|
||||
/// and `context` for diversification.
|
||||
/// and `context` for diversification. Ownership of the buffer is taken
|
||||
/// by the function and returned via the Ok result to ensure no key
|
||||
/// material leaks if the function fails.
|
||||
///
|
||||
/// See RFC5705 for more details on what this does and is for.
|
||||
///
|
||||
|
@ -747,14 +749,16 @@ impl<Data> ConnectionCommon<Data> {
|
|||
///
|
||||
/// This function fails if called prior to the handshake completing;
|
||||
/// check with [`CommonState::is_handshaking`] first.
|
||||
pub fn export_keying_material(
|
||||
pub fn export_keying_material<T: AsMut<[u8]>>(
|
||||
&self,
|
||||
output: &mut [u8],
|
||||
mut output: T,
|
||||
label: &[u8],
|
||||
context: Option<&[u8]>,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<T, Error> {
|
||||
match self.state.as_ref() {
|
||||
Ok(st) => st.export_keying_material(output, label, context),
|
||||
Ok(st) => st
|
||||
.export_keying_material(output.as_mut(), label, context)
|
||||
.map(|_| output),
|
||||
Err(e) => Err(e.clone()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2029,25 +2029,21 @@ fn do_exporter_test(client_config: ClientConfig, server_config: ServerConfig) {
|
|||
);
|
||||
do_handshake(&mut client, &mut server);
|
||||
|
||||
assert_debug_eq(
|
||||
client.export_keying_material(&mut client_secret, b"label", Some(b"context")),
|
||||
Ok(()),
|
||||
);
|
||||
assert_debug_eq(
|
||||
server.export_keying_material(&mut server_secret, b"label", Some(b"context")),
|
||||
Ok(()),
|
||||
);
|
||||
assert!(client
|
||||
.export_keying_material(&mut client_secret, b"label", Some(b"context"))
|
||||
.is_ok());
|
||||
assert!(server
|
||||
.export_keying_material(&mut server_secret, b"label", Some(b"context"))
|
||||
.is_ok());
|
||||
assert_eq!(client_secret.to_vec(), server_secret.to_vec());
|
||||
|
||||
assert_debug_eq(
|
||||
client.export_keying_material(&mut client_secret, b"label", None),
|
||||
Ok(()),
|
||||
);
|
||||
assert!(client
|
||||
.export_keying_material(&mut client_secret, b"label", None)
|
||||
.is_ok());
|
||||
assert_ne!(client_secret.to_vec(), server_secret.to_vec());
|
||||
assert_debug_eq(
|
||||
server.export_keying_material(&mut server_secret, b"label", None),
|
||||
Ok(()),
|
||||
);
|
||||
assert!(server
|
||||
.export_keying_material(&mut server_secret, b"label", None)
|
||||
.is_ok(),);
|
||||
assert_eq!(client_secret.to_vec(), server_secret.to_vec());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue