Skip to content

Commit

Permalink
[webauthn] Update Windows Hello button label
Browse files Browse the repository at this point in the history
Update the Windows native authenticator button label to better match the
transports supported by Windows Hello for the specific request.

These changes are guarded by the kWebAuthnNewPasskeyUI flag.

UXW document: go/passkey-metadata-sync-uxw

Bug: 1459273
Change-Id: Ie01b38763811d3607504ba0a56e1e17840004a3b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4790868
Reviewed-by: Adam Langley <agl@chromium.org>
Commit-Queue: Nina Satragno <nsatragno@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1187548}
  • Loading branch information
nsatragno authored and Chromium LUCI CQ committed Aug 23, 2023
1 parent 384b171 commit 076abb0
Show file tree
Hide file tree
Showing 9 changed files with 381 additions and 48 deletions.
6 changes: 6 additions & 0 deletions chrome/app/generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -14622,9 +14622,15 @@ Please help our engineers fix this problem. Tell us what happened right before y
<message name="IDS_WEBAUTHN_TRANSPORT_WINDOWS_HELLO_OR_SECURITY_KEY" desc="Menu item text. The user selects this to use Windows Hello or a security key (an external physical device for user authentication). Windows Hello is a Microsoft brand and should be translated the same as it is in Windows. If you edit the language code in https://support.microsoft.com/en-us/windows/learn-about-windows-hello-and-set-it-up-dae28983-8242-bb2a-d3d1-87c9d265a5f0 you can see how Microsoft translates it in several languages. (It is often left untranslated.)">
Windows Hello or external security key
</message>
<message name="IDS_WEBAUTHN_TRANSPORT_WINDOWS_HELLO" desc="Menu item text. The user selects this to use Windows Hello. Windows Hello is a Microsoft brand and should be translated the same as it is in Windows. If you edit the language code in https://support.microsoft.com/en-us/windows/learn-about-windows-hello-and-set-it-up-dae28983-8242-bb2a-d3d1-87c9d265a5f0 you can see how Microsoft translates it in several languages. (It is often left untranslated.)">
Windows Hello
</message>
<message name="IDS_WEBAUTHN_TRANSPORT_ICLOUD_KEYCHAIN" desc="Menu item text. The user selects this to use iCloud Keychain. iCloud Keychain is an Apple brand and should be translated the same as it is in Apple devices. If you edit the language code in https://support.apple.com/es-es/HT204085 you can see how Apple translates it in several languages. ('Keychain' is usually localized.)">
iCloud Keychain
</message>
<message name="IDS_WEBAUTHN_TRANSPORT_EXTERNAL_SECURITY_KEY" desc="Menu item text. The user selects this to use a security key (an external physical device for user authentication).">
Use an external security key
</message>
<message name="IDS_WEBAUTHN_USB_ACTIVATE_DESCRIPTION" desc="Description in the dialog instructing the user to plug in and activate (e.g. press a button on) their USB security key (an external physical device for user authentication).">
Insert your security key and touch it
</message>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6fc71b29aefba8534294a4c167b10835578f484f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1e6bf5a51b4486ae9e6eb6a6103e3b4d2cd67807
117 changes: 92 additions & 25 deletions chrome/browser/webauthn/authenticator_request_dialog_model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -244,22 +244,84 @@ int GetHybridButtonLabel(bool has_security_key, bool specific_phones_listed) {
}
}

// SourcePriority determines which credential will be used when doing a modal()
// SourcePriority determines which credential will be used when doing a modal
// get and multiple platform authenticators have credentials, all with the same
// user ID.
int SourcePriority(device::AuthenticatorType source) {
switch (source) {
case device::AuthenticatorType::kEnclave:
return 3;
return 4;
case device::AuthenticatorType::kICloudKeychain:
return 2;
return 3;
case device::AuthenticatorType::kTouchID:
return 2;
case device::AuthenticatorType::kWinNative:
return 1;
default:
return 0;
}
}

// Returns the ID of a string and authenticator transport to label a button that
// triggers the Windows native WebAuthn API, or absl::nullopt if the button
// should not be shown. The transport represents the option Windows will prefer
// when tapping the button and is used to pick an icon and position on the list.
absl::optional<std::pair<int, AuthenticatorTransport>> GetWindowsAPIButtonLabel(
const device::FidoRequestHandlerBase::TransportAvailabilityInfo&
transport_availability,
bool specific_phones_listed) {
if (!transport_availability.has_win_native_api_authenticator) {
return absl::nullopt;
}
bool win_handles_internal;
bool win_handles_hybrid;
bool win_handles_security_key;
if (transport_availability.request_type ==
device::FidoRequestType::kGetAssertion) {
win_handles_internal =
transport_availability.transport_list_did_include_internal &&
transport_availability.has_platform_authenticator_credential ==
device::FidoRequestHandlerBase::RecognizedCredential::kUnknown;
win_handles_hybrid =
transport_availability.transport_list_did_include_hybrid &&
WebAuthnApiSupportsHybrid();
win_handles_security_key =
transport_availability.transport_list_did_include_security_key;
} else {
win_handles_internal = transport_availability.make_credential_attachment ==
device::AuthenticatorAttachment::kPlatform ||
transport_availability.make_credential_attachment ==
device::AuthenticatorAttachment::kAny;
win_handles_security_key =
transport_availability.make_credential_attachment ==
device::AuthenticatorAttachment::kCrossPlatform ||
transport_availability.make_credential_attachment ==
device::AuthenticatorAttachment::kAny;
win_handles_hybrid =
WebAuthnApiSupportsHybrid() && win_handles_security_key;
}
if (win_handles_internal) {
if (win_handles_security_key) {
return std::make_pair(
IDS_WEBAUTHN_TRANSPORT_WINDOWS_HELLO_OR_SECURITY_KEY,
AuthenticatorTransport::kInternal);
} else {
return std::make_pair(IDS_WEBAUTHN_TRANSPORT_WINDOWS_HELLO,
AuthenticatorTransport::kInternal);
}
}
if (win_handles_hybrid) {
return std::make_pair(
GetHybridButtonLabel(win_handles_security_key, specific_phones_listed),
AuthenticatorTransport::kHybrid);
}
if (win_handles_security_key) {
return std::make_pair(IDS_WEBAUTHN_TRANSPORT_EXTERNAL_SECURITY_KEY,
AuthenticatorTransport::kUsbHumanInterfaceDevice);
}
return absl::nullopt;
}

} // namespace

AuthenticatorRequestDialogModel::EphemeralState::EphemeralState() = default;
Expand Down Expand Up @@ -1620,29 +1682,19 @@ void AuthenticatorRequestDialogModel::PopulateMechanisms() {
base::Unretained(this)));
}

bool show_windows_button = true;
if (is_new_get_assertion_ui) {
if (transport_availability_.request_is_internal_only) {
show_windows_button =
transport_availability_.has_platform_authenticator_credential ==
device::FidoRequestHandlerBase::RecognizedCredential::kUnknown;
} else if (transport_availability_.is_only_hybrid_or_internal) {
show_windows_button =
transport_availability_.has_platform_authenticator_credential ==
device::FidoRequestHandlerBase::RecognizedCredential::kUnknown ||
windows_handles_hybrid;
}
absl::optional<std::pair<int, AuthenticatorTransport>> windows_button_label;
if (base::FeatureList::IsEnabled(device::kWebAuthnNewPasskeyUI)) {
windows_button_label = GetWindowsAPIButtonLabel(transport_availability_,
specific_phones_listed);
} else if (win_native_api_enabled()) {
windows_button_label =
std::make_pair(IDS_WEBAUTHN_TRANSPORT_WINDOWS_HELLO_OR_SECURITY_KEY,
AuthenticatorTransport::kInternal);
}
if (win_native_api_enabled() && show_windows_button) {
const std::u16string desc = l10n_util::GetStringUTF16(
IDS_WEBAUTHN_TRANSPORT_WINDOWS_HELLO_OR_SECURITY_KEY);
// TODO(crbug.com/1459273): Update the label depending on transports that
// Windows can serve.
mechanisms_.emplace_back(
Mechanism::WindowsAPI(), desc, desc,
GetTransportIcon(AuthenticatorTransport::kInternal),
base::BindRepeating(&AuthenticatorRequestDialogModel::StartWinNativeApi,
base::Unretained(this)));
if (windows_button_label &&
windows_button_label->second == AuthenticatorTransport::kInternal) {
// Add the Windows button before phones if it can trigger Windows Hello.
AddWindowsButton(windows_button_label->first, windows_button_label->second);
}

if (base::Contains(transport_availability_.available_transports, kCable) &&
Expand Down Expand Up @@ -1719,6 +1771,21 @@ void AuthenticatorRequestDialogModel::PopulateMechanisms() {
&AuthenticatorRequestDialogModel::StartGuidedFlowForTransport,
base::Unretained(this), transport));
}
// Add the Windows native API button last if it does not do Windows Hello.
if (windows_button_label &&
windows_button_label->second != AuthenticatorTransport::kInternal) {
AddWindowsButton(windows_button_label->first, windows_button_label->second);
}
}

void AuthenticatorRequestDialogModel::AddWindowsButton(
int label,
AuthenticatorTransport transport) {
const std::u16string desc = l10n_util::GetStringUTF16(label);
mechanisms_.emplace_back(
Mechanism::WindowsAPI(), desc, desc, GetTransportIcon(transport),
base::BindRepeating(&AuthenticatorRequestDialogModel::StartWinNativeApi,
base::Unretained(this)));
}

absl::optional<size_t>
Expand Down
4 changes: 4 additions & 0 deletions chrome/browser/webauthn/authenticator_request_dialog_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,10 @@ class AuthenticatorRequestDialogModel {
// PopulateMechanisms fills in |mechanisms_|.
void PopulateMechanisms();

// Adds a button that triggers Windows Hello with the specified string ID and
// transport icon.
void AddWindowsButton(int label, AuthenticatorTransport transport);

// IndexOfPriorityMechanism returns the index, in |mechanisms_|, of the
// Mechanism that should be triggered immediately, if any.
absl::optional<size_t> IndexOfPriorityMechanism();
Expand Down

0 comments on commit 076abb0

Please sign in to comment.