age_setup/types/
secret_key.rs1use 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}