1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_COMMON_H_ 6 #define CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_COMMON_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <string> 12 #include <utility> 13 #include <vector> 14 15 #include "base/containers/flat_set.h" 16 #include "base/containers/span.h" 17 #include "base/macros.h" 18 #include "base/optional.h" 19 #include "content/common/content_export.h" 20 #include "content/public/browser/authenticator_request_client_delegate.h" 21 #include "content/public/browser/web_contents_observer.h" 22 #include "device/fido/authenticator_get_assertion_response.h" 23 #include "device/fido/authenticator_make_credential_response.h" 24 #include "device/fido/authenticator_selection_criteria.h" 25 #include "device/fido/client_data.h" 26 #include "device/fido/ctap_get_assertion_request.h" 27 #include "device/fido/ctap_make_credential_request.h" 28 #include "device/fido/fido_constants.h" 29 #include "device/fido/fido_transport_protocol.h" 30 #include "third_party/blink/public/mojom/webauthn/authenticator.mojom.h" 31 #include "url/origin.h" 32 33 namespace base { 34 class OneShotTimer; 35 } 36 37 namespace device { 38 39 class FidoRequestHandlerBase; 40 41 enum class FidoReturnCode : uint8_t; 42 43 enum class GetAssertionStatus; 44 enum class MakeCredentialStatus; 45 46 } // namespace device 47 48 namespace url { 49 class Origin; 50 } 51 52 namespace content { 53 54 class BrowserContext; 55 class RenderFrameHost; 56 class WebAuthRequestSecurityChecker; 57 58 namespace client_data { 59 // These enumerate the possible values for the `type` member of 60 // CollectedClientData. See 61 // https://w3c.github.io/webauthn/#dom-collectedclientdata-type 62 CONTENT_EXPORT extern const char kCreateType[]; 63 CONTENT_EXPORT extern const char kGetType[]; 64 } // namespace client_data 65 66 // Common code for any WebAuthn Authenticator interfaces. 67 class CONTENT_EXPORT AuthenticatorCommon { 68 public: 69 // Permits setting timer for testing. 70 AuthenticatorCommon(RenderFrameHost* render_frame_host, 71 std::unique_ptr<base::OneShotTimer>); 72 virtual ~AuthenticatorCommon(); 73 74 // This is not-quite an implementation of blink::mojom::Authenticator. The 75 // first two functions take the caller's origin explicitly. This allows the 76 // caller origin to be overridden if needed. 77 void MakeCredential( 78 url::Origin caller_origin, 79 blink::mojom::PublicKeyCredentialCreationOptionsPtr options, 80 blink::mojom::Authenticator::MakeCredentialCallback callback); 81 void GetAssertion(url::Origin caller_origin, 82 blink::mojom::PublicKeyCredentialRequestOptionsPtr options, 83 blink::mojom::Authenticator::GetAssertionCallback callback); 84 void IsUserVerifyingPlatformAuthenticatorAvailable( 85 blink::mojom::Authenticator:: 86 IsUserVerifyingPlatformAuthenticatorAvailableCallback callback); 87 void Cancel(); 88 89 void Cleanup(); 90 91 void DisableUI(); 92 93 protected: 94 virtual std::unique_ptr<AuthenticatorRequestClientDelegate> 95 CreateRequestDelegate(); 96 97 std::unique_ptr<AuthenticatorRequestClientDelegate> request_delegate_; 98 99 private: 100 friend class AuthenticatorImplTest; 101 102 // Enumerates whether or not to check that the WebContents has focus. 103 enum class Focus { 104 kDoCheck, 105 kDontCheck, 106 }; 107 108 // Replaces the current |request_| with a |MakeCredentialRequestHandler|, 109 // effectively restarting the request. 110 void StartMakeCredentialRequest(bool allow_skipping_pin_touch); 111 112 // Replaces the current |request_| with a |GetAssertionRequestHandler|, 113 // effectively restarting the request. 114 void StartGetAssertionRequest(bool allow_skipping_pin_touch); 115 116 bool IsFocused() const; 117 118 // Callback to handle the async response from a U2fDevice. 119 void OnRegisterResponse( 120 device::MakeCredentialStatus status_code, 121 base::Optional<device::AuthenticatorMakeCredentialResponse> response_data, 122 const device::FidoAuthenticator* authenticator); 123 124 // Callback to complete the registration process once a decision about 125 // whether or not to return attestation data has been made. 126 void OnRegisterResponseAttestationDecided( 127 device::AuthenticatorMakeCredentialResponse response_data, 128 bool is_transport_used_internal, 129 bool attestation_permitted); 130 131 // Callback to handle the async response from a U2fDevice. 132 void OnSignResponse( 133 device::GetAssertionStatus status_code, 134 base::Optional<std::vector<device::AuthenticatorGetAssertionResponse>> 135 response_data, 136 const device::FidoAuthenticator* authenticator); 137 138 // Runs when timer expires and cancels all issued requests to a U2fDevice. 139 void OnTimeout(); 140 // Cancels the currently pending request (if any) with the supplied status. 141 void CancelWithStatus(blink::mojom::AuthenticatorStatus status); 142 // Runs when the user cancels WebAuthN request via UI dialog. 143 void OnCancelFromUI(); 144 145 // Called when a GetAssertion has completed, either because an allow_list was 146 // used and so an answer is returned directly, or because the user selected an 147 // account from the options. 148 void OnAccountSelected(device::AuthenticatorGetAssertionResponse response); 149 150 // Signals to the request delegate that the request has failed for |reason|. 151 // The request delegate decides whether to present the user with a visual 152 // error before the request is finally resolved with |status|. 153 void SignalFailureToRequestDelegate( 154 const device::FidoAuthenticator* authenticator, 155 AuthenticatorRequestClientDelegate::InterestingFailureReason reason, 156 blink::mojom::AuthenticatorStatus status); 157 158 void InvokeCallbackAndCleanup( 159 blink::mojom::Authenticator::MakeCredentialCallback callback, 160 blink::mojom::AuthenticatorStatus status, 161 blink::mojom::MakeCredentialAuthenticatorResponsePtr response = nullptr, 162 Focus focus_check = Focus::kDontCheck); 163 void InvokeCallbackAndCleanup( 164 blink::mojom::Authenticator::GetAssertionCallback callback, 165 blink::mojom::AuthenticatorStatus status, 166 blink::mojom::GetAssertionAuthenticatorResponsePtr response = nullptr); 167 168 BrowserContext* browser_context() const; 169 170 RenderFrameHost* const render_frame_host_; 171 std::unique_ptr<device::FidoRequestHandlerBase> request_; 172 blink::mojom::Authenticator::MakeCredentialCallback 173 make_credential_response_callback_; 174 blink::mojom::Authenticator::GetAssertionCallback 175 get_assertion_response_callback_; 176 std::string client_data_json_; 177 bool attestation_requested_; 178 // empty_allow_list_ is true iff a GetAssertion is currently pending and the 179 // request did not list any credential IDs in the allow list. 180 bool empty_allow_list_ = false; 181 bool disable_ui_ = false; 182 url::Origin caller_origin_; 183 std::string relying_party_id_; 184 scoped_refptr<WebAuthRequestSecurityChecker> security_checker_; 185 std::unique_ptr<base::OneShotTimer> timer_; 186 base::Optional<device::AuthenticatorSelectionCriteria> 187 authenticator_selection_criteria_; 188 base::Optional<std::string> app_id_; 189 base::Optional<device::CtapMakeCredentialRequest> 190 ctap_make_credential_request_; 191 base::Optional<device::CtapGetAssertionRequest> ctap_get_assertion_request_; 192 // awaiting_attestation_response_ is true if the embedder has been queried 193 // about an attestsation decision and the response is still pending. 194 bool awaiting_attestation_response_ = false; 195 blink::mojom::AuthenticatorStatus error_awaiting_user_acknowledgement_ = 196 blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR; 197 198 base::WeakPtrFactory<AuthenticatorCommon> weak_factory_{this}; 199 200 DISALLOW_COPY_AND_ASSIGN(AuthenticatorCommon); 201 }; 202 203 } // namespace content 204 205 #endif // CONTENT_BROWSER_WEBAUTH_AUTHENTICATOR_COMMON_H_ 206