Skip to main content

age_setup/types/
secret_key.rs

1use crate::security::zeroize::wipe_memory;
2use std::fmt;
3#[derive(Debug, Clone)]
4pub struct SecretKey {
5    inner: Vec<u8>,
6}
7impl SecretKey {
8    pub(crate) fn new(raw: String) -> Self {
9        Self {
10            inner: raw.into_bytes(),
11        }
12    }
13    #[must_use]
14    pub fn expose(&self) -> &str {
15        std::str::from_utf8(&self.inner).expect("SecretKey inner buffer must be valid UTF-8")
16    }
17}
18impl Drop for SecretKey {
19    fn drop(&mut self) {
20        let _ = wipe_memory(&mut self.inner);
21    }
22}
23impl fmt::Display for SecretKey {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        write!(f, "[REDACTED]")
26    }
27}
28#[cfg(test)]
29mod tests {
30    use super::*;
31    #[test]
32    fn test_secret_key_expose() {
33        let sk = SecretKey::new("test".to_string());
34        assert_eq!(sk.expose(), "test");
35    }
36    #[test]
37    fn test_secret_key_display() {
38        let sk = SecretKey::new("test".to_string());
39        assert_eq!(format!("{}", sk), "[REDACTED]");
40    }
41    #[test]
42    fn test_secret_key_clone() {
43        let sk1 = SecretKey::new("secret".to_string());
44        let sk2 = sk1.clone();
45        assert_eq!(sk1.expose(), sk2.expose());
46    }
47    #[test]
48    fn test_secret_key_drop_calls_wipe() {
49        let sk = SecretKey::new("secret".to_string());
50        drop(sk);
51    }
52}