Skip to content

Commit 877e09d

Browse files
Merge pull request #63 from msirringhaus/refactoring
Fix #61: Refactor model.rs and management.rs
2 parents 506cbf8 + 4f2bd14 commit 877e09d

File tree

10 files changed

+1801
-1715
lines changed

10 files changed

+1801
-1715
lines changed

libwebauthn/src/management.rs

Lines changed: 4 additions & 547 deletions
Large diffs are not rendered by default.
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
pub use crate::transport::error::{CtapError, Error};
2+
use crate::transport::Channel;
3+
use crate::webauthn::handle_errors;
4+
use crate::webauthn::{user_verification, UsedPinUvAuthToken};
5+
use crate::{
6+
ops::webauthn::UserVerificationRequirement,
7+
pin::{PinProvider, PinUvAuthProtocol},
8+
proto::ctap2::{
9+
Ctap2, Ctap2AuthTokenPermissionRole, Ctap2AuthenticatorConfigCommand,
10+
Ctap2AuthenticatorConfigRequest, Ctap2GetInfoResponse, Ctap2UserVerifiableRequest,
11+
},
12+
};
13+
use async_trait::async_trait;
14+
use serde_bytes::ByteBuf;
15+
use serde_cbor::ser::to_vec;
16+
use std::time::Duration;
17+
use tracing::info;
18+
19+
#[async_trait]
20+
pub trait AuthenticatorConfig {
21+
async fn toggle_always_uv(
22+
&mut self,
23+
pin_provider: &Box<dyn PinProvider>,
24+
timeout: Duration,
25+
) -> Result<(), Error>;
26+
27+
async fn enable_enterprise_attestation(
28+
&mut self,
29+
pin_provider: &Box<dyn PinProvider>,
30+
timeout: Duration,
31+
) -> Result<(), Error>;
32+
33+
async fn set_min_pin_length(
34+
&mut self,
35+
new_pin_length: u64,
36+
pin_provider: &Box<dyn PinProvider>,
37+
timeout: Duration,
38+
) -> Result<(), Error>;
39+
40+
async fn force_change_pin(
41+
&mut self,
42+
force: bool,
43+
pin_provider: &Box<dyn PinProvider>,
44+
timeout: Duration,
45+
) -> Result<(), Error>;
46+
47+
async fn set_min_pin_length_rpids(
48+
&mut self,
49+
rpids: Vec<String>,
50+
pin_provider: &Box<dyn PinProvider>,
51+
timeout: Duration,
52+
) -> Result<(), Error>;
53+
}
54+
55+
#[async_trait]
56+
impl<C> AuthenticatorConfig for C
57+
where
58+
C: Channel,
59+
{
60+
async fn toggle_always_uv(
61+
&mut self,
62+
pin_provider: &Box<dyn PinProvider>,
63+
timeout: Duration,
64+
) -> Result<(), Error> {
65+
let mut req = Ctap2AuthenticatorConfigRequest::new_toggle_always_uv();
66+
67+
loop {
68+
let uv_auth_used = user_verification(
69+
self,
70+
UserVerificationRequirement::Required,
71+
&mut req,
72+
pin_provider,
73+
timeout,
74+
)
75+
.await?;
76+
// On success, this is an all-empty Ctap2AuthenticatorConfigResponse
77+
handle_errors!(
78+
self,
79+
self.ctap2_authenticator_config(&req, timeout).await,
80+
uv_auth_used
81+
)
82+
}
83+
}
84+
85+
async fn enable_enterprise_attestation(
86+
&mut self,
87+
pin_provider: &Box<dyn PinProvider>,
88+
timeout: Duration,
89+
) -> Result<(), Error> {
90+
let mut req = Ctap2AuthenticatorConfigRequest::new_enable_enterprise_attestation();
91+
92+
loop {
93+
let uv_auth_used = user_verification(
94+
self,
95+
UserVerificationRequirement::Required,
96+
&mut req,
97+
pin_provider,
98+
timeout,
99+
)
100+
.await?;
101+
// On success, this is an all-empty Ctap2AuthenticatorConfigResponse
102+
handle_errors!(
103+
self,
104+
self.ctap2_authenticator_config(&req, timeout).await,
105+
uv_auth_used
106+
)
107+
}
108+
}
109+
110+
async fn set_min_pin_length(
111+
&mut self,
112+
new_pin_length: u64,
113+
pin_provider: &Box<dyn PinProvider>,
114+
timeout: Duration,
115+
) -> Result<(), Error> {
116+
let mut req = Ctap2AuthenticatorConfigRequest::new_set_min_pin_length(new_pin_length);
117+
118+
loop {
119+
let uv_auth_used = user_verification(
120+
self,
121+
UserVerificationRequirement::Required,
122+
&mut req,
123+
pin_provider,
124+
timeout,
125+
)
126+
.await?;
127+
// On success, this is an all-empty Ctap2AuthenticatorConfigResponse
128+
handle_errors!(
129+
self,
130+
self.ctap2_authenticator_config(&req, timeout).await,
131+
uv_auth_used
132+
)
133+
}
134+
}
135+
136+
async fn force_change_pin(
137+
&mut self,
138+
force: bool,
139+
pin_provider: &Box<dyn PinProvider>,
140+
timeout: Duration,
141+
) -> Result<(), Error> {
142+
let mut req = Ctap2AuthenticatorConfigRequest::new_force_change_pin(force);
143+
144+
loop {
145+
let uv_auth_used = user_verification(
146+
self,
147+
UserVerificationRequirement::Required,
148+
&mut req,
149+
pin_provider,
150+
timeout,
151+
)
152+
.await?;
153+
// On success, this is an all-empty Ctap2AuthenticatorConfigResponse
154+
handle_errors!(
155+
self,
156+
self.ctap2_authenticator_config(&req, timeout).await,
157+
uv_auth_used
158+
)
159+
}
160+
}
161+
162+
async fn set_min_pin_length_rpids(
163+
&mut self,
164+
rpids: Vec<String>,
165+
pin_provider: &Box<dyn PinProvider>,
166+
timeout: Duration,
167+
) -> Result<(), Error> {
168+
let mut req = Ctap2AuthenticatorConfigRequest::new_set_min_pin_length_rpids(rpids);
169+
loop {
170+
let uv_auth_used = user_verification(
171+
self,
172+
UserVerificationRequirement::Required,
173+
&mut req,
174+
pin_provider,
175+
timeout,
176+
)
177+
.await?;
178+
// On success, this is an all-empty Ctap2AuthenticatorConfigResponse
179+
handle_errors!(
180+
self,
181+
self.ctap2_authenticator_config(&req, timeout).await,
182+
uv_auth_used
183+
)
184+
}
185+
}
186+
}
187+
188+
impl Ctap2UserVerifiableRequest for Ctap2AuthenticatorConfigRequest {
189+
fn ensure_uv_set(&mut self) {
190+
// No-op
191+
}
192+
193+
fn calculate_and_set_uv_auth(
194+
&mut self,
195+
uv_proto: &Box<dyn PinUvAuthProtocol>,
196+
uv_auth_token: &[u8],
197+
) {
198+
// pinUvAuthParam (0x04): the result of calling
199+
// authenticate(pinUvAuthToken, 32×0xff || 0x0d || uint8(subCommand) || subCommandParams).
200+
let mut data = vec![0xff; 32];
201+
data.push(0x0D);
202+
data.push(self.subcommand as u8);
203+
if self.subcommand == Ctap2AuthenticatorConfigCommand::SetMinPINLength {
204+
data.extend(to_vec(&self.subcommand_params).unwrap());
205+
}
206+
let uv_auth_param = uv_proto.authenticate(uv_auth_token, &data);
207+
self.protocol = Some(uv_proto.version());
208+
self.uv_auth_param = Some(ByteBuf::from(uv_auth_param));
209+
}
210+
211+
fn client_data_hash(&self) -> &[u8] {
212+
unreachable!()
213+
}
214+
215+
fn permissions(&self) -> Ctap2AuthTokenPermissionRole {
216+
return Ctap2AuthTokenPermissionRole::AUTHENTICATOR_CONFIGURATION;
217+
}
218+
219+
fn permissions_rpid(&self) -> Option<&str> {
220+
None
221+
}
222+
223+
fn can_use_uv(&self, info: &Ctap2GetInfoResponse) -> bool {
224+
info.option_enabled("uvAcfg")
225+
}
226+
}

0 commit comments

Comments
 (0)