use base64::engine::general_purpose::STANDARD;
use base64::Engine as _;
use crate::error::SamlError;
const BASE64_OUTPUT_LIMIT_EXCEEDED: &str = "ERR_BASE64_OUTPUT_LIMIT_EXCEEDED";
pub fn base64_encode(input: &[u8]) -> String {
STANDARD.encode(input)
}
pub fn base64_decode(input: &str) -> Result<Vec<u8>, SamlError> {
let normalized: String = input.split_whitespace().collect();
Ok(STANDARD.decode(normalized)?)
}
pub fn base64_decode_with_limit(input: &str, max_output_len: usize) -> Result<Vec<u8>, SamlError> {
let normalized_len = input
.bytes()
.filter(|byte| !byte.is_ascii_whitespace())
.count();
let max_encoded_len = max_output_len
.saturating_add(2)
.saturating_div(3)
.saturating_mul(4);
if normalized_len > max_encoded_len {
return Err(SamlError::Invalid(BASE64_OUTPUT_LIMIT_EXCEEDED.into()));
}
let mut normalized = String::with_capacity(normalized_len);
normalized.extend(input.chars().filter(|ch| !ch.is_whitespace()));
let out = STANDARD.decode(normalized)?;
if out.len() > max_output_len {
return Err(SamlError::Invalid(BASE64_OUTPUT_LIMIT_EXCEEDED.into()));
}
Ok(out)
}