1#[cfg(feature = "zeroize")]
10use zeroize::{DefaultIsZeroes, Zeroize, ZeroizeOnDrop, Zeroizing};
11
12#[cfg(feature = "zeroize")]
13use secrecy::{ExposeSecret, SecretBox};
14
15#[cfg(feature = "zeroize")]
16pub type FixedZeroizing<T> = Zeroizing<T>;
17
18#[cfg(feature = "zeroize")]
20pub struct DynamicZeroizing<T: ?Sized + Zeroize>(SecretBox<T>);
21
22#[cfg(feature = "zeroize")]
23impl<T: ?Sized + Zeroize> DynamicZeroizing<T> {
24 #[inline(always)]
25 pub fn new(value: Box<T>) -> Self {
26 Self(SecretBox::new(value))
27 }
28}
29
30#[cfg(feature = "zeroize")]
32impl<T: ?Sized + Zeroize> core::fmt::Debug for DynamicZeroizing<T> {
33 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34 f.write_str("[REDACTED]")
35 }
36}
37
38#[cfg(feature = "zeroize")]
40impl<S: ?Sized + Zeroize> ExposeSecret<S> for DynamicZeroizing<S> {
41 #[inline(always)]
42 fn expose_secret(&self) -> &S {
43 self.0.expose_secret()
44 }
45}
46
47#[cfg(feature = "zeroize")]
49impl<T: Zeroize + DefaultIsZeroes> Zeroize for DynamicZeroizing<T> {
50 fn zeroize(&mut self) {
51 self.0.zeroize();
52 }
53}
54
55#[cfg(feature = "zeroize")]
57impl<T: ?Sized + Zeroize> ZeroizeOnDrop for DynamicZeroizing<T> {}
58
59#[cfg(feature = "zeroize")]
61impl<T: Zeroize> From<crate::Fixed<T>> for FixedZeroizing<T> {
62 #[inline(always)]
63 fn from(fixed: crate::Fixed<T>) -> Self {
64 Zeroizing::new(fixed.0)
65 }
66}
67
68#[cfg(feature = "zeroize")]
69impl<T: ?Sized + Zeroize> From<crate::Dynamic<T>> for DynamicZeroizing<T> {
70 #[inline(always)]
71 fn from(dynamic: crate::Dynamic<T>) -> Self {
72 Self(SecretBox::new(dynamic.0))
73 }
74}
75
76#[cfg(feature = "zeroize")]
78impl<T: Zeroize> Zeroize for crate::Fixed<T> {
79 fn zeroize(&mut self) {
80 self.0.zeroize();
81 }
82}
83
84#[cfg(feature = "zeroize")]
85impl<T: Zeroize + DefaultIsZeroes> Zeroize for crate::Dynamic<T> {
86 fn zeroize(&mut self) {
87 self.0.zeroize();
88 }
89}
90
91#[cfg(feature = "zeroize")]
92impl<T: Zeroize> ZeroizeOnDrop for crate::Fixed<T> {}
93
94#[cfg(feature = "zeroize")]
95impl<T: ?Sized + Zeroize> ZeroizeOnDrop for crate::Dynamic<T> {}
96
97#[cfg(feature = "zeroize")]
102impl<T: Zeroize + Send + 'static> From<T> for DynamicZeroizing<T> {
103 #[inline(always)]
104 fn from(value: T) -> Self {
105 Self::new(Box::new(value))
106 }
107}
108
109#[cfg(feature = "zeroize")]
110impl<T: Zeroize + DefaultIsZeroes + Send + 'static> From<Box<T>> for DynamicZeroizing<T> {
111 #[inline(always)]
112 fn from(boxed: Box<T>) -> Self {
113 Self::new(boxed)
114 }
115}
116
117#[cfg(feature = "zeroize")]
118impl From<&str> for DynamicZeroizing<String> {
119 #[inline(always)]
120 fn from(s: &str) -> Self {
121 Self::new(Box::new(s.to_string()))
122 }
123}