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}