1 // Copyright 2018 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_VIRTUAL_AUTHENTICATOR_H_
6 #define CONTENT_BROWSER_WEBAUTH_VIRTUAL_AUTHENTICATOR_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/containers/span.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/optional.h"
17 #include "content/common/content_export.h"
18 #include "device/fido/fido_constants.h"
19 #include "device/fido/virtual_fido_device.h"
20 #include "mojo/public/cpp/bindings/pending_receiver.h"
21 #include "mojo/public/cpp/bindings/receiver_set.h"
22 #include "services/data_decoder/public/cpp/data_decoder.h"
23 #include "third_party/blink/public/mojom/webauthn/virtual_authenticator.mojom.h"
24 
25 namespace content {
26 
27 // Implements the Mojo interface representing a stateful virtual authenticator.
28 //
29 // This class has very little logic itself, it merely stores a unique ID and the
30 // state of the authenticator, whereas performing all cryptographic operations
31 // is delegated to the VirtualFidoDevice class.
32 class CONTENT_EXPORT VirtualAuthenticator
33     : public blink::test::mojom::VirtualAuthenticator {
34  public:
35   VirtualAuthenticator(device::ProtocolVersion protocol,
36                        device::Ctap2Version ctap2_version,
37                        device::FidoTransportProtocol transport,
38                        device::AuthenticatorAttachment attachment,
39                        bool has_resident_key,
40                        bool has_user_verification,
41                        bool has_large_blob);
42   ~VirtualAuthenticator() override;
43 
44   void AddReceiver(
45       mojo::PendingReceiver<blink::test::mojom::VirtualAuthenticator> receiver);
46 
registrations()47   const device::VirtualFidoDevice::State::RegistrationsMap& registrations()
48       const {
49     return state_->registrations;
50   }
51 
52   // Register a new credential. Returns true if the registration was successful,
53   // false otherwise.
54   bool AddRegistration(std::vector<uint8_t> key_handle,
55                        const std::string& rp_id,
56                        base::span<const uint8_t> private_key,
57                        int32_t counter);
58 
59   // Register a new resident credential. Returns true if the registration was
60   // successful, false otherwise.
61   bool AddResidentRegistration(std::vector<uint8_t> key_handle,
62                                std::string rp_id,
63                                base::span<const uint8_t> private_key,
64                                int32_t counter,
65                                std::vector<uint8_t> user_handle);
66 
67   // Removes all the credentials.
68   void ClearRegistrations();
69 
70   // Remove a credential identified by |key_handle|. Returns true if the
71   // credential was found and removed, false otherwise.
72   bool RemoveRegistration(const std::vector<uint8_t>& key_handle);
73 
74   // Sets whether tests of user presence succeed or not for new requests sent to
75   // this authenticator. The default is true.
76   void SetUserPresence(bool is_user_present);
77 
78   // Sets whether user verification should succeed or not for new requests sent
79   // to this authenticator. Defaults to true.
set_user_verified(bool is_user_verified)80   void set_user_verified(bool is_user_verified) {
81     is_user_verified_ = is_user_verified;
82   }
83 
has_resident_key()84   bool has_resident_key() const { return has_resident_key_; }
85 
transport()86   device::FidoTransportProtocol transport() const { return state_->transport; }
unique_id()87   const std::string& unique_id() const { return unique_id_; }
88 
is_user_verifying_platform_authenticator()89   bool is_user_verifying_platform_authenticator() const {
90     return attachment_ == device::AuthenticatorAttachment::kPlatform &&
91            has_user_verification_;
92   }
93 
94   // Constructs a VirtualFidoDevice instance that will perform cryptographic
95   // operations on behalf of, and using the state stored in this virtual
96   // authenticator.
97   //
98   // There is an N:1 relationship between VirtualFidoDevices and this class, so
99   // this method can be called any number of times.
100   std::unique_ptr<device::FidoDevice> ConstructDevice();
101 
102   // blink::test::mojom::VirtualAuthenticator:
103   void GetLargeBlob(const std::vector<uint8_t>& key_handle,
104                     GetLargeBlobCallback callback) override;
105   void SetLargeBlob(const std::vector<uint8_t>& key_handle,
106                     const std::vector<uint8_t>& blob,
107                     SetLargeBlobCallback callback) override;
108 
109  protected:
110   // blink::test::mojom::VirtualAuthenticator:
111   void GetUniqueId(GetUniqueIdCallback callback) override;
112 
113   void GetRegistrations(GetRegistrationsCallback callback) override;
114   void AddRegistration(blink::test::mojom::RegisteredKeyPtr registration,
115                        AddRegistrationCallback callback) override;
116   void ClearRegistrations(ClearRegistrationsCallback callback) override;
117   void RemoveRegistration(const std::vector<uint8_t>& key_handle,
118                           RemoveRegistrationCallback callback) override;
119 
120   void SetUserVerified(bool verified,
121                        SetUserVerifiedCallback callback) override;
122 
123  private:
124   void OnLargeBlobUncompressed(
125       GetLargeBlobCallback callback,
126       data_decoder::DataDecoder::ResultOrError<mojo_base::BigBuffer> result);
127   void OnLargeBlobCompressed(
128       base::span<const uint8_t> key_handle,
129       SetLargeBlobCallback callback,
130       data_decoder::DataDecoder::ResultOrError<mojo_base::BigBuffer> result);
131 
132   const device::ProtocolVersion protocol_;
133   const device::Ctap2Version ctap2_version_;
134   const device::AuthenticatorAttachment attachment_;
135   const bool has_resident_key_;
136   const bool has_user_verification_;
137   const bool has_large_blob_;
138   bool is_user_verified_ = true;
139   const std::string unique_id_;
140   bool is_user_present_;
141   data_decoder::DataDecoder data_decoder_;
142   scoped_refptr<device::VirtualFidoDevice::State> state_;
143   mojo::ReceiverSet<blink::test::mojom::VirtualAuthenticator> receiver_set_;
144 
145   base::WeakPtrFactory<VirtualAuthenticator> weak_factory_{this};
146 
147   DISALLOW_COPY_AND_ASSIGN(VirtualAuthenticator);
148 };
149 
150 }  // namespace content
151 
152 #endif  // CONTENT_BROWSER_WEBAUTH_VIRTUAL_AUTHENTICATOR_H_
153