Skip to main content

secure_gate/
lib.rs

1// #![doc = include_str!("../README.md")] //uncomment for doctest runs
2
3// Forbid unsafe code unconditionally
4#![forbid(unsafe_code)]
5#![warn(missing_docs)]
6
7//! Secure wrappers for secrets with **explicit access** and **mandatory zeroization** — a
8//! `no_std`-compatible, zero-overhead library with audit-friendly access patterns.
9//!
10//! Secrets are **automatically zeroized on drop** (the inner type must implement [`Zeroize`](zeroize::Zeroize)).
11//! Explicit access only via [`RevealSecret`]/[`RevealSecretMut`] — no `Deref`, no accidental leaks.
12//! `Debug` always prints `[REDACTED]`.
13//!
14//! - [`Fixed<T>`] — stack-allocated, compile-time-sized secrets (keys, nonces, tokens)
15//! - [`Dynamic<T>`] — heap-allocated, variable-length secrets (passwords, API keys, ciphertexts)
16//!
17//! # Feature flags
18//!
19//! - `alloc` *(default)*: Heap-allocated [`Dynamic<T>`] + full zeroization of spare capacity
20//! - `std`: Full `std` support (implies `alloc`)
21//! - `ct-eq`: [`ConstantTimeEq`] constant-time equality (`subtle`)
22//! - `rand`: `from_random()` via `SysRng`; `from_rng()` for any caller-supplied `TryRng + TryCryptoRng`; `no_std` compatible for `Fixed<T>` (no heap required)
23//! - `cloneable`: [`CloneableSecret`] opt-in cloning
24//! - `serde-serialize` / `serde-deserialize`: Serde support
25//! - `encoding-hex` / `encoding-base64` / `encoding-bech32` / `encoding-bech32m`: Per-format encoding
26//! - `full`: All features
27//!
28//! # no_std
29//!
30//! `no_std` compatible. [`Fixed<T>`] works without `alloc`. Enable `alloc` (default) for
31//! [`Dynamic<T>`]. For pure stack / embedded builds, use `default-features = false`.
32//!
33//! See the [README](https://github.com/Slurp9187/secure-gate/blob/main/README.md) and
34//! [SECURITY.md](https://github.com/Slurp9187/secure-gate/blob/main/SECURITY.md) for full details.
35
36#[cfg(feature = "alloc")]
37extern crate alloc;
38
39#[cfg(feature = "alloc")]
40mod dynamic;
41
42/// Fixed-size secret wrapper types - always available with zero dependencies.
43/// These provide fundamental secure storage abstractions for fixed-size data.
44mod fixed;
45
46/// Centralized error types - always available.
47mod error;
48
49/// Core traits for wrapper polymorphism - always available.
50pub mod traits;
51
52#[cfg(feature = "alloc")]
53/// Heap-allocated secret wrapper with explicit access and automatic zeroization on drop.
54///
55/// Requires `alloc` feature. Inner type must implement `Zeroize`.
56pub use dynamic::Dynamic;
57
58#[cfg(all(feature = "alloc", feature = "serde-deserialize"))]
59/// Default maximum byte length for `Dynamic<Vec<u8>>` / `Dynamic<String>` deserialization (1 MiB).
60///
61/// The standard `serde::Deserialize` impl for both types rejects payloads exceeding this value.
62/// Pass a custom ceiling to [`Dynamic::deserialize_with_limit`] when a different limit is needed.
63///
64/// **Important:** this limit is enforced *after* the upstream deserializer has fully
65/// materialized the payload. It is a **result-length acceptance bound**, not a
66/// pre-allocation DoS guard. For untrusted input, enforce size limits at the
67/// transport or parser layer upstream.
68pub use dynamic::MAX_DESERIALIZE_BYTES;
69
70/// Stack-allocated secret wrapper with explicit access and automatic zeroization on drop.
71///
72/// Always available. Inner type must implement `Zeroize`.
73pub use fixed::Fixed;
74
75#[cfg(feature = "cloneable")]
76/// Marker trait for secrets that can be cloned.
77///
78/// Enables cloning of wrapped secrets. Requires `cloneable` feature.
79pub use traits::CloneableSecret;
80
81#[cfg(feature = "ct-eq")]
82/// Constant-time equality for secrets.
83///
84/// Provides `ct_eq()` method using `subtle`. Requires `ct-eq` feature.
85pub use traits::ConstantTimeEq;
86
87/// Explicit immutable access to secret contents.
88///
89/// Provides `expose_secret()` and `with_secret()` methods.
90pub use traits::RevealSecret;
91
92/// Explicit mutable access to secret contents.
93///
94/// Provides `expose_secret_mut()` and `with_secret_mut()` methods.
95pub use traits::RevealSecretMut;
96
97#[cfg(feature = "serde-serialize")]
98/// Marker trait for secrets that can be serialized with Serde.
99///
100/// Enables serialization. Requires `serde-serialize` feature.
101pub use traits::SerializableSecret;
102
103// Type alias macros (always available)
104mod macros;
105
106#[cfg(feature = "encoding-base64")]
107pub use traits::FromBase64UrlStr;
108
109#[cfg(feature = "encoding-bech32")]
110pub use traits::FromBech32Str;
111
112#[cfg(feature = "encoding-bech32m")]
113pub use traits::FromBech32mStr;
114
115#[cfg(feature = "encoding-hex")]
116pub use traits::FromHexStr;
117
118#[cfg(feature = "encoding-base64")]
119pub use traits::ToBase64Url;
120
121#[cfg(feature = "encoding-bech32")]
122pub use traits::ToBech32;
123
124#[cfg(feature = "encoding-bech32m")]
125pub use traits::ToBech32m;
126
127#[cfg(feature = "encoding-hex")]
128pub use traits::ToHex;
129
130#[cfg(any(
131    feature = "encoding-hex",
132    feature = "encoding-base64",
133    feature = "encoding-bech32",
134    feature = "encoding-bech32m",
135))]
136pub use traits::SecureDecoding;
137
138#[cfg(any(
139    feature = "encoding-hex",
140    feature = "encoding-base64",
141    feature = "encoding-bech32",
142    feature = "encoding-bech32m",
143))]
144pub use traits::SecureEncoding;
145
146#[cfg(any(feature = "encoding-bech32", feature = "encoding-bech32m"))]
147pub use error::Bech32Error;
148
149#[cfg(feature = "encoding-base64")]
150pub use error::Base64Error;
151
152#[cfg(feature = "encoding-hex")]
153pub use error::HexError;
154
155pub use error::DecodingError;
156pub use error::FromSliceError;
157
158/// secrecy compatibility layers — drop-in replacements for the `secrecy` crate.
159///
160/// Enable with `features = ["secrecy-compat"]`. Two sub-modules are provided:
161/// [`compat::v10`] mirrors secrecy 0.10.1 (`SecretBox<S>`, heap-allocated), and
162/// [`compat::v08`] mirrors secrecy 0.8.0 (`Secret<S>`, stack-allocated). Shared
163/// traits ([`compat::ExposeSecret`], [`compat::CloneableSecret`], etc.) live in the
164/// module root. See each sub-module for a full migration guide.
165#[cfg(feature = "secrecy-compat")]
166pub mod compat;