1 // Copyright 2013 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 CHROMEOS_DBUS_CRYPTOHOME_FAKE_CRYPTOHOME_CLIENT_H_
6 #define CHROMEOS_DBUS_CRYPTOHOME_FAKE_CRYPTOHOME_CLIENT_H_
7
8 #include <stdint.h>
9
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <utility>
14 #include <vector>
15
16 #include "base/macros.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/observer_list.h"
19 #include "base/optional.h"
20 #include "base/timer/timer.h"
21 #include "chromeos/dbus/cryptohome/cryptohome_client.h"
22 #include "chromeos/dbus/cryptohome/key.pb.h"
23 #include "chromeos/dbus/cryptohome/rpc.pb.h"
24
25 namespace chromeos {
26
COMPONENT_EXPORT(CRYPTOHOME_CLIENT)27 class COMPONENT_EXPORT(CRYPTOHOME_CLIENT) FakeCryptohomeClient
28 : public CryptohomeClient {
29 public:
30 // FakeCryptohomeClient can be embedded in unit tests, but the
31 // InitializeFake/Shutdown pattern should be preferred. Constructing the
32 // instance will set the global instance for the fake and for the base class,
33 // so the static Get() accessor can be used with that pattern.
34 FakeCryptohomeClient();
35 ~FakeCryptohomeClient() override;
36
37 // Checks that a FakeCryptohome instance was initialized and returns it.
38 static FakeCryptohomeClient* Get();
39
40 // Expose stub password for tests.
41 static const char kStubTpmPassword[];
42
43 // CryptohomeClient overrides
44 void AddObserver(Observer* observer) override;
45 void RemoveObserver(Observer* observer) override;
46 void WaitForServiceToBeAvailable(
47 WaitForServiceToBeAvailableCallback callback) override;
48 void IsMounted(DBusMethodCallback<bool> callback) override;
49 void UnmountEx(const cryptohome::UnmountRequest& request,
50 DBusMethodCallback<cryptohome::BaseReply> callback) override;
51 void MigrateKeyEx(
52 const cryptohome::AccountIdentifier& account,
53 const cryptohome::AuthorizationRequest& auth_request,
54 const cryptohome::MigrateKeyRequest& migrate_request,
55 DBusMethodCallback<cryptohome::BaseReply> callback) override;
56 void RemoveEx(const cryptohome::AccountIdentifier& account,
57 DBusMethodCallback<cryptohome::BaseReply> callback) override;
58 void RenameCryptohome(
59 const cryptohome::AccountIdentifier& cryptohome_id_from,
60 const cryptohome::AccountIdentifier& cryptohome_id_to,
61 DBusMethodCallback<cryptohome::BaseReply> callback) override;
62 void GetAccountDiskUsage(
63 const cryptohome::AccountIdentifier& account_id,
64 DBusMethodCallback<cryptohome::BaseReply> callback) override;
65 void GetSystemSalt(
66 DBusMethodCallback<std::vector<uint8_t>> callback) override;
67 void GetSanitizedUsername(const cryptohome::AccountIdentifier& cryptohome_id,
68 DBusMethodCallback<std::string> callback) override;
69 std::string BlockingGetSanitizedUsername(
70 const cryptohome::AccountIdentifier& cryptohome_id) override;
71 void MountGuestEx(
72 const cryptohome::MountGuestRequest& request,
73 DBusMethodCallback<cryptohome::BaseReply> callback) override;
74 void GetRsuDeviceId(
75 DBusMethodCallback<cryptohome::BaseReply> callback) override;
76 void TpmIsReady(DBusMethodCallback<bool> callback) override;
77 void TpmIsEnabled(DBusMethodCallback<bool> callback) override;
78 bool CallTpmIsEnabledAndBlock(bool* enabled) override;
79 void TpmGetPassword(DBusMethodCallback<std::string> callback) override;
80 void TpmIsOwned(DBusMethodCallback<bool> callback) override;
81 bool CallTpmIsOwnedAndBlock(bool* owned) override;
82 void TpmIsBeingOwned(DBusMethodCallback<bool> callback) override;
83 bool CallTpmIsBeingOwnedAndBlock(bool* owning) override;
84 void TpmCanAttemptOwnership(VoidDBusMethodCallback callback) override;
85 void TpmClearStoredPassword(VoidDBusMethodCallback callback) override;
86 bool CallTpmClearStoredPasswordAndBlock() override;
87 void Pkcs11IsTpmTokenReady(DBusMethodCallback<bool> callback) override;
88 void Pkcs11GetTpmTokenInfo(
89 DBusMethodCallback<TpmTokenInfo> callback) override;
90 void Pkcs11GetTpmTokenInfoForUser(
91 const cryptohome::AccountIdentifier& cryptohome_id,
92 DBusMethodCallback<TpmTokenInfo> callback) override;
93 bool InstallAttributesGet(const std::string& name,
94 std::vector<uint8_t>* value,
95 bool* successful) override;
96 bool InstallAttributesSet(const std::string& name,
97 const std::vector<uint8_t>& value,
98 bool* successful) override;
99 bool InstallAttributesFinalize(bool* successful) override;
100 void InstallAttributesIsReady(DBusMethodCallback<bool> callback) override;
101 bool InstallAttributesIsInvalid(bool* is_invalid) override;
102 bool InstallAttributesIsFirstInstall(bool* is_first_install) override;
103 void TpmGetVersion(DBusMethodCallback<TpmVersionInfo> callback) override;
104 void GetKeyDataEx(
105 const cryptohome::AccountIdentifier& cryptohome_id,
106 const cryptohome::AuthorizationRequest& auth,
107 const cryptohome::GetKeyDataRequest& request,
108 DBusMethodCallback<cryptohome::BaseReply> callback) override;
109 void CheckKeyEx(const cryptohome::AccountIdentifier& cryptohome_id,
110 const cryptohome::AuthorizationRequest& auth,
111 const cryptohome::CheckKeyRequest& request,
112 DBusMethodCallback<cryptohome::BaseReply> callback) override;
113 void MountEx(const cryptohome::AccountIdentifier& cryptohome_id,
114 const cryptohome::AuthorizationRequest& auth,
115 const cryptohome::MountRequest& request,
116 DBusMethodCallback<cryptohome::BaseReply> callback) override;
117 void LockToSingleUserMountUntilReboot(
118 const cryptohome::LockToSingleUserMountUntilRebootRequest& request,
119 DBusMethodCallback<cryptohome::BaseReply> callback) override;
120 void AddKeyEx(const cryptohome::AccountIdentifier& cryptohome_id,
121 const cryptohome::AuthorizationRequest& auth,
122 const cryptohome::AddKeyRequest& request,
123 DBusMethodCallback<cryptohome::BaseReply> callback) override;
124 void AddDataRestoreKey(
125 const cryptohome::AccountIdentifier& cryptohome_id,
126 const cryptohome::AuthorizationRequest& auth,
127 DBusMethodCallback<cryptohome::BaseReply> callback) override;
128 void UpdateKeyEx(const cryptohome::AccountIdentifier& cryptohome_id,
129 const cryptohome::AuthorizationRequest& auth,
130 const cryptohome::UpdateKeyRequest& request,
131 DBusMethodCallback<cryptohome::BaseReply> callback) override;
132 void RemoveKeyEx(const cryptohome::AccountIdentifier& cryptohome_id,
133 const cryptohome::AuthorizationRequest& auth,
134 const cryptohome::RemoveKeyRequest& request,
135 DBusMethodCallback<cryptohome::BaseReply> callback) override;
136 void MassRemoveKeys(
137 const cryptohome::AccountIdentifier& cryptohome_id,
138 const cryptohome::AuthorizationRequest& auth,
139 const cryptohome::MassRemoveKeysRequest& request,
140 DBusMethodCallback<cryptohome::BaseReply> callback) override;
141 void GetBootAttribute(
142 const cryptohome::GetBootAttributeRequest& request,
143 DBusMethodCallback<cryptohome::BaseReply> callback) override;
144 void SetBootAttribute(
145 const cryptohome::SetBootAttributeRequest& request,
146 DBusMethodCallback<cryptohome::BaseReply> callback) override;
147 void FlushAndSignBootAttributes(
148 const cryptohome::FlushAndSignBootAttributesRequest& request,
149 DBusMethodCallback<cryptohome::BaseReply> callback) override;
150 void GetTpmStatus(
151 const cryptohome::GetTpmStatusRequest& request,
152 DBusMethodCallback<cryptohome::BaseReply> callback) override;
153 void MigrateToDircrypto(const cryptohome::AccountIdentifier& cryptohome_id,
154 const cryptohome::MigrateToDircryptoRequest& request,
155 VoidDBusMethodCallback callback) override;
156 void RemoveFirmwareManagementParametersFromTpm(
157 const cryptohome::RemoveFirmwareManagementParametersRequest& request,
158 DBusMethodCallback<cryptohome::BaseReply> callback) override;
159 void SetFirmwareManagementParametersInTpm(
160 const cryptohome::SetFirmwareManagementParametersRequest& request,
161 DBusMethodCallback<cryptohome::BaseReply> callback) override;
162 void NeedsDircryptoMigration(
163 const cryptohome::AccountIdentifier& cryptohome_id,
164 DBusMethodCallback<bool> callback) override;
165 void GetSupportedKeyPolicies(
166 const cryptohome::GetSupportedKeyPoliciesRequest& request,
167 DBusMethodCallback<cryptohome::BaseReply> callback) override;
168 void IsQuotaSupported(DBusMethodCallback<bool> callback) override;
169 void GetCurrentSpaceForUid(uid_t android_uid,
170 DBusMethodCallback<int64_t> callback) override;
171 void GetCurrentSpaceForGid(gid_t android_gid,
172 DBusMethodCallback<int64_t> callback) override;
173 void CheckHealth(const cryptohome::CheckHealthRequest& request,
174 DBusMethodCallback<cryptohome::BaseReply> callback) override;
175 void StartFingerprintAuthSession(
176 const cryptohome::AccountIdentifier& id,
177 const cryptohome::StartFingerprintAuthSessionRequest& request,
178 DBusMethodCallback<cryptohome::BaseReply> callback) override;
179 void EndFingerprintAuthSession(
180 const cryptohome::EndFingerprintAuthSessionRequest& request,
181 DBusMethodCallback<cryptohome::BaseReply> callback) override;
182
183 /////////// Test helpers ////////////
184
185 // Changes the behavior of WaitForServiceToBeAvailable(). This method runs
186 // pending callbacks if is_available is true.
187 void SetServiceIsAvailable(bool is_available);
188
189 // Runs pending availability callbacks reporting that the service is
190 // unavailable. Expects service not to be available when called.
191 void ReportServiceIsNotAvailable();
192
193 // Changes the behavior of TpmIsReady().
194 void set_tpm_is_ready(bool value) { tpm_is_ready_ = value; }
195
196 // Changes the behavior of TpmIsEnabled().
197 void set_tpm_is_enabled(bool value) { tpm_is_enabled_ = value; }
198
199 // Sets whether the MountEx() call should fail when the |create| field is not
200 // provided (the error code will be CRYPTOHOME_ERROR_ACCOUNT_NOT_FOUND).
201 // This allows to simulate the behavior during the new user profile creation.
202 void set_mount_create_required(bool mount_create_required) {
203 mount_create_required_ = mount_create_required;
204 }
205
206 // Sets the unmount result of Unmount() call.
207 void set_unmount_result(bool result) { unmount_result_ = result; }
208
209 // Sets the system salt which will be returned from GetSystemSalt(). By
210 // default, GetSystemSalt() returns the value generated by
211 // GetStubSystemSalt().
212 void set_system_salt(const std::vector<uint8_t>& system_salt) {
213 system_salt_ = system_salt;
214 }
215
216 // Returns the stub system salt as raw bytes. (not as a string encoded in the
217 // format used by SystemSaltGetter::ConvertRawSaltToHexString()).
218 static std::vector<uint8_t> GetStubSystemSalt();
219
220 // Marks |cryptohome_id| as using ecryptfs (|use_ecryptfs|=true) or dircrypto
221 // (|use_ecryptfs|=false).
222 void SetEcryptfsUserHome(const cryptohome::AccountIdentifier& cryptohome_id,
223 bool use_ecryptfs);
224
225 // Sets whether dircrypto migration update should be run automatically.
226 // If set to false, the client will not send any dircrypto migration progress
227 // updates on its own - a test that sets this will have to call
228 // NotifyDircryptoMigrationProgress() for the progress to update.
229 void set_run_default_dircrypto_migration(bool value) {
230 run_default_dircrypto_migration_ = value;
231 }
232
233 // Sets the CryptohomeError value to return.
234 void set_cryptohome_error(cryptohome::CryptohomeErrorCode error) {
235 cryptohome_error_ = error;
236 }
237
238 void set_supports_low_entropy_credentials(bool supports) {
239 supports_low_entropy_credentials_ = supports;
240 }
241
242 void set_enable_auth_check(bool enable_auth_check) {
243 enable_auth_check_ = enable_auth_check;
244 }
245
246 void set_rsu_device_id(const std::string& rsu_device_id) {
247 rsu_device_id_ = rsu_device_id;
248 }
249
250 // Calls TpmInitStatusUpdated() on Observer instances.
251 void NotifyTpmInitStatusUpdated(bool ready,
252 bool owned,
253 bool was_owned_this_boot);
254
255 // Calls DircryptoMigrationProgress() on Observer instances.
256 void NotifyDircryptoMigrationProgress(
257 cryptohome::DircryptoMigrationStatus status,
258 uint64_t current,
259 uint64_t total);
260
261 // Notifies LowDiskSpace() to Observer instances.
262 void NotifyLowDiskSpace(uint64_t disk_free_bytes);
263
264 // MountEx getters.
265 const cryptohome::MountRequest& get_last_mount_request() const {
266 return last_mount_request_;
267 }
268 bool to_migrate_from_ecryptfs() const {
269 return last_mount_request_.to_migrate_from_ecryptfs();
270 }
271 bool hidden_mount() const { return last_mount_request_.hidden_mount(); }
272 bool public_mount() const { return last_mount_request_.public_mount(); }
273 const cryptohome::AuthorizationRequest& get_last_mount_authentication()
274 const {
275 return last_mount_auth_request_;
276 }
277 const std::string& get_secret_for_last_mount_authentication() const {
278 return last_mount_auth_request_.key().secret();
279 }
280
281 // MigrateToDircrypto getters.
282 const cryptohome::AccountIdentifier& get_id_for_disk_migrated_to_dircrypto()
283 const {
284 return id_for_disk_migrated_to_dircrypto_;
285 }
286 bool minimal_migration() const {
287 return last_migrate_to_dircrypto_request_.minimal_migration();
288 }
289
290 int remove_firmware_management_parameters_from_tpm_call_count() const {
291 return remove_firmware_management_parameters_from_tpm_call_count_;
292 }
293
294 bool is_device_locked_to_single_user() const {
295 return is_device_locked_to_single_user_;
296 }
297
298 void set_requires_powerwash(bool requires_powerwash) {
299 requires_powerwash_ = requires_powerwash;
300 }
301
302 private:
303 void ReturnProtobufMethodCallback(
304 const cryptohome::BaseReply& reply,
305 DBusMethodCallback<cryptohome::BaseReply> callback);
306
307 // Posts tasks which return fake results to the UI thread.
308 void ReturnAsyncMethodResult(AsyncMethodCallback callback);
309
310 // Posts tasks which return fake data to the UI thread.
311 void ReturnAsyncMethodData(AsyncMethodCallback callback,
312 const std::string& data);
313
314 // This method is used to implement ReturnAsyncMethodResult without data.
315 void ReturnAsyncMethodResultInternal(AsyncMethodCallback callback);
316
317 // This method is used to implement ReturnAsyncMethodResult with data.
318 void ReturnAsyncMethodDataInternal(AsyncMethodCallback callback,
319 const std::string& data);
320
321 // This method is used to implement MigrateToDircrypto with simulated progress
322 // updates.
323 void OnDircryptoMigrationProgressUpdated();
324
325 // Notifies AsyncCallStatus() to Observer instances.
326 void NotifyAsyncCallStatus(int async_id, bool return_status, int return_code);
327
328 // Notifies AsyncCallStatusWithData() to Observer instances.
329 void NotifyAsyncCallStatusWithData(int async_id,
330 bool return_status,
331 const std::string& data);
332
333 // Loads install attributes from the stub file.
334 bool LoadInstallAttributes();
335
336 // Returns true if |cryptohome_id| has been marked as being an ecryptfs user
337 // home using SetEcryptfsUserHome.
338 bool IsEcryptfsUserHome(const cryptohome::AccountIdentifier& cryptohome_id);
339
340 // Finds a key matching the given label. Wildcard labels are supported.
341 std::map<std::string, cryptohome::Key>::const_iterator FindKey(
342 const std::map<std::string, cryptohome::Key>& keys,
343 const std::string& label);
344
345 bool service_is_available_ = true;
346 // If set, WaitForServiceToBeAvailable will run the callback, even if service
347 // is not available (instead of adding the callback to pending callback list).
348 bool service_reported_not_available_ = false;
349 base::ObserverList<Observer>::Unchecked observer_list_;
350
351 int remove_firmware_management_parameters_from_tpm_call_count_ = 0;
352
353 int async_call_id_ = 1;
354 bool mount_create_required_ = false;
355 bool unmount_result_ = true;
356 std::vector<uint8_t> system_salt_{GetStubSystemSalt()};
357
358 std::vector<WaitForServiceToBeAvailableCallback>
359 pending_wait_for_service_to_be_available_callbacks_;
360
361 // A stub store for InstallAttributes, mapping an attribute name to the
362 // associated data blob. Used to implement InstallAttributesSet and -Get.
363 std::map<std::string, std::vector<uint8_t>> install_attrs_;
364 bool locked_;
365
366 std::map<cryptohome::AccountIdentifier,
367 std::map<std::string, cryptohome::Key>>
368 key_data_map_;
369
370 // Set of account identifiers whose user homes use ecryptfs. User homes not
371 // mentioned here use dircrypto.
372 std::set<cryptohome::AccountIdentifier> ecryptfs_user_homes_;
373
374 base::RepeatingTimer dircrypto_migration_progress_timer_;
375 uint64_t dircrypto_migration_progress_ = 0;
376
377 bool run_default_dircrypto_migration_ = true;
378 bool supports_low_entropy_credentials_ = false;
379 // Controls if CheckKeyEx actually checks the key.
380 bool enable_auth_check_ = false;
381 bool tpm_is_ready_ = true;
382 bool tpm_is_enabled_ = true;
383
384 // Reply to GetRsuDeviceId().
385 std::string rsu_device_id_;
386
387 // MountEx fields.
388 cryptohome::CryptohomeErrorCode cryptohome_error_ =
389 cryptohome::CRYPTOHOME_ERROR_NOT_SET;
390 cryptohome::MountRequest last_mount_request_;
391 cryptohome::AuthorizationRequest last_mount_auth_request_;
392
393 // MigrateToDircrypto fields.
394 cryptohome::AccountIdentifier id_for_disk_migrated_to_dircrypto_;
395 cryptohome::MigrateToDircryptoRequest last_migrate_to_dircrypto_request_;
396
397 // Used by LockToSingleUserMountUntilReboot.
398 bool is_device_locked_to_single_user_ = false;
399
400 // Used by GetStateRequiresPowerwash
401 bool requires_powerwash_ = false;
402
403 base::WeakPtrFactory<FakeCryptohomeClient> weak_ptr_factory_{this};
404
405 DISALLOW_COPY_AND_ASSIGN(FakeCryptohomeClient);
406 };
407
408 } // namespace chromeos
409
410 #endif // CHROMEOS_DBUS_CRYPTOHOME_FAKE_CRYPTOHOME_CLIENT_H_
411