#include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
#include <algorithm>
#include <array>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "base/check.h"
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/i18n/time_formatting.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/time/default_clock.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_service.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_observer.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/sync/device_info_sync_service_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h"
#include "chrome/browser/ui/webauthn/user_actions.h"
#include "chrome/browser/webauthn/authenticator_request_dialog_controller.h"
#include "chrome/browser/webauthn/authenticator_request_dialog_model.h"
#include "chrome/browser/webauthn/cablev2_devices.h"
#include "chrome/browser/webauthn/enclave_manager.h"
#include "chrome/browser/webauthn/gpm_enclave_controller.h"
#include "chrome/browser/webauthn/passkey_model_factory.h"
#include "chrome/browser/webauthn/unexportable_key_utils.h"
#include "chrome/browser/webauthn/webauthn_pref_names.h"
#include "chrome/browser/webauthn/webauthn_switches.h"
#include "chrome/common/chrome_version.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/device_event_log/device_event_log.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/base/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/sync/base/features.h"
#include "components/sync/base/user_selectable_type.h"
#include "components/sync/protocol/webauthn_credential_specifics.pb.h"
#include "components/sync/service/sync_service.h"
#include "components/sync/service/sync_user_settings.h"
#include "components/sync_device_info/device_info.h"
#include "components/sync_device_info/device_info_sync_service.h"
#include "components/sync_device_info/device_info_tracker.h"
#include "components/trusted_vault/frontend_trusted_vault_connection.h"
#include "components/user_prefs/user_prefs.h"
#include "components/webauthn/core/browser/passkey_model.h"
#include "content/public/browser/authenticator_request_client_delegate.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/device_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/visibility.h"
#include "content/public/browser/web_authentication_request_proxy.h"
#include "content/public/browser/web_contents.h"
#include "crypto/random.h"
#include "crypto/unexportable_key.h"
#include "device/fido/cable/cable_discovery_data.h"
#include "device/fido/cable/v2_constants.h"
#include "device/fido/cable/v2_handshake.h"
#include "device/fido/discoverable_credential_metadata.h"
#include "device/fido/enclave/constants.h"
#include "device/fido/features.h"
#include "device/fido/fido_authenticator.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_discovery_base.h"
#include "device/fido/fido_discovery_factory.h"
#include "device/fido/fido_request_handler_base.h"
#include "device/fido/fido_transport_protocol.h"
#include "device/fido/fido_types.h"
#include "device/fido/mac/icloud_keychain.h"
#include "device/fido/public_key_credential_descriptor.h"
#include "device/fido/public_key_credential_user_entity.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/url_pattern.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/base/url_util.h"
#include "services/device/public/mojom/usb_manager.mojom.h"
#include "third_party/icu/source/common/unicode/locid.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
#include "url/url_constants.h"
#include "url/url_util.h"
#if BUILDFLAG(IS_MAC)
#include "base/base64.h"
#include "chrome/browser/ui/webauthn/user_actions.h"
#include "chrome/browser/webauthn/chrome_authenticator_request_delegate_mac.h"
#include "device/fido/mac/authenticator.h"
#include "device/fido/mac/credential_metadata.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "ui/views/widget/widget.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "chrome/browser/webauthn/local_credential_management_win.h"
#include "device/fido/win/authenticator.h"
#include "device/fido/win/webauthn_api.h"
#endif
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/webauthn/chromeos/passkey_dialog_controller.h"
#include "chrome/browser/webauthn/chromeos/passkey_discovery.h"
#include "chrome/browser/webauthn/chromeos/passkey_service.h"
#include "chrome/browser/webauthn/chromeos/passkey_service_factory.h"
#include "chromeos/components/webauthn/webauthn_request_registrar.h"
#include "ui/aura/window.h"
#endif
namespace {
ChromeAuthenticatorRequestDelegate::TestObserver* g_observer = …;
static constexpr char kGoogleRpId[] = …;
bool IsWebAuthnRPIDListedInSecurityKeyPermitAttestationPolicy(
content::BrowserContext* browser_context,
const std::string& relying_party_id) { … }
bool IsOriginListedInEnterpriseAttestationSwitch(
const url::Origin& caller_origin) { … }
bool IsCredentialFromPlatformAuthenticator(
device::DiscoverableCredentialMetadata cred) { … }
bool UserIdHasGooglePasskeyAuthPrefix(const std::vector<uint8_t>& user_id) { … }
void FilterGoogleAuthPasskeys(
std::vector<device::DiscoverableCredentialMetadata>* passkeys) { … }
bool ExtensionCanAssertRpId(const extensions::Extension& extension,
const std::string& rp_id) { … }
#if BUILDFLAG(IS_MAC)
const char kWebAuthnTouchIdMetadataSecretPrefName[] =
"webauthn.touchid.metadata_secret";
const char kWebAuthnTouchIdLastUsed[] = "webauthn.touchid.last_used";
const int kMacOsRecentlyUsedMaxDays = 31;
#endif
class CableLinkingEventHandler : public ProfileObserver { … };
#if BUILDFLAG(IS_MAC)
bool UserDeniedICloudKeychainPermission() {
const std::optional<bool> has_permission =
device::fido::icloud_keychain::HasPermission();
return has_permission && has_permission.value() == false;
}
bool AccountHasPasskeys(Profile* profile) {
webauthn::PasskeyModel* passkey_model =
PasskeyModelFactory::GetInstance()->GetForProfile(profile);
CHECK(passkey_model);
return !passkey_model->IsEmpty();
}
bool AccountHasNonAppleDevice(Profile* profile) {
syncer::DeviceInfoSyncService* const sync_service =
DeviceInfoSyncServiceFactory::GetForProfile(profile);
if (!sync_service) {
return false;
}
syncer::DeviceInfoTracker* const tracker =
sync_service->GetDeviceInfoTracker();
const std::vector<const syncer::DeviceInfo*> devices =
tracker->GetAllDeviceInfo();
return base::ranges::any_of(devices, [](const auto* device) {
switch (device->os_type()) {
case syncer::DeviceInfo::OsType::kIOS:
case syncer::DeviceInfo::OsType::kMac:
return false;
default:
return true;
}
});
}
bool EnclaveCanBeDefault(Profile* profile) {
if (AccountHasPasskeys(profile)) {
FIDO_LOG(EVENT)
<< "Enclave can be default because account already has passkeys.";
return true;
}
if (AccountHasNonAppleDevice(profile)) {
FIDO_LOG(EVENT)
<< "Enclave can be default because non-Apple device found in Sync.";
return true;
}
if (!device::fido::icloud_keychain::IsSupported()) {
FIDO_LOG(EVENT)
<< "Enclave can be default because iCloud Keychain isn't supported.";
return true;
}
if (!IsICloudDriveEnabled()) {
FIDO_LOG(EVENT)
<< "Enclave can be default because iCloud Drive isn't enabled.";
return true;
}
if (UserDeniedICloudKeychainPermission()) {
FIDO_LOG(EVENT) << "Enclave can be default because iCloud Keychain "
"permission is denied.";
return true;
}
FIDO_LOG(EVENT) << "Enclave cannot be the default for this request. No "
"enabling conditions apply.";
return false;
}
#else
bool EnclaveCanBeDefault(Profile* profile) { … }
#endif
bool SkipGpmPasskeyCreationForOwnAccount(
device::FidoRequestType request_type,
const std::string& rp_id,
std::string_view user_name,
const CoreAccountInfo& primary_account_info) { … }
}
ChromeWebAuthenticationDelegate::ChromeWebAuthenticationDelegate() = default;
ChromeWebAuthenticationDelegate::~ChromeWebAuthenticationDelegate() = default;
bool ChromeWebAuthenticationDelegate::
OverrideCallerOriginAndRelyingPartyIdValidation(
content::BrowserContext* browser_context,
const url::Origin& caller_origin,
const std::string& relying_party_id) { … }
bool ChromeWebAuthenticationDelegate::OriginMayUseRemoteDesktopClientOverride(
content::BrowserContext* browser_context,
const url::Origin& caller_origin) { … }
std::optional<std::string>
ChromeWebAuthenticationDelegate::MaybeGetRelyingPartyIdOverride(
const std::string& claimed_relying_party_id,
const url::Origin& caller_origin) { … }
bool ChromeWebAuthenticationDelegate::ShouldPermitIndividualAttestation(
content::BrowserContext* browser_context,
const url::Origin& caller_origin,
const std::string& relying_party_id) { … }
bool ChromeWebAuthenticationDelegate::SupportsResidentKeys(
content::RenderFrameHost* render_frame_host) { … }
bool ChromeWebAuthenticationDelegate::SupportsPasskeyMetadataSyncing() { … }
bool ChromeWebAuthenticationDelegate::IsFocused(
content::WebContents* web_contents) { … }
void ChromeWebAuthenticationDelegate::
IsUserVerifyingPlatformAuthenticatorAvailableOverride(
content::RenderFrameHost* render_frame_host,
base::OnceCallback<void(std::optional<bool>)> callback) { … }
content::WebAuthenticationRequestProxy*
ChromeWebAuthenticationDelegate::MaybeGetRequestProxy(
content::BrowserContext* browser_context,
const url::Origin& caller_origin) { … }
void ChromeWebAuthenticationDelegate::DeletePasskey(
content::WebContents* web_contents,
const std::vector<uint8_t>& passkey_credential_id,
const std::string& relying_party_id) { … }
void ChromeWebAuthenticationDelegate::DeleteUnacceptedPasskeys(
content::WebContents* web_contents,
const std::string& relying_party_id,
const std::vector<uint8_t>& user_id,
const std::vector<std::vector<uint8_t>>& all_accepted_credentials_ids) { … }
void ChromeWebAuthenticationDelegate::UpdateUserPasskeys(
content::WebContents* web_contents,
const std::string& relying_party_id,
std::vector<uint8_t>& user_id,
const std::string& name,
const std::string& display_name) { … }
#if BUILDFLAG(IS_MAC)
ChromeWebAuthenticationDelegate::TouchIdAuthenticatorConfig
ChromeWebAuthenticationDelegate::TouchIdAuthenticatorConfigForProfile(
Profile* profile) {
constexpr char kKeychainAccessGroup[] =
MAC_TEAM_IDENTIFIER_STRING "." MAC_BUNDLE_IDENTIFIER_STRING ".webauthn";
std::string metadata_secret =
profile->GetPrefs()->GetString(kWebAuthnTouchIdMetadataSecretPrefName);
if (metadata_secret.empty() ||
!base::Base64Decode(metadata_secret, &metadata_secret)) {
metadata_secret = device::fido::mac::GenerateCredentialMetadataSecret();
profile->GetPrefs()->SetString(
kWebAuthnTouchIdMetadataSecretPrefName,
base::Base64Encode(base::as_bytes(base::make_span(metadata_secret))));
}
return TouchIdAuthenticatorConfig{
.keychain_access_group = kKeychainAccessGroup,
.metadata_secret = std::move(metadata_secret)};
}
std::optional<ChromeWebAuthenticationDelegate::TouchIdAuthenticatorConfig>
ChromeWebAuthenticationDelegate::GetTouchIdAuthenticatorConfig(
content::BrowserContext* browser_context) {
return TouchIdAuthenticatorConfigForProfile(
Profile::FromBrowserContext(browser_context));
}
#endif
#if BUILDFLAG(IS_CHROMEOS)
content::WebAuthenticationDelegate::ChromeOSGenerateRequestIdCallback
ChromeWebAuthenticationDelegate::GetGenerateRequestIdCallback(
content::RenderFrameHost* render_frame_host) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
aura::Window* window =
render_frame_host->GetNativeView()->GetToplevelWindow();
return chromeos::webauthn::WebAuthnRequestRegistrar::Get()
->GetRegisterCallback(window);
}
#endif
void ChromeWebAuthenticationDelegate::BrowserProvidedPasskeysAvailable(
content::BrowserContext* browser_context,
base::OnceCallback<void(bool)> callback) { … }
std::vector<std::unique_ptr<device::cablev2::Pairing>>
ChromeAuthenticatorRequestDelegate::TestObserver::
GetCablePairingsFromSyncedDevices() { … }
void ChromeAuthenticatorRequestDelegate::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) { … }
ChromeAuthenticatorRequestDelegate::ChromeAuthenticatorRequestDelegate(
content::RenderFrameHost* render_frame_host)
: … { … }
ChromeAuthenticatorRequestDelegate::~ChromeAuthenticatorRequestDelegate() { … }
void ChromeAuthenticatorRequestDelegate::SetGlobalObserverForTesting(
TestObserver* observer) { … }
base::WeakPtr<ChromeAuthenticatorRequestDelegate>
ChromeAuthenticatorRequestDelegate::AsWeakPtr() { … }
GPMEnclaveController*
ChromeAuthenticatorRequestDelegate::enclave_controller_for_testing() const { … }
#if BUILDFLAG(IS_CHROMEOS)
chromeos::PasskeyDialogController&
ChromeAuthenticatorRequestDelegate::chromeos_passkey_controller_for_testing()
const {
CHECK(chromeos_passkey_controller_);
return *chromeos_passkey_controller_;
}
#endif
void ChromeAuthenticatorRequestDelegate::SetRelyingPartyId(
const std::string& rp_id) { … }
bool ChromeAuthenticatorRequestDelegate::DoesBlockRequestOnFailure(
InterestingFailureReason reason) { … }
void ChromeAuthenticatorRequestDelegate::OnTransactionSuccessful(
RequestSource request_source,
device::FidoRequestType request_type,
device::AuthenticatorType authenticator_type) { … }
void ChromeAuthenticatorRequestDelegate::RegisterActionCallbacks(
base::OnceClosure cancel_callback,
base::RepeatingClosure start_over_callback,
AccountPreselectedCallback account_preselected_callback,
device::FidoRequestHandlerBase::RequestCallback request_callback,
base::RepeatingClosure bluetooth_adapter_power_on_callback,
base::RepeatingCallback<
void(device::FidoRequestHandlerBase::BlePermissionCallback)>
request_ble_permission_callback) { … }
void ChromeAuthenticatorRequestDelegate::ShouldReturnAttestation(
const std::string& relying_party_id,
const device::FidoAuthenticator* authenticator,
bool is_enterprise_attestation,
base::OnceCallback<void(bool)> callback) { … }
std::vector<std::unique_ptr<device::FidoDiscoveryBase>>
ChromeAuthenticatorRequestDelegate::CreatePlatformDiscoveries() { … }
void ChromeAuthenticatorRequestDelegate::ConfigureDiscoveries(
const url::Origin& origin,
const std::string& rp_id,
RequestSource request_source,
device::FidoRequestType request_type,
std::optional<device::ResidentKeyRequirement> resident_key_requirement,
device::UserVerificationRequirement user_verification_requirement,
std::optional<std::string_view> user_name,
base::span<const device::CableDiscoveryData> pairings_from_extension,
bool browser_provided_passkeys_available,
device::FidoDiscoveryFactory* discovery_factory) { … }
void ChromeAuthenticatorRequestDelegate::SetHints(
const AuthenticatorRequestClientDelegate::Hints& hints) { … }
void ChromeAuthenticatorRequestDelegate::SelectAccount(
std::vector<device::AuthenticatorGetAssertionResponse> responses,
base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)>
callback) { … }
void ChromeAuthenticatorRequestDelegate::DisableUI() { … }
bool ChromeAuthenticatorRequestDelegate::IsWebAuthnUIEnabled() { … }
void ChromeAuthenticatorRequestDelegate::SetConditionalRequest(
bool is_conditional) { … }
void ChromeAuthenticatorRequestDelegate::SetCredentialIdFilter(
std::vector<device::PublicKeyCredentialDescriptor> credential_list) { … }
void ChromeAuthenticatorRequestDelegate::SetUserEntityForMakeCredentialRequest(
const device::PublicKeyCredentialUserEntity& user_entity) { … }
void ChromeAuthenticatorRequestDelegate::OnTransportAvailabilityEnumerated(
device::FidoRequestHandlerBase::TransportAvailabilityInfo data) { … }
bool ChromeAuthenticatorRequestDelegate::EmbedderControlsAuthenticatorDispatch(
const device::FidoAuthenticator& authenticator) { … }
void ChromeAuthenticatorRequestDelegate::FidoAuthenticatorAdded(
const device::FidoAuthenticator& authenticator) { … }
void ChromeAuthenticatorRequestDelegate::FidoAuthenticatorRemoved(
std::string_view authenticator_id) { … }
void ChromeAuthenticatorRequestDelegate::BluetoothAdapterStatusChanged(
device::FidoRequestHandlerBase::BleStatus ble_status) { … }
bool ChromeAuthenticatorRequestDelegate::SupportsPIN() const { … }
void ChromeAuthenticatorRequestDelegate::CollectPIN(
CollectPINOptions options,
base::OnceCallback<void(std::u16string)> provide_pin_cb) { … }
void ChromeAuthenticatorRequestDelegate::StartBioEnrollment(
base::OnceClosure next_callback) { … }
void ChromeAuthenticatorRequestDelegate::OnSampleCollected(
int bio_samples_remaining) { … }
void ChromeAuthenticatorRequestDelegate::FinishCollectToken() { … }
void ChromeAuthenticatorRequestDelegate::OnRetryUserVerification(int attempts) { … }
void ChromeAuthenticatorRequestDelegate::OnStartOver() { … }
void ChromeAuthenticatorRequestDelegate::OnModelDestroyed(
AuthenticatorRequestDialogModel* model) { … }
void ChromeAuthenticatorRequestDelegate::OnCancelRequest() { … }
void ChromeAuthenticatorRequestDelegate::OnManageDevicesClicked() { … }
void ChromeAuthenticatorRequestDelegate::SetPassEmptyUsbDeviceManagerForTesting(
bool value) { … }
void ChromeAuthenticatorRequestDelegate::SetTrustedVaultConnectionForTesting(
std::unique_ptr<trusted_vault::TrustedVaultConnection> connection) { … }
void ChromeAuthenticatorRequestDelegate::SetClockForTesting(
base::Clock* clock) { … }
content::RenderFrameHost*
ChromeAuthenticatorRequestDelegate::GetRenderFrameHost() const { … }
content::BrowserContext* ChromeAuthenticatorRequestDelegate::GetBrowserContext()
const { … }
void ChromeAuthenticatorRequestDelegate::ShowUI(
device::FidoRequestHandlerBase::TransportAvailabilityInfo tai) { … }
void ChromeAuthenticatorRequestDelegate::OnReadyForUI() { … }
bool ChromeAuthenticatorRequestDelegate::ShouldPermitCableExtension(
const url::Origin& origin) { … }
void ChromeAuthenticatorRequestDelegate::OnInvalidatedCablePairing(
std::unique_ptr<device::cablev2::Pairing> failed_pairing) { … }
void ChromeAuthenticatorRequestDelegate::OnCableEvent(
device::cablev2::Event event) { … }
void ChromeAuthenticatorRequestDelegate::GetPhoneContactableGpmPasskeysForRpId(
std::vector<device::DiscoverableCredentialMetadata>* passkeys) { … }
void ChromeAuthenticatorRequestDelegate::FilterRecognizedCredentials(
device::FidoRequestHandlerBase::TransportAvailabilityInfo* tai) { … }
#if BUILDFLAG(IS_MAC)
std::optional<int> ChromeAuthenticatorRequestDelegate::DaysSinceDate(
const std::string& formatted_date,
const base::Time now) {
int year, month, day_of_month;
if (sscanf(formatted_date.c_str(), "%u-%u-%u", &year, &month,
&day_of_month) != 3) {
return std::nullopt;
}
const base::Time::Exploded exploded = {
.year = year, .month = month, .day_of_month = day_of_month};
base::Time t;
if (!base::Time::FromUTCExploded(exploded, &t) || now < t) {
return std::nullopt;
}
const base::TimeDelta difference = now - t;
return difference.InDays();
}
std::optional<bool> ChromeAuthenticatorRequestDelegate::GetICloudKeychainPref(
const PrefService* prefs) {
const PrefService::Preference* pref =
prefs->FindPreference(prefs::kCreatePasskeysInICloudKeychain);
if (pref->IsDefaultValue()) {
return std::nullopt;
}
return pref->GetValue()->GetBool();
}
bool ChromeAuthenticatorRequestDelegate::IsActiveProfileAuthenticatorUser(
const PrefService* prefs) {
const std::string& last_used = prefs->GetString(kWebAuthnTouchIdLastUsed);
if (last_used.empty()) {
return false;
}
const std::optional<int> days = DaysSinceDate(last_used, base::Time::Now());
return days.has_value() && days.value() <= kMacOsRecentlyUsedMaxDays;
}
bool ChromeAuthenticatorRequestDelegate::ShouldCreateInICloudKeychain(
RequestSource request_source,
bool is_active_profile_authenticator_user,
bool has_icloud_drive_enabled,
bool request_is_for_google_com,
std::optional<bool> preference) {
if (request_source != RequestSource::kWebAuthentication) {
return false;
}
if (preference.has_value()) {
return *preference;
}
const base::Feature* feature;
if (request_is_for_google_com) {
feature = &device::kWebAuthnICloudKeychainForGoogle;
} else {
if (is_active_profile_authenticator_user) {
if (has_icloud_drive_enabled) {
feature = &device::kWebAuthnICloudKeychainForActiveWithDrive;
} else {
feature = &device::kWebAuthnICloudKeychainForActiveWithoutDrive;
}
} else {
if (has_icloud_drive_enabled) {
feature = &device::kWebAuthnICloudKeychainForInactiveWithDrive;
} else {
feature = &device::kWebAuthnICloudKeychainForInactiveWithoutDrive;
}
}
}
return base::FeatureList::IsEnabled(*feature);
}
void ChromeAuthenticatorRequestDelegate::ConfigureICloudKeychain(
RequestSource request_source,
const std::string& rp_id) {
const PrefService* prefs =
Profile::FromBrowserContext(GetBrowserContext())->GetPrefs();
const bool is_icloud_drive_enabled = IsICloudDriveEnabled();
const bool is_active_profile_authenticator_user =
IsActiveProfileAuthenticatorUser(prefs);
dialog_controller_->set_allow_icloud_keychain(
request_source == RequestSource::kWebAuthentication);
dialog_controller_->set_has_icloud_drive_enabled(is_icloud_drive_enabled);
dialog_controller_->set_is_active_profile_authenticator_user(
is_active_profile_authenticator_user);
dialog_controller_->set_should_create_in_icloud_keychain(
ShouldCreateInICloudKeychain(
request_source, is_active_profile_authenticator_user,
is_icloud_drive_enabled, rp_id == "google.com",
GetICloudKeychainPref(prefs)));
}
#endif