Skip to main content

codec_base64/
decode.rs

1// SPDX-FileCopyrightText: 2026 ReallyMe LLC
2//
3// SPDX-License-Identifier: MIT OR Apache-2.0
4
5use base64::{decoded_len_estimate, engine::general_purpose::STANDARD, Engine as _};
6use zeroize::Zeroizing;
7
8use crate::{error::Base64Error, MAX_BASE64_INPUT_LEN};
9
10/// Decode standard padded Base64 from RFC 4648.
11pub fn base64_to_bytes(input: &str) -> Result<Vec<u8>, Base64Error> {
12    if input.len() > MAX_BASE64_INPUT_LEN {
13        return Err(Base64Error::InputTooLarge);
14    }
15    // A late alphabet or padding error may follow successfully decoded secret
16    // bytes. Keep ownership here so the partial output is wiped on failure.
17    let mut output = Zeroizing::new(vec![0_u8; decoded_len_estimate(input.len())]);
18    let length = STANDARD
19        .decode_slice(input.as_bytes(), output.as_mut_slice())
20        .map_err(|_| Base64Error::Invalid)?;
21    output.truncate(length);
22    Ok(core::mem::take(&mut *output))
23}