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 #include "content/browser/webauth/virtual_authenticator.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/guid.h"
11 #include "crypto/ec_private_key.h"
12 #include "device/fido/fido_parsing_utils.h"
13 #include "device/fido/public_key_credential_rp_entity.h"
14 #include "device/fido/public_key_credential_user_entity.h"
15 #include "device/fido/virtual_ctap2_device.h"
16 #include "device/fido/virtual_u2f_device.h"
17
18 namespace content {
19
VirtualAuthenticator(::device::ProtocolVersion protocol,::device::FidoTransportProtocol transport,::device::AuthenticatorAttachment attachment,bool has_resident_key,bool has_user_verification)20 VirtualAuthenticator::VirtualAuthenticator(
21 ::device::ProtocolVersion protocol,
22 ::device::FidoTransportProtocol transport,
23 ::device::AuthenticatorAttachment attachment,
24 bool has_resident_key,
25 bool has_user_verification)
26 : protocol_(protocol),
27 attachment_(attachment),
28 has_resident_key_(has_resident_key),
29 has_user_verification_(has_user_verification),
30 unique_id_(base::GenerateGUID()),
31 state_(base::MakeRefCounted<::device::VirtualFidoDevice::State>()) {
32 state_->transport = transport;
33 // If the authenticator has user verification, simulate having set it up
34 // already.
35 state_->fingerprints_enrolled = has_user_verification_;
36 SetUserPresence(true);
37 }
38
39 VirtualAuthenticator::~VirtualAuthenticator() = default;
40
AddReceiver(mojo::PendingReceiver<blink::test::mojom::VirtualAuthenticator> receiver)41 void VirtualAuthenticator::AddReceiver(
42 mojo::PendingReceiver<blink::test::mojom::VirtualAuthenticator> receiver) {
43 receiver_set_.Add(this, std::move(receiver));
44 }
45
AddRegistration(std::vector<uint8_t> key_handle,const std::string & rp_id,const std::vector<uint8_t> & private_key,int32_t counter)46 bool VirtualAuthenticator::AddRegistration(
47 std::vector<uint8_t> key_handle,
48 const std::string& rp_id,
49 const std::vector<uint8_t>& private_key,
50 int32_t counter) {
51 auto ec_private_key =
52 crypto::ECPrivateKey::CreateFromPrivateKeyInfo(private_key);
53 if (!ec_private_key)
54 return false;
55
56 return state_->registrations
57 .emplace(
58 std::move(key_handle),
59 ::device::VirtualFidoDevice::RegistrationData(
60 std::move(ec_private_key),
61 ::device::fido_parsing_utils::CreateSHA256Hash(rp_id), counter))
62 .second;
63 }
64
AddResidentRegistration(std::vector<uint8_t> key_handle,std::string rp_id,const std::vector<uint8_t> & private_key,int32_t counter,std::vector<uint8_t> user_handle)65 bool VirtualAuthenticator::AddResidentRegistration(
66 std::vector<uint8_t> key_handle,
67 std::string rp_id,
68 const std::vector<uint8_t>& private_key,
69 int32_t counter,
70 std::vector<uint8_t> user_handle) {
71 auto ec_private_key =
72 crypto::ECPrivateKey::CreateFromPrivateKeyInfo(private_key);
73 if (!ec_private_key)
74 return false;
75
76 return state_->InjectResidentKey(
77 std::move(key_handle),
78 device::PublicKeyCredentialRpEntity(std::move(rp_id)),
79 device::PublicKeyCredentialUserEntity(std::move(user_handle)), counter,
80 std::move(ec_private_key));
81 }
82
ClearRegistrations()83 void VirtualAuthenticator::ClearRegistrations() {
84 state_->registrations.clear();
85 }
86
RemoveRegistration(const std::vector<uint8_t> & key_handle)87 bool VirtualAuthenticator::RemoveRegistration(
88 const std::vector<uint8_t>& key_handle) {
89 return state_->registrations.erase(key_handle) != 0;
90 }
91
SetUserPresence(bool is_user_present)92 void VirtualAuthenticator::SetUserPresence(bool is_user_present) {
93 is_user_present_ = is_user_present;
94 state_->simulate_press_callback = base::BindRepeating(
95 [](bool is_user_present, device::VirtualFidoDevice* device) {
96 return is_user_present;
97 },
98 is_user_present);
99 }
100
ConstructDevice()101 std::unique_ptr<::device::FidoDevice> VirtualAuthenticator::ConstructDevice() {
102 switch (protocol_) {
103 case ::device::ProtocolVersion::kU2f:
104 return std::make_unique<::device::VirtualU2fDevice>(state_);
105 case ::device::ProtocolVersion::kCtap2: {
106 device::VirtualCtap2Device::Config config;
107 config.resident_key_support = has_resident_key_;
108 config.internal_uv_support = has_user_verification_;
109 config.is_platform_authenticator =
110 attachment_ == ::device::AuthenticatorAttachment::kPlatform;
111 config.user_verification_succeeds = is_user_verified_;
112 return std::make_unique<::device::VirtualCtap2Device>(state_, config);
113 }
114 default:
115 NOTREACHED();
116 return std::make_unique<::device::VirtualU2fDevice>(state_);
117 }
118 }
119
GetUniqueId(GetUniqueIdCallback callback)120 void VirtualAuthenticator::GetUniqueId(GetUniqueIdCallback callback) {
121 std::move(callback).Run(unique_id_);
122 }
123
GetRegistrations(GetRegistrationsCallback callback)124 void VirtualAuthenticator::GetRegistrations(GetRegistrationsCallback callback) {
125 std::vector<blink::test::mojom::RegisteredKeyPtr> mojo_registered_keys;
126 for (const auto& registration : state_->registrations) {
127 auto mojo_registered_key = blink::test::mojom::RegisteredKey::New();
128 mojo_registered_key->key_handle = registration.first;
129 mojo_registered_key->counter = registration.second.counter;
130 mojo_registered_key->rp_id =
131 registration.second.rp ? registration.second.rp->id : "";
132 registration.second.private_key->ExportPrivateKey(
133 &mojo_registered_key->private_key);
134 mojo_registered_keys.push_back(std::move(mojo_registered_key));
135 }
136 std::move(callback).Run(std::move(mojo_registered_keys));
137 }
138
AddRegistration(blink::test::mojom::RegisteredKeyPtr registration,AddRegistrationCallback callback)139 void VirtualAuthenticator::AddRegistration(
140 blink::test::mojom::RegisteredKeyPtr registration,
141 AddRegistrationCallback callback) {
142 std::move(callback).Run(AddRegistration(
143 std::move(registration->key_handle), std::move(registration->rp_id),
144 registration->private_key, registration->counter));
145 }
146
ClearRegistrations(ClearRegistrationsCallback callback)147 void VirtualAuthenticator::ClearRegistrations(
148 ClearRegistrationsCallback callback) {
149 ClearRegistrations();
150 std::move(callback).Run();
151 }
152
RemoveRegistration(const std::vector<uint8_t> & key_handle,RemoveRegistrationCallback callback)153 void VirtualAuthenticator::RemoveRegistration(
154 const std::vector<uint8_t>& key_handle,
155 RemoveRegistrationCallback callback) {
156 std::move(callback).Run(RemoveRegistration(std::move(key_handle)));
157 }
158
SetUserVerified(bool verified,SetUserVerifiedCallback callback)159 void VirtualAuthenticator::SetUserVerified(bool verified,
160 SetUserVerifiedCallback callback) {
161 is_user_verified_ = verified;
162 std::move(callback).Run();
163 }
164
165 } // namespace content
166