From 298db9ea9940e08139b8f535d60a7d32321a2c23 Mon Sep 17 00:00:00 2001 From: kaczmarczyck <43844792+kaczmarczyck@users.noreply.github.com> Date: Tue, 9 Jan 2024 21:04:47 +0100 Subject: [PATCH] Public method to check if sleeping is allowed (#674) --- libraries/opensk/src/ctap/client_pin.rs | 10 ++++++++++ libraries/opensk/src/ctap/mod.rs | 6 ++++++ libraries/opensk/src/lib.rs | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/libraries/opensk/src/ctap/client_pin.rs b/libraries/opensk/src/ctap/client_pin.rs index 4b19d83..1a69729 100644 --- a/libraries/opensk/src/ctap/client_pin.rs +++ b/libraries/opensk/src/ctap/client_pin.rs @@ -140,6 +140,12 @@ impl ClientPin { } } + /// Checks if a PIN UV token is in use. + pub fn has_token(&mut self, env: &mut E) -> bool { + self.update_timeouts(env); + self.pin_uv_auth_token_state.is_in_use() + } + /// Gets a reference to the PIN protocol of the given version. fn get_pin_protocol(&self, pin_uv_auth_protocol: PinUvAuthProtocol) -> &PinProtocol { match pin_uv_auth_protocol { @@ -1507,9 +1513,11 @@ mod test { let mut env = TestEnv::default(); let mut client_pin = ClientPin::::new(&mut env); let message = [0xAA]; + assert!(!client_pin.has_token(&mut env)); client_pin .pin_uv_auth_token_state .begin_using_pin_uv_auth_token(&mut env); + assert!(client_pin.has_token(&mut env)); let pin_uv_auth_token_v1 = client_pin .get_pin_protocol(PinUvAuthProtocol::V1) @@ -1655,6 +1663,7 @@ mod test { .has_permissions_rp_id("example.com"), Ok(()) ); + assert!(client_pin.has_token(&mut env)); env.clock().advance(30001); client_pin.update_timeouts(&mut env); @@ -1672,6 +1681,7 @@ mod test { .has_permissions_rp_id("example.com"), Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID) ); + assert!(!client_pin.has_token(&mut env)); } #[test] diff --git a/libraries/opensk/src/ctap/mod.rs b/libraries/opensk/src/ctap/mod.rs index 509179d..605e7d1 100644 --- a/libraries/opensk/src/ctap/mod.rs +++ b/libraries/opensk/src/ctap/mod.rs @@ -602,6 +602,12 @@ impl CtapState { self.stateful_command_permission.clear_old_channels(channel); } + /// Checks if the application has any timers running. + pub fn can_sleep(&mut self, env: &mut E) -> bool { + !self.client_pin.has_token(env) + && self.stateful_command_permission.get_command(env).is_err() + } + pub fn process_command( &mut self, env: &mut E, diff --git a/libraries/opensk/src/lib.rs b/libraries/opensk/src/lib.rs index f62aacf..0c16311 100644 --- a/libraries/opensk/src/lib.rs +++ b/libraries/opensk/src/lib.rs @@ -116,6 +116,10 @@ impl Ctap { self.hid.should_wink(&mut self.env) } + pub fn can_sleep(&mut self) -> bool { + !self.should_wink() && self.state.can_sleep(&mut self.env) + } + #[cfg(feature = "with_ctap1")] pub fn u2f_grant_user_presence(&mut self) { self.state.u2f_grant_user_presence(&mut self.env) @@ -201,6 +205,7 @@ mod test { fn test_hard_reset() { let env = TestEnv::default(); let mut ctap = Ctap::::new(env); + assert!(!ctap.can_sleep()); // Send Init, receive Init response. let mut init_response = ctap.process_hid_packet(&init_packet(), Transport::MainHid); @@ -223,6 +228,7 @@ mod test { let mut env = TestEnv::default(); env.set_boots_after_soft_reset(true); let mut ctap = Ctap::::new(env); + assert!(ctap.can_sleep()); // Send Init, receive Init response. let mut init_response = ctap.process_hid_packet(&init_packet(), Transport::MainHid);