pub struct Dynamic<T: ?Sized + Zeroize> { /* private fields */ }Expand description
Heap-allocated secret wrapper with explicit access and automatic zeroization on drop.
Requires alloc feature. Inner type must implement Zeroize.
Zero-cost heap-allocated wrapper for variable-length secrets.
Requires alloc. Inner type must implement Zeroize for automatic zeroization on drop
(including spare capacity in Vec/String).
No Deref, AsRef, or Copy by default — all access requires
expose_secret() or
with_secret() (scoped, preferred).
For the common concrete types, Dynamic::<Vec<u8>>::new_with and
Dynamic::<String>::new_with are the matching scoped constructors —
closures that write directly into the wrapper. new(value) remains
available as the ergonomic default. Debug always prints [REDACTED].
Implementations§
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
pub fn to_hex(&self) -> String
pub fn to_hex_upper(&self) -> String
pub fn to_base64url(&self) -> String
Source§impl Dynamic<String>
impl Dynamic<String>
Sourcepub fn new_with<F>(f: F) -> Self
pub fn new_with<F>(f: F) -> Self
Closure-based constructor for consistent API with Fixed::new_with.
The actual secret data is allocated on the heap; this method exists
for ergonomic uniformity across the crate.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn from_random(len: usize) -> Self
pub fn from_random(len: usize) -> Self
Allocates a Vec<u8> of length len, fills it with cryptographically secure random bytes,
and wraps it.
Uses the system RNG (OsRng). Requires the rand feature and alloc
(implicit — Dynamic<T> itself requires alloc).
§Panics
Panics if the RNG fails (TryRngCore::try_fill_bytes
returns Err). This is treated as a fatal environment error.
Sourcepub fn from_rng<R: TryRngCore + TryCryptoRng>(
len: usize,
rng: &mut R,
) -> Result<Self, R::Error>
pub fn from_rng<R: TryRngCore + TryCryptoRng>( len: usize, rng: &mut R, ) -> Result<Self, R::Error>
Allocates a Vec<u8> of length len, fills it from rng, and wraps it.
Accepts any TryCryptoRng + TryRngCore (e.g. a
seeded generator for deterministic tests). Requires the rand feature and alloc.
§Errors
Returns R::Error if try_fill_bytes fails.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn try_from_hex(s: &str) -> Result<Self, HexError>
pub fn try_from_hex(s: &str) -> Result<Self, HexError>
Decodes a lowercase hex string into Dynamic<Vec<u8>>.
The decoded buffer is kept inside a Zeroizing wrapper until after the
Box allocation completes, guaranteeing zeroization even on OOM panic.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn try_from_base64url(s: &str) -> Result<Self, Base64Error>
pub fn try_from_base64url(s: &str) -> Result<Self, Base64Error>
Decodes a Base64url (unpadded) string into Dynamic<Vec<u8>>.
The decoded buffer is kept inside a Zeroizing wrapper until after the
Box allocation completes, guaranteeing zeroization even on OOM panic.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn try_from_bech32_unchecked(s: &str) -> Result<Self, Bech32Error>
pub fn try_from_bech32_unchecked(s: &str) -> Result<Self, Bech32Error>
Decodes a Bech32 (BIP-173) string into Dynamic<Vec<u8>>.
The decoded buffer is kept inside a Zeroizing wrapper until after the
Box allocation completes, guaranteeing zeroization even on OOM panic.
§Warning
The HRP is not validated — any HRP will be accepted as long as the checksum
is valid. For security-critical code where cross-protocol confusion must be
prevented, use try_from_bech32.
Sourcepub fn try_from_bech32(s: &str, expected_hrp: &str) -> Result<Self, Bech32Error>
pub fn try_from_bech32(s: &str, expected_hrp: &str) -> Result<Self, Bech32Error>
Decodes a Bech32 (BIP-173) string into Dynamic<Vec<u8>>, validating that the HRP
matches expected_hrp (case-insensitive).
The decoded buffer is kept inside a Zeroizing wrapper until after the
Box allocation completes, guaranteeing zeroization even on OOM panic.
Prefer this over try_from_bech32_unchecked in
security-critical code to prevent cross-protocol confusion attacks.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn try_from_bech32m_unchecked(s: &str) -> Result<Self, Bech32Error>
pub fn try_from_bech32m_unchecked(s: &str) -> Result<Self, Bech32Error>
Decodes a Bech32m (BIP-350) string into Dynamic<Vec<u8>>.
The decoded buffer is kept inside a Zeroizing wrapper until after the
Box allocation completes, guaranteeing zeroization even on OOM panic.
§Warning
The HRP is not validated — any HRP will be accepted as long as the checksum
is valid. For security-critical code where cross-protocol confusion must be
prevented, use try_from_bech32m.
Sourcepub fn try_from_bech32m(
s: &str,
expected_hrp: &str,
) -> Result<Self, Bech32Error>
pub fn try_from_bech32m( s: &str, expected_hrp: &str, ) -> Result<Self, Bech32Error>
Decodes a Bech32m (BIP-350) string into Dynamic<Vec<u8>>, validating that the HRP
matches expected_hrp (case-insensitive).
The decoded buffer is kept inside a Zeroizing wrapper until after the
Box allocation completes, guaranteeing zeroization even on OOM panic.
Prefer this over try_from_bech32m_unchecked in
security-critical code to prevent cross-protocol confusion attacks.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn deserialize_with_limit<'de, D>(
deserializer: D,
limit: usize,
) -> Result<Self, D::Error>where
D: Deserializer<'de>,
pub fn deserialize_with_limit<'de, D>(
deserializer: D,
limit: usize,
) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Deserializes into Dynamic<Vec<u8>>, rejecting payloads larger than limit bytes.
The standard serde::Deserialize impl calls this with MAX_DESERIALIZE_BYTES.
Use this method directly when you need a tighter or looser ceiling.
The intermediate buffer is kept inside a Zeroizing wrapper until after the Box
allocation completes, guaranteeing zeroization even on OOM panic. Oversized buffers
are also zeroized before the error is returned.
Important: this limit is enforced after the upstream deserializer has fully materialized the payload. It is a result-length acceptance bound, not a pre-allocation DoS guard. For untrusted input, enforce size limits at the transport or parser layer upstream.
Source§impl Dynamic<String>
impl Dynamic<String>
Sourcepub fn deserialize_with_limit<'de, D>(
deserializer: D,
limit: usize,
) -> Result<Self, D::Error>where
D: Deserializer<'de>,
pub fn deserialize_with_limit<'de, D>(
deserializer: D,
limit: usize,
) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Deserializes into Dynamic<String>, rejecting payloads larger than limit bytes.
The standard serde::Deserialize impl calls this with MAX_DESERIALIZE_BYTES.
Use this method directly when you need a tighter or looser ceiling.
The intermediate buffer is kept inside a Zeroizing wrapper until after the Box
allocation completes, guaranteeing zeroization even on OOM panic. Oversized buffers
are also zeroized before the error is returned.
Important: this limit is enforced after the upstream deserializer has fully materialized the payload. It is a result-length acceptance bound, not a pre-allocation DoS guard. For untrusted input, enforce size limits at the transport or parser layer upstream.
Trait Implementations§
Source§impl<T: Zeroize + CloneableSecret> Clone for Dynamic<T>
Available on crate feature cloneable only.
impl<T: Zeroize + CloneableSecret> Clone for Dynamic<T>
cloneable only.Source§impl<T> ConstantTimeEq for Dynamic<T>
Available on crate feature ct-eq only.
impl<T> ConstantTimeEq for Dynamic<T>
ct-eq only.Source§impl<'de> Deserialize<'de> for Dynamic<String>
Available on crate feature serde-deserialize only.
impl<'de> Deserialize<'de> for Dynamic<String>
serde-deserialize only.Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl<'de> Deserialize<'de> for Dynamic<Vec<u8>>
Available on crate feature serde-deserialize only.
impl<'de> Deserialize<'de> for Dynamic<Vec<u8>>
serde-deserialize only.Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl ExposeSecret<String> for Dynamic<String>
impl ExposeSecret<String> for Dynamic<String>
Source§fn expose_secret(&self) -> &String
fn expose_secret(&self) -> &String
Source§impl<T: Zeroize> ExposeSecret<Vec<T>> for Dynamic<Vec<T>>
impl<T: Zeroize> ExposeSecret<Vec<T>> for Dynamic<Vec<T>>
Source§fn expose_secret(&self) -> &Vec<T>
fn expose_secret(&self) -> &Vec<T>
Source§impl ExposeSecretMut<String> for Dynamic<String>
impl ExposeSecretMut<String> for Dynamic<String>
Source§fn expose_secret_mut(&mut self) -> &mut String
fn expose_secret_mut(&mut self) -> &mut String
Source§impl<T: Zeroize> ExposeSecretMut<Vec<T>> for Dynamic<Vec<T>>
impl<T: Zeroize> ExposeSecretMut<Vec<T>> for Dynamic<Vec<T>>
Source§fn expose_secret_mut(&mut self) -> &mut Vec<T>
fn expose_secret_mut(&mut self) -> &mut Vec<T>
Source§impl From<Dynamic<String>> for SecretBox<String>
Converts a Dynamic<String> back into a SecretBox<String>.
impl From<Dynamic<String>> for SecretBox<String>
Converts a Dynamic<String> back into a SecretBox<String>.
Clones the inner String. Both the source and the new wrapper are zeroized on drop.
Source§impl From<Dynamic<String>> for SecretString
Converts a Dynamic<String> into a SecretString (= SecretBox<str>).
impl From<Dynamic<String>> for SecretString
Converts a Dynamic<String> into a SecretString (= SecretBox<str>).
Clones the inner string. Both ends are zeroized on drop.
Source§impl<S: Clone + Zeroize + 'static> From<Dynamic<Vec<S>>> for SecretBox<Vec<S>>
Converts a Dynamic<Vec<S>> back into a SecretBox<Vec<S>>.
impl<S: Clone + Zeroize + 'static> From<Dynamic<Vec<S>>> for SecretBox<Vec<S>>
Converts a Dynamic<Vec<S>> back into a SecretBox<Vec<S>>.
Clones the inner Vec. Both ends are zeroized on drop.
Source§impl<T: Clone + Zeroize + 'static> From<Dynamic<Vec<T>>> for Secret<Vec<T>>
Converts a Dynamic<Vec<T>> into Secret<Vec<T>>.
impl<T: Clone + Zeroize + 'static> From<Dynamic<Vec<T>>> for Secret<Vec<T>>
Converts a Dynamic<Vec<T>> into Secret<Vec<T>>.
Source§impl<T: Clone + Zeroize + 'static> From<Secret<Vec<T>>> for Dynamic<Vec<T>>
Converts Secret<Vec<T>> into a Dynamic<Vec<T>>.
impl<T: Clone + Zeroize + 'static> From<Secret<Vec<T>>> for Dynamic<Vec<T>>
Converts Secret<Vec<T>> into a Dynamic<Vec<T>>.
Source§impl<S: Clone + Zeroize + 'static> From<SecretBox<S>> for Dynamic<S>
Converts a SecretBox<S> into a Dynamic<S> (primary migration path).
impl<S: Clone + Zeroize + 'static> From<SecretBox<S>> for Dynamic<S>
Converts a SecretBox<S> into a Dynamic<S> (primary migration path).
Requires S: Clone because the inner Box<S> cannot be moved out of SecretBox
without unsafe code (SecretBox has a Drop impl). The clone is immediately
wrapped in Dynamic and the original is zeroized on drop.
For zero-copy migration, construct Dynamic<S> directly instead.
Source§impl From<SecretBox<str>> for Dynamic<String>
Converts a SecretString (= SecretBox<str>) into a Dynamic<String>.
impl From<SecretBox<str>> for Dynamic<String>
Converts a SecretString (= SecretBox<str>) into a Dynamic<String>.
Clones the inner str into a new String. Both ends are zeroized on drop.
Source§fn from(sb: SecretString) -> Self
fn from(sb: SecretString) -> Self
Source§impl RevealSecret for Dynamic<String>
impl RevealSecret for Dynamic<String>
Source§fn with_secret<F, R>(&self, f: F) -> R
fn with_secret<F, R>(&self, f: F) -> R
Source§fn expose_secret(&self) -> &String
fn expose_secret(&self) -> &String
Source§impl<T: Zeroize> RevealSecret for Dynamic<Vec<T>>
impl<T: Zeroize> RevealSecret for Dynamic<Vec<T>>
Source§fn with_secret<F, R>(&self, f: F) -> R
fn with_secret<F, R>(&self, f: F) -> R
Source§fn expose_secret(&self) -> &Vec<T>
fn expose_secret(&self) -> &Vec<T>
Source§impl RevealSecretMut for Dynamic<String>
impl RevealSecretMut for Dynamic<String>
Source§impl<T: Zeroize + SerializableSecret> Serialize for Dynamic<T>
Available on crate feature serde-serialize only.
impl<T: Zeroize + SerializableSecret> Serialize for Dynamic<T>
serde-serialize only.