bluetooth: Shutdown BluetoothAdapter before DBus on ChromeOS.
[chromium-blink-merge.git] / chromeos / dbus / fake_cryptohome_client.cc
blobb678adabb01f154b526490c7ac6641b0012a2424
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"
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "base/location.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/path_service.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "chromeos/chromeos_paths.h"
14 #include "chromeos/dbus/cryptohome/key.pb.h"
15 #include "chromeos/dbus/cryptohome/rpc.pb.h"
16 #include "third_party/cros_system_api/dbus/service_constants.h"
17 #include "third_party/protobuf/src/google/protobuf/io/coded_stream.h"
18 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h"
19 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
21 namespace chromeos {
23 FakeCryptohomeClient::FakeCryptohomeClient()
24 : service_is_available_(true),
25 async_call_id_(1),
26 unmount_result_(true),
27 system_salt_(GetStubSystemSalt()),
28 weak_ptr_factory_(this) {
29 base::FilePath cache_path;
30 locked_ = PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path) &&
31 base::PathExists(cache_path);
34 FakeCryptohomeClient::~FakeCryptohomeClient() {}
36 void FakeCryptohomeClient::Init(dbus::Bus* bus) {
39 void FakeCryptohomeClient::SetAsyncCallStatusHandlers(
40 const AsyncCallStatusHandler& handler,
41 const AsyncCallStatusWithDataHandler& data_handler) {
42 async_call_status_handler_ = handler;
43 async_call_status_data_handler_ = data_handler;
46 void FakeCryptohomeClient::ResetAsyncCallStatusHandlers() {
47 async_call_status_handler_.Reset();
48 async_call_status_data_handler_.Reset();
51 void FakeCryptohomeClient::WaitForServiceToBeAvailable(
52 const WaitForServiceToBeAvailableCallback& callback) {
53 if (service_is_available_) {
54 base::MessageLoop::current()->PostTask(FROM_HERE,
55 base::Bind(callback, true));
56 } else {
57 pending_wait_for_service_to_be_available_callbacks_.push_back(callback);
61 void FakeCryptohomeClient::IsMounted(
62 const BoolDBusMethodCallback& callback) {
63 base::MessageLoop::current()->PostTask(
64 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
67 bool FakeCryptohomeClient::Unmount(bool* success) {
68 *success = unmount_result_;
69 return true;
72 void FakeCryptohomeClient::AsyncCheckKey(
73 const std::string& username,
74 const std::string& key,
75 const AsyncMethodCallback& callback) {
76 ReturnAsyncMethodResult(callback, false);
79 void FakeCryptohomeClient::AsyncMigrateKey(
80 const std::string& username,
81 const std::string& from_key,
82 const std::string& to_key,
83 const AsyncMethodCallback& callback) {
84 ReturnAsyncMethodResult(callback, false);
87 void FakeCryptohomeClient::AsyncRemove(
88 const std::string& username,
89 const AsyncMethodCallback& callback) {
90 ReturnAsyncMethodResult(callback, false);
93 void FakeCryptohomeClient::GetSystemSalt(
94 const GetSystemSaltCallback& callback) {
95 base::MessageLoop::current()->PostTask(
96 FROM_HERE,
97 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, system_salt_));
100 void FakeCryptohomeClient::GetSanitizedUsername(
101 const std::string& username,
102 const StringDBusMethodCallback& callback) {
103 // Even for stub implementation we have to return different values so that
104 // multi-profiles would work.
105 std::string sanitized_username = GetStubSanitizedUsername(username);
106 base::MessageLoop::current()->PostTask(
107 FROM_HERE,
108 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, sanitized_username));
111 std::string FakeCryptohomeClient::BlockingGetSanitizedUsername(
112 const std::string& username) {
113 return GetStubSanitizedUsername(username);
116 void FakeCryptohomeClient::AsyncMount(const std::string& username,
117 const std::string& key,
118 int flags,
119 const AsyncMethodCallback& callback) {
120 ReturnAsyncMethodResult(callback, false);
123 void FakeCryptohomeClient::AsyncAddKey(
124 const std::string& username,
125 const std::string& key,
126 const std::string& new_key,
127 const AsyncMethodCallback& callback) {
128 ReturnAsyncMethodResult(callback, false);
131 void FakeCryptohomeClient::AsyncMountGuest(
132 const AsyncMethodCallback& callback) {
133 ReturnAsyncMethodResult(callback, false);
136 void FakeCryptohomeClient::AsyncMountPublic(
137 const std::string& public_mount_id,
138 int flags,
139 const AsyncMethodCallback& callback) {
140 ReturnAsyncMethodResult(callback, false);
143 void FakeCryptohomeClient::TpmIsReady(
144 const BoolDBusMethodCallback& callback) {
145 base::MessageLoop::current()->PostTask(
146 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
149 void FakeCryptohomeClient::TpmIsEnabled(
150 const BoolDBusMethodCallback& callback) {
151 base::MessageLoop::current()->PostTask(
152 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
155 bool FakeCryptohomeClient::CallTpmIsEnabledAndBlock(bool* enabled) {
156 *enabled = true;
157 return true;
160 void FakeCryptohomeClient::TpmGetPassword(
161 const StringDBusMethodCallback& callback) {
162 const char kStubTpmPassword[] = "Stub-TPM-password";
163 base::MessageLoop::current()->PostTask(
164 FROM_HERE,
165 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS,
166 std::string(kStubTpmPassword)));
169 void FakeCryptohomeClient::TpmIsOwned(
170 const BoolDBusMethodCallback& callback) {
171 base::MessageLoop::current()->PostTask(
172 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
175 bool FakeCryptohomeClient::CallTpmIsOwnedAndBlock(bool* owned) {
176 *owned = true;
177 return true;
180 void FakeCryptohomeClient::TpmIsBeingOwned(
181 const BoolDBusMethodCallback& callback) {
182 base::MessageLoop::current()->PostTask(
183 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
186 bool FakeCryptohomeClient::CallTpmIsBeingOwnedAndBlock(bool* owning) {
187 *owning = true;
188 return true;
191 void FakeCryptohomeClient::TpmCanAttemptOwnership(
192 const VoidDBusMethodCallback& callback) {
193 base::MessageLoop::current()->PostTask(
194 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
197 void FakeCryptohomeClient::TpmClearStoredPassword(
198 const VoidDBusMethodCallback& callback) {
199 base::MessageLoop::current()->PostTask(
200 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
203 bool FakeCryptohomeClient::CallTpmClearStoredPasswordAndBlock() {
204 return true;
207 void FakeCryptohomeClient::Pkcs11IsTpmTokenReady(
208 const BoolDBusMethodCallback& callback) {
209 base::MessageLoop::current()->PostTask(
210 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
213 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfo(
214 const Pkcs11GetTpmTokenInfoCallback& callback) {
215 const char kStubTPMTokenName[] = "StubTPMTokenName";
216 const char kStubUserPin[] = "012345";
217 const int kStubSlot = 0;
218 base::MessageLoop::current()->PostTask(
219 FROM_HERE,
220 base::Bind(callback,
221 DBUS_METHOD_CALL_SUCCESS,
222 std::string(kStubTPMTokenName),
223 std::string(kStubUserPin),
224 kStubSlot));
227 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfoForUser(
228 const std::string& username,
229 const Pkcs11GetTpmTokenInfoCallback& callback) {
230 Pkcs11GetTpmTokenInfo(callback);
233 bool FakeCryptohomeClient::InstallAttributesGet(const std::string& name,
234 std::vector<uint8>* value,
235 bool* successful) {
236 if (install_attrs_.find(name) != install_attrs_.end()) {
237 *value = install_attrs_[name];
238 *successful = true;
239 } else {
240 value->clear();
241 *successful = false;
243 return true;
246 bool FakeCryptohomeClient::InstallAttributesSet(
247 const std::string& name,
248 const std::vector<uint8>& value,
249 bool* successful) {
250 install_attrs_[name] = value;
251 *successful = true;
252 return true;
255 bool FakeCryptohomeClient::InstallAttributesFinalize(bool* successful) {
256 locked_ = true;
257 *successful = true;
259 // Persist the install attributes so that they can be reloaded if the
260 // browser is restarted. This is used for ease of development when device
261 // enrollment is required.
262 // The cryptohome::SerializedInstallAttributes protobuf lives in
263 // chrome/browser/chromeos, so it can't be used directly here; use the
264 // low-level protobuf API instead to just write the name-value pairs.
265 // The cache file is read by EnterpriseInstallAttributes::ReadCacheFile.
266 base::FilePath cache_path;
267 if (!PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path))
268 return false;
270 std::string result;
272 // |result| can be used only after the StringOutputStream goes out of
273 // scope.
274 google::protobuf::io::StringOutputStream result_stream(&result);
275 google::protobuf::io::CodedOutputStream result_output(&result_stream);
277 // These tags encode a variable-length value on the wire, which can be
278 // used to encode strings, bytes and messages. We only needs constants
279 // for tag numbers 1 and 2 (see install_attributes.proto).
280 const int kVarLengthTag1 = (1 << 3) | 0x2;
281 const int kVarLengthTag2 = (2 << 3) | 0x2;
283 typedef std::map<std::string, std::vector<uint8> >::const_iterator Iter;
284 for (Iter it = install_attrs_.begin(); it != install_attrs_.end(); ++it) {
285 std::string attr;
287 google::protobuf::io::StringOutputStream attr_stream(&attr);
288 google::protobuf::io::CodedOutputStream attr_output(&attr_stream);
290 attr_output.WriteVarint32(kVarLengthTag1);
291 attr_output.WriteVarint32(it->first.size());
292 attr_output.WriteString(it->first);
293 attr_output.WriteVarint32(kVarLengthTag2);
294 attr_output.WriteVarint32(it->second.size());
295 attr_output.WriteRaw(it->second.data(), it->second.size());
298 // Two CodedOutputStreams are needed because inner messages must be
299 // prefixed by their total length, which can't be easily computed before
300 // writing their tags and values.
301 result_output.WriteVarint32(kVarLengthTag2);
302 result_output.WriteVarint32(attr.size());
303 result_output.WriteRaw(attr.data(), attr.size());
307 // The real implementation does a blocking wait on the dbus call; the fake
308 // implementation must have this file written before returning.
309 base::ThreadRestrictions::ScopedAllowIO allow_io;
310 base::WriteFile(cache_path, result.data(), result.size());
312 return true;
315 void FakeCryptohomeClient::InstallAttributesIsReady(
316 const BoolDBusMethodCallback& callback) {
317 base::MessageLoop::current()->PostTask(
318 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
321 bool FakeCryptohomeClient::InstallAttributesIsInvalid(bool* is_invalid) {
322 *is_invalid = false;
323 return true;
326 bool FakeCryptohomeClient::InstallAttributesIsFirstInstall(
327 bool* is_first_install) {
328 *is_first_install = !locked_;
329 return true;
332 void FakeCryptohomeClient::TpmAttestationIsPrepared(
333 const BoolDBusMethodCallback& callback) {
334 base::MessageLoop::current()->PostTask(
335 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
338 void FakeCryptohomeClient::TpmAttestationIsEnrolled(
339 const BoolDBusMethodCallback& callback) {
340 base::MessageLoop::current()->PostTask(
341 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
344 void FakeCryptohomeClient::AsyncTpmAttestationCreateEnrollRequest(
345 chromeos::attestation::PrivacyCAType pca_type,
346 const AsyncMethodCallback& callback) {
347 ReturnAsyncMethodResult(callback, true);
350 void FakeCryptohomeClient::AsyncTpmAttestationEnroll(
351 chromeos::attestation::PrivacyCAType pca_type,
352 const std::string& pca_response,
353 const AsyncMethodCallback& callback) {
354 ReturnAsyncMethodResult(callback, false);
357 void FakeCryptohomeClient::AsyncTpmAttestationCreateCertRequest(
358 chromeos::attestation::PrivacyCAType pca_type,
359 attestation::AttestationCertificateProfile certificate_profile,
360 const std::string& user_id,
361 const std::string& request_origin,
362 const AsyncMethodCallback& callback) {
363 ReturnAsyncMethodResult(callback, true);
366 void FakeCryptohomeClient::AsyncTpmAttestationFinishCertRequest(
367 const std::string& pca_response,
368 attestation::AttestationKeyType key_type,
369 const std::string& user_id,
370 const std::string& key_name,
371 const AsyncMethodCallback& callback) {
372 ReturnAsyncMethodResult(callback, true);
375 void FakeCryptohomeClient::TpmAttestationDoesKeyExist(
376 attestation::AttestationKeyType key_type,
377 const std::string& user_id,
378 const std::string& key_name,
379 const BoolDBusMethodCallback& callback) {
380 base::MessageLoop::current()->PostTask(
381 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
384 void FakeCryptohomeClient::TpmAttestationGetCertificate(
385 attestation::AttestationKeyType key_type,
386 const std::string& user_id,
387 const std::string& key_name,
388 const DataMethodCallback& callback) {
389 base::MessageLoop::current()->PostTask(
390 FROM_HERE,
391 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
394 void FakeCryptohomeClient::TpmAttestationGetPublicKey(
395 attestation::AttestationKeyType key_type,
396 const std::string& user_id,
397 const std::string& key_name,
398 const DataMethodCallback& callback) {
399 base::MessageLoop::current()->PostTask(
400 FROM_HERE,
401 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
404 void FakeCryptohomeClient::TpmAttestationRegisterKey(
405 attestation::AttestationKeyType key_type,
406 const std::string& user_id,
407 const std::string& key_name,
408 const AsyncMethodCallback& callback) {
409 ReturnAsyncMethodResult(callback, true);
412 void FakeCryptohomeClient::TpmAttestationSignEnterpriseChallenge(
413 attestation::AttestationKeyType key_type,
414 const std::string& user_id,
415 const std::string& key_name,
416 const std::string& domain,
417 const std::string& device_id,
418 attestation::AttestationChallengeOptions options,
419 const std::string& challenge,
420 const AsyncMethodCallback& callback) {
421 ReturnAsyncMethodResult(callback, true);
424 void FakeCryptohomeClient::TpmAttestationSignSimpleChallenge(
425 attestation::AttestationKeyType key_type,
426 const std::string& user_id,
427 const std::string& key_name,
428 const std::string& challenge,
429 const AsyncMethodCallback& callback) {
430 ReturnAsyncMethodResult(callback, true);
433 void FakeCryptohomeClient::TpmAttestationGetKeyPayload(
434 attestation::AttestationKeyType key_type,
435 const std::string& user_id,
436 const std::string& key_name,
437 const DataMethodCallback& callback) {
438 base::MessageLoop::current()->PostTask(
439 FROM_HERE,
440 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
443 void FakeCryptohomeClient::TpmAttestationSetKeyPayload(
444 attestation::AttestationKeyType key_type,
445 const std::string& user_id,
446 const std::string& key_name,
447 const std::string& payload,
448 const BoolDBusMethodCallback& callback) {
449 base::MessageLoop::current()->PostTask(
450 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
453 void FakeCryptohomeClient::TpmAttestationDeleteKeys(
454 attestation::AttestationKeyType key_type,
455 const std::string& user_id,
456 const std::string& key_prefix,
457 const BoolDBusMethodCallback& callback) {
458 base::MessageLoop::current()->PostTask(
459 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
462 void FakeCryptohomeClient::GetKeyDataEx(
463 const cryptohome::AccountIdentifier& id,
464 const cryptohome::AuthorizationRequest& auth,
465 const cryptohome::GetKeyDataRequest& request,
466 const ProtobufMethodCallback& callback) {
467 cryptohome::BaseReply reply;
468 reply.MutableExtension(cryptohome::GetKeyDataReply::reply);
469 ReturnProtobufMethodCallback(reply, callback);
472 void FakeCryptohomeClient::CheckKeyEx(
473 const cryptohome::AccountIdentifier& id,
474 const cryptohome::AuthorizationRequest& auth,
475 const cryptohome::CheckKeyRequest& request,
476 const ProtobufMethodCallback& callback) {
477 cryptohome::BaseReply reply;
478 ReturnProtobufMethodCallback(reply, callback);
481 void FakeCryptohomeClient::MountEx(
482 const cryptohome::AccountIdentifier& id,
483 const cryptohome::AuthorizationRequest& auth,
484 const cryptohome::MountRequest& request,
485 const ProtobufMethodCallback& callback) {
486 cryptohome::BaseReply reply;
487 cryptohome::MountReply* mount =
488 reply.MutableExtension(cryptohome::MountReply::reply);
489 mount->set_sanitized_username(GetStubSanitizedUsername(id.email()));
490 ReturnProtobufMethodCallback(reply, callback);
493 void FakeCryptohomeClient::AddKeyEx(
494 const cryptohome::AccountIdentifier& id,
495 const cryptohome::AuthorizationRequest& auth,
496 const cryptohome::AddKeyRequest& request,
497 const ProtobufMethodCallback& callback) {
498 cryptohome::BaseReply reply;
499 ReturnProtobufMethodCallback(reply, callback);
502 void FakeCryptohomeClient::RemoveKeyEx(
503 const cryptohome::AccountIdentifier& id,
504 const cryptohome::AuthorizationRequest& auth,
505 const cryptohome::RemoveKeyRequest& request,
506 const ProtobufMethodCallback& callback) {
507 cryptohome::BaseReply reply;
508 ReturnProtobufMethodCallback(reply, callback);
511 void FakeCryptohomeClient::UpdateKeyEx(
512 const cryptohome::AccountIdentifier& id,
513 const cryptohome::AuthorizationRequest& auth,
514 const cryptohome::UpdateKeyRequest& request,
515 const ProtobufMethodCallback& callback) {
516 cryptohome::BaseReply reply;
517 ReturnProtobufMethodCallback(reply, callback);
520 void FakeCryptohomeClient::GetBootAttribute(
521 const cryptohome::GetBootAttributeRequest& request,
522 const ProtobufMethodCallback& callback) {
523 cryptohome::BaseReply reply;
524 cryptohome::GetBootAttributeReply* attr_reply =
525 reply.MutableExtension(cryptohome::GetBootAttributeReply::reply);
526 attr_reply->set_value("");
527 ReturnProtobufMethodCallback(reply, callback);
530 void FakeCryptohomeClient::SetBootAttribute(
531 const cryptohome::SetBootAttributeRequest& request,
532 const ProtobufMethodCallback& callback) {
533 cryptohome::BaseReply reply;
534 ReturnProtobufMethodCallback(reply, callback);
537 void FakeCryptohomeClient::FlushAndSignBootAttributes(
538 const cryptohome::FlushAndSignBootAttributesRequest& request,
539 const ProtobufMethodCallback& callback) {
540 cryptohome::BaseReply reply;
541 ReturnProtobufMethodCallback(reply, callback);
544 void FakeCryptohomeClient::SetServiceIsAvailable(bool is_available) {
545 service_is_available_ = is_available;
546 if (is_available) {
547 std::vector<WaitForServiceToBeAvailableCallback> callbacks;
548 callbacks.swap(pending_wait_for_service_to_be_available_callbacks_);
549 for (size_t i = 0; i < callbacks.size(); ++i)
550 callbacks[i].Run(is_available);
554 // static
555 std::vector<uint8> FakeCryptohomeClient::GetStubSystemSalt() {
556 const char kStubSystemSalt[] = "stub_system_salt";
557 return std::vector<uint8>(kStubSystemSalt,
558 kStubSystemSalt + arraysize(kStubSystemSalt) - 1);
561 void FakeCryptohomeClient::ReturnProtobufMethodCallback(
562 const cryptohome::BaseReply& reply,
563 const ProtobufMethodCallback& callback) {
564 base::MessageLoop::current()->PostTask(
565 FROM_HERE,
566 base::Bind(callback,
567 DBUS_METHOD_CALL_SUCCESS,
568 true,
569 reply));
572 void FakeCryptohomeClient::ReturnAsyncMethodResult(
573 const AsyncMethodCallback& callback,
574 bool returns_data) {
575 base::MessageLoop::current()->PostTask(
576 FROM_HERE,
577 base::Bind(&FakeCryptohomeClient::ReturnAsyncMethodResultInternal,
578 weak_ptr_factory_.GetWeakPtr(),
579 callback,
580 returns_data));
583 void FakeCryptohomeClient::ReturnAsyncMethodResultInternal(
584 const AsyncMethodCallback& callback,
585 bool returns_data) {
586 callback.Run(async_call_id_);
587 if (!returns_data && !async_call_status_handler_.is_null()) {
588 base::MessageLoop::current()->PostTask(
589 FROM_HERE,
590 base::Bind(async_call_status_handler_,
591 async_call_id_,
592 true,
593 cryptohome::MOUNT_ERROR_NONE));
594 } else if (returns_data && !async_call_status_data_handler_.is_null()) {
595 base::MessageLoop::current()->PostTask(
596 FROM_HERE,
597 base::Bind(async_call_status_data_handler_,
598 async_call_id_,
599 true,
600 std::string()));
602 ++async_call_id_;
605 } // namespace chromeos