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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! Traits for mutable secret revelation.
//!
//! > **Import path:** `use secure_gate::RevealSecretMut;`
//!
//! This module defines the [`RevealSecretMut`] trait, which extends
//! [`RevealSecret`] to provide controlled mutable access to secrets.
//!
//! The secret wrappers (`Fixed<T>`, `Dynamic<T>`, and the newtypes the macros
//! generate over them) implement this trait. [`EncodedSecret`](crate::EncodedSecret)
//! deliberately does **not**: encoded output is reached only through `Deref` and its
//! named consumers, so there is no mutable path into it.
//!
//! # Security Model
//!
//! - **Scoped mutation preferred**: `with_secret_mut` limits the mutable borrow
//! to the closure lifetime, minimizing exposure risk.
//! - **Direct mutable exposure** (`expose_secret_mut`) is an explicit escape hatch
//! for legitimate needs (e.g., FFI, third-party APIs that require `&mut T`).
//! - **Zero-cost**: All methods use `#[inline(always)]` where appropriate.
//! - **Inheritance**: You automatically get `with_secret` and `expose_secret` from
//! [`RevealSecret`]. `.len()` / `.is_empty()` come from
//! [`SecretLen`](crate::SecretLen), which is a separate trait.
//! - **No implicit leaks**: No `DerefMut`, `AsMut`, or accidental borrowing.
//!
//! # Usage Guidelines
//!
//! The preferred and recommended way to access secrets is the scoped `with_secret` /
//! `with_secret_mut` methods. `expose_secret` / `expose_secret_mut` are escape hatches
//! for rare cases and should be audited closely.
//!
//! - Prefer scoped methods (`with_secret_mut`) in application code.
//! - Use `expose_secret_mut` **only** when you need a long-lived mutable reference
//! (e.g., passing raw pointer to C FFI or interfacing with legacy APIs).
//! - Audit every `expose_secret_mut` call — they should be rare and well-justified.
//!
//! # Examples
//!
//! Scoped mutable access (recommended):
//!
//! ```rust
//! use secure_gate::{Fixed, RevealSecretMut, RevealSecret};
//!
//! let mut secret = Fixed::new([0u8; 4]);
//! secret.with_secret_mut(|bytes| bytes[0] = 42);
//! assert_eq!(secret.expose_secret()[0], 42);
//! ```
//!
//!
//! Polymorphic generic code (works for any mutable secret wrapper):
//!
//! ```rust
//! use secure_gate::RevealSecretMut;
//!
//! fn mutate_first_byte<S: RevealSecretMut>(secret: &mut S)
//! where
//! S::Inner: AsMut<[u8]>,
//! {
//! secret.with_secret_mut(|bytes| {
//! if let Some(first) = bytes.as_mut().first_mut() {
//! *first = 99;
//! }
//! });
//! }
//! ```
//!
//! This trait (together with [`RevealSecret`]) enforces the core security principle of secure-gate:
//! **all secret access (read or write) must be explicit and auditable**.
//! Scoped methods are preferred in nearly all cases.
use crateRevealSecret;
/// Trait for mutable access to secrets.
///
/// Extends [`RevealSecret`], so you also get read-only access (`with_secret`,
/// `expose_secret`, `into_inner`). Length accessors live on
/// [`SecretLen`](crate::SecretLen), a separate trait implemented only where a
/// length is meaningful.
///
/// Implemented by `Fixed<T>`, `Dynamic<T>`, and the newtypes the macros generate
/// over them. [`EncodedSecret`](crate::EncodedSecret) implements neither this trait
/// nor [`RevealSecret`]: encoded output has no mutable path into it.