Skip to main content

secure_gate/traits/
mod.rs

1//! Traits for polymorphic secret handling.
2//!
3//! > **Note:** All traits in this module are re-exported at the crate root
4//! > (`secure_gate::RevealSecret`, not `secure_gate::traits::RevealSecret`).
5//! > You should never need to import from `secure_gate::traits::*` directly.
6//!
7//! This module defines the core traits that enable generic, zero-cost, and secure
8//! operations across different secret wrapper types (`Fixed<T>`, `Dynamic<T>`, etc.).
9//! These traits allow writing polymorphic code that preserves strong security invariants:
10//! explicit access, controlled mutability, timing safety, and opt-in risk features.
11//!
12//! # Core Traits
13//!
14//! | Trait                  | Purpose                                      | Requires Feature         | Notes                                                                 |
15//! |------------------------|----------------------------------------------|--------------------------|-----------------------------------------------------------------------|
16//! | [`RevealSecret`]       | Read-only scoped / direct access             | Always available         | Preferred: `with_secret` (scoped); escape hatch: `expose_secret`      |
17//! | [`SecretLen`]          | Length metadata (`len`, `byte_len`, …)       | Always available         | Only for `[T; N]`, `String`, `Vec<T>`; does not expose contents, but length can itself be sensitive — see trait docs |
18//! | [`RevealSecretMut`]    | Mutable scoped / direct access               | Always available         | Same preference: `with_secret_mut` over `expose_secret_mut`           |
19//! | [`SentinelValue`]      | Inert placeholder left by `into_inner`       | Always available         | Implemented for `[T; N]` (any `N`), `String`, `Vec<T>`                |
20//! | [`ConstantTimeEq`]     | Deterministic constant-time equality         | `ct-eq`                  | Timing-attack resistant byte comparison                               |
21//! | [`CloneableSecret`]    | Opt-in marker for safe cloning               | `cloneable`              | Requires explicit impl on inner type; zeroize preserved. See [`SECURITY.md`](https://github.com/Slurp9187/secure-gate/blob/main/SECURITY.md) for opt-in risk details. |
22//! | [`SerializableSecret`] | Opt-in marker for Serde serialization        | `serde-serialize`        | Serialization exposes secret — use with extreme caution. See [`SECURITY.md`](https://github.com/Slurp9187/secure-gate/blob/main/SECURITY.md) for opt-in risk details. |
23//! | [`SecureEncoding`]     | Marker + blanket impl for encoding traits    | Any `encoding-*`         | Enables `ToHex`, `ToBase32`, `ToBase64Url`, `ToBech32`, `ToBech32m`   |
24//! | [`SecureDecoding`]     | Marker + blanket impl for decoding traits    | Any `encoding-*`         | Enables `FromHexStr`, `FromBase32Str`, `FromBase64UrlStr`, etc.       |
25//!
26//! # Security Guarantees
27//!
28//! - **No implicit access while held** — Reaching a secret inside `Fixed`/`Dynamic`
29//!   requires an explicit trait method. The output wrappers returned by extraction
30//!   ([`InnerSecret`], [`EncodedSecret`]) deref by design
31//! - **Scoped preference** — `with_secret` / `with_secret_mut` limit borrow lifetime
32//! - **Zero-cost** — All methods use `#[inline(always)]` where possible
33//! - **Timing safety** — `ConstantTimeEq` provides constant-time equality
34//! - **Opt-in risk** — Cloning and serialization require deliberate marker impls
35//! - **Read-only enforcement** — Encoding wrappers and random types only expose immutable access
36//!
37//! # Feature Gates
38//!
39//! Some traits are only available when their corresponding Cargo features are enabled:
40//!
41//! - `ct-eq`          → [`ConstantTimeEq`]
42//! - `cloneable`      → [`CloneableSecret`]
43//! - `serde-serialize`→ [`SerializableSecret`]
44//! - `encoding-*`     → [`SecureEncoding`], [`SecureDecoding`], and per-format traits
45//!
46//! The encoding traits (`ToHex`, `FromHexStr`, etc.) are re-exported from submodules for convenience.
47//!
48//! See individual trait docs for detailed usage and examples.
49
50pub mod revealed_secrets;
51pub use revealed_secrets::InnerSecret;
52
53#[cfg(feature = "alloc")]
54pub use revealed_secrets::EncodedSecret;
55
56pub mod reveal_secret;
57pub use reveal_secret::{RevealSecret, SecretLen};
58
59pub mod reveal_secret_mut;
60pub use reveal_secret_mut::RevealSecretMut;
61
62pub mod sentinel_value;
63pub use sentinel_value::SentinelValue;
64
65#[cfg(feature = "ct-eq")]
66pub mod constant_time_eq;
67#[cfg(feature = "ct-eq")]
68pub use constant_time_eq::ConstantTimeEq;
69
70pub mod decoding;
71pub mod encoding;
72
73// Re-export per-format decoding traits (feature-gated; blanket impls return Vec<u8> — alloc required)
74#[cfg(all(feature = "encoding-base32", feature = "alloc"))]
75pub use decoding::FromBase32Str;
76
77#[cfg(all(feature = "encoding-base64", feature = "alloc"))]
78pub use decoding::FromBase64UrlStr;
79
80#[cfg(all(feature = "encoding-bech32", feature = "alloc"))]
81pub use decoding::FromBech32Str;
82
83#[cfg(all(feature = "encoding-bech32m", feature = "alloc"))]
84pub use decoding::FromBech32mStr;
85
86#[cfg(all(feature = "encoding-hex", feature = "alloc"))]
87pub use decoding::FromHexStr;
88
89// Re-export per-format encoding traits (feature-gated)
90// Note: blanket impls of ToBase32, ToBase64Url, ToBech32, ToBech32m require alloc (String output).
91// The traits themselves are exported unconditionally so inherent methods on Fixed/Dynamic
92// can call them; the blanket impls gate the alloc dependency.
93#[cfg(all(feature = "encoding-base32", feature = "alloc"))]
94pub use encoding::ToBase32;
95
96#[cfg(all(feature = "encoding-base64", feature = "alloc"))]
97pub use encoding::ToBase64Url;
98
99#[cfg(all(feature = "encoding-bech32", feature = "alloc"))]
100pub use encoding::ToBech32;
101
102#[cfg(all(feature = "encoding-bech32m", feature = "alloc"))]
103pub use encoding::ToBech32m;
104
105#[cfg(all(feature = "encoding-hex", feature = "alloc"))]
106pub use encoding::ToHex;
107
108/// Marker trait for types that support secure encoding operations.
109///
110/// Automatically implemented for any type that implements `AsRef<[u8]>`,
111/// such as `&[u8]`, `Vec<u8>`, `[u8; N]`, etc. This enables blanket impls
112/// of the individual encoding traits (`ToHex`, `ToBase32`, `ToBase64Url`, `ToBech32`, etc.).
113///
114/// Since this is a marker trait (no methods), it exists only to allow trait
115/// bounds and extension methods to be available where appropriate.
116///
117/// Requires at least one `encoding-*` feature to be enabled.
118#[cfg(any(
119    feature = "encoding-hex",
120    feature = "encoding-base32",
121    feature = "encoding-base64",
122    feature = "encoding-bech32",
123    feature = "encoding-bech32m",
124))]
125pub trait SecureEncoding {}
126
127#[cfg(any(
128    feature = "encoding-hex",
129    feature = "encoding-base32",
130    feature = "encoding-base64",
131    feature = "encoding-bech32",
132    feature = "encoding-bech32m",
133))]
134impl<T: AsRef<[u8]> + ?Sized> SecureEncoding for T {}
135
136/// Marker trait for types that support secure decoding operations.
137///
138/// Automatically implemented for any type that implements `AsRef<str>`,
139/// such as `&str`, `String`, etc. This enables blanket impls of the
140/// individual decoding traits (`FromHexStr`, `FromBase32Str`, `FromBase64UrlStr`, etc.).
141///
142/// Like `SecureEncoding`, this is a marker trait with no methods — it exists
143/// to allow trait bounds and extension methods where relevant.
144///
145/// Requires at least one `encoding-*` feature to be enabled.
146#[cfg(any(
147    feature = "encoding-hex",
148    feature = "encoding-base32",
149    feature = "encoding-base64",
150    feature = "encoding-bech32",
151    feature = "encoding-bech32m",
152))]
153pub trait SecureDecoding {}
154
155#[cfg(any(
156    feature = "encoding-hex",
157    feature = "encoding-base32",
158    feature = "encoding-base64",
159    feature = "encoding-bech32",
160    feature = "encoding-bech32m",
161))]
162impl<T: AsRef<str> + ?Sized> SecureDecoding for T {}
163
164#[cfg(feature = "cloneable")]
165pub mod cloneable_secret;
166#[cfg(feature = "cloneable")]
167pub use cloneable_secret::CloneableSecret;
168
169#[cfg(feature = "serde-serialize")]
170pub mod serializable_secret;
171#[cfg(feature = "serde-serialize")]
172pub use serializable_secret::SerializableSecret;