quinn_boring/
key_log.rs

1use crate::Error;
2use std::fmt::{Debug, Display, Formatter};
3use std::str::FromStr;
4
5const CLIENT_RANDOM: &str = "CLIENT_RANDOM";
6const CLIENT_EARLY_TRAFFIC_SECRET: &str = "CLIENT_EARLY_TRAFFIC_SECRET";
7const CLIENT_HANDSHAKE_TRAFFIC_SECRET: &str = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
8const SERVER_HANDSHAKE_TRAFFIC_SECRET: &str = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
9const CLIENT_TRAFFIC_SECRET_0: &str = "CLIENT_TRAFFIC_SECRET_0";
10const SERVER_TRAFFIC_SECRET_0: &str = "SERVER_TRAFFIC_SECRET_0";
11const EXPORTER_SECRET: &str = "EXPORTER_SECRET";
12
13/// Enumeration of the possible values for the keylog label.
14/// See <https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format>
15/// for details.
16#[derive(Eq, PartialEq)]
17pub enum KeyLogLabel {
18    ClientRandom,
19    ClientEarlyTrafficSecret,
20    ClientHandshakeTrafficSecret,
21    ServerHandshakeTrafficSecret,
22    ClientTrafficSecret0,
23    ServerTrafficSecret0,
24    ExporterSecret,
25}
26
27impl KeyLogLabel {
28    pub fn to_str(&self) -> &'static str {
29        match self {
30            KeyLogLabel::ClientRandom => CLIENT_RANDOM,
31            KeyLogLabel::ClientEarlyTrafficSecret => CLIENT_EARLY_TRAFFIC_SECRET,
32            KeyLogLabel::ClientHandshakeTrafficSecret => CLIENT_HANDSHAKE_TRAFFIC_SECRET,
33            KeyLogLabel::ServerHandshakeTrafficSecret => SERVER_HANDSHAKE_TRAFFIC_SECRET,
34            KeyLogLabel::ClientTrafficSecret0 => CLIENT_TRAFFIC_SECRET_0,
35            KeyLogLabel::ServerTrafficSecret0 => SERVER_TRAFFIC_SECRET_0,
36            KeyLogLabel::ExporterSecret => EXPORTER_SECRET,
37        }
38    }
39}
40
41impl Debug for KeyLogLabel {
42    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
43        f.write_str(self.to_str())
44    }
45}
46
47impl Display for KeyLogLabel {
48    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49        f.write_str(self.to_str())
50    }
51}
52
53impl FromStr for KeyLogLabel {
54    type Err = Error;
55
56    fn from_str(s: &str) -> Result<Self, Self::Err> {
57        match s {
58            CLIENT_RANDOM => Ok(Self::ClientRandom),
59            CLIENT_EARLY_TRAFFIC_SECRET => Ok(Self::ClientEarlyTrafficSecret),
60            CLIENT_HANDSHAKE_TRAFFIC_SECRET => Ok(Self::ClientHandshakeTrafficSecret),
61            SERVER_HANDSHAKE_TRAFFIC_SECRET => Ok(Self::ServerHandshakeTrafficSecret),
62            CLIENT_TRAFFIC_SECRET_0 => Ok(Self::ClientTrafficSecret0),
63            SERVER_TRAFFIC_SECRET_0 => Ok(Self::ServerTrafficSecret0),
64            EXPORTER_SECRET => Ok(Self::ExporterSecret),
65            _ => Err(Error::invalid_input(format!(
66                "unable to parse keylog label: {}",
67                s
68            ))),
69        }
70    }
71}
72
73/// Provides a handler for logging key material. This is intended for debugging use with
74/// tools like Wireshark.
75pub trait KeyLog: Send + Sync {
76    /// Logs the given `secret`. `client_random` is provided for
77    /// session identification.  `label` describes precisely what
78    /// `secret` means.
79    ///
80    /// Details of the format are described in:
81    /// <https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format>
82    fn log_key(&self, label: KeyLogLabel, client_random: &str, secret: &str);
83}
84
85/// A [KeyLog] that does nothing.
86pub struct NoKeyLog;
87
88impl KeyLog for NoKeyLog {
89    fn log_key(&self, _: KeyLogLabel, _: &str, _: &str) {}
90}