Skip to content

Commit 935c5c4

Browse files
Allow pinUvAuthProtocols to be null if UV is not required
1 parent 5d0e94c commit 935c5c4

2 files changed

Lines changed: 28 additions & 18 deletions

File tree

libwebauthn/src/pin.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,10 @@ where
391391
return Err(Error::Platform(PlatformError::PinTooLong));
392392
}
393393

394-
let uv_proto = select_uv_proto(&get_info_response).await?;
394+
let Some(uv_proto) = select_uv_proto(&get_info_response).await else {
395+
error!("No supported PIN/UV auth protocols found");
396+
return Err(Error::Ctap(CtapError::Other));
397+
};
395398

396399
let current_pin = match get_info_response.options.as_ref().unwrap().get("clientPin") {
397400
// Obtaining the current PIN, if one is set

libwebauthn/src/webauthn.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,17 @@ pub trait WebAuthn {
8787

8888
pub(crate) async fn select_uv_proto(
8989
get_info_response: &Ctap2GetInfoResponse,
90-
) -> Result<Box<dyn PinUvAuthProtocol>, Error> {
90+
) -> Option<Box<dyn PinUvAuthProtocol>> {
9191
for &protocol in get_info_response.pin_auth_protos.iter().flatten() {
9292
match protocol {
93-
1 => return Ok(Box::new(PinUvAuthProtocolOne::new())),
94-
2 => return Ok(Box::new(PinUvAuthProtocolTwo::new())),
93+
1 => return Some(Box::new(PinUvAuthProtocolOne::new())),
94+
2 => return Some(Box::new(PinUvAuthProtocolTwo::new())),
9595
_ => (),
9696
};
9797
}
9898

99-
error!(?get_info_response.pin_auth_protos, "No supported PIN/UV auth protocols found");
100-
Err(Error::Ctap(CtapError::Other))
99+
warn!(?get_info_response.pin_auth_protos, "No supported PIN/UV auth protocols found");
100+
None
101101
}
102102

103103
#[async_trait]
@@ -310,18 +310,21 @@ where
310310
{
311311
let get_info_response = channel.ctap2_get_info().await?;
312312
ctap2_request.handle_legacy_preview(&get_info_response);
313-
let uv_proto = select_uv_proto(&get_info_response).await?;
314-
let token_identifier = Ctap2AuthTokenPermission::new(
315-
uv_proto.version(),
316-
ctap2_request.permissions(),
317-
ctap2_request.permissions_rpid(),
318-
);
319-
if let Some(uv_auth_token) = channel.get_uv_auth_token(&token_identifier) {
320-
ctap2_request.calculate_and_set_uv_auth(&uv_proto, uv_auth_token);
321-
Ok(UsedPinUvAuthToken::FromStorage)
322-
} else {
323-
user_verification_helper(channel, user_verification, ctap2_request, timeout).await
313+
let maybe_uv_proto = select_uv_proto(&get_info_response).await;
314+
315+
if let Some(uv_proto) = maybe_uv_proto {
316+
let token_identifier = Ctap2AuthTokenPermission::new(
317+
uv_proto.version(),
318+
ctap2_request.permissions(),
319+
ctap2_request.permissions_rpid(),
320+
);
321+
if let Some(uv_auth_token) = channel.get_uv_auth_token(&token_identifier) {
322+
ctap2_request.calculate_and_set_uv_auth(&uv_proto, uv_auth_token);
323+
return Ok(UsedPinUvAuthToken::FromStorage);
324+
}
324325
}
326+
327+
user_verification_helper(channel, user_verification, ctap2_request, timeout).await
325328
}
326329

327330
#[instrument(skip_all)]
@@ -378,7 +381,11 @@ where
378381
return Ok(UsedPinUvAuthToken::LegacyUV);
379382
}
380383

381-
let uv_proto = select_uv_proto(&get_info_response).await?;
384+
let Some(uv_proto) = select_uv_proto(&get_info_response).await else {
385+
error!("No supported PIN/UV auth protocols found");
386+
return Err(Error::Ctap(CtapError::Other));
387+
};
388+
382389
// For operations that include a PIN, we want to fetch one before obtaining a shared secret.
383390
// This prevents the shared secret from expiring whilst we wait for the user to enter a PIN.
384391
let pin = match uv_operation {

0 commit comments

Comments
 (0)