Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 5 | #ifndef CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_COMMON_IMPL_H_ |
| 6 | #define CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_COMMON_IMPL_H_ |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 7 | |
| 8 | #include <stdint.h> |
| 9 | |
| 10 | #include <memory> |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 11 | #include <optional> |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 12 | #include <string> |
| 13 | #include <vector> |
| 14 | |
Nina Satragno | 6e0f1ab | 2024-06-13 22:28:11 | [diff] [blame] | 15 | #include "base/memory/weak_ptr.h" |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 16 | #include "base/types/strong_alias.h" |
Ken Buchanan | be8629f | 2025-01-11 03:37:16 | [diff] [blame] | 17 | #include "content/browser/webauth/client_data_json.h" |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 18 | #include "content/common/content_export.h" |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 19 | #include "content/public/browser/authenticator_common.h" |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 20 | #include "content/public/browser/authenticator_request_client_delegate.h" |
Adam Langley | b038582 | 2021-03-19 23:34:00 | [diff] [blame] | 21 | #include "content/public/browser/global_routing_id.h" |
Martin Kreichgauer | 165ff72 | 2021-08-26 01:33:52 | [diff] [blame] | 22 | #include "content/public/browser/web_authentication_request_proxy.h" |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 23 | #include "device/fido/authenticator_get_assertion_response.h" |
| 24 | #include "device/fido/authenticator_make_credential_response.h" |
Ken Buchanan | be8629f | 2025-01-11 03:37:16 | [diff] [blame] | 25 | #include "device/fido/fido_request_handler_base.h" |
Adam Langley | 6f8b030d | 2020-04-06 20:10:57 | [diff] [blame] | 26 | #include "device/fido/make_credential_request_handler.h" |
Julie Jeongeun Kim | b6a0a1f | 2019-03-21 05:08:26 | [diff] [blame] | 27 | #include "third_party/blink/public/mojom/webauthn/authenticator.mojom.h" |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 28 | |
| 29 | namespace device { |
| 30 | |
Martin Kreichgauer | 0b24720b | 2020-08-17 19:58:23 | [diff] [blame] | 31 | class FidoDiscoveryFactory; |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 32 | |
| 33 | enum class FidoReturnCode : uint8_t; |
| 34 | |
Martin Kreichgauer | abd93b98 | 2019-08-30 19:35:38 | [diff] [blame] | 35 | enum class GetAssertionStatus; |
| 36 | enum class MakeCredentialStatus; |
| 37 | |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 38 | } // namespace device |
| 39 | |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 40 | namespace url { |
| 41 | class Origin; |
| 42 | } |
| 43 | |
| 44 | namespace content { |
| 45 | |
| 46 | class BrowserContext; |
| 47 | class RenderFrameHost; |
Ken Buchanan | 3889e2b | 2020-02-11 04:26:53 | [diff] [blame] | 48 | class WebAuthRequestSecurityChecker; |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 49 | |
Martin Kreichgauer | 3b3a657 | 2020-09-24 08:49:48 | [diff] [blame] | 50 | enum class RequestExtension; |
Adam Langley | 70a2415 | 2022-08-30 02:01:04 | [diff] [blame] | 51 | enum class AttestationErasureOption; |
Martin Kreichgauer | 3b3a657 | 2020-09-24 08:49:48 | [diff] [blame] | 52 | |
Andrii Natiahlyi | 6b2f4b1 | 2024-09-03 14:58:42 | [diff] [blame] | 53 | // https://w3c.github.io/webauthn/#enumdef-clientcapability |
| 54 | namespace client_capabilities { |
| 55 | |
Nina Satragno | 7e1175ff | 2024-09-17 15:12:35 | [diff] [blame] | 56 | // This is the subset of client capabilities computed by the browser. See also |
| 57 | // //third_party/blink/renderer/modules/credentialmanagement/public_key_credential.cc. |
Martin Kreichgauer | a57d2f1 | 2025-03-12 16:47:45 | [diff] [blame] | 58 | inline constexpr char kConditionalCreate[] = "conditionalCreate"; |
Andrii Natiahlyi | 6b2f4b1 | 2024-09-03 14:58:42 | [diff] [blame] | 59 | inline constexpr char kConditionalGet[] = "conditionalGet"; |
| 60 | inline constexpr char kHybridTransport[] = "hybridTransport"; |
| 61 | inline constexpr char kPasskeyPlatformAuthenticator[] = |
| 62 | "passkeyPlatformAuthenticator"; |
| 63 | inline constexpr char kUserVerifyingPlatformAuthenticator[] = |
| 64 | "userVerifyingPlatformAuthenticator"; |
| 65 | inline constexpr char kRelatedOrigins[] = "relatedOrigins"; |
Adem Derinel | d564032 | 2025-04-24 09:14:06 | [diff] [blame] | 66 | inline constexpr char kImmediateGet[] = "immediateGet"; |
Andrii Natiahlyi | 6b2f4b1 | 2024-09-03 14:58:42 | [diff] [blame] | 67 | |
| 68 | } // namespace client_capabilities |
| 69 | |
Manas Verma | 9ba1369 | 2019-03-21 21:01:00 | [diff] [blame] | 70 | // Common code for any WebAuthn Authenticator interfaces. |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 71 | class CONTENT_EXPORT AuthenticatorCommonImpl : public AuthenticatorCommon { |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 72 | public: |
Adam Langley | 3ec44c2 | 2023-08-10 01:04:01 | [diff] [blame] | 73 | // ServingRequestsFor enumerates the sources of WebAuthn requests. |
| 74 | enum class ServingRequestsFor { |
| 75 | // kInternalUses is for synthesized requests that don't originate from |
| 76 | // any Javascript call. |
| 77 | kInternalUses, |
| 78 | // kWebContents is for typical cases where Javascript is making a |
| 79 | // `navigator.credentials` call. |
| 80 | kWebContents, |
| 81 | }; |
| 82 | |
Nina Satragno | 129251c | 2023-10-23 21:50:40 | [diff] [blame] | 83 | // These values are persisted to logs. Entries should not be renumbered and |
| 84 | // numeric values should never be reused. |
Ken Buchanan | d5edc078 | 2024-06-10 22:01:22 | [diff] [blame] | 85 | enum class CredentialRequestResult { |
Nina Satragno | 129251c | 2023-10-23 21:50:40 | [diff] [blame] | 86 | kTimeout = 0, |
| 87 | kUserCancelled = 1, |
| 88 | |
| 89 | kWinNativeSuccess = 2, |
| 90 | kWinNativeError = 3, |
| 91 | |
| 92 | kTouchIDSuccess = 4, |
| 93 | kTouchIDError = 5, |
| 94 | |
| 95 | kChromeOSSuccess = 6, |
| 96 | kChromeOSError = 7, |
| 97 | |
| 98 | kPhoneSuccess = 8, |
| 99 | kPhoneError = 9, |
| 100 | |
| 101 | kICloudKeychainSuccess = 10, |
| 102 | kICloudKeychainError = 11, |
| 103 | |
| 104 | kEnclaveSuccess = 12, |
| 105 | kEnclaveError = 13, |
| 106 | |
| 107 | kOtherSuccess = 14, |
| 108 | kOtherError = 15, |
| 109 | |
| 110 | kMaxValue = kOtherError, |
| 111 | }; |
| 112 | |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 113 | // Creates a new AuthenticatorCommonImpl. Callers must ensure that this |
| 114 | // instance outlives the RenderFrameHost. |
Adam Langley | 3ec44c2 | 2023-08-10 01:04:01 | [diff] [blame] | 115 | explicit AuthenticatorCommonImpl(RenderFrameHost* render_frame_host, |
| 116 | ServingRequestsFor serving_requests_for); |
Peter Boström | 828b902 | 2021-09-21 02:28:43 | [diff] [blame] | 117 | |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 118 | AuthenticatorCommonImpl(const AuthenticatorCommonImpl&) = delete; |
| 119 | AuthenticatorCommonImpl& operator=(const AuthenticatorCommonImpl&) = delete; |
Peter Boström | 828b902 | 2021-09-21 02:28:43 | [diff] [blame] | 120 | |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 121 | ~AuthenticatorCommonImpl() override; |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 122 | |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 123 | // AuthenticatorCommon: |
Manas Verma | 9ba1369 | 2019-03-21 21:01:00 | [diff] [blame] | 124 | void MakeCredential( |
| 125 | url::Origin caller_origin, |
| 126 | blink::mojom::PublicKeyCredentialCreationOptionsPtr options, |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 127 | blink::mojom::Authenticator::MakeCredentialCallback callback) override; |
Adem Derinel | 72e11db | 2025-02-11 15:58:00 | [diff] [blame] | 128 | void GetCredential( |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 129 | url::Origin caller_origin, |
| 130 | blink::mojom::PublicKeyCredentialRequestOptionsPtr options, |
| 131 | blink::mojom::PaymentOptionsPtr payment, |
Adem Derinel | 72e11db | 2025-02-11 15:58:00 | [diff] [blame] | 132 | blink::mojom::Authenticator::GetCredentialCallback callback) override; |
Manas Verma | 9ba1369 | 2019-03-21 21:01:00 | [diff] [blame] | 133 | void IsUserVerifyingPlatformAuthenticatorAvailable( |
Martin Kreichgauer | 1f4aa59 | 2023-01-06 18:39:37 | [diff] [blame] | 134 | url::Origin caller_origin, |
Manas Verma | 9ba1369 | 2019-03-21 21:01:00 | [diff] [blame] | 135 | blink::mojom::Authenticator:: |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 136 | IsUserVerifyingPlatformAuthenticatorAvailableCallback callback) |
| 137 | override; |
Nina Satragno | c3444e8f | 2022-08-04 22:43:00 | [diff] [blame] | 138 | void IsConditionalMediationAvailable( |
Martin Kreichgauer | 1f4aa59 | 2023-01-06 18:39:37 | [diff] [blame] | 139 | url::Origin caller_origin, |
Nina Satragno | c3444e8f | 2022-08-04 22:43:00 | [diff] [blame] | 140 | blink::mojom::Authenticator::IsConditionalMediationAvailableCallback |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 141 | callback) override; |
| 142 | void Cancel() override; |
| 143 | void Cleanup() override; |
| 144 | void DisableUI() override; |
Nina Satragno | 8d67dec3 | 2023-04-18 22:10:44 | [diff] [blame] | 145 | void DisableTLSCheck() override; |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 146 | RenderFrameHost* GetRenderFrameHost() const override; |
| 147 | void EnableRequestProxyExtensionsAPISupport() override; |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 148 | |
Andrii Natiahlyi | 6b2f4b1 | 2024-09-03 14:58:42 | [diff] [blame] | 149 | // GetClientCapabilities returns a list WebAuthn capabilities of the browser |
| 150 | // via the `callback` parameter. Websites can use this information to |
| 151 | // determine which WebAuthn features and extensions are supported and tailor |
| 152 | // their requests accordingly. |
| 153 | void GetClientCapabilities( |
| 154 | url::Origin caller_origin, |
| 155 | blink::mojom::Authenticator::GetClientCapabilitiesCallback callback); |
| 156 | |
Gabriel Viera | 7bc08f21 | 2024-07-10 15:42:33 | [diff] [blame] | 157 | // Report attempts to report a WebAuthn credential on behalf of |
| 158 | // `caller_origin` using the supplied `options` and invokes `callback` with |
| 159 | // the result. |
| 160 | void Report(url::Origin caller_origin, |
| 161 | blink::mojom::PublicKeyCredentialReportOptionsPtr options, |
| 162 | blink::mojom::Authenticator::ReportCallback callback); |
| 163 | |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 164 | protected: |
Martin Kreichgauer | 37ace49 | 2021-04-08 23:36:46 | [diff] [blame] | 165 | // MaybeCreateRequestDelegate returns the embedder-provided implementation of |
| 166 | // AuthenticatorRequestClientDelegate, which encapsulates per-request state |
| 167 | // relevant to the embedder, e.g. because it is used to display browser UI. |
| 168 | // |
| 169 | // Chrome may return nullptr here in order to ensure that at most one request |
| 170 | // per WebContents is ongoing at once. |
Nina Satragno | f3b63e7 | 2019-08-20 16:44:38 | [diff] [blame] | 171 | virtual std::unique_ptr<AuthenticatorRequestClientDelegate> |
Martin Kreichgauer | 37ace49 | 2021-04-08 23:36:46 | [diff] [blame] | 172 | MaybeCreateRequestDelegate(); |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 173 | |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 174 | private: |
Manas Verma | 9ba1369 | 2019-03-21 21:01:00 | [diff] [blame] | 175 | friend class AuthenticatorImplTest; |
Adam Langley | f59b5560 | 2023-07-05 19:51:20 | [diff] [blame] | 176 | struct RequestState; |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 177 | // A RequestKey is a magic value that identifies a request. Since requests can |
| 178 | // be canceled, some callbacks need to ensure that they're still operating on |
| 179 | // the same request when they resolve. |
| 180 | using RequestKey = base::StrongAlias<class RequestKeyTag, uint64_t>; |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 181 | |
| 182 | // Enumerates whether or not to check that the WebContents has focus. |
| 183 | enum class Focus { |
| 184 | kDoCheck, |
| 185 | kDontCheck, |
| 186 | }; |
| 187 | |
Adam Langley | 6d16761b | 2023-11-01 21:39:51 | [diff] [blame] | 188 | void ContinueMakeCredentialAfterRpIdCheck( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 189 | RequestKey request_key, |
Adam Langley | 6d16761b | 2023-11-01 21:39:51 | [diff] [blame] | 190 | url::Origin caller_origin, |
| 191 | blink::mojom::PublicKeyCredentialCreationOptionsPtr options, |
| 192 | bool is_cross_origin_iframe, |
| 193 | blink::mojom::AuthenticatorStatus rp_id_validation_result); |
Martin Kreichgauer | 90c3da4 | 2024-05-09 18:34:26 | [diff] [blame] | 194 | void ContinueMakeCredentialAfterBrowserPasskeysAvailabilityCheck( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 195 | RequestKey request_key, |
Martin Kreichgauer | 90c3da4 | 2024-05-09 18:34:26 | [diff] [blame] | 196 | bool available); |
Ken Buchanan | 90fe2955 | 2024-04-26 21:15:48 | [diff] [blame] | 197 | void ContinueMakeCredentialAfterIsUvpaaOverrideCheck( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 198 | RequestKey request_key, |
Ken Buchanan | 90fe2955 | 2024-04-26 21:15:48 | [diff] [blame] | 199 | std::optional<bool> is_uvpaa_override); |
Adam Langley | 6d16761b | 2023-11-01 21:39:51 | [diff] [blame] | 200 | |
| 201 | void ContinueGetAssertionAfterRpIdCheck( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 202 | RequestKey request_key, |
Adam Langley | 6d16761b | 2023-11-01 21:39:51 | [diff] [blame] | 203 | url::Origin caller_origin, |
| 204 | blink::mojom::PublicKeyCredentialRequestOptionsPtr options, |
| 205 | blink::mojom::PaymentOptionsPtr payment_options, |
| 206 | bool is_cross_origin_iframe, |
| 207 | blink::mojom::AuthenticatorStatus rp_id_validation_result); |
Martin Kreichgauer | 90c3da4 | 2024-05-09 18:34:26 | [diff] [blame] | 208 | void ContinueGetAssertionAfterBrowserPasskeysAvailabilityCheck( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 209 | RequestKey request_key, |
Martin Kreichgauer | 90c3da4 | 2024-05-09 18:34:26 | [diff] [blame] | 210 | bool available); |
Ken Buchanan | 90fe2955 | 2024-04-26 21:15:48 | [diff] [blame] | 211 | void ContinueGetAssertionAfterIsUvpaaOverrideCheck( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 212 | RequestKey request_key, |
Ken Buchanan | 90fe2955 | 2024-04-26 21:15:48 | [diff] [blame] | 213 | std::optional<bool> is_uvpaa_override); |
| 214 | |
| 215 | void ContinueIsUvpaaAfterOverrideCheck( |
| 216 | blink::mojom::Authenticator:: |
| 217 | IsUserVerifyingPlatformAuthenticatorAvailableCallback callback, |
Andrii Natiahlyi | 6b2f4b1 | 2024-09-03 14:58:42 | [diff] [blame] | 218 | bool is_get_client_capabilities_call, |
Ken Buchanan | 90fe2955 | 2024-04-26 21:15:48 | [diff] [blame] | 219 | std::optional<bool> is_uvpaa_override); |
| 220 | |
| 221 | void ContinueIsConditionalMediationAvailableAfterOverrideCheck( |
| 222 | url::Origin caller_origin, |
| 223 | blink::mojom::Authenticator::IsConditionalMediationAvailableCallback |
| 224 | callback, |
| 225 | std::optional<bool> is_uvpaa_override); |
Adam Langley | 6d16761b | 2023-11-01 21:39:51 | [diff] [blame] | 226 | |
Gabriel Viera | 7bc08f21 | 2024-07-10 15:42:33 | [diff] [blame] | 227 | void ContinueReportAfterRpIdCheck( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 228 | RequestKey request_key, |
Gabriel Viera | 7bc08f21 | 2024-07-10 15:42:33 | [diff] [blame] | 229 | blink::mojom::PublicKeyCredentialReportOptionsPtr options, |
| 230 | blink::mojom::AuthenticatorStatus rp_id_validation_result); |
| 231 | |
Adem Derinel | dc2d52f | 2024-09-19 08:06:56 | [diff] [blame] | 232 | void GetMetricsWrappedMakeCredentialCallback( |
| 233 | blink::mojom::Authenticator::MakeCredentialCallback callback, |
| 234 | blink::mojom::AuthenticatorStatus status, |
| 235 | blink::mojom::MakeCredentialAuthenticatorResponsePtr |
| 236 | authenticator_response, |
| 237 | blink::mojom::WebAuthnDOMExceptionDetailsPtr dom_exception_details); |
| 238 | |
Adem Derinel | 72e11db | 2025-02-11 15:58:00 | [diff] [blame] | 239 | void GetMetricsWrappedGetCredentialCallback( |
| 240 | blink::mojom::Authenticator::GetCredentialCallback callback, |
| 241 | blink::mojom::GetCredentialResponsePtr response); |
Adem Derinel | dc2d52f | 2024-09-19 08:06:56 | [diff] [blame] | 242 | |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 243 | // Replaces the current |request_handler_| with a |
| 244 | // |MakeCredentialRequestHandler|, effectively restarting the request. |
Nina Satragno | 70589ab | 2019-10-02 16:40:04 | [diff] [blame] | 245 | void StartMakeCredentialRequest(bool allow_skipping_pin_touch); |
Nina Satragno | 31e3fa4 | 2019-06-03 21:44:28 | [diff] [blame] | 246 | |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 247 | // Replaces the current |request_handler_| with a |
| 248 | // |GetAssertionRequestHandler|, effectively restarting the request. |
Nina Satragno | 70589ab | 2019-10-02 16:40:04 | [diff] [blame] | 249 | void StartGetAssertionRequest(bool allow_skipping_pin_touch); |
Nina Satragno | 31e3fa4 | 2019-06-03 21:44:28 | [diff] [blame] | 250 | |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 251 | bool IsFocused() const; |
| 252 | |
Andrii Natiahlyi | e480a49 | 2024-09-18 15:20:37 | [diff] [blame] | 253 | // Checks if hybrid transport is supported on this device, i.e. if it has a |
| 254 | // Bluetooth adapter that supports BLE. If so, runs |callback| with `true`. |
| 255 | // Otherwise, or if Bluetooth is disabled by Permissions Policy, runs |
| 256 | // |callback| with `false`. |
| 257 | void IsHybridTransportSupported(base::OnceCallback<void(bool)> callback); |
| 258 | |
Andrii Natiahlyi | 6b2f4b1 | 2024-09-03 14:58:42 | [diff] [blame] | 259 | // `is_get_client_capabilities_call` is true if this call originated from the |
| 260 | // `GetClientCapabilities` method. The UMA metric is only recorded if this is |
| 261 | // false, i.e. the call came directly from |
| 262 | // `IsUserVerifyingPlatformAuthenticatorAvailable`. |
| 263 | void IsUvpaaAvailableInternal( |
| 264 | url::Origin caller_origin, |
| 265 | blink::mojom::Authenticator:: |
| 266 | IsUserVerifyingPlatformAuthenticatorAvailableCallback callback, |
| 267 | bool is_get_client_capabilities_call); |
| 268 | |
Nina Satragno | fe6e52ad7 | 2022-06-01 14:04:14 | [diff] [blame] | 269 | void DispatchGetAssertionRequest( |
| 270 | const std::string& authenticator_id, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 271 | std::optional<std::vector<uint8_t>> credential_id); |
Nina Satragno | fe6e52ad7 | 2022-06-01 14:04:14 | [diff] [blame] | 272 | |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 273 | // Callback to handle the async response from a U2fDevice. |
| 274 | void OnRegisterResponse( |
Martin Kreichgauer | abd93b98 | 2019-08-30 19:35:38 | [diff] [blame] | 275 | device::MakeCredentialStatus status_code, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 276 | std::optional<device::AuthenticatorMakeCredentialResponse> response_data, |
Martin Kreichgauer | 3676c728 | 2019-07-19 19:27:22 | [diff] [blame] | 277 | const device::FidoAuthenticator* authenticator); |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 278 | |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 279 | // Callback to handle the async response from a U2fDevice. |
| 280 | void OnSignResponse( |
Martin Kreichgauer | abd93b98 | 2019-08-30 19:35:38 | [diff] [blame] | 281 | device::GetAssertionStatus status_code, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 282 | std::optional<std::vector<device::AuthenticatorGetAssertionResponse>> |
Adam Langley | 3ec44c2 | 2023-08-10 01:04:01 | [diff] [blame] | 283 | response_data, |
| 284 | device::FidoAuthenticator* authenticator); |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 285 | |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 286 | // Begins a timeout at the beginning of a request. |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 287 | void BeginRequestTimeout(std::optional<base::TimeDelta> timeout); |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 288 | |
Adem Derinel | 38626c2 | 2025-05-22 13:31:58 | [diff] [blame] | 289 | // Called when a request times out. This is for options.timeout parameter. |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 290 | void OnTimeout(); |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 291 | |
Adem Derinel | 38626c2 | 2025-05-22 13:31:58 | [diff] [blame] | 292 | // Begins a timeout at the beginning of an immediate mediation request. |
| 293 | void BeginImmediateRequestTimeout(); |
| 294 | |
| 295 | // Called when an immediate mediation request times out. |
| 296 | void OnImmediateTimeout(); |
| 297 | |
| 298 | // Cancels the immediate mediation timer when the UI is shown. |
| 299 | void CancelImmediateTimeout(); |
| 300 | |
Adem Derinel | be67ee7 | 2025-06-16 07:01:30 | [diff] [blame] | 301 | // Cancels the current request if it's an immediate mediation and no immediate |
| 302 | // mediation UI was shown. |
| 303 | void CancelRequestForImmediateMediation(); |
| 304 | |
Suzy Li | d4dda9c | 2019-05-10 17:36:42 | [diff] [blame] | 305 | // Cancels the currently pending request (if any) with the supplied status. |
| 306 | void CancelWithStatus(blink::mojom::AuthenticatorStatus status); |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 307 | |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 308 | // Runs when the user cancels WebAuthN request via UI dialog. |
Suzy Li | d4dda9c | 2019-05-10 17:36:42 | [diff] [blame] | 309 | void OnCancelFromUI(); |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 310 | |
Adam Langley | f72000b | 2019-03-27 16:04:24 | [diff] [blame] | 311 | // Called when a GetAssertion has completed, either because an allow_list was |
| 312 | // used and so an answer is returned directly, or because the user selected an |
| 313 | // account from the options. |
| 314 | void OnAccountSelected(device::AuthenticatorGetAssertionResponse response); |
| 315 | |
Martin Kreichgauer | 86faed3 | 2019-08-29 18:44:44 | [diff] [blame] | 316 | // Signals to the request delegate that the request has failed for |reason|. |
| 317 | // The request delegate decides whether to present the user with a visual |
| 318 | // error before the request is finally resolved with |status|. |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 319 | void SignalFailureToRequestDelegate( |
Martin Kreichgauer | 86faed3 | 2019-08-29 18:44:44 | [diff] [blame] | 320 | AuthenticatorRequestClientDelegate::InterestingFailureReason reason, |
| 321 | blink::mojom::AuthenticatorStatus status); |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 322 | |
zakaria ridouh | 15ce79e1 | 2021-09-24 20:20:14 | [diff] [blame] | 323 | // Creates a make credential response |
| 324 | blink::mojom::MakeCredentialAuthenticatorResponsePtr |
| 325 | CreateMakeCredentialResponse( |
| 326 | device::AuthenticatorMakeCredentialResponse response_data, |
| 327 | AttestationErasureOption attestation_erasure); |
| 328 | |
Martin Kreichgauer | 393f5ef | 2021-03-30 23:57:57 | [diff] [blame] | 329 | // Runs |make_credential_response_callback_| and then Cleanup(). |
| 330 | void CompleteMakeCredentialRequest( |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 331 | blink::mojom::AuthenticatorStatus status, |
Manas Verma | 9ba1369 | 2019-03-21 21:01:00 | [diff] [blame] | 332 | blink::mojom::MakeCredentialAuthenticatorResponsePtr response = nullptr, |
Martin Kreichgauer | 6119e84 | 2022-01-28 01:52:41 | [diff] [blame] | 333 | blink::mojom::WebAuthnDOMExceptionDetailsPtr dom_exception_details = |
| 334 | nullptr, |
Manas Verma | 9ba1369 | 2019-03-21 21:01:00 | [diff] [blame] | 335 | Focus focus_check = Focus::kDontCheck); |
Martin Kreichgauer | 393f5ef | 2021-03-30 23:57:57 | [diff] [blame] | 336 | |
zakaria ridouh | 15ce79e1 | 2021-09-24 20:20:14 | [diff] [blame] | 337 | // Creates a get assertion response. |
| 338 | blink::mojom::GetAssertionAuthenticatorResponsePtr CreateGetAssertionResponse( |
Nina Satragno | 7f33f9b | 2023-01-31 22:09:03 | [diff] [blame] | 339 | device::AuthenticatorGetAssertionResponse response_data); |
zakaria ridouh | 15ce79e1 | 2021-09-24 20:20:14 | [diff] [blame] | 340 | |
Nina Satragno | 63637f3 | 2022-04-27 18:18:57 | [diff] [blame] | 341 | // Runs |get_assertion_response_callback_| and then Cleanup(). |
Martin Kreichgauer | 393f5ef | 2021-03-30 23:57:57 | [diff] [blame] | 342 | void CompleteGetAssertionRequest( |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 343 | blink::mojom::AuthenticatorStatus status, |
Martin Kreichgauer | 6119e84 | 2022-01-28 01:52:41 | [diff] [blame] | 344 | blink::mojom::GetAssertionAuthenticatorResponsePtr response = nullptr, |
| 345 | blink::mojom::WebAuthnDOMExceptionDetailsPtr dom_exception_details = |
| 346 | nullptr); |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 347 | |
Adem Derinel | 72e11db | 2025-02-11 15:58:00 | [diff] [blame] | 348 | void HandlePasswordResponse(password_manager::CredentialInfo credential); |
| 349 | |
Adam Langley | 3ec44c2 | 2023-08-10 01:04:01 | [diff] [blame] | 350 | AuthenticatorRequestClientDelegate::RequestSource RequestSource() const; |
Adam Langley | b038582 | 2021-03-19 23:34:00 | [diff] [blame] | 351 | BrowserContext* GetBrowserContext() const; |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 352 | |
Gabriel Viera | 7bc08f21 | 2024-07-10 15:42:33 | [diff] [blame] | 353 | // Runs |report_response_callback_| and then Cleanup(). |
| 354 | void CompleteReportRequest(blink::mojom::AuthenticatorStatus status, |
| 355 | blink::mojom::WebAuthnDOMExceptionDetailsPtr |
| 356 | dom_exception_details = nullptr); |
| 357 | |
Martin Kreichgauer | 0b24720b | 2020-08-17 19:58:23 | [diff] [blame] | 358 | // Returns the FidoDiscoveryFactory for the current request. This may be a |
| 359 | // real instance, or one injected by the Virtual Authenticator environment, or |
| 360 | // a unit testing fake. InitDiscoveryFactory() must be called before this |
| 361 | // accessor. It gets reset at the end of each request by Cleanup(). |
| 362 | device::FidoDiscoveryFactory* discovery_factory(); |
Martin Kreichgauer | 4ce13be | 2022-10-28 23:20:21 | [diff] [blame] | 363 | void InitDiscoveryFactory(); |
Martin Kreichgauer | 0b24720b | 2020-08-17 19:58:23 | [diff] [blame] | 364 | |
Martin Kreichgauer | 1f4aa59 | 2023-01-06 18:39:37 | [diff] [blame] | 365 | WebAuthenticationRequestProxy* GetWebAuthnRequestProxyIfActive( |
| 366 | const url::Origin& caller_origin); |
Martin Kreichgauer | 165ff72 | 2021-08-26 01:33:52 | [diff] [blame] | 367 | |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 368 | void OnMakeCredentialProxyResponse( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 369 | RequestKey request_key, |
Martin Kreichgauer | b27f631 | 2022-01-25 00:03:32 | [diff] [blame] | 370 | WebAuthenticationRequestProxy::RequestId request_id, |
Martin Kreichgauer | 6119e84 | 2022-01-28 01:52:41 | [diff] [blame] | 371 | blink::mojom::WebAuthnDOMExceptionDetailsPtr error, |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 372 | blink::mojom::MakeCredentialAuthenticatorResponsePtr response); |
| 373 | |
Martin Kreichgauer | 1beaff0 | 2022-02-02 18:58:42 | [diff] [blame] | 374 | void OnGetAssertionProxyResponse( |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 375 | RequestKey request_key, |
Martin Kreichgauer | 1beaff0 | 2022-02-02 18:58:42 | [diff] [blame] | 376 | WebAuthenticationRequestProxy::RequestId request_id, |
| 377 | blink::mojom::WebAuthnDOMExceptionDetailsPtr error, |
| 378 | blink::mojom::GetAssertionAuthenticatorResponsePtr response); |
| 379 | |
Ken Buchanan | be8629f | 2025-01-11 03:37:16 | [diff] [blame] | 380 | void UpdateChallengeFromUrl( |
| 381 | ClientDataJsonParams params, |
| 382 | std::optional<base::span<const uint8_t>> challenge); |
| 383 | |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 384 | // Get an identifier for the current request. Callbacks that might span a |
| 385 | // cancelation must hold one of these values to check whether they're still |
| 386 | // pertinent when called. |
| 387 | RequestKey GetRequestKey(); |
| 388 | // Check whether the given `RequestKey` identifies the current request. |
| 389 | [[nodiscard]] bool CheckRequestKey(RequestKey key); |
| 390 | |
Alexander Timin | 8690530c | 2021-06-19 00:34:32 | [diff] [blame] | 391 | const GlobalRenderFrameHostId render_frame_host_id_; |
Adam Langley | 3ec44c2 | 2023-08-10 01:04:01 | [diff] [blame] | 392 | const ServingRequestsFor serving_requests_for_; |
Adam Langley | f59b5560 | 2023-07-05 19:51:20 | [diff] [blame] | 393 | const scoped_refptr<WebAuthRequestSecurityChecker> security_checker_; |
| 394 | |
| 395 | // These members hold state that spans different requests. All |
| 396 | // request-specific state should go in `RequestState` to ensure that it's |
| 397 | // cleared between requests. |
Avi Drissman | c306dde7 | 2023-07-02 18:46:27 | [diff] [blame] | 398 | bool disable_tls_check_ = false; |
Adam Langley | f59b5560 | 2023-07-05 19:51:20 | [diff] [blame] | 399 | bool disable_ui_ = false; |
Martin Kreichgauer | 8c97189a | 2022-01-10 20:31:43 | [diff] [blame] | 400 | bool enable_request_proxy_api_ = false; |
Martin Kreichgauer | 3b3a657 | 2020-09-24 08:49:48 | [diff] [blame] | 401 | |
Adam Langley | e8ba2cc | 2024-08-06 13:53:23 | [diff] [blame] | 402 | // The RequestKey of the next request. This starts at one so that a |
| 403 | // `RequestKey` that was default initialized to zero is invalid. |
| 404 | uint64_t next_request_key_ = 1; |
| 405 | |
Adam Langley | f59b5560 | 2023-07-05 19:51:20 | [diff] [blame] | 406 | // req_state_ contains all state specific to a single WebAuthn call. It |
| 407 | // only contains a value when a request is being processed. |
| 408 | std::unique_ptr<RequestState> req_state_; |
Martin Kreichgauer | b27f631 | 2022-01-25 00:03:32 | [diff] [blame] | 409 | |
Ken Buchanan | 90fe2955 | 2024-04-26 21:15:48 | [diff] [blame] | 410 | // Cached values from the WebAuthenticationDelegate. |
Martin Kreichgauer | 90c3da4 | 2024-05-09 18:34:26 | [diff] [blame] | 411 | bool browser_passkeys_available_ = false; |
Ken Buchanan | 90fe2955 | 2024-04-26 21:15:48 | [diff] [blame] | 412 | std::optional<bool> is_uvpaa_override_; |
| 413 | |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 414 | base::WeakPtrFactory<AuthenticatorCommonImpl> weak_factory_{this}; |
Manas Verma | 2ff0cc57 | 2019-03-19 23:42:56 | [diff] [blame] | 415 | }; |
| 416 | |
| 417 | } // namespace content |
| 418 | |
Amos Lim | 12696e5e3 | 2022-09-16 07:37:58 | [diff] [blame] | 419 | #endif // CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_COMMON_IMPL_H_ |