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.
5 #include "chromeos/dbus/fake_cryptohome_client.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chromeos/dbus/cryptohome/key.pb.h"
11 #include "chromeos/dbus/cryptohome/rpc.pb.h"
12 #include "crypto/nss_util.h"
13 #include "third_party/cros_system_api/dbus/service_constants.h"
17 FakeCryptohomeClient::FakeCryptohomeClient()
18 : service_is_available_(true),
20 tpm_is_ready_counter_(0),
21 unmount_result_(true),
22 system_salt_(GetStubSystemSalt()),
24 weak_ptr_factory_(this) {}
26 FakeCryptohomeClient::~FakeCryptohomeClient() {}
28 void FakeCryptohomeClient::Init(dbus::Bus* bus) {
31 void FakeCryptohomeClient::SetAsyncCallStatusHandlers(
32 const AsyncCallStatusHandler& handler,
33 const AsyncCallStatusWithDataHandler& data_handler) {
34 async_call_status_handler_ = handler;
35 async_call_status_data_handler_ = data_handler;
38 void FakeCryptohomeClient::ResetAsyncCallStatusHandlers() {
39 async_call_status_handler_.Reset();
40 async_call_status_data_handler_.Reset();
43 void FakeCryptohomeClient::WaitForServiceToBeAvailable(
44 const WaitForServiceToBeAvailableCallback& callback) {
45 if (service_is_available_) {
46 base::MessageLoop::current()->PostTask(FROM_HERE,
47 base::Bind(callback, true));
49 pending_wait_for_service_to_be_available_callbacks_.push_back(callback);
53 void FakeCryptohomeClient::IsMounted(
54 const BoolDBusMethodCallback& callback) {
55 base::MessageLoop::current()->PostTask(
56 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
59 bool FakeCryptohomeClient::Unmount(bool* success) {
60 *success = unmount_result_;
64 void FakeCryptohomeClient::AsyncCheckKey(
65 const std::string& username,
66 const std::string& key,
67 const AsyncMethodCallback& callback) {
68 ReturnAsyncMethodResult(callback, false);
71 void FakeCryptohomeClient::AsyncMigrateKey(
72 const std::string& username,
73 const std::string& from_key,
74 const std::string& to_key,
75 const AsyncMethodCallback& callback) {
76 ReturnAsyncMethodResult(callback, false);
79 void FakeCryptohomeClient::AsyncRemove(
80 const std::string& username,
81 const AsyncMethodCallback& callback) {
82 ReturnAsyncMethodResult(callback, false);
85 void FakeCryptohomeClient::GetSystemSalt(
86 const GetSystemSaltCallback& callback) {
87 base::MessageLoop::current()->PostTask(
89 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, system_salt_));
92 void FakeCryptohomeClient::GetSanitizedUsername(
93 const std::string& username,
94 const StringDBusMethodCallback& callback) {
95 // Even for stub implementation we have to return different values so that
96 // multi-profiles would work.
97 std::string sanitized_username = GetStubSanitizedUsername(username);
98 base::MessageLoop::current()->PostTask(
100 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, sanitized_username));
103 std::string FakeCryptohomeClient::BlockingGetSanitizedUsername(
104 const std::string& username) {
105 return GetStubSanitizedUsername(username);
108 void FakeCryptohomeClient::AsyncMount(const std::string& username,
109 const std::string& key,
111 const AsyncMethodCallback& callback) {
112 ReturnAsyncMethodResult(callback, false);
115 void FakeCryptohomeClient::AsyncAddKey(
116 const std::string& username,
117 const std::string& key,
118 const std::string& new_key,
119 const AsyncMethodCallback& callback) {
120 ReturnAsyncMethodResult(callback, false);
123 void FakeCryptohomeClient::AsyncMountGuest(
124 const AsyncMethodCallback& callback) {
125 ReturnAsyncMethodResult(callback, false);
128 void FakeCryptohomeClient::AsyncMountPublic(
129 const std::string& public_mount_id,
131 const AsyncMethodCallback& callback) {
132 ReturnAsyncMethodResult(callback, false);
135 void FakeCryptohomeClient::TpmIsReady(
136 const BoolDBusMethodCallback& callback) {
137 base::MessageLoop::current()->PostTask(
138 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
141 void FakeCryptohomeClient::TpmIsEnabled(
142 const BoolDBusMethodCallback& callback) {
143 base::MessageLoop::current()->PostTask(
144 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
147 bool FakeCryptohomeClient::CallTpmIsEnabledAndBlock(bool* enabled) {
152 void FakeCryptohomeClient::TpmGetPassword(
153 const StringDBusMethodCallback& callback) {
154 const char kStubTpmPassword[] = "Stub-TPM-password";
155 base::MessageLoop::current()->PostTask(
157 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS,
158 std::string(kStubTpmPassword)));
161 void FakeCryptohomeClient::TpmIsOwned(
162 const BoolDBusMethodCallback& callback) {
163 base::MessageLoop::current()->PostTask(
164 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
167 bool FakeCryptohomeClient::CallTpmIsOwnedAndBlock(bool* owned) {
172 void FakeCryptohomeClient::TpmIsBeingOwned(
173 const BoolDBusMethodCallback& callback) {
174 base::MessageLoop::current()->PostTask(
175 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
178 bool FakeCryptohomeClient::CallTpmIsBeingOwnedAndBlock(bool* owning) {
183 void FakeCryptohomeClient::TpmCanAttemptOwnership(
184 const VoidDBusMethodCallback& callback) {
185 base::MessageLoop::current()->PostTask(
186 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
189 void FakeCryptohomeClient::TpmClearStoredPassword(
190 const VoidDBusMethodCallback& callback) {
191 base::MessageLoop::current()->PostTask(
192 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
195 bool FakeCryptohomeClient::CallTpmClearStoredPasswordAndBlock() {
199 void FakeCryptohomeClient::Pkcs11IsTpmTokenReady(
200 const BoolDBusMethodCallback& callback) {
201 base::MessageLoop::current()->PostTask(
202 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
205 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfo(
206 const Pkcs11GetTpmTokenInfoCallback& callback) {
207 const char kStubUserPin[] = "012345";
208 const int kStubSlot = 0;
209 base::MessageLoop::current()->PostTask(
212 DBUS_METHOD_CALL_SUCCESS,
213 std::string(crypto::kTestTPMTokenName),
214 std::string(kStubUserPin),
218 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfoForUser(
219 const std::string& username,
220 const Pkcs11GetTpmTokenInfoCallback& callback) {
221 Pkcs11GetTpmTokenInfo(callback);
224 bool FakeCryptohomeClient::InstallAttributesGet(const std::string& name,
225 std::vector<uint8>* value,
227 if (install_attrs_.find(name) != install_attrs_.end()) {
228 *value = install_attrs_[name];
237 bool FakeCryptohomeClient::InstallAttributesSet(
238 const std::string& name,
239 const std::vector<uint8>& value,
241 install_attrs_[name] = value;
246 bool FakeCryptohomeClient::InstallAttributesFinalize(bool* successful) {
252 void FakeCryptohomeClient::InstallAttributesIsReady(
253 const BoolDBusMethodCallback& callback) {
254 base::MessageLoop::current()->PostTask(
255 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
258 bool FakeCryptohomeClient::InstallAttributesIsInvalid(bool* is_invalid) {
263 bool FakeCryptohomeClient::InstallAttributesIsFirstInstall(
264 bool* is_first_install) {
265 *is_first_install = !locked_;
269 void FakeCryptohomeClient::TpmAttestationIsPrepared(
270 const BoolDBusMethodCallback& callback) {
271 base::MessageLoop::current()->PostTask(
272 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
275 void FakeCryptohomeClient::TpmAttestationIsEnrolled(
276 const BoolDBusMethodCallback& callback) {
277 base::MessageLoop::current()->PostTask(
278 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
281 void FakeCryptohomeClient::AsyncTpmAttestationCreateEnrollRequest(
282 chromeos::attestation::PrivacyCAType pca_type,
283 const AsyncMethodCallback& callback) {
284 ReturnAsyncMethodResult(callback, true);
287 void FakeCryptohomeClient::AsyncTpmAttestationEnroll(
288 chromeos::attestation::PrivacyCAType pca_type,
289 const std::string& pca_response,
290 const AsyncMethodCallback& callback) {
291 ReturnAsyncMethodResult(callback, false);
294 void FakeCryptohomeClient::AsyncTpmAttestationCreateCertRequest(
295 chromeos::attestation::PrivacyCAType pca_type,
296 attestation::AttestationCertificateProfile certificate_profile,
297 const std::string& user_id,
298 const std::string& request_origin,
299 const AsyncMethodCallback& callback) {
300 ReturnAsyncMethodResult(callback, true);
303 void FakeCryptohomeClient::AsyncTpmAttestationFinishCertRequest(
304 const std::string& pca_response,
305 attestation::AttestationKeyType key_type,
306 const std::string& user_id,
307 const std::string& key_name,
308 const AsyncMethodCallback& callback) {
309 ReturnAsyncMethodResult(callback, true);
312 void FakeCryptohomeClient::TpmAttestationDoesKeyExist(
313 attestation::AttestationKeyType key_type,
314 const std::string& user_id,
315 const std::string& key_name,
316 const BoolDBusMethodCallback& callback) {
317 base::MessageLoop::current()->PostTask(
318 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
321 void FakeCryptohomeClient::TpmAttestationGetCertificate(
322 attestation::AttestationKeyType key_type,
323 const std::string& user_id,
324 const std::string& key_name,
325 const DataMethodCallback& callback) {
326 base::MessageLoop::current()->PostTask(
328 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
331 void FakeCryptohomeClient::TpmAttestationGetPublicKey(
332 attestation::AttestationKeyType key_type,
333 const std::string& user_id,
334 const std::string& key_name,
335 const DataMethodCallback& callback) {
336 base::MessageLoop::current()->PostTask(
338 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
341 void FakeCryptohomeClient::TpmAttestationRegisterKey(
342 attestation::AttestationKeyType key_type,
343 const std::string& user_id,
344 const std::string& key_name,
345 const AsyncMethodCallback& callback) {
346 ReturnAsyncMethodResult(callback, true);
349 void FakeCryptohomeClient::TpmAttestationSignEnterpriseChallenge(
350 attestation::AttestationKeyType key_type,
351 const std::string& user_id,
352 const std::string& key_name,
353 const std::string& domain,
354 const std::string& device_id,
355 attestation::AttestationChallengeOptions options,
356 const std::string& challenge,
357 const AsyncMethodCallback& callback) {
358 ReturnAsyncMethodResult(callback, true);
361 void FakeCryptohomeClient::TpmAttestationSignSimpleChallenge(
362 attestation::AttestationKeyType key_type,
363 const std::string& user_id,
364 const std::string& key_name,
365 const std::string& challenge,
366 const AsyncMethodCallback& callback) {
367 ReturnAsyncMethodResult(callback, true);
370 void FakeCryptohomeClient::TpmAttestationGetKeyPayload(
371 attestation::AttestationKeyType key_type,
372 const std::string& user_id,
373 const std::string& key_name,
374 const DataMethodCallback& callback) {
375 base::MessageLoop::current()->PostTask(
377 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
380 void FakeCryptohomeClient::TpmAttestationSetKeyPayload(
381 attestation::AttestationKeyType key_type,
382 const std::string& user_id,
383 const std::string& key_name,
384 const std::string& payload,
385 const BoolDBusMethodCallback& callback) {
386 base::MessageLoop::current()->PostTask(
387 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
390 void FakeCryptohomeClient::TpmAttestationDeleteKeys(
391 attestation::AttestationKeyType key_type,
392 const std::string& user_id,
393 const std::string& key_prefix,
394 const BoolDBusMethodCallback& callback) {
395 base::MessageLoop::current()->PostTask(
396 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
399 void FakeCryptohomeClient::CheckKeyEx(
400 const cryptohome::AccountIdentifier& id,
401 const cryptohome::AuthorizationRequest& auth,
402 const cryptohome::CheckKeyRequest& request,
403 const ProtobufMethodCallback& callback) {
404 ReturnProtobufMethodCallback(id.email(), callback);
407 void FakeCryptohomeClient::MountEx(
408 const cryptohome::AccountIdentifier& id,
409 const cryptohome::AuthorizationRequest& auth,
410 const cryptohome::MountRequest& request,
411 const ProtobufMethodCallback& callback) {
412 ReturnProtobufMethodCallback(id.email(), callback);
415 void FakeCryptohomeClient::AddKeyEx(
416 const cryptohome::AccountIdentifier& id,
417 const cryptohome::AuthorizationRequest& auth,
418 const cryptohome::AddKeyRequest& request,
419 const ProtobufMethodCallback& callback) {
420 ReturnProtobufMethodCallback(id.email(), callback);
423 void FakeCryptohomeClient::RemoveKeyEx(
424 const cryptohome::AccountIdentifier& id,
425 const cryptohome::AuthorizationRequest& auth,
426 const cryptohome::RemoveKeyRequest& request,
427 const ProtobufMethodCallback& callback) {
428 ReturnProtobufMethodCallback(id.email(), callback);
431 void FakeCryptohomeClient::UpdateKeyEx(
432 const cryptohome::AccountIdentifier& id,
433 const cryptohome::AuthorizationRequest& auth,
434 const cryptohome::UpdateKeyRequest& request,
435 const ProtobufMethodCallback& callback) {
436 ReturnProtobufMethodCallback(id.email(), callback);
439 void FakeCryptohomeClient::SetServiceIsAvailable(bool is_available) {
440 service_is_available_ = is_available;
442 std::vector<WaitForServiceToBeAvailableCallback> callbacks;
443 callbacks.swap(pending_wait_for_service_to_be_available_callbacks_);
444 for (size_t i = 0; i < callbacks.size(); ++i)
445 callbacks[i].Run(is_available);
450 std::vector<uint8> FakeCryptohomeClient::GetStubSystemSalt() {
451 const char kStubSystemSalt[] = "stub_system_salt";
452 return std::vector<uint8>(kStubSystemSalt,
453 kStubSystemSalt + arraysize(kStubSystemSalt) - 1);
456 void FakeCryptohomeClient::ReturnProtobufMethodCallback(
457 const std::string& userid,
458 const ProtobufMethodCallback& callback) {
459 cryptohome::BaseReply reply;
460 reply.set_error(cryptohome::CRYPTOHOME_ERROR_NOT_SET);
461 cryptohome::MountReply* mount =
462 reply.MutableExtension(cryptohome::MountReply::reply);
463 mount->set_sanitized_username(GetStubSanitizedUsername(userid));
464 base::MessageLoop::current()->PostTask(
467 DBUS_METHOD_CALL_SUCCESS,
472 void FakeCryptohomeClient::ReturnAsyncMethodResult(
473 const AsyncMethodCallback& callback,
475 base::MessageLoop::current()->PostTask(
477 base::Bind(&FakeCryptohomeClient::ReturnAsyncMethodResultInternal,
478 weak_ptr_factory_.GetWeakPtr(),
483 void FakeCryptohomeClient::ReturnAsyncMethodResultInternal(
484 const AsyncMethodCallback& callback,
486 callback.Run(async_call_id_);
487 if (!returns_data && !async_call_status_handler_.is_null()) {
488 base::MessageLoop::current()->PostTask(
490 base::Bind(async_call_status_handler_,
493 cryptohome::MOUNT_ERROR_NONE));
494 } else if (returns_data && !async_call_status_data_handler_.is_null()) {
495 base::MessageLoop::current()->PostTask(
497 base::Bind(async_call_status_data_handler_,
505 } // namespace chromeos