mirror of
https://github.com/LordGrimmauld/yubi-oath-rs.git
synced 2025-03-04 05:44:40 +01:00
hook refresh provider into refreshable cred
This commit is contained in:
parent
8e8c89f39a
commit
1348183976
2 changed files with 23 additions and 21 deletions
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue