shadow_crypt_core/
memory.rs1use zeroize::Zeroizing;
6
7#[derive(Debug)]
9pub struct SecureString(Zeroizing<String>);
10
11impl SecureString {
12 pub fn new(s: String) -> Self {
14 Self(Zeroizing::new(s))
15 }
16
17 pub fn as_str(&self) -> &str {
19 self.0.as_str()
20 }
21
22 pub fn is_empty(&self) -> bool {
24 self.0.is_empty()
25 }
26}
27
28impl Clone for SecureString {
29 fn clone(&self) -> Self {
30 Self::new(self.0.as_str().to_string())
31 }
32}
33
34#[derive(Debug, Clone)]
36pub struct SecureKey(Zeroizing<[u8; 32]>);
37
38impl SecureKey {
39 pub fn new(key: [u8; 32]) -> Self {
41 Self(Zeroizing::new(key))
42 }
43
44 pub fn as_bytes(&self) -> &[u8; 32] {
46 &self.0
47 }
48}
49
50#[derive(Debug, Clone)]
52pub struct SecureBytes(Zeroizing<Vec<u8>>);
53
54impl SecureBytes {
55 pub fn new(data: Vec<u8>) -> Self {
57 Self(Zeroizing::new(data))
58 }
59
60 pub fn as_slice(&self) -> &[u8] {
62 &self.0
63 }
64
65 pub fn with_capacity(capacity: usize) -> Self {
67 Self(Zeroizing::new(Vec::with_capacity(capacity)))
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_secure_string_basic() {
77 let s = SecureString::new("test_password".to_string());
78 assert_eq!(s.as_str(), "test_password");
79 assert!(!s.is_empty());
80
81 let empty = SecureString::new(String::new());
82 assert!(empty.is_empty());
83 }
84
85 #[test]
86 fn test_secure_string_clone() {
87 let original = SecureString::new("test_password".to_string());
88 let cloned = original.clone();
89 assert_eq!(original.as_str(), cloned.as_str());
90 }
91
92 #[test]
93 fn test_secure_key_basic() {
94 let key_bytes = [42u8; 32];
95 let key = SecureKey::new(key_bytes);
96 assert_eq!(key.as_bytes(), &key_bytes);
97 }
98
99 #[test]
100 fn test_secure_key_clone() {
101 let key_bytes = [42u8; 32];
102 let original = SecureKey::new(key_bytes);
103 let cloned = original.clone();
104 assert_eq!(original.as_bytes(), cloned.as_bytes());
105 }
106
107 #[test]
108 fn test_secure_bytes_basic() {
109 let data = vec![1, 2, 3, 4, 5];
110 let secure_data = SecureBytes::new(data.clone());
111 assert_eq!(secure_data.as_slice(), data.as_slice());
112 }
113
114 #[test]
115 fn test_secure_bytes_with_capacity() {
116 let capacity = 100;
117 let secure_data = SecureBytes::with_capacity(capacity);
118 assert!(secure_data.as_slice().is_empty());
119 }
121}