dexios_core/
protected.rs

1//! This is a basic wrapper for secret/hidden values
2//!
3//! It implements zeroize-on-drop, meaning the data is securely erased from memory once it goes out of scope.
4//! You may call `drop()` prematurely if you wish to erase it sooner.
5//!
6//! `Protected` values are also hidden from `fmt::Debug`, and will display `[REDACTED]` instead.
7//!
8//! The only way to access the data within a `Protected` value is to call `.expose()` - this is to prevent accidental leakage.
9//! This also makes any `Protected` value easier to audit, as you are able to quickly view wherever the data is accessed.
10//!
11//! `Protected` values are not able to be copied within memory, to prevent accidental leakage. They are able to be `cloned` however - but this is always explicit and you will be aware of it.
12//!
13//! I'd like to give a huge thank you to the authors of the [secrecy crate](https://crates.io/crates/secrecy),
14//! as that crate's functionality inspired this implementation.
15//!
16//! # Examples
17//!
18//! ```rust,ignore
19//! let secret_data = "this is classified information".to_string();
20//! let protected_data = Protected::new(secret_data);
21//!
22//! // the only way to access the data within the `Protected` wrapper
23//! // is by calling `.expose()`
24//! let value = protected_data.expose();
25//! ```
26//!
27
28use std::fmt::Debug;
29use zeroize::Zeroize;
30
31#[derive(Clone)]
32pub struct Protected<T>
33where
34    T: Zeroize,
35{
36    data: T,
37}
38
39impl<T> std::ops::Deref for Protected<T>
40where
41    T: Zeroize,
42{
43    type Target = T;
44
45    fn deref(&self) -> &Self::Target {
46        &self.data
47    }
48}
49
50impl<T> Protected<T>
51where
52    T: Zeroize,
53{
54    pub fn new(value: T) -> Self {
55        Protected { data: value }
56    }
57
58    pub fn expose(&self) -> &T {
59        &self.data
60    }
61}
62
63impl<T> Drop for Protected<T>
64where
65    T: Zeroize,
66{
67    fn drop(&mut self) {
68        self.data.zeroize();
69    }
70}
71
72impl<T> Debug for Protected<T>
73where
74    T: Zeroize,
75{
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        f.write_str("[REDACTED]")
78    }
79}