mls_spec/
sensitive_bytes.rs1use crate::macros::ref_forward_tls_impl;
2
3#[derive(Clone, Default, Ord, PartialOrd, zeroize::Zeroize, zeroize::ZeroizeOnDrop)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[repr(transparent)]
8pub struct SensitiveBytes(Vec<u8>);
9
10impl SensitiveBytes {
11 pub fn as_slice(&self) -> &[u8] {
12 self.0.as_slice()
13 }
14
15 pub fn ct_eq_slice(&self, slice: impl AsRef<[u8]>) -> bool {
16 use subtle::ConstantTimeEq as _;
17 self.0.ct_eq(slice.as_ref()).into()
18 }
19
20 pub fn clear(&mut self) {
21 use zeroize::Zeroize as _;
22 self.0.zeroize();
23 self.0.clear();
24 }
25}
26
27impl std::hash::Hash for SensitiveBytes {
28 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
29 self.0.hash(state);
30 }
31}
32
33#[cfg(not(feature = "hazmat"))]
34impl std::fmt::Debug for SensitiveBytes {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 write!(f, "[REDACTED]")
37 }
38}
39
40#[cfg(not(feature = "hazmat"))]
41impl std::fmt::Display for SensitiveBytes {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 write!(f, "[REDACTED]")
44 }
45}
46
47#[cfg(feature = "hazmat")]
48impl std::fmt::Debug for SensitiveBytes {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(f, "{:?}", &self.0)
51 }
52}
53
54#[cfg(feature = "hazmat")]
55impl std::fmt::Display for SensitiveBytes {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 write!(f, "{}", &hex::encode(self.0.as_slice()))
58 }
59}
60
61impl tls_codec::Size for SensitiveBytes {
62 fn tls_serialized_len(&self) -> usize {
63 crate::tlspl::bytes::tls_serialized_len(&self.0)
64 }
65}
66
67impl tls_codec::Serialize for SensitiveBytes {
68 fn tls_serialize<W: std::io::Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
69 crate::tlspl::bytes::tls_serialize(&self.0, writer)
70 }
71}
72
73impl tls_codec::Deserialize for SensitiveBytes {
74 fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Self, tls_codec::Error>
75 where
76 Self: Sized,
77 {
78 Ok(Self(crate::tlspl::bytes::tls_deserialize(bytes)?))
79 }
80}
81
82ref_forward_tls_impl!(SensitiveBytes);
83
84impl From<Vec<u8>> for SensitiveBytes {
85 fn from(value: Vec<u8>) -> Self {
86 Self(value)
87 }
88}
89
90impl From<SensitiveBytes> for Vec<u8> {
91 fn from(val: SensitiveBytes) -> Self {
92 val.0.clone()
93 }
94}
95
96impl PartialEq for SensitiveBytes {
97 fn eq(&self, other: &Self) -> bool {
98 use subtle::ConstantTimeEq as _;
99 self.0.ct_eq(&other.0).into()
100 }
101}
102
103impl Eq for SensitiveBytes {}
104
105impl std::ops::Deref for SensitiveBytes {
106 type Target = [u8];
107 fn deref(&self) -> &Self::Target {
108 self.0.as_slice()
109 }
110}
111
112impl std::ops::DerefMut for SensitiveBytes {
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 self.0.as_mut_slice()
115 }
116}