hook refresh provider into refreshable cred

This commit is contained in:
Grimmauld 2025-02-12 11:03:58 +01:00
parent 8e8c89f39a
commit 1348183976
No known key found for this signature in database
2 changed files with 23 additions and 21 deletions

View file

@ -71,22 +71,22 @@ fn clone_with_lifetime<'a>(data: &'a [u8]) -> Vec<u8> {
data.to_vec() // `to_vec()` will return a Vec<u8> that has its own ownership data.to_vec() // `to_vec()` will return a Vec<u8> that has its own ownership
} }
pub struct RefreshableOathCredential { pub struct RefreshableOathCredential<'a> {
pub cred: OathCredential, pub cred: OathCredential,
pub code: Option<OathCodeDisplay>, pub code: Option<OathCodeDisplay>,
pub valid_from: u64, pub valid_from: u64,
pub valid_to: u64, pub valid_to: u64,
try_refresh_func: Option<Box<dyn Fn(OathCredential, SystemTime) -> Option<OathCodeDisplay>>>, refresh_provider: &'a OathSession<'a>,
} }
impl RefreshableOathCredential { impl<'a> RefreshableOathCredential<'a> {
pub fn new(cred: OathCredential) -> Self { pub fn new(cred: OathCredential, refresh_provider: &'a OathSession<'a>) -> Self {
RefreshableOathCredential { RefreshableOathCredential {
cred, cred,
code: None, code: None,
valid_from: 0, valid_from: 0,
valid_to: 0, valid_to: 0,
try_refresh_func: None, refresh_provider,
} }
} }
@ -109,15 +109,14 @@ impl RefreshableOathCredential {
pub fn refresh(&mut self) { pub fn refresh(&mut self) {
let timestamp = SystemTime::now(); let timestamp = SystemTime::now();
let refresh_result = if let Some(refresh_func) = self.try_refresh_func.as_deref() { let refresh_result = self
refresh_func(self.cred.to_owned(), timestamp) .refresh_provider
} else { .calculate_code(self.cred.to_owned(), Some(timestamp))
None .ok();
};
self.force_update(refresh_result, timestamp); self.force_update(refresh_result, timestamp);
} }
pub fn get_or_refresh(mut self) -> RefreshableOathCredential { pub fn get_or_refresh(mut self) -> RefreshableOathCredential<'a> {
if !self.is_valid() { if !self.is_valid() {
self.refresh(); self.refresh();
} }
@ -190,13 +189,12 @@ impl<'a> OathSession<'a> {
let timestamp = time_to_u64(timestamp_sys.unwrap_or_else(SystemTime::now)); let timestamp = time_to_u64(timestamp_sys.unwrap_or_else(SystemTime::now));
let mut data = to_tlv(Tag::Name, &cred.id_data.format_cred_id()); let mut data = to_tlv(Tag::Name, &cred.id_data.format_cred_id());
if cred.id_data.oath_type == OathType::Totp {
let extend = match cred.id_data.oath_type { data.extend(to_tlv(
OathType::Totp => _get_challenge(timestamp, cred.id_data.period as u64).to_vec(), Tag::Challenge,
OathType::Hotp => vec![], &_get_challenge(timestamp, cred.id_data.period as u64),
}; ));
}
data.extend(to_tlv(Tag::Challenge, &extend));
let resp = self.transaction_context.apdu_read_all( let resp = self.transaction_context.apdu_read_all(
0, 0,
@ -241,7 +239,7 @@ impl<'a> OathSession<'a> {
touch_required: touch, touch_required: touch,
}; };
let mut refreshable_cred = RefreshableOathCredential::new(cred); // todo: refresh callback let mut refreshable_cred = RefreshableOathCredential::new(cred, self);
refreshable_cred.force_update(code, timestamp); refreshable_cred.force_update(code, timestamp);
key_buffer.push(refreshable_cred); key_buffer.push(refreshable_cred);

View file

@ -2,9 +2,11 @@
mod lib_ykoath2; mod lib_ykoath2;
use core::time;
use lib_ykoath2::OathSession; use lib_ykoath2::OathSession;
use pcsc; use pcsc;
use std::process; use std::process;
use std::thread;
// use crate::args::Cli; // use crate::args::Cli;
// use clap::Parser; // use clap::Parser;
@ -49,10 +51,12 @@ fn main() {
println!("No credentials on device {}", device_label); println!("No credentials on device {}", device_label);
} }
thread::sleep(time::Duration::from_secs(45)); // show refresh is working
// Enumerate the OATH codes // Enumerate the OATH codes
for oath in codes { for oath in codes {
let recalculated = session.calculate_code(oath.cred, None).unwrap(); // let recalculated = session.calculate_code(oath.cred, None).unwrap();
println!("Found OATH label: {}", recalculated.display()); println!("Found OATH label: {}", oath.get_or_refresh().display());
} }
} }
} }