rama_tls_rustls/
key_log.rs

1use crate::dep::rustls::KeyLog;
2use rama_core::error::OpaqueError;
3use rama_net::tls::keylog::{KeyLogFileHandle, new_key_log_file_handle};
4use std::fmt;
5
6#[derive(Debug, Clone)]
7/// [`KeyLog`] implementation that opens a file for the given path.
8pub struct KeyLogFile(KeyLogFileHandle);
9
10impl KeyLogFile {
11    /// Makes a new [`KeyLogFile`].
12    pub fn new(path: String) -> Result<Self, OpaqueError> {
13        let handle = new_key_log_file_handle(path)?;
14        Ok(KeyLogFile(handle))
15    }
16}
17
18impl KeyLog for KeyLogFile {
19    #[inline]
20    fn log(&self, label: &str, client_random: &[u8], secret: &[u8]) {
21        let line = format!(
22            "{} {:02x} {:02x}\n",
23            label,
24            PlainHex {
25                slice: client_random
26            },
27            PlainHex { slice: secret },
28        );
29        self.0.write_log_line(line);
30    }
31}
32
33struct PlainHex<'a, T: 'a> {
34    slice: &'a [T],
35}
36
37impl<T: fmt::LowerHex> fmt::LowerHex for PlainHex<'_, T> {
38    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39        fmt_inner_hex(self.slice, f, fmt::LowerHex::fmt)
40    }
41}
42
43fn fmt_inner_hex<T, F: Fn(&T, &mut fmt::Formatter) -> fmt::Result>(
44    slice: &[T],
45    f: &mut fmt::Formatter,
46    fmt_fn: F,
47) -> fmt::Result {
48    for val in slice.iter() {
49        fmt_fn(val, f)?;
50    }
51    Ok(())
52}