1 | use core::fmt::Debug; |
2 | |
3 | #[cfg (doc)] |
4 | use crate::KeyLogFile; |
5 | |
6 | /// This trait represents the ability to do something useful |
7 | /// with key material, such as logging it to a file for debugging. |
8 | /// |
9 | /// Naturally, secrets passed over the interface are *extremely* |
10 | /// sensitive and can break the security of past, present and |
11 | /// future sessions. |
12 | /// |
13 | /// You'll likely want some interior mutability in your |
14 | /// implementation to make this useful. |
15 | /// |
16 | /// See [`KeyLogFile`] that implements the standard |
17 | /// `SSLKEYLOGFILE` environment variable behaviour. |
18 | pub trait KeyLog: Debug + Send + Sync { |
19 | /// Log the given `secret`. `client_random` is provided for |
20 | /// session identification. `label` describes precisely what |
21 | /// `secret` means: |
22 | /// |
23 | /// - `CLIENT_RANDOM`: `secret` is the master secret for a TLSv1.2 session. |
24 | /// - `CLIENT_EARLY_TRAFFIC_SECRET`: `secret` encrypts early data |
25 | /// transmitted by a client |
26 | /// - `SERVER_HANDSHAKE_TRAFFIC_SECRET`: `secret` encrypts |
27 | /// handshake messages from the server during a TLSv1.3 handshake. |
28 | /// - `CLIENT_HANDSHAKE_TRAFFIC_SECRET`: `secret` encrypts |
29 | /// handshake messages from the client during a TLSv1.3 handshake. |
30 | /// - `SERVER_TRAFFIC_SECRET_0`: `secret` encrypts post-handshake data |
31 | /// from the server in a TLSv1.3 session. |
32 | /// - `CLIENT_TRAFFIC_SECRET_0`: `secret` encrypts post-handshake data |
33 | /// from the client in a TLSv1.3 session. |
34 | /// - `EXPORTER_SECRET`: `secret` is the post-handshake exporter secret |
35 | /// in a TLSv1.3 session. |
36 | /// |
37 | /// These strings are selected to match the NSS key log format: |
38 | /// <https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format> |
39 | fn log(&self, label: &str, client_random: &[u8], secret: &[u8]); |
40 | |
41 | /// Indicates whether the secret with label `label` will be logged. |
42 | /// |
43 | /// If `will_log` returns true then `log` will be called with the secret. |
44 | /// Otherwise, `log` will not be called for the secret. This is a |
45 | /// performance optimization. |
46 | fn will_log(&self, _label: &str) -> bool { |
47 | true |
48 | } |
49 | } |
50 | |
51 | /// KeyLog that does exactly nothing. |
52 | #[derive (Debug)] |
53 | pub struct NoKeyLog; |
54 | |
55 | impl KeyLog for NoKeyLog { |
56 | fn log(&self, _: &str, _: &[u8], _: &[u8]) {} |
57 | #[inline ] |
58 | fn will_log(&self, _label: &str) -> bool { |
59 | false |
60 | } |
61 | } |
62 | |