diff --git a/libvdrtools/indy-utils/src/crypto/base64/rust_base64.rs b/libvdrtools/indy-utils/src/crypto/base64/rust_base64.rs index 1c48f23779..204d91fc60 100644 --- a/libvdrtools/indy-utils/src/crypto/base64/rust_base64.rs +++ b/libvdrtools/indy-utils/src/crypto/base64/rust_base64.rs @@ -1,6 +1,17 @@ -use base64::{engine::general_purpose, Engine}; +use base64::{ + alphabet, + engine::{general_purpose, DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig}, + Engine, +}; use indy_api_types::errors::prelude::*; +/// Default general purpose configuration, but padding decode mode of 'indifferent' (will decode +/// either) +const ANY_PADDING: GeneralPurposeConfig = + GeneralPurposeConfig::new().with_decode_padding_mode(DecodePaddingMode::Indifferent); +/// Standard Base64 URL Safe decoding and encoding, with indifference for padding mode when decoding +const URL_SAFE_ANY_PADDING: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, ANY_PADDING); + pub fn encode(doc: &[u8]) -> String { general_purpose::STANDARD.encode(doc) } @@ -16,7 +27,7 @@ pub fn encode_urlsafe(doc: &[u8]) -> String { } pub fn decode_urlsafe(doc: &str) -> Result, IndyError> { - general_purpose::URL_SAFE.decode(doc).map_err(|e| { + URL_SAFE_ANY_PADDING.decode(doc).map_err(|e| { e.to_indy( IndyErrorKind::InvalidStructure, "Invalid base64URL_SAFE sequence", @@ -55,4 +66,13 @@ mod tests { assert!(result.is_ok(), "Got error"); assert_eq!(&[1, 2, 3], &result.unwrap()[..]); } + + #[test] + fn decode_urlsafe_works_with_or_without_padding() { + let result = decode_urlsafe("YWJjZA=="); + assert_eq!(vec![97, 98, 99, 100], result.unwrap()); + + let result = decode_urlsafe("YWJjZA"); + assert_eq!(vec![97, 98, 99, 100], result.unwrap()); + } }