pub struct Dynamic<T: ?Sized + Zeroize> { /* private fields */ }alloc only.Expand description
Heap-allocated secret wrapper with explicit access and automatic zeroization on drop.
Variable-length secrets (passwords, API keys, ciphertexts). Inner type must implement
Zeroize. Secret bytes live on the heap only — never on the stack. Requires alloc.
See Fixed<T> for the stack-allocated alternative.
use secure_gate::{Dynamic, RevealSecret};
let pw: Dynamic<String> = Dynamic::new(String::from("hunter2"));
assert_eq!(pw.with_secret(|s: &String| s.len()), 7);
assert_eq!(format!("{:?}", pw), "[REDACTED]");Zero-cost heap-allocated wrapper for variable-length secrets.
Dynamic<T> stores a T: Zeroize value in a Box<T> and unconditionally zeroizes
it on drop (including Vec/String spare capacity). There is no Deref, AsRef,
or Copy — every access is explicit through RevealSecret
or RevealSecretMut.
This is not Fixed<T> — it is the heap-allocated alternative for variable-length
secrets. Secret bytes never reside on the stack.
§Examples
use secure_gate::{Dynamic, RevealSecret, SecretLen};
let pw: Dynamic<String> = Dynamic::new(String::from("hunter2"));
assert_eq!(pw.with_secret(|s: &String| s.len()), 7);
assert_eq!(format!("{:?}", pw), "[REDACTED]");§Constructors for Dynamic<Vec<u8>>
| Constructor | Feature | Notes |
|---|---|---|
new(value) | — | Accepts Vec<u8>, &[u8], Box<Vec<u8>> |
new_with(f) | — | Scoped closure construction |
try_from_hex(s) | encoding-hex | Constant-time hex decoding |
try_from_base32(s) | encoding-base32 | Constant-time Base32 decoding |
try_from_base64url(s) | encoding-base64 | Constant-time Base64url decoding |
try_from_bech32(s, hrp) | encoding-bech32 | HRP-validated Bech32 |
try_from_bech32_unchecked(s) | encoding-bech32 | Bech32 without HRP check |
try_from_bech32m(s, hrp) | encoding-bech32 | HRP-validated Bech32m |
try_from_bech32m_unchecked(s) | encoding-bech32 | Bech32m without HRP check |
from_random(len) | rand | System RNG |
from_rng(len, rng) | rand | Custom RNG |
§See also
RevealSecret/RevealSecretMut— the 3-tier access traits.Fixed<T>— stack-allocated alternative.
Implementations§
Source§impl<T: ?Sized + Zeroize> Dynamic<T>
impl<T: ?Sized + Zeroize> Dynamic<T>
Sourcepub fn new<U>(value: U) -> Self
pub fn new<U>(value: U) -> Self
Wraps value in a Box<T> and returns a Dynamic<T>.
Accepts any type that implements Into<Box<T>> — including owned values,
Box<T>, String, Vec<u8>, &str (via the blanket From<&str> impl), etc.
Equivalent to Dynamic::from(value) — #[doc(alias = "from")] is set so both
names appear in docs.rs search.
Requires the alloc feature (which Dynamic<T> itself always requires).
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn try_from_hex(s: &str) -> Result<Self, HexError>
Available on crate feature encoding-hex only.
pub fn try_from_hex(s: &str) -> Result<Self, HexError>
encoding-hex only.Decodes a hex string (lowercase, uppercase, or mixed) 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_base32(s: &str) -> Result<Self, Base32Error>
Available on crate feature encoding-base32 only.
pub fn try_from_base32(s: &str) -> Result<Self, Base32Error>
encoding-base32 only.Decodes an uppercase, unpadded Base32 (RFC 4648 §6) 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.
Decoding is strict about the alphabet, case, padding and length, but lenient
about non-canonical trailing bits: unused bits in the final group are ignored
rather than rejected, so "MZ" and "MY" both decode to [0x66]. Decoding is
therefore not injective — two distinct strings can yield the same bytes, and
only encoder-produced strings are canonical. Do not use the decoded value to
decide that two encoded strings were equal.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn try_from_base64url(s: &str) -> Result<Self, Base64Error>
Available on crate feature encoding-base64 only.
pub fn try_from_base64url(s: &str) -> Result<Self, Base64Error>
encoding-base64 only.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(s: &str, expected_hrp: &str) -> Result<Self, Bech32Error>
Available on crate feature encoding-bech32 only.
pub fn try_from_bech32(s: &str, expected_hrp: &str) -> Result<Self, Bech32Error>
encoding-bech32 only.Decodes a Bech32 (BIP-173) string into Dynamic<Vec<u8>>, validating the HRP
(case-insensitive).
The decoded buffer is kept inside a Zeroizing wrapper until after the
Box allocation completes, guaranteeing zeroization even on OOM panic.
HRP comparison is non-constant-time — this is intentional, as the HRP is public metadata, not secret material.
Sourcepub fn try_from_bech32_sized<const C: usize>(
s: &str,
expected_hrp: &str,
) -> Result<Self, Bech32Error>
Available on crate feature encoding-bech32 only.
pub fn try_from_bech32_sized<const C: usize>( s: &str, expected_hrp: &str, ) -> Result<Self, Bech32Error>
encoding-bech32 only.Like try_from_bech32, accepting strings up to C
characters.
C is the bech32 code length: the cap on the whole encoded string. Pass the C
the string was encoded with, or any larger value. See
Bech32Sized for what C above
BECH32_CODE_LENGTH costs.
Sourcepub fn try_from_bech32_unchecked(s: &str) -> Result<Self, Bech32Error>
Available on crate feature encoding-bech32 only.
pub fn try_from_bech32_unchecked(s: &str) -> Result<Self, Bech32Error>
encoding-bech32 only.Decodes a Bech32 (BIP-173) string into Dynamic<Vec<u8>> without validating the HRP.
Use try_from_bech32 in security-critical code to prevent
cross-protocol confusion attacks.
Sourcepub fn try_from_bech32_unchecked_sized<const C: usize>(
s: &str,
) -> Result<Self, Bech32Error>
Available on crate feature encoding-bech32 only.
pub fn try_from_bech32_unchecked_sized<const C: usize>( s: &str, ) -> Result<Self, Bech32Error>
encoding-bech32 only.Like try_from_bech32_unchecked, accepting
strings up to C characters.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn try_from_bech32m(
s: &str,
expected_hrp: &str,
) -> Result<Self, Bech32Error>
Available on crate feature encoding-bech32 only.
pub fn try_from_bech32m( s: &str, expected_hrp: &str, ) -> Result<Self, Bech32Error>
encoding-bech32 only.Decodes a Bech32m (BIP-350) string into Dynamic<Vec<u8>>, validating the HRP
(case-insensitive).
The decoded buffer is kept inside a Zeroizing wrapper until after the
Box allocation completes, guaranteeing zeroization even on OOM panic.
Sourcepub fn try_from_bech32m_sized<const C: usize>(
s: &str,
expected_hrp: &str,
) -> Result<Self, Bech32Error>
Available on crate feature encoding-bech32 only.
pub fn try_from_bech32m_sized<const C: usize>( s: &str, expected_hrp: &str, ) -> Result<Self, Bech32Error>
encoding-bech32 only.Like try_from_bech32m, accepting strings up to C
characters. See Bech32mSized for what C above
BECH32_CODE_LENGTH costs.
Sourcepub fn try_from_bech32m_unchecked(s: &str) -> Result<Self, Bech32Error>
Available on crate feature encoding-bech32 only.
pub fn try_from_bech32m_unchecked(s: &str) -> Result<Self, Bech32Error>
encoding-bech32 only.Decodes a Bech32m (BIP-350) string into Dynamic<Vec<u8>> without validating the HRP.
Use try_from_bech32m in security-critical code.
Sourcepub fn try_from_bech32m_unchecked_sized<const C: usize>(
s: &str,
) -> Result<Self, Bech32Error>
Available on crate feature encoding-bech32 only.
pub fn try_from_bech32m_unchecked_sized<const C: usize>( s: &str, ) -> Result<Self, Bech32Error>
encoding-bech32 only.Like try_from_bech32m_unchecked, accepting
strings up to C characters.
Source§impl Dynamic<Vec<u8>>
Construction helpers and random generation for Dynamic<Vec<u8>>.
impl Dynamic<Vec<u8>>
Construction helpers and random generation for Dynamic<Vec<u8>>.
Sourcepub fn new_with<F>(f: F) -> Self
pub fn new_with<F>(f: F) -> Self
Closure-based constructor that protects against closure panics.
The intermediate Vec<u8> is held inside a Zeroizing wrapper for the
entire duration of the closure, so any bytes the closure writes are
zeroed during stack unwinding if f panics. Constructed via the same
Zeroizing + swap pattern used by from_protected_bytes.
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 that protects against closure panics.
The intermediate String is held inside a Zeroizing wrapper for the
entire duration of the closure, so any bytes the closure writes are
zeroed during stack unwinding if f panics. Constructed via the same
Zeroizing + swap pattern used by from_protected_bytes.
Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn from_random(len: usize) -> Self
Available on crate feature rand only.
pub fn from_random(len: usize) -> Self
rand only.Fills a new Vec<u8> with len cryptographically secure random bytes and wraps it.
Uses the system RNG (SysRng). Requires the rand feature (and
alloc, which Dynamic<Vec<u8>> always needs).
§Panics
Panics if the system RNG fails to provide bytes (TryRng::try_fill_bytes
returns Err). This is treated as a fatal environment error.
§Examples
use secure_gate::{Dynamic, RevealSecret, SecretLen};
let nonce: Dynamic<Vec<u8>> = Dynamic::from_random(24);
assert_eq!(nonce.len(), 24);Sourcepub fn from_rng<R: TryRng + TryCryptoRng>(
len: usize,
rng: &mut R,
) -> Result<Self, R::Error>
Available on crate feature rand only.
pub fn from_rng<R: TryRng + TryCryptoRng>( len: usize, rng: &mut R, ) -> Result<Self, R::Error>
rand only.Allocates a Vec<u8> of length len, fills it from rng, and wraps it.
Accepts any TryCryptoRng + TryRng — for example,
a seeded StdRng for deterministic tests. Requires the rand
feature and alloc (implicit — Dynamic<T> itself requires it).
§Errors
Returns R::Error if try_fill_bytes fails.
§Examples
use rand::rngs::StdRng;
use rand::SeedableRng;
use secure_gate::Dynamic;
let mut rng = StdRng::from_seed([9u8; 32]);
let nonce: Dynamic<Vec<u8>> = Dynamic::from_rng(24, &mut rng).expect("rng fill");Source§impl Dynamic<Vec<u8>>
impl Dynamic<Vec<u8>>
Sourcepub fn as_reader(&self) -> DynamicReader<'_> ⓘ
Available on crate feature std only.
pub fn as_reader(&self) -> DynamicReader<'_> ⓘ
std only.Returns a DynamicReader that implements std::io::Read.
This replaces the common with_secret + Cursor boilerplate:
use std::io;
use secure_gate::Dynamic;
let secret = Dynamic::<Vec<u8>>::new(vec![1, 2, 3, 4]);
// Before: awkward closure + Cursor dance
// secret.with_secret(|b| io::copy(&mut Cursor::new(b), &mut encryptor))?;
// After: pipe directly into an encrypted writer — no intermediate buffer
let mut encryptor = io::sink(); // stand-in for a real encryptor
io::copy(&mut secret.as_reader(), &mut encryptor).unwrap();§Security
Each read() call copies secret bytes into the caller’s buffer.
Prefer piping directly into encrypted writers rather than reading
into intermediate buffers. The caller is responsible for zeroizing
any destination buffer.
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>,
Available on crate feature serde-deserialize only.
pub fn deserialize_with_limit<'de, D>(
deserializer: D,
limit: usize,
) -> Result<Self, D::Error>where
D: Deserializer<'de>,
serde-deserialize only.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.
Zeroization scope. Once the upstream deserializer returns a complete
Vec<u8>, the value is wrapped in Zeroizing and stays protected for the
rest of this function: oversized buffers are zeroized before the error is
returned, and an OOM panic in the subsequent Box allocation triggers
zeroization on unwind. However, this guarantee does not extend backwards
into the deserializer itself. If the upstream Vec<u8> visitor accumulates
bytes element-by-element (e.g., a JSON sequence) and fails partway through,
the partial buffer is owned by the visitor and dropped as a plain Vec<u8> —
not zeroized. In the typical untrusted-input threat model the partial bytes
are attacker-controlled (the malformed payload they sent), so the practical
disclosure surface is bounded; but if your threat model includes deserialization
of trusted-but-corruptible secret material, treat the deserialize step as
outside the zeroization boundary and use from_protected_bytes (private API)
or new_with for in-process construction instead.
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>,
Available on crate feature serde-deserialize only.
pub fn deserialize_with_limit<'de, D>(
deserializer: D,
limit: usize,
) -> Result<Self, D::Error>where
D: Deserializer<'de>,
serde-deserialize only.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.
Zeroization scope. Once the upstream deserializer returns a complete
String, the value is wrapped in Zeroizing and stays protected for the
rest of this function: oversized buffers are zeroized before the error is
returned, and an OOM panic in the subsequent Box allocation triggers
zeroization on unwind. However, this guarantee does not extend backwards
into the deserializer itself. If the upstream String visitor accumulates
characters and fails partway through (e.g., on an invalid UTF-8 boundary),
the partial buffer is owned by the visitor and dropped as a plain String —
not zeroized. In the typical untrusted-input threat model the partial bytes
are attacker-controlled (the malformed payload they sent), so the practical
disclosure surface is bounded; but if your threat model includes deserialization
of trusted-but-corruptible secret material, treat the deserialize step as
outside the zeroization boundary and use from_protected_bytes (private API)
or new_with for in-process construction instead.
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.Opt-in cloning — requires cloneable feature and CloneableSecret
marker. Each clone is independently zeroized on drop, but cloning increases exposure surface.
impl<T: Zeroize + CloneableSecret> Clone for Dynamic<T>
cloneable only.Opt-in cloning — requires cloneable feature and CloneableSecret
marker. Each clone is independently zeroized on drop, but cloning increases exposure surface.
Source§impl<T> ConstantTimeEq for Dynamic<T>
Available on crate feature ct-eq only.Constant-time equality for Dynamic<T> — routes through expose_secret().
impl<T> ConstantTimeEq for Dynamic<T>
ct-eq only.Constant-time equality for Dynamic<T> — routes through expose_secret().
== is deliberately not implemented. Always use ct_eq.
Source§impl<T: ?Sized + Zeroize> Debug for Dynamic<T>
Always prints [REDACTED] — secrets never appear in debug output.
impl<T: ?Sized + Zeroize> Debug for Dynamic<T>
Always prints [REDACTED] — secrets never appear in debug output.
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<'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<T: ?Sized + Zeroize> Drop for Dynamic<T>
Unconditionally zeroizes the inner value when the wrapper is dropped.
impl<T: ?Sized + Zeroize> Drop for Dynamic<T>
Unconditionally zeroizes the inner value when the wrapper is dropped.
Warning: Drop does not run under panic = "abort".
Source§impl<T: ?Sized + Zeroize> From<Box<T>> for Dynamic<T>
Zero-copy wrapping of an already-boxed value.
impl<T: ?Sized + Zeroize> From<Box<T>> for Dynamic<T>
Zero-copy wrapping of an already-boxed value.
Source§impl<T: ?Sized + Zeroize> RevealSecret for Dynamic<T>
impl<T: ?Sized + Zeroize> RevealSecret for Dynamic<T>
Source§fn into_inner(self) -> T
fn into_inner(self) -> T
Consumes self and transfers ownership of the plain inner value.
Allocation note: allocates one small Box<T> sentinel (24 bytes for
String/Vec on 64-bit) before the swap. If that allocation panics (OOM),
self.inner is unchanged and Dynamic::drop zeroizes the real secret during
unwind — confidentiality is preserved. This is the same OOM-safety pattern
used by from_protected_bytes and deserialize_with_limit.
See RevealSecret::into_inner for the full
contract. Protection ends at this call: the returned value is an ordinary
String / Vec<T>, moved out without copying.
Source§fn with_secret<F, R>(&self, f: F) -> R
fn with_secret<F, R>(&self, f: F) -> R
Source§fn expose_secret(&self) -> &T
fn expose_secret(&self) -> &T
Source§impl SecretLen for Dynamic<String>
impl SecretLen for Dynamic<String>
Source§impl<T: Zeroize> SecretLen for Dynamic<Vec<T>>
impl<T: Zeroize> SecretLen for Dynamic<Vec<T>>
Source§impl<T: Zeroize + SerializableSecret> Serialize for Dynamic<T>
Available on crate feature serde-serialize only.Opt-in serialization — requires serde-serialize feature and
SerializableSecret marker. Serialization exposes the
full secret — audit every impl.
impl<T: Zeroize + SerializableSecret> Serialize for Dynamic<T>
serde-serialize only.Opt-in serialization — requires serde-serialize feature and
SerializableSecret marker. Serialization exposes the
full secret — audit every impl.
Source§impl ToBase32 for Dynamic<Vec<u8>>
Available on crate feature encoding-base32 only.Base32 encoding for Dynamic<Vec<u8>>; delegates via with_secret.
impl ToBase32 for Dynamic<Vec<u8>>
encoding-base32 only.Base32 encoding for Dynamic<Vec<u8>>; delegates via with_secret.
Bring the trait into scope: use secure_gate::ToBase32;.
use secure_gate::{Dynamic, ToBase32};
let token: Dynamic<Vec<u8>> = Dynamic::from(&[0xABu8; 4][..]);
assert_eq!(&*token.to_base32(), "VOV2XKY");Source§fn to_base32(&self) -> EncodedSecret
fn to_base32(&self) -> EncodedSecret
Source§impl ToBase64Url for Dynamic<Vec<u8>>
Available on crate feature encoding-base64 only.Base64url encoding for Dynamic<Vec<u8>>; delegates via with_secret.
impl ToBase64Url for Dynamic<Vec<u8>>
encoding-base64 only.Base64url encoding for Dynamic<Vec<u8>>; delegates via with_secret.
Bring the trait into scope: use secure_gate::ToBase64Url;.
use secure_gate::{Dynamic, ToBase64Url};
let token: Dynamic<Vec<u8>> = Dynamic::from(&[0xABu8; 4][..]);
assert_eq!(&*token.to_base64url(), "q6urqw");Source§fn to_base64url(&self) -> EncodedSecret
fn to_base64url(&self) -> EncodedSecret
Source§impl ToBech32 for Dynamic<Vec<u8>>
Available on crate feature encoding-bech32 only.Bech32 encoding for Dynamic<Vec<u8>>; delegates via with_secret.
impl ToBech32 for Dynamic<Vec<u8>>
encoding-bech32 only.Bech32 encoding for Dynamic<Vec<u8>>; delegates via with_secret.
Bring the trait into scope: use secure_gate::ToBech32;.
Source§fn try_to_bech32(
&self,
hrp: &str,
case: Case,
) -> Result<EncodedSecret, Bech32Error>
fn try_to_bech32( &self, hrp: &str, case: Case, ) -> Result<EncodedSecret, Bech32Error>
Source§fn try_to_bech32_sized<const C: usize>(
&self,
hrp: &str,
case: Case,
) -> Result<EncodedSecret, Bech32Error>
fn try_to_bech32_sized<const C: usize>( &self, hrp: &str, case: Case, ) -> Result<EncodedSecret, Bech32Error>
Source§impl ToBech32m for Dynamic<Vec<u8>>
Available on crate feature encoding-bech32 only.Bech32m encoding for Dynamic<Vec<u8>>; delegates via with_secret.
impl ToBech32m for Dynamic<Vec<u8>>
encoding-bech32 only.Bech32m encoding for Dynamic<Vec<u8>>; delegates via with_secret.
Bring the trait into scope: use secure_gate::ToBech32m;.
Source§fn try_to_bech32m(
&self,
hrp: &str,
case: Case,
) -> Result<EncodedSecret, Bech32Error>
fn try_to_bech32m( &self, hrp: &str, case: Case, ) -> Result<EncodedSecret, Bech32Error>
Source§fn try_to_bech32m_sized<const C: usize>(
&self,
hrp: &str,
case: Case,
) -> Result<EncodedSecret, Bech32Error>
fn try_to_bech32m_sized<const C: usize>( &self, hrp: &str, case: Case, ) -> Result<EncodedSecret, Bech32Error>
Source§impl ToHex for Dynamic<Vec<u8>>
Available on crate feature encoding-hex only.Hex encoding for Dynamic<Vec<u8>>; delegates via with_secret.
impl ToHex for Dynamic<Vec<u8>>
encoding-hex only.Hex encoding for Dynamic<Vec<u8>>; delegates via with_secret.
Deliberately not implemented for Dynamic<String> — hex-encoding
textual secrets is a design smell; convert explicitly inside with_secret
if genuinely needed. Bring the trait into scope: use secure_gate::ToHex;.
use secure_gate::{Dynamic, ToHex};
let token: Dynamic<Vec<u8>> = Dynamic::from(&[0xDEu8, 0xAD][..]);
assert_eq!(&*token.to_hex(), "dead");Source§fn to_hex(&self) -> EncodedSecret
fn to_hex(&self) -> EncodedSecret
Source§fn to_hex_upper(&self) -> EncodedSecret
fn to_hex_upper(&self) -> EncodedSecret
Source§impl Write for Dynamic<Vec<u8>>
Available on crate feature std only.Streams bytes directly into the protected buffer via RevealSecretMut.
impl Write for Dynamic<Vec<u8>>
std only.Streams bytes directly into the protected buffer via RevealSecretMut.
Data flows into the wrapper, so no intermediate unprotected Vec<u8> is
accumulated before wrapping.
§Growth wipes the outgoing buffer
Writing past the current capacity cannot simply delegate to Vec: Vec would
reallocate, copy the secret into the new allocation, and hand the old one
back to the allocator with the plaintext still in it. This impl grows by hand
instead — it allocates the larger buffer, copies, zeroizes the old buffer
(contents and spare capacity), and only then releases it.
Pre-sizing with Vec::with_capacity avoids the copy altogether and is worth
doing when the length is known up front:
use std::io::Write;
use secure_gate::Dynamic;
let payload = b"decrypted payload";
// Pre-sized: no growth, so no copy and nothing to wipe.
let mut secret = Dynamic::<Vec<u8>>::new(Vec::with_capacity(payload.len()));
secret.write_all(payload).unwrap();This addresses only the buffer this impl owns. A caller who grows the Vec
themselves through with_secret_mut
or expose_secret_mut holds
&mut Vec<u8> directly, and their reallocation is outside this crate’s
control — see the heap-reallocation residue section in SECURITY.md.
Source§fn write(&mut self, buf: &[u8]) -> Result<usize>
fn write(&mut self, buf: &[u8]) -> Result<usize>
Source§fn flush(&mut self) -> Result<()>
fn flush(&mut self) -> Result<()>
Source§fn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
can_vector)1.0.0 · Source§fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
Source§fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
write_all_vectored)Source§impl<T: ?Sized + Zeroize> Zeroize for Dynamic<T>
Zeroizes the inner value (including Vec/String spare capacity).
impl<T: ?Sized + Zeroize> Zeroize for Dynamic<T>
Zeroizes the inner value (including Vec/String spare capacity).
Warning: does not run under panic = "abort".
impl<T: ?Sized + Zeroize> ZeroizeOnDrop for Dynamic<T>
Marker confirming that Dynamic<T> always zeroizes on drop.