Skip to main content

base64_ng/buffers/
secret_conversions.rs

1use super::secret::SecretBuffer;
2use crate::{DecodeError, DecodedBuffer, EncodedBuffer, STANDARD};
3
4#[cfg(feature = "alloc")]
5impl From<alloc::vec::Vec<u8>> for SecretBuffer {
6    /// Wraps an owned vector as sensitive material.
7    ///
8    /// Spare capacity is cleared immediately before the vector is stored.
9    /// Use [`SecretBuffer::from_slice`] when the source data is borrowed.
10    fn from(bytes: alloc::vec::Vec<u8>) -> Self {
11        Self::from_vec(bytes)
12    }
13}
14
15#[cfg(feature = "alloc")]
16impl From<alloc::string::String> for SecretBuffer {
17    /// Wraps an owned UTF-8 string as sensitive material.
18    ///
19    /// The string is consumed without copying its initialized bytes. Spare
20    /// vector capacity is cleared immediately before the bytes are stored.
21    fn from(text: alloc::string::String) -> Self {
22        Self::from_vec(text.into_bytes())
23    }
24}
25
26#[cfg(feature = "alloc")]
27impl<const CAP: usize> From<EncodedBuffer<CAP>> for SecretBuffer {
28    /// Copies visible encoded bytes from a stack-backed buffer into an owned
29    /// redacted buffer.
30    ///
31    /// The consumed stack-backed buffer clears its backing array when it is
32    /// dropped at the end of the conversion.
33    fn from(buffer: EncodedBuffer<CAP>) -> Self {
34        Self::from_slice(buffer.as_bytes())
35    }
36}
37
38#[cfg(feature = "alloc")]
39impl<const CAP: usize> From<DecodedBuffer<CAP>> for SecretBuffer {
40    /// Copies visible decoded bytes from a stack-backed buffer into an owned
41    /// redacted buffer.
42    ///
43    /// The consumed stack-backed buffer clears its backing array when it is
44    /// dropped at the end of the conversion.
45    fn from(buffer: DecodedBuffer<CAP>) -> Self {
46        Self::from_slice(buffer.as_bytes())
47    }
48}
49
50#[cfg(feature = "alloc")]
51impl TryFrom<&[u8]> for SecretBuffer {
52    type Error = DecodeError;
53
54    /// Decodes strict standard padded Base64 into a redacted owned buffer.
55    ///
56    /// Use [`crate::Engine::decode_secret`] or [`crate::Profile::decode_secret`]
57    /// when a different alphabet, padding mode, or line-wrapping profile is
58    /// required. These conversions always use [`crate::STANDARD`]; URL-safe,
59    /// bcrypt, crypt, MIME, PEM, and custom alphabets must use an explicit
60    /// engine or profile.
61    ///
62    /// # Security
63    ///
64    /// This idiomatic conversion uses the strict standard decoder, not the
65    /// constant-time-oriented decoder. It may branch or return early on
66    /// malformed input and reports exact [`DecodeError`] positions. For
67    /// secret-bearing tokens or key material where malformed-input timing
68    /// matters, use [`crate::ct::CtEngine::decode_secret`] through
69    /// [`crate::ct::STANDARD`], or use staged decode and then wrap the
70    /// successful output in `SecretBuffer`.
71    fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
72        STANDARD.decode_secret(input)
73    }
74}
75
76#[cfg(feature = "alloc")]
77impl<const N: usize> TryFrom<&[u8; N]> for SecretBuffer {
78    type Error = DecodeError;
79
80    /// Decodes a strict standard padded Base64 byte array into a redacted
81    /// owned buffer.
82    ///
83    /// Use [`crate::Engine::decode_secret`] or [`crate::Profile::decode_secret`]
84    /// when a different alphabet, padding mode, or line-wrapping profile is
85    /// required. These conversions always use [`crate::STANDARD`]; URL-safe,
86    /// bcrypt, crypt, MIME, PEM, and custom alphabets must use an explicit
87    /// engine or profile.
88    ///
89    /// # Security
90    ///
91    /// This idiomatic conversion uses the strict standard decoder, not the
92    /// constant-time-oriented decoder. It may branch or return early on
93    /// malformed input and reports exact [`DecodeError`] positions. For
94    /// secret-bearing tokens or key material where malformed-input timing
95    /// matters, use [`crate::ct::CtEngine::decode_secret`] through
96    /// [`crate::ct::STANDARD`], or use staged decode and then wrap the
97    /// successful output in `SecretBuffer`.
98    fn try_from(input: &[u8; N]) -> Result<Self, Self::Error> {
99        Self::try_from(&input[..])
100    }
101}
102
103#[cfg(feature = "alloc")]
104impl TryFrom<&str> for SecretBuffer {
105    type Error = DecodeError;
106
107    /// Decodes strict standard padded Base64 text into a redacted owned buffer.
108    ///
109    /// Use [`crate::Engine::decode_secret`] or [`crate::Profile::decode_secret`]
110    /// when a different alphabet, padding mode, or line-wrapping profile is
111    /// required. These conversions always use [`crate::STANDARD`]; URL-safe,
112    /// bcrypt, crypt, MIME, PEM, and custom alphabets must use an explicit
113    /// engine or profile.
114    ///
115    /// # Security
116    ///
117    /// This idiomatic conversion uses the strict standard decoder, not the
118    /// constant-time-oriented decoder. It may branch or return early on
119    /// malformed input and reports exact [`DecodeError`] positions. For
120    /// secret-bearing tokens or key material where malformed-input timing
121    /// matters, use [`crate::ct::CtEngine::decode_secret`] through
122    /// [`crate::ct::STANDARD`], or use staged decode and then wrap the
123    /// successful output in `SecretBuffer`.
124    fn try_from(input: &str) -> Result<Self, Self::Error> {
125        Self::try_from(input.as_bytes())
126    }
127}
128
129#[cfg(feature = "alloc")]
130impl core::str::FromStr for SecretBuffer {
131    type Err = DecodeError;
132
133    /// Decodes strict standard padded Base64 text into a redacted owned buffer.
134    ///
135    /// Use [`crate::Engine::decode_secret`] or [`crate::Profile::decode_secret`]
136    /// when a different alphabet, padding mode, or line-wrapping profile is
137    /// required. These conversions always use [`crate::STANDARD`]; URL-safe,
138    /// bcrypt, crypt, MIME, PEM, and custom alphabets must use an explicit
139    /// engine or profile.
140    ///
141    /// # Security
142    ///
143    /// This idiomatic conversion uses the strict standard decoder, not the
144    /// constant-time-oriented decoder. It may branch or return early on
145    /// malformed input and reports exact [`DecodeError`] positions. For
146    /// secret-bearing tokens or key material where malformed-input timing
147    /// matters, use [`crate::ct::CtEngine::decode_secret`] through
148    /// [`crate::ct::STANDARD`], or use staged decode and then wrap the
149    /// successful output in `SecretBuffer`.
150    fn from_str(input: &str) -> Result<Self, Self::Err> {
151        Self::try_from(input)
152    }
153}