1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Sentinel placeholders for owned secret extraction.
//!
//! > **Import path:** `use secure_gate::SentinelValue;`
//!
//! [`RevealSecret::into_inner`](crate::RevealSecret::into_inner) moves the real
//! secret out of a wrapper while the wrapper's `Drop` impl still runs afterwards.
//! Something inert must be left behind for that `Drop` to zeroize —
//! [`SentinelValue::sentinel_value`] produces it.
//!
//! `Default` is *not* used for this purpose because the standard library only
//! implements `Default` for arrays up to 32 elements, which would make
//! `into_inner` unusable for common secret sizes such as `[u8; 64]`
//! (Ed25519 expanded keys, HMAC-SHA512 keys). The `[T; N]` implementation here
//! uses [`core::array::from_fn`], which works for every `N`.
/// Produces the inert placeholder left inside a wrapper after
/// [`into_inner`](crate::RevealSecret::into_inner) moves the real secret out.
///
/// # Contract
///
/// A sentinel must be cheap to construct and must never contain secret
/// material — it exists only so the wrapper's `Drop` impl zeroizes a harmless
/// value instead of the already-moved secret. The provided implementations
/// return an all-default array, an empty `String`, or an empty `Vec`.
///
/// # Provided implementations
///
/// | Type | Sentinel | Notes |
/// |------|----------|-------|
/// | `[T; N]` where `T: Default` | `[T::default(); N]` | Any `N` — not limited to 32 like `Default` |
/// | `String` | `String::new()` | Requires `alloc`; no allocation |
/// | `Vec<T>` | `Vec::new()` | Requires `alloc`; no allocation |
///
/// Implement this for your own inner types to make `into_inner` available on
/// wrappers around them. For inner types where every representable value is
/// meaningful secret material (i.e. no safe placeholder exists), do not
/// implement this trait — `into_inner` then stays uncallable for them, which
/// is the safe default.