Skip to main content

rtc_crypto/
secret.rs

1use std::fmt;
2
3use zeroize::Zeroizing;
4
5/// An owned byte vector that zeroizes its allocation when dropped.
6pub struct SecretVec(Zeroizing<Vec<u8>>);
7
8impl SecretVec {
9    /// Wraps secret bytes.
10    #[must_use]
11    pub fn new(bytes: Vec<u8>) -> Self {
12        Self(Zeroizing::new(bytes))
13    }
14
15    /// Returns the number of secret bytes.
16    #[must_use]
17    pub fn len(&self) -> usize {
18        self.0.len()
19    }
20
21    /// Returns whether the secret is empty.
22    #[must_use]
23    pub fn is_empty(&self) -> bool {
24        self.0.is_empty()
25    }
26
27    /// Explicitly unwraps the secret bytes. The returned vector is no longer automatically zeroized.
28    #[must_use]
29    pub fn into_bytes(mut self) -> Vec<u8> {
30        std::mem::take(&mut *self.0)
31    }
32}
33
34impl AsRef<[u8]> for SecretVec {
35    fn as_ref(&self) -> &[u8] {
36        self.0.as_slice()
37    }
38}
39
40impl AsMut<[u8]> for SecretVec {
41    fn as_mut(&mut self) -> &mut [u8] {
42        self.0.as_mut_slice()
43    }
44}
45
46impl Clone for SecretVec {
47    fn clone(&self) -> Self {
48        Self::new(self.as_ref().to_vec())
49    }
50}
51
52impl fmt::Debug for SecretVec {
53    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
54        formatter
55            .debug_struct("SecretVec")
56            .field("len", &self.len())
57            .field("bytes", &"[REDACTED]")
58            .finish()
59    }
60}
61
62impl From<Vec<u8>> for SecretVec {
63    fn from(value: Vec<u8>) -> Self {
64        Self::new(value)
65    }
66}