secure_gate/
lib.rs

1// src/lib.rs
2//! # secure-gate: Zero-cost secure wrappers for secrets
3//!
4//! This crate provides safe, ergonomic wrappers for handling sensitive data in memory
5//! with zero runtime overhead. It supports both stack-allocated fixed-size secrets
6//! and heap-allocated dynamic secrets, with optional automatic zeroing on drop.
7//!
8//! Key components:
9//! - [`Fixed<T>`]: Stack-allocated for fixed-size secrets (e.g., keys, nonces).
10//! - [`Dynamic<T>`]: Heap-allocated for dynamic secrets (e.g., passwords, vectors).
11//! - Zeroizing variants: [`FixedZeroizing<T>`] and [`DynamicZeroizing<T>`] for auto-wiping (with `zeroize` feature).
12//! - Macros: [`fixed_alias!`], [`dynamic_alias!`], [`secure!`], [`secure_zeroizing!`] for ergonomic usage.
13//!
14//! # Features
15//!
16//! - `zeroize`: Enables automatic memory wiping on drop via `zeroize` and `secrecy`.
17//! - `rand`: Enables `SecureRandomExt::random()` for generating fixed-size secrets.
18//! - `conversions`: **Optional** — adds `.to_hex()`, `.to_hex_upper()`, `.to_base64url()`, and `.ct_eq()` to all fixed-size secrets.
19//! - `serde`: Optional serialization support (deserialization disabled for `Dynamic<T>` for security).
20//! - Works in `no_std` + `alloc` environments.
21//!
22//! # Quick Start
23//!
24//! ```
25//! use secure_gate::{fixed_alias, dynamic_alias};
26//!
27//! #[cfg(feature = "rand")]
28//! use secure_gate::{random_alias, SecureRandomExt};
29//!
30//! fixed_alias!(Aes256Key, 32);
31//! dynamic_alias!(Password, String);
32//!
33//! #[cfg(feature = "rand")]
34//! {
35//!     random_alias!(RandomAes256Key, 32);
36//!     let key = RandomAes256Key::new();
37//!     let _ = key.expose_secret();
38//! }
39//!
40//! #[cfg(all(feature = "rand", feature = "conversions"))]
41//! {
42//!     use secure_gate::{SecureConversionsExt};
43//!     random_alias!(RandomAes256Key, 32);
44//!     let key = RandomAes256Key::new();
45//!     let hex = key.expose_secret().to_hex();
46//!     let b64 = key.expose_secret().to_base64url();
47//!     assert!(key.expose_secret().ct_eq(key.expose_secret()));
48//! }
49//!
50//! let pw: Password = "hunter2".into();
51//! assert_eq!(pw.expose_secret(), "hunter2");
52//! ```
53//!
54//! See individual modules for detailed documentation.
55
56#![cfg_attr(not(feature = "zeroize"), forbid(unsafe_code))]
57extern crate alloc;
58
59// Core modules
60mod dynamic;
61mod fixed;
62mod macros;
63
64// Feature-gated modules
65#[cfg(feature = "zeroize")]
66mod zeroize;
67
68#[cfg(feature = "serde")]
69mod serde;
70
71#[cfg(feature = "conversions")]
72pub mod conversions;
73
74// Public API
75pub use dynamic::Dynamic;
76pub use fixed::Fixed;
77
78// Zeroize integration (opt-in)
79#[cfg(feature = "zeroize")]
80pub use zeroize::{DynamicZeroizing, FixedZeroizing};
81
82// Re-export Zeroizing cleanly — no privacy conflict
83#[cfg(feature = "zeroize")]
84pub type Zeroizing<T> = ::zeroize::Zeroizing<T>;
85
86#[cfg(feature = "zeroize")]
87pub use ::zeroize::{Zeroize, ZeroizeOnDrop};
88
89// RNG integration (opt-in)
90#[cfg(feature = "rand")]
91pub mod rng;
92
93#[cfg(feature = "rand")]
94pub use rng::{RandomBytes, SecureRandomExt};
95
96// Conversions integration (opt-in)
97#[cfg(feature = "conversions")]
98pub use conversions::SecureConversionsExt;
99
100#[cfg(all(feature = "rand", feature = "conversions"))]
101pub use conversions::RandomHex;