use base64::{engine::general_purpose, Engine as _}; use hmac::{Mac, SimpleHmac}; use sha2::Sha256; use crate::{LibraryResult, LibraryError}; pub struct RegToken { token: Vec, } impl RegToken { pub fn parse_from_qrcode_uri(uri: &str) -> LibraryResult { if uri.len() <= 23 { return Err(LibraryError::DecodeError("RegTokenUri too short".to_string())); } if !uri.starts_with("urn:dhl.de:regtoken:v1:") { return Err(LibraryError::DecodeError("RegTokenUri has invalid magic".to_string())); } let token = &uri[23..]; let token = general_purpose::STANDARD.decode(token); let Ok(mut token) = token else { return Err(LibraryError::DecodeError("RegTokenUri not decodeable (base64)".to_string())); }; if token.len() > 64 { return Err(LibraryError::DecodeError("RegToken longer than expected".to_string())); } if token.len() < 32 { token.extend(vec![0; 32 - token.len()].iter()) } Ok(RegToken { token }) } pub fn customer_password(&self) -> String { general_purpose::STANDARD.encode(&self.token[32..]) } pub fn hmac(&self) -> SimpleHmac { let mac = SimpleHmac::::new_from_slice(&self.token[0..32]) .expect("HMAC can take key of any size"); mac } }