use crate::keys::IssuerKeyStore; use crate::payload::Rsp6Ticket; use anyhow::anyhow; use num_bigint::BigUint; pub mod keys; pub mod payload; #[cfg(feature = "wasm")] pub mod wasm; fn base26_decode(input: &str) -> BigUint { let mut out = BigUint::new(Vec::new()); for val in input.as_bytes().iter().rev() { out *= 26u32; out += *val - b'A'; } BigUint::from_bytes_le(&out.to_bytes_be()) } fn strip_padding(tkt: &[u8]) -> Option<&[u8]> { if tkt.is_empty() { return None; } match tkt[0] { 1 => { // PKCS#1 v1 let tkt = &tkt[1..]; let mut iter = tkt.iter(); loop { match iter.next()? { 0 => { return Some(iter.as_slice()); } 255 => {} _ => return None, } } } 2 => { // PKCS#1 v2 let tkt = &tkt[1..]; let mut iter = tkt.iter(); loop { match iter.next()? { 0 => { return Some(iter.as_slice()); } _ => {} } } } _ => None, } } pub fn decode_ticket(iks: &IssuerKeyStore, ticket_str: &str) -> anyhow::Result { if ticket_str.len() < 16 { return Err(anyhow!("ticket too short")); } if &ticket_str[0..2] != "06" { return Err(anyhow!( "ticket isn't a RSP6 ticket: magic was {}", &ticket_str[0..2] )); } let issuer_id = &ticket_str[13..15]; let ticket = base26_decode(&ticket_str[15..]); let keys = iks .keys .get(issuer_id) .ok_or_else(|| anyhow!("unknown issuer ID {}", issuer_id))?; for key in keys { let message = ticket.modpow(&key.public_exponent, &key.modulus); let message = message.to_bytes_be(); if let Some(unpadded) = strip_padding(&message) { let ticket = Rsp6Ticket::decode(unpadded, issuer_id.into(), ticket_str[11..13].into())?; return Ok(ticket); } } Err(anyhow!( "all signature unwrap attempts failed (tried {} keys for issuer {})", keys.len(), issuer_id )) } #[cfg(test)] mod test { #[test] fn test_base26() { assert_eq!( super::base26_decode("RANEBZCYPNQVMMYJBOJBONYSIYXTREYFSHTZFZEXWTVBNXJBFVOFBMXVQPZTFWVYSWYKINRXRVDCCUWUERKQZKYBPVIIAPJOOFJJXUBFGNVXGXTCFPBHXYVPEKWIURBEOYTYNZUXWVIXHAODACOQLZEQKRUNGWSJHIIWOYSNXJKVYWIGLWCIZKAHFKKAKRDUQSQBGEJMOFCSHSKXSFDDKYCFQI").to_bytes_be(), [53, 242, 184, 141, 14, 99, 169, 215, 200, 223, 85, 250, 45, 253, 184, 100, 225, 124, 82, 70, 138, 222, 246, 185, 192, 129, 247, 218, 24, 26, 249, 112, 74, 225, 71, 139, 27, 50, 218, 11, 93, 238, 232, 163, 151, 68, 159, 146, 80, 133, 11, 45, 57, 245, 163, 117, 218, 11, 187, 246, 18, 147, 88, 171, 133, 216, 166, 47, 232, 246, 198, 170, 99, 36, 120, 114, 73, 207, 19, 218, 202, 146, 158, 223, 107, 234, 171, 172, 20, 189, 133, 246, 192, 248, 57, 111, 65, 65, 135, 64, 241, 99, 87, 107, 75, 40, 224, 223, 100, 53, 180, 212, 53, 200, 172, 117, 127, 248, 193, 0, 147, 167, 222, 81, 135, 158, 135, 137] ) } }