age_setup/types/
secret_key.rs1use crate::security::zeroize::wipe_memory;
4use std::fmt;
5
6#[derive(Debug, Clone)]
11pub struct SecretKey {
12 inner: Vec<u8>,
13}
14
15impl SecretKey {
16 pub(crate) fn new(raw: String) -> Self {
18 Self {
19 inner: raw.into_bytes(),
20 }
21 }
22
23 #[must_use]
32 pub fn expose(&self) -> &str {
33 std::str::from_utf8(&self.inner).expect("SecretKey inner buffer must be valid UTF-8")
34 }
35}
36
37impl Drop for SecretKey {
38 fn drop(&mut self) {
39 let _ = wipe_memory(&mut self.inner);
40 }
41}
42
43impl fmt::Display for SecretKey {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 write!(f, "[REDACTED]")
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn test_secret_key_expose() {
55 let sk = SecretKey::new("test".to_string());
56 assert_eq!(sk.expose(), "test");
57 }
58
59 #[test]
60 fn test_secret_key_display() {
61 let sk = SecretKey::new("test".to_string());
62 assert_eq!(format!("{}", sk), "[REDACTED]");
63 }
64
65 #[test]
66 fn test_secret_key_clone() {
67 let sk1 = SecretKey::new("secret".to_string());
68 let sk2 = sk1.clone();
69 assert_eq!(sk1.expose(), sk2.expose());
70 }
71
72 #[test]
73 fn test_secret_key_drop_calls_wipe() {
74 let sk = SecretKey::new("secret".to_string());
75 drop(sk); }
77}