[WebAuthn] Stop offering GPM bootstrapping after user declines twice
If the user backs out of the GPM enclave bootstrapping screen twice without clicking through it then we will now deprioritize it as an option. After that, passkey creation will not use the enclave as a priority mechanism, although it will still be an option on the mechanism selection screen that will allow bootstrapping if selected. Also, synced GPM passkeys will trigger hybrid for assertions. Bug: 40274370 Change-Id: I34604f3899bdfd169cad1930bbee1a614c792f12 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5529798 Reviewed-by: Adam Langley <agl@chromium.org> Commit-Queue: Ken Buchanan <kenrb@chromium.org> Cr-Commit-Position: refs/heads/main@{#1299568}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
b55c686e42
commit
cfa287ac7d
chrome/browser/webauthn
authenticator_request_dialog_model.ccchrome_authenticator_request_delegate.ccgpm_enclave_controller.ccwebauthn_pref_names.ccwebauthn_pref_names.h
device/fido/enclave
@ -48,6 +48,7 @@
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "device/fido/cable/cable_discovery_data.h"
|
||||
#include "device/fido/discoverable_credential_metadata.h"
|
||||
#include "device/fido/enclave/constants.h"
|
||||
#include "device/fido/enclave/metrics.h"
|
||||
#include "device/fido/features.h"
|
||||
#include "device/fido/fido_authenticator.h"
|
||||
@ -663,9 +664,22 @@ void AuthenticatorRequestDialogController::StartFlow(
|
||||
}
|
||||
|
||||
void AuthenticatorRequestDialogController::StartOver() {
|
||||
if (enclave_was_priority_mechanism_) {
|
||||
if (model_->step() == Step::kTrustThisComputerCreation ||
|
||||
model_->step() == Step::kTrustThisComputerAssertion) {
|
||||
auto* pref_service = Profile::FromBrowserContext(
|
||||
model_->GetRenderFrameHost()->GetBrowserContext())
|
||||
->GetOriginalProfile()
|
||||
->GetPrefs();
|
||||
int current_gpm_decline_count = pref_service->GetInteger(
|
||||
webauthn::pref_names::kEnclaveDeclinedGPMBootstrappingCount);
|
||||
pref_service->SetInteger(
|
||||
webauthn::pref_names::kEnclaveDeclinedGPMBootstrappingCount,
|
||||
std::min(current_gpm_decline_count + 1,
|
||||
device::enclave::kMaxGPMBootstrapPrompts));
|
||||
} else if (enclave_was_priority_mechanism_) {
|
||||
auto* pref_service = Profile::FromBrowserContext(
|
||||
model_->GetRenderFrameHost()->GetBrowserContext())
|
||||
->GetOriginalProfile()
|
||||
->GetPrefs();
|
||||
int current_gpm_decline_count = pref_service->GetInteger(
|
||||
webauthn::pref_names::kEnclaveDeclinedGPMCredentialCreationCount);
|
||||
@ -2515,13 +2529,22 @@ AuthenticatorRequestDialogController::IndexOfPriorityMechanism() {
|
||||
device::FidoRequestType::kMakeCredential);
|
||||
|
||||
Profile* profile = Profile::FromBrowserContext(
|
||||
model_->GetRenderFrameHost()->GetBrowserContext());
|
||||
model_->GetRenderFrameHost()->GetBrowserContext())
|
||||
->GetOriginalProfile();
|
||||
const bool enclave_decline_limit_reached =
|
||||
profile->GetPrefs()->GetInteger(
|
||||
webauthn::pref_names::kEnclaveDeclinedGPMCredentialCreationCount) >=
|
||||
kMaxPriorityGPMCredentialCreations;
|
||||
// If a user has declined bootstrapping too many times then GPM will still
|
||||
// be available in the mechanism selection screen for credential creation,
|
||||
// but it can no longer be a priority mechanism.
|
||||
const bool enclave_bootstrap_limit_reached =
|
||||
profile->GetPrefs()->GetInteger(
|
||||
webauthn::pref_names::kEnclaveDeclinedGPMBootstrappingCount) >=
|
||||
device::enclave::kMaxGPMBootstrapPrompts;
|
||||
if (base::FeatureList::IsEnabled(device::kWebAuthnEnclaveAuthenticator) &&
|
||||
!enclave_decline_limit_reached && enclave_enabled_ &&
|
||||
!enclave_decline_limit_reached && !enclave_bootstrap_limit_reached &&
|
||||
enclave_enabled_ &&
|
||||
*transport_availability_.make_credential_attachment ==
|
||||
device::AuthenticatorAttachment::kPlatform) {
|
||||
priority_list.emplace_back(Mechanism::Enclave());
|
||||
|
@ -615,6 +615,8 @@ void ChromeAuthenticatorRequestDelegate::RegisterProfilePrefs(
|
||||
registry->RegisterListPref(prefs::kSecurityKeyPermitAttestation);
|
||||
registry->RegisterIntegerPref(
|
||||
webauthn::pref_names::kEnclaveDeclinedGPMCredentialCreationCount, 0);
|
||||
registry->RegisterIntegerPref(
|
||||
webauthn::pref_names::kEnclaveDeclinedGPMBootstrappingCount, 0);
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
LocalCredentialManagementWin::RegisterProfilePrefs(registry);
|
||||
#endif
|
||||
@ -1388,7 +1390,14 @@ void ChromeAuthenticatorRequestDelegate::GetPhoneContactableGpmPasskeysForRpId(
|
||||
credentials = chromeos_passkey_controller_->credentials();
|
||||
type = device::AuthenticatorType::kChromeOSPasskeys;
|
||||
#else
|
||||
if (enclave_controller_) {
|
||||
int enclave_bootstrap_limit_reached =
|
||||
Profile::FromBrowserContext(GetBrowserContext())
|
||||
->GetOriginalProfile()
|
||||
->GetPrefs()
|
||||
->GetInteger(
|
||||
webauthn::pref_names::kEnclaveDeclinedGPMBootstrappingCount) >=
|
||||
device::enclave::kMaxGPMBootstrapPrompts;
|
||||
if (enclave_controller_ && !enclave_bootstrap_limit_reached) {
|
||||
credentials = enclave_controller_->creds();
|
||||
type = device::AuthenticatorType::kEnclave;
|
||||
#endif
|
||||
|
@ -901,6 +901,10 @@ void GPMEnclaveController::OnTrustThisComputer() {
|
||||
model_->SetStep(Step::kGPMConfirmOffTheRecordCreate);
|
||||
return;
|
||||
}
|
||||
Profile::FromBrowserContext(model_->GetRenderFrameHost()->GetBrowserContext())
|
||||
->GetPrefs()
|
||||
->SetInteger(webauthn::pref_names::kEnclaveDeclinedGPMBootstrappingCount,
|
||||
0);
|
||||
model_->SetStep(Step::kRecoverSecurityDomain);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,9 @@ const char kAllowWithBrokenCerts[] = "webauthn.allow_with_broken_certs";
|
||||
const char kEnclaveDeclinedGPMCredentialCreationCount[] =
|
||||
"webauthn.enclave_declined_gpm_credential_creation_count";
|
||||
|
||||
const char kEnclaveDeclinedGPMBootstrappingCount[] =
|
||||
"webauthn.enclave_declined_gpm_bootstrapping_count";
|
||||
|
||||
const char kEnclaveFailedPINAttemptsCount[] =
|
||||
"webauthn.enclave_failed_pin_attempts_count";
|
||||
|
||||
|
@ -15,6 +15,9 @@ extern const char kAllowWithBrokenCerts[];
|
||||
// request.
|
||||
extern const char kEnclaveDeclinedGPMCredentialCreationCount[];
|
||||
|
||||
// Tracks how many times a user has declined GPM bootstrapping on this device.
|
||||
extern const char kEnclaveDeclinedGPMBootstrappingCount[];
|
||||
|
||||
// Tracks how many consecutive failed GPM PIN attempts have been made to the
|
||||
// enclave service from this device and profile.
|
||||
extern const char kEnclaveFailedPINAttemptsCount[];
|
||||
|
@ -45,6 +45,10 @@ inline constexpr size_t kCounterIDLen = 8;
|
||||
// The length of a recovery key store "vault handle" value.
|
||||
inline constexpr size_t kVaultHandleLen = 17;
|
||||
|
||||
// The maximum number of times that GPM enclave bootstrapping can be declined
|
||||
// before it becomes deprioritized as an authenticator option.
|
||||
inline constexpr int kMaxGPMBootstrapPrompts = 2;
|
||||
|
||||
// The list of algorithms that are acceptable as device identity keys.
|
||||
inline constexpr crypto::SignatureVerifier::SignatureAlgorithm
|
||||
kSigningAlgorithms[] = {
|
||||
|
Reference in New Issue
Block a user