Fix compilation error encountered when DEBUG set to 1.
[chromium-blink-merge.git] / chromeos / dbus / fake_cryptohome_client.cc
blob3e6fefafe38efd4f7e229cc930c8145e1b3eff89
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/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 "crypto/nss_util.h"
17 #include "third_party/cros_system_api/dbus/service_constants.h"
18 #include "third_party/protobuf/src/google/protobuf/io/coded_stream.h"
19 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h"
20 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
22 namespace chromeos {
24 FakeCryptohomeClient::FakeCryptohomeClient()
25 : service_is_available_(true),
26 async_call_id_(1),
27 tpm_is_ready_counter_(0),
28 unmount_result_(true),
29 system_salt_(GetStubSystemSalt()),
30 weak_ptr_factory_(this) {
31 base::FilePath cache_path;
32 locked_ = PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path) &&
33 base::PathExists(cache_path);
36 FakeCryptohomeClient::~FakeCryptohomeClient() {}
38 void FakeCryptohomeClient::Init(dbus::Bus* bus) {
41 void FakeCryptohomeClient::SetAsyncCallStatusHandlers(
42 const AsyncCallStatusHandler& handler,
43 const AsyncCallStatusWithDataHandler& data_handler) {
44 async_call_status_handler_ = handler;
45 async_call_status_data_handler_ = data_handler;
48 void FakeCryptohomeClient::ResetAsyncCallStatusHandlers() {
49 async_call_status_handler_.Reset();
50 async_call_status_data_handler_.Reset();
53 void FakeCryptohomeClient::WaitForServiceToBeAvailable(
54 const WaitForServiceToBeAvailableCallback& callback) {
55 if (service_is_available_) {
56 base::MessageLoop::current()->PostTask(FROM_HERE,
57 base::Bind(callback, true));
58 } else {
59 pending_wait_for_service_to_be_available_callbacks_.push_back(callback);
63 void FakeCryptohomeClient::IsMounted(
64 const BoolDBusMethodCallback& callback) {
65 base::MessageLoop::current()->PostTask(
66 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
69 bool FakeCryptohomeClient::Unmount(bool* success) {
70 *success = unmount_result_;
71 return true;
74 void FakeCryptohomeClient::AsyncCheckKey(
75 const std::string& username,
76 const std::string& key,
77 const AsyncMethodCallback& callback) {
78 ReturnAsyncMethodResult(callback, false);
81 void FakeCryptohomeClient::AsyncMigrateKey(
82 const std::string& username,
83 const std::string& from_key,
84 const std::string& to_key,
85 const AsyncMethodCallback& callback) {
86 ReturnAsyncMethodResult(callback, false);
89 void FakeCryptohomeClient::AsyncRemove(
90 const std::string& username,
91 const AsyncMethodCallback& callback) {
92 ReturnAsyncMethodResult(callback, false);
95 void FakeCryptohomeClient::GetSystemSalt(
96 const GetSystemSaltCallback& callback) {
97 base::MessageLoop::current()->PostTask(
98 FROM_HERE,
99 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, system_salt_));
102 void FakeCryptohomeClient::GetSanitizedUsername(
103 const std::string& username,
104 const StringDBusMethodCallback& callback) {
105 // Even for stub implementation we have to return different values so that
106 // multi-profiles would work.
107 std::string sanitized_username = GetStubSanitizedUsername(username);
108 base::MessageLoop::current()->PostTask(
109 FROM_HERE,
110 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, sanitized_username));
113 std::string FakeCryptohomeClient::BlockingGetSanitizedUsername(
114 const std::string& username) {
115 return GetStubSanitizedUsername(username);
118 void FakeCryptohomeClient::AsyncMount(const std::string& username,
119 const std::string& key,
120 int flags,
121 const AsyncMethodCallback& callback) {
122 ReturnAsyncMethodResult(callback, false);
125 void FakeCryptohomeClient::AsyncAddKey(
126 const std::string& username,
127 const std::string& key,
128 const std::string& new_key,
129 const AsyncMethodCallback& callback) {
130 ReturnAsyncMethodResult(callback, false);
133 void FakeCryptohomeClient::AsyncMountGuest(
134 const AsyncMethodCallback& callback) {
135 ReturnAsyncMethodResult(callback, false);
138 void FakeCryptohomeClient::AsyncMountPublic(
139 const std::string& public_mount_id,
140 int flags,
141 const AsyncMethodCallback& callback) {
142 ReturnAsyncMethodResult(callback, false);
145 void FakeCryptohomeClient::TpmIsReady(
146 const BoolDBusMethodCallback& callback) {
147 base::MessageLoop::current()->PostTask(
148 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
151 void FakeCryptohomeClient::TpmIsEnabled(
152 const BoolDBusMethodCallback& callback) {
153 base::MessageLoop::current()->PostTask(
154 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
157 bool FakeCryptohomeClient::CallTpmIsEnabledAndBlock(bool* enabled) {
158 *enabled = true;
159 return true;
162 void FakeCryptohomeClient::TpmGetPassword(
163 const StringDBusMethodCallback& callback) {
164 const char kStubTpmPassword[] = "Stub-TPM-password";
165 base::MessageLoop::current()->PostTask(
166 FROM_HERE,
167 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS,
168 std::string(kStubTpmPassword)));
171 void FakeCryptohomeClient::TpmIsOwned(
172 const BoolDBusMethodCallback& callback) {
173 base::MessageLoop::current()->PostTask(
174 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
177 bool FakeCryptohomeClient::CallTpmIsOwnedAndBlock(bool* owned) {
178 *owned = true;
179 return true;
182 void FakeCryptohomeClient::TpmIsBeingOwned(
183 const BoolDBusMethodCallback& callback) {
184 base::MessageLoop::current()->PostTask(
185 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
188 bool FakeCryptohomeClient::CallTpmIsBeingOwnedAndBlock(bool* owning) {
189 *owning = true;
190 return true;
193 void FakeCryptohomeClient::TpmCanAttemptOwnership(
194 const VoidDBusMethodCallback& callback) {
195 base::MessageLoop::current()->PostTask(
196 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
199 void FakeCryptohomeClient::TpmClearStoredPassword(
200 const VoidDBusMethodCallback& callback) {
201 base::MessageLoop::current()->PostTask(
202 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
205 bool FakeCryptohomeClient::CallTpmClearStoredPasswordAndBlock() {
206 return true;
209 void FakeCryptohomeClient::Pkcs11IsTpmTokenReady(
210 const BoolDBusMethodCallback& callback) {
211 base::MessageLoop::current()->PostTask(
212 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
215 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfo(
216 const Pkcs11GetTpmTokenInfoCallback& callback) {
217 const char kStubUserPin[] = "012345";
218 const int kStubSlot = 0;
219 base::MessageLoop::current()->PostTask(
220 FROM_HERE,
221 base::Bind(callback,
222 DBUS_METHOD_CALL_SUCCESS,
223 std::string(crypto::kTestTPMTokenName),
224 std::string(kStubUserPin),
225 kStubSlot));
228 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfoForUser(
229 const std::string& username,
230 const Pkcs11GetTpmTokenInfoCallback& callback) {
231 Pkcs11GetTpmTokenInfo(callback);
234 bool FakeCryptohomeClient::InstallAttributesGet(const std::string& name,
235 std::vector<uint8>* value,
236 bool* successful) {
237 if (install_attrs_.find(name) != install_attrs_.end()) {
238 *value = install_attrs_[name];
239 *successful = true;
240 } else {
241 value->clear();
242 *successful = false;
244 return true;
247 bool FakeCryptohomeClient::InstallAttributesSet(
248 const std::string& name,
249 const std::vector<uint8>& value,
250 bool* successful) {
251 install_attrs_[name] = value;
252 *successful = true;
253 return true;
256 bool FakeCryptohomeClient::InstallAttributesFinalize(bool* successful) {
257 locked_ = true;
258 *successful = true;
260 // Persist the install attributes so that they can be reloaded if the
261 // browser is restarted. This is used for ease of development when device
262 // enrollment is required.
263 // The cryptohome::SerializedInstallAttributes protobuf lives in
264 // chrome/browser/chromeos, so it can't be used directly here; use the
265 // low-level protobuf API instead to just write the name-value pairs.
266 // The cache file is read by EnterpriseInstallAttributes::ReadCacheFile.
267 base::FilePath cache_path;
268 if (!PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path))
269 return false;
271 std::string result;
273 // |result| can be used only after the StringOutputStream goes out of
274 // scope.
275 google::protobuf::io::StringOutputStream result_stream(&result);
276 google::protobuf::io::CodedOutputStream result_output(&result_stream);
278 // These tags encode a variable-length value on the wire, which can be
279 // used to encode strings, bytes and messages. We only needs constants
280 // for tag numbers 1 and 2 (see install_attributes.proto).
281 const int kVarLengthTag1 = (1 << 3) | 0x2;
282 const int kVarLengthTag2 = (2 << 3) | 0x2;
284 typedef std::map<std::string, std::vector<uint8> >::const_iterator Iter;
285 for (Iter it = install_attrs_.begin(); it != install_attrs_.end(); ++it) {
286 std::string attr;
288 google::protobuf::io::StringOutputStream attr_stream(&attr);
289 google::protobuf::io::CodedOutputStream attr_output(&attr_stream);
291 attr_output.WriteVarint32(kVarLengthTag1);
292 attr_output.WriteVarint32(it->first.size());
293 attr_output.WriteString(it->first);
294 attr_output.WriteVarint32(kVarLengthTag2);
295 attr_output.WriteVarint32(it->second.size());
296 attr_output.WriteRaw(it->second.data(), it->second.size());
299 // Two CodedOutputStreams are needed because inner messages must be
300 // prefixed by their total length, which can't be easily computed before
301 // writing their tags and values.
302 result_output.WriteVarint32(kVarLengthTag2);
303 result_output.WriteVarint32(attr.size());
304 result_output.WriteRaw(attr.data(), attr.size());
308 // The real implementation does a blocking wait on the dbus call; the fake
309 // implementation must have this file written before returning.
310 base::ThreadRestrictions::ScopedAllowIO allow_io;
311 base::WriteFile(cache_path, result.data(), result.size());
313 return true;
316 void FakeCryptohomeClient::InstallAttributesIsReady(
317 const BoolDBusMethodCallback& callback) {
318 base::MessageLoop::current()->PostTask(
319 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
322 bool FakeCryptohomeClient::InstallAttributesIsInvalid(bool* is_invalid) {
323 *is_invalid = false;
324 return true;
327 bool FakeCryptohomeClient::InstallAttributesIsFirstInstall(
328 bool* is_first_install) {
329 *is_first_install = !locked_;
330 return true;
333 void FakeCryptohomeClient::TpmAttestationIsPrepared(
334 const BoolDBusMethodCallback& callback) {
335 base::MessageLoop::current()->PostTask(
336 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
339 void FakeCryptohomeClient::TpmAttestationIsEnrolled(
340 const BoolDBusMethodCallback& callback) {
341 base::MessageLoop::current()->PostTask(
342 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
345 void FakeCryptohomeClient::AsyncTpmAttestationCreateEnrollRequest(
346 chromeos::attestation::PrivacyCAType pca_type,
347 const AsyncMethodCallback& callback) {
348 ReturnAsyncMethodResult(callback, true);
351 void FakeCryptohomeClient::AsyncTpmAttestationEnroll(
352 chromeos::attestation::PrivacyCAType pca_type,
353 const std::string& pca_response,
354 const AsyncMethodCallback& callback) {
355 ReturnAsyncMethodResult(callback, false);
358 void FakeCryptohomeClient::AsyncTpmAttestationCreateCertRequest(
359 chromeos::attestation::PrivacyCAType pca_type,
360 attestation::AttestationCertificateProfile certificate_profile,
361 const std::string& user_id,
362 const std::string& request_origin,
363 const AsyncMethodCallback& callback) {
364 ReturnAsyncMethodResult(callback, true);
367 void FakeCryptohomeClient::AsyncTpmAttestationFinishCertRequest(
368 const std::string& pca_response,
369 attestation::AttestationKeyType key_type,
370 const std::string& user_id,
371 const std::string& key_name,
372 const AsyncMethodCallback& callback) {
373 ReturnAsyncMethodResult(callback, true);
376 void FakeCryptohomeClient::TpmAttestationDoesKeyExist(
377 attestation::AttestationKeyType key_type,
378 const std::string& user_id,
379 const std::string& key_name,
380 const BoolDBusMethodCallback& callback) {
381 base::MessageLoop::current()->PostTask(
382 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
385 void FakeCryptohomeClient::TpmAttestationGetCertificate(
386 attestation::AttestationKeyType key_type,
387 const std::string& user_id,
388 const std::string& key_name,
389 const DataMethodCallback& callback) {
390 base::MessageLoop::current()->PostTask(
391 FROM_HERE,
392 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
395 void FakeCryptohomeClient::TpmAttestationGetPublicKey(
396 attestation::AttestationKeyType key_type,
397 const std::string& user_id,
398 const std::string& key_name,
399 const DataMethodCallback& callback) {
400 base::MessageLoop::current()->PostTask(
401 FROM_HERE,
402 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
405 void FakeCryptohomeClient::TpmAttestationRegisterKey(
406 attestation::AttestationKeyType key_type,
407 const std::string& user_id,
408 const std::string& key_name,
409 const AsyncMethodCallback& callback) {
410 ReturnAsyncMethodResult(callback, true);
413 void FakeCryptohomeClient::TpmAttestationSignEnterpriseChallenge(
414 attestation::AttestationKeyType key_type,
415 const std::string& user_id,
416 const std::string& key_name,
417 const std::string& domain,
418 const std::string& device_id,
419 attestation::AttestationChallengeOptions options,
420 const std::string& challenge,
421 const AsyncMethodCallback& callback) {
422 ReturnAsyncMethodResult(callback, true);
425 void FakeCryptohomeClient::TpmAttestationSignSimpleChallenge(
426 attestation::AttestationKeyType key_type,
427 const std::string& user_id,
428 const std::string& key_name,
429 const std::string& challenge,
430 const AsyncMethodCallback& callback) {
431 ReturnAsyncMethodResult(callback, true);
434 void FakeCryptohomeClient::TpmAttestationGetKeyPayload(
435 attestation::AttestationKeyType key_type,
436 const std::string& user_id,
437 const std::string& key_name,
438 const DataMethodCallback& callback) {
439 base::MessageLoop::current()->PostTask(
440 FROM_HERE,
441 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
444 void FakeCryptohomeClient::TpmAttestationSetKeyPayload(
445 attestation::AttestationKeyType key_type,
446 const std::string& user_id,
447 const std::string& key_name,
448 const std::string& payload,
449 const BoolDBusMethodCallback& callback) {
450 base::MessageLoop::current()->PostTask(
451 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
454 void FakeCryptohomeClient::TpmAttestationDeleteKeys(
455 attestation::AttestationKeyType key_type,
456 const std::string& user_id,
457 const std::string& key_prefix,
458 const BoolDBusMethodCallback& callback) {
459 base::MessageLoop::current()->PostTask(
460 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
463 void FakeCryptohomeClient::CheckKeyEx(
464 const cryptohome::AccountIdentifier& id,
465 const cryptohome::AuthorizationRequest& auth,
466 const cryptohome::CheckKeyRequest& request,
467 const ProtobufMethodCallback& callback) {
468 cryptohome::BaseReply reply;
469 ReturnProtobufMethodCallback(reply, callback);
472 void FakeCryptohomeClient::MountEx(
473 const cryptohome::AccountIdentifier& id,
474 const cryptohome::AuthorizationRequest& auth,
475 const cryptohome::MountRequest& request,
476 const ProtobufMethodCallback& callback) {
477 cryptohome::BaseReply reply;
478 cryptohome::MountReply* mount =
479 reply.MutableExtension(cryptohome::MountReply::reply);
480 mount->set_sanitized_username(GetStubSanitizedUsername(id.email()));
481 ReturnProtobufMethodCallback(reply, callback);
484 void FakeCryptohomeClient::AddKeyEx(
485 const cryptohome::AccountIdentifier& id,
486 const cryptohome::AuthorizationRequest& auth,
487 const cryptohome::AddKeyRequest& request,
488 const ProtobufMethodCallback& callback) {
489 cryptohome::BaseReply reply;
490 ReturnProtobufMethodCallback(reply, callback);
493 void FakeCryptohomeClient::RemoveKeyEx(
494 const cryptohome::AccountIdentifier& id,
495 const cryptohome::AuthorizationRequest& auth,
496 const cryptohome::RemoveKeyRequest& request,
497 const ProtobufMethodCallback& callback) {
498 cryptohome::BaseReply reply;
499 ReturnProtobufMethodCallback(reply, callback);
502 void FakeCryptohomeClient::UpdateKeyEx(
503 const cryptohome::AccountIdentifier& id,
504 const cryptohome::AuthorizationRequest& auth,
505 const cryptohome::UpdateKeyRequest& request,
506 const ProtobufMethodCallback& callback) {
507 cryptohome::BaseReply reply;
508 ReturnProtobufMethodCallback(reply, callback);
511 void FakeCryptohomeClient::GetBootAttribute(
512 const cryptohome::GetBootAttributeRequest& request,
513 const ProtobufMethodCallback& callback) {
514 cryptohome::BaseReply reply;
515 cryptohome::GetBootAttributeReply* attr_reply =
516 reply.MutableExtension(cryptohome::GetBootAttributeReply::reply);
517 attr_reply->set_value("");
518 ReturnProtobufMethodCallback(reply, callback);
521 void FakeCryptohomeClient::SetBootAttribute(
522 const cryptohome::SetBootAttributeRequest& request,
523 const ProtobufMethodCallback& callback) {
524 cryptohome::BaseReply reply;
525 ReturnProtobufMethodCallback(reply, callback);
528 void FakeCryptohomeClient::FlushAndSignBootAttributes(
529 const cryptohome::FlushAndSignBootAttributesRequest& request,
530 const ProtobufMethodCallback& callback) {
531 cryptohome::BaseReply reply;
532 ReturnProtobufMethodCallback(reply, callback);
535 void FakeCryptohomeClient::SetServiceIsAvailable(bool is_available) {
536 service_is_available_ = is_available;
537 if (is_available) {
538 std::vector<WaitForServiceToBeAvailableCallback> callbacks;
539 callbacks.swap(pending_wait_for_service_to_be_available_callbacks_);
540 for (size_t i = 0; i < callbacks.size(); ++i)
541 callbacks[i].Run(is_available);
545 // static
546 std::vector<uint8> FakeCryptohomeClient::GetStubSystemSalt() {
547 const char kStubSystemSalt[] = "stub_system_salt";
548 return std::vector<uint8>(kStubSystemSalt,
549 kStubSystemSalt + arraysize(kStubSystemSalt) - 1);
552 void FakeCryptohomeClient::ReturnProtobufMethodCallback(
553 const cryptohome::BaseReply& reply,
554 const ProtobufMethodCallback& callback) {
555 base::MessageLoop::current()->PostTask(
556 FROM_HERE,
557 base::Bind(callback,
558 DBUS_METHOD_CALL_SUCCESS,
559 true,
560 reply));
563 void FakeCryptohomeClient::ReturnAsyncMethodResult(
564 const AsyncMethodCallback& callback,
565 bool returns_data) {
566 base::MessageLoop::current()->PostTask(
567 FROM_HERE,
568 base::Bind(&FakeCryptohomeClient::ReturnAsyncMethodResultInternal,
569 weak_ptr_factory_.GetWeakPtr(),
570 callback,
571 returns_data));
574 void FakeCryptohomeClient::ReturnAsyncMethodResultInternal(
575 const AsyncMethodCallback& callback,
576 bool returns_data) {
577 callback.Run(async_call_id_);
578 if (!returns_data && !async_call_status_handler_.is_null()) {
579 base::MessageLoop::current()->PostTask(
580 FROM_HERE,
581 base::Bind(async_call_status_handler_,
582 async_call_id_,
583 true,
584 cryptohome::MOUNT_ERROR_NONE));
585 } else if (returns_data && !async_call_status_data_handler_.is_null()) {
586 base::MessageLoop::current()->PostTask(
587 FROM_HERE,
588 base::Bind(async_call_status_data_handler_,
589 async_call_id_,
590 true,
591 std::string()));
593 ++async_call_id_;
596 } // namespace chromeos