From ee50c7d6bb206348e043771a6f30c403f5344ac6 Mon Sep 17 00:00:00 2001 From: Alexander Korolev <alexander.korolev.germany@gmail.com> Date: Sun, 17 Sep 2023 17:54:48 +0200 Subject: [PATCH] fixed regression in at_hash behavior --- src/claims.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/claims.rs b/src/claims.rs index 9a4c3a5..82f2876 100644 --- a/src/claims.rs +++ b/src/claims.rs @@ -1,8 +1,16 @@ use crate::Userinfo; -use base64::{engine::general_purpose::URL_SAFE, Engine as _}; +use base64::{ + alphabet, + engine::{GeneralPurpose, GeneralPurposeConfig}, + Engine as _, +}; use biscuit::SingleOrMultiple; use url::Url; +const ANYPAD: GeneralPurposeConfig = GeneralPurposeConfig::new() + .with_decode_padding_mode(base64::engine::DecodePaddingMode::Indifferent); +const URL_SAFE_ANYPAD: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, ANYPAD); + /// The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be Authenticated is the ID Token data structure. The ID Token is a security token that contains Claims about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims. The ID Token is represented as a JSON Web Token (JWT) [JWT]. pub trait Claims { /// Issuer Identifier for the Issuer of the response. The iss value is a case sensitive URL using the https scheme that contains scheme, host, and optionally, port number and path components and no query or fragment components. @@ -39,7 +47,7 @@ pub trait Claims { /// /// The returned Vec is the first 128 bits of the access token hash using alg's hash alg fn at_hash_to_vec(&self) -> Option<Vec<u8>> { - URL_SAFE.decode(self.at_hash()?).ok() + URL_SAFE_ANYPAD.decode(self.at_hash()?).ok() } /// Decodes c_hash. Returns None if it doesn't exist or something goes wrong. /// @@ -47,6 +55,20 @@ pub trait Claims { /// /// The returned Vec is the first 128 bits of the code hash using alg's hash alg fn c_hash_to_vec(&self) -> Option<Vec<u8>> { - URL_SAFE.decode(self.c_hash()?).ok() + URL_SAFE_ANYPAD.decode(self.c_hash()?).ok() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn decode_at_hash() { + let x = URL_SAFE_ANYPAD.decode("zglPCMCEP7ilF3LP_NExow"); + let y = URL_SAFE_ANYPAD.decode("zglPCMCEP7ilF3LP_NExow=="); + assert!(x.is_ok()); + assert!(y.is_ok()); + assert_eq!(x, y); } }