Add an extension override bubble and warning box for proxy extensions.
[chromium-blink-merge.git] / chromeos / dbus / fake_cryptohome_client.cc
blob1796e0429c1ba7f27732344ad75df07d87b117b8
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/worker_pool.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 {
24 // Helper to asynchronously write a file in the WorkerPool.
25 void PersistFile(const base::FilePath& path, const std::string& content) {
26 base::WriteFile(path, content.data(), content.size());
29 } // namespace
31 namespace chromeos {
33 FakeCryptohomeClient::FakeCryptohomeClient()
34 : service_is_available_(true),
35 async_call_id_(1),
36 tpm_is_ready_counter_(0),
37 unmount_result_(true),
38 system_salt_(GetStubSystemSalt()),
39 weak_ptr_factory_(this) {
40 base::FilePath cache_path;
41 locked_ = PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path) &&
42 base::PathExists(cache_path);
45 FakeCryptohomeClient::~FakeCryptohomeClient() {}
47 void FakeCryptohomeClient::Init(dbus::Bus* bus) {
50 void FakeCryptohomeClient::SetAsyncCallStatusHandlers(
51 const AsyncCallStatusHandler& handler,
52 const AsyncCallStatusWithDataHandler& data_handler) {
53 async_call_status_handler_ = handler;
54 async_call_status_data_handler_ = data_handler;
57 void FakeCryptohomeClient::ResetAsyncCallStatusHandlers() {
58 async_call_status_handler_.Reset();
59 async_call_status_data_handler_.Reset();
62 void FakeCryptohomeClient::WaitForServiceToBeAvailable(
63 const WaitForServiceToBeAvailableCallback& callback) {
64 if (service_is_available_) {
65 base::MessageLoop::current()->PostTask(FROM_HERE,
66 base::Bind(callback, true));
67 } else {
68 pending_wait_for_service_to_be_available_callbacks_.push_back(callback);
72 void FakeCryptohomeClient::IsMounted(
73 const BoolDBusMethodCallback& callback) {
74 base::MessageLoop::current()->PostTask(
75 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
78 bool FakeCryptohomeClient::Unmount(bool* success) {
79 *success = unmount_result_;
80 return true;
83 void FakeCryptohomeClient::AsyncCheckKey(
84 const std::string& username,
85 const std::string& key,
86 const AsyncMethodCallback& callback) {
87 ReturnAsyncMethodResult(callback, false);
90 void FakeCryptohomeClient::AsyncMigrateKey(
91 const std::string& username,
92 const std::string& from_key,
93 const std::string& to_key,
94 const AsyncMethodCallback& callback) {
95 ReturnAsyncMethodResult(callback, false);
98 void FakeCryptohomeClient::AsyncRemove(
99 const std::string& username,
100 const AsyncMethodCallback& callback) {
101 ReturnAsyncMethodResult(callback, false);
104 void FakeCryptohomeClient::GetSystemSalt(
105 const GetSystemSaltCallback& callback) {
106 base::MessageLoop::current()->PostTask(
107 FROM_HERE,
108 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, system_salt_));
111 void FakeCryptohomeClient::GetSanitizedUsername(
112 const std::string& username,
113 const StringDBusMethodCallback& callback) {
114 // Even for stub implementation we have to return different values so that
115 // multi-profiles would work.
116 std::string sanitized_username = GetStubSanitizedUsername(username);
117 base::MessageLoop::current()->PostTask(
118 FROM_HERE,
119 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, sanitized_username));
122 std::string FakeCryptohomeClient::BlockingGetSanitizedUsername(
123 const std::string& username) {
124 return GetStubSanitizedUsername(username);
127 void FakeCryptohomeClient::AsyncMount(const std::string& username,
128 const std::string& key,
129 int flags,
130 const AsyncMethodCallback& callback) {
131 ReturnAsyncMethodResult(callback, false);
134 void FakeCryptohomeClient::AsyncAddKey(
135 const std::string& username,
136 const std::string& key,
137 const std::string& new_key,
138 const AsyncMethodCallback& callback) {
139 ReturnAsyncMethodResult(callback, false);
142 void FakeCryptohomeClient::AsyncMountGuest(
143 const AsyncMethodCallback& callback) {
144 ReturnAsyncMethodResult(callback, false);
147 void FakeCryptohomeClient::AsyncMountPublic(
148 const std::string& public_mount_id,
149 int flags,
150 const AsyncMethodCallback& callback) {
151 ReturnAsyncMethodResult(callback, false);
154 void FakeCryptohomeClient::TpmIsReady(
155 const BoolDBusMethodCallback& callback) {
156 base::MessageLoop::current()->PostTask(
157 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
160 void FakeCryptohomeClient::TpmIsEnabled(
161 const BoolDBusMethodCallback& callback) {
162 base::MessageLoop::current()->PostTask(
163 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
166 bool FakeCryptohomeClient::CallTpmIsEnabledAndBlock(bool* enabled) {
167 *enabled = true;
168 return true;
171 void FakeCryptohomeClient::TpmGetPassword(
172 const StringDBusMethodCallback& callback) {
173 const char kStubTpmPassword[] = "Stub-TPM-password";
174 base::MessageLoop::current()->PostTask(
175 FROM_HERE,
176 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS,
177 std::string(kStubTpmPassword)));
180 void FakeCryptohomeClient::TpmIsOwned(
181 const BoolDBusMethodCallback& callback) {
182 base::MessageLoop::current()->PostTask(
183 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
186 bool FakeCryptohomeClient::CallTpmIsOwnedAndBlock(bool* owned) {
187 *owned = true;
188 return true;
191 void FakeCryptohomeClient::TpmIsBeingOwned(
192 const BoolDBusMethodCallback& callback) {
193 base::MessageLoop::current()->PostTask(
194 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
197 bool FakeCryptohomeClient::CallTpmIsBeingOwnedAndBlock(bool* owning) {
198 *owning = true;
199 return true;
202 void FakeCryptohomeClient::TpmCanAttemptOwnership(
203 const VoidDBusMethodCallback& callback) {
204 base::MessageLoop::current()->PostTask(
205 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
208 void FakeCryptohomeClient::TpmClearStoredPassword(
209 const VoidDBusMethodCallback& callback) {
210 base::MessageLoop::current()->PostTask(
211 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
214 bool FakeCryptohomeClient::CallTpmClearStoredPasswordAndBlock() {
215 return true;
218 void FakeCryptohomeClient::Pkcs11IsTpmTokenReady(
219 const BoolDBusMethodCallback& callback) {
220 base::MessageLoop::current()->PostTask(
221 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
224 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfo(
225 const Pkcs11GetTpmTokenInfoCallback& callback) {
226 const char kStubUserPin[] = "012345";
227 const int kStubSlot = 0;
228 base::MessageLoop::current()->PostTask(
229 FROM_HERE,
230 base::Bind(callback,
231 DBUS_METHOD_CALL_SUCCESS,
232 std::string(crypto::kTestTPMTokenName),
233 std::string(kStubUserPin),
234 kStubSlot));
237 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfoForUser(
238 const std::string& username,
239 const Pkcs11GetTpmTokenInfoCallback& callback) {
240 Pkcs11GetTpmTokenInfo(callback);
243 bool FakeCryptohomeClient::InstallAttributesGet(const std::string& name,
244 std::vector<uint8>* value,
245 bool* successful) {
246 if (install_attrs_.find(name) != install_attrs_.end()) {
247 *value = install_attrs_[name];
248 *successful = true;
249 } else {
250 value->clear();
251 *successful = false;
253 return true;
256 bool FakeCryptohomeClient::InstallAttributesSet(
257 const std::string& name,
258 const std::vector<uint8>& value,
259 bool* successful) {
260 install_attrs_[name] = value;
261 *successful = true;
262 return true;
265 bool FakeCryptohomeClient::InstallAttributesFinalize(bool* successful) {
266 locked_ = true;
267 *successful = true;
269 // Persist the install attributes so that they can be reloaded if the
270 // browser is restarted. This is used for ease of development when device
271 // enrollment is required.
272 // The cryptohome::SerializedInstallAttributes protobuf lives in
273 // chrome/browser/chromeos, so it can't be used directly here; use the
274 // low-level protobuf API instead to just write the name-value pairs.
275 // The cache file is read by EnterpriseInstallAttributes::ReadCacheFile.
276 base::FilePath cache_path;
277 if (!PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path))
278 return false;
280 std::string result;
282 // |result| can be used only after the StringOutputStream goes out of
283 // scope.
284 google::protobuf::io::StringOutputStream result_stream(&result);
285 google::protobuf::io::CodedOutputStream result_output(&result_stream);
287 // These tags encode a variable-length value on the wire, which can be
288 // used to encode strings, bytes and messages. We only needs constants
289 // for tag numbers 1 and 2 (see install_attributes.proto).
290 const int kVarLengthTag1 = (1 << 3) | 0x2;
291 const int kVarLengthTag2 = (2 << 3) | 0x2;
293 typedef std::map<std::string, std::vector<uint8> >::const_iterator Iter;
294 for (Iter it = install_attrs_.begin(); it != install_attrs_.end(); ++it) {
295 std::string attr;
297 google::protobuf::io::StringOutputStream attr_stream(&attr);
298 google::protobuf::io::CodedOutputStream attr_output(&attr_stream);
300 attr_output.WriteVarint32(kVarLengthTag1);
301 attr_output.WriteVarint32(it->first.size());
302 attr_output.WriteString(it->first);
303 attr_output.WriteVarint32(kVarLengthTag2);
304 attr_output.WriteVarint32(it->second.size());
305 attr_output.WriteRaw(it->second.data(), it->second.size());
308 // Two CodedOutputStreams are needed because inner messages must be
309 // prefixed by their total length, which can't be easily computed before
310 // writing their tags and values.
311 result_output.WriteVarint32(kVarLengthTag2);
312 result_output.WriteVarint32(attr.size());
313 result_output.WriteRaw(attr.data(), attr.size());
317 base::WorkerPool::PostTask(
318 FROM_HERE, base::Bind(&PersistFile, cache_path, result), false);
320 return true;
323 void FakeCryptohomeClient::InstallAttributesIsReady(
324 const BoolDBusMethodCallback& callback) {
325 base::MessageLoop::current()->PostTask(
326 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
329 bool FakeCryptohomeClient::InstallAttributesIsInvalid(bool* is_invalid) {
330 *is_invalid = false;
331 return true;
334 bool FakeCryptohomeClient::InstallAttributesIsFirstInstall(
335 bool* is_first_install) {
336 *is_first_install = !locked_;
337 return true;
340 void FakeCryptohomeClient::TpmAttestationIsPrepared(
341 const BoolDBusMethodCallback& callback) {
342 base::MessageLoop::current()->PostTask(
343 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
346 void FakeCryptohomeClient::TpmAttestationIsEnrolled(
347 const BoolDBusMethodCallback& callback) {
348 base::MessageLoop::current()->PostTask(
349 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
352 void FakeCryptohomeClient::AsyncTpmAttestationCreateEnrollRequest(
353 chromeos::attestation::PrivacyCAType pca_type,
354 const AsyncMethodCallback& callback) {
355 ReturnAsyncMethodResult(callback, true);
358 void FakeCryptohomeClient::AsyncTpmAttestationEnroll(
359 chromeos::attestation::PrivacyCAType pca_type,
360 const std::string& pca_response,
361 const AsyncMethodCallback& callback) {
362 ReturnAsyncMethodResult(callback, false);
365 void FakeCryptohomeClient::AsyncTpmAttestationCreateCertRequest(
366 chromeos::attestation::PrivacyCAType pca_type,
367 attestation::AttestationCertificateProfile certificate_profile,
368 const std::string& user_id,
369 const std::string& request_origin,
370 const AsyncMethodCallback& callback) {
371 ReturnAsyncMethodResult(callback, true);
374 void FakeCryptohomeClient::AsyncTpmAttestationFinishCertRequest(
375 const std::string& pca_response,
376 attestation::AttestationKeyType key_type,
377 const std::string& user_id,
378 const std::string& key_name,
379 const AsyncMethodCallback& callback) {
380 ReturnAsyncMethodResult(callback, true);
383 void FakeCryptohomeClient::TpmAttestationDoesKeyExist(
384 attestation::AttestationKeyType key_type,
385 const std::string& user_id,
386 const std::string& key_name,
387 const BoolDBusMethodCallback& callback) {
388 base::MessageLoop::current()->PostTask(
389 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
392 void FakeCryptohomeClient::TpmAttestationGetCertificate(
393 attestation::AttestationKeyType key_type,
394 const std::string& user_id,
395 const std::string& key_name,
396 const DataMethodCallback& callback) {
397 base::MessageLoop::current()->PostTask(
398 FROM_HERE,
399 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
402 void FakeCryptohomeClient::TpmAttestationGetPublicKey(
403 attestation::AttestationKeyType key_type,
404 const std::string& user_id,
405 const std::string& key_name,
406 const DataMethodCallback& callback) {
407 base::MessageLoop::current()->PostTask(
408 FROM_HERE,
409 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
412 void FakeCryptohomeClient::TpmAttestationRegisterKey(
413 attestation::AttestationKeyType key_type,
414 const std::string& user_id,
415 const std::string& key_name,
416 const AsyncMethodCallback& callback) {
417 ReturnAsyncMethodResult(callback, true);
420 void FakeCryptohomeClient::TpmAttestationSignEnterpriseChallenge(
421 attestation::AttestationKeyType key_type,
422 const std::string& user_id,
423 const std::string& key_name,
424 const std::string& domain,
425 const std::string& device_id,
426 attestation::AttestationChallengeOptions options,
427 const std::string& challenge,
428 const AsyncMethodCallback& callback) {
429 ReturnAsyncMethodResult(callback, true);
432 void FakeCryptohomeClient::TpmAttestationSignSimpleChallenge(
433 attestation::AttestationKeyType key_type,
434 const std::string& user_id,
435 const std::string& key_name,
436 const std::string& challenge,
437 const AsyncMethodCallback& callback) {
438 ReturnAsyncMethodResult(callback, true);
441 void FakeCryptohomeClient::TpmAttestationGetKeyPayload(
442 attestation::AttestationKeyType key_type,
443 const std::string& user_id,
444 const std::string& key_name,
445 const DataMethodCallback& callback) {
446 base::MessageLoop::current()->PostTask(
447 FROM_HERE,
448 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
451 void FakeCryptohomeClient::TpmAttestationSetKeyPayload(
452 attestation::AttestationKeyType key_type,
453 const std::string& user_id,
454 const std::string& key_name,
455 const std::string& payload,
456 const BoolDBusMethodCallback& callback) {
457 base::MessageLoop::current()->PostTask(
458 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
461 void FakeCryptohomeClient::TpmAttestationDeleteKeys(
462 attestation::AttestationKeyType key_type,
463 const std::string& user_id,
464 const std::string& key_prefix,
465 const BoolDBusMethodCallback& callback) {
466 base::MessageLoop::current()->PostTask(
467 FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
470 void FakeCryptohomeClient::CheckKeyEx(
471 const cryptohome::AccountIdentifier& id,
472 const cryptohome::AuthorizationRequest& auth,
473 const cryptohome::CheckKeyRequest& request,
474 const ProtobufMethodCallback& callback) {
475 ReturnProtobufMethodCallback(id.email(), callback);
478 void FakeCryptohomeClient::MountEx(
479 const cryptohome::AccountIdentifier& id,
480 const cryptohome::AuthorizationRequest& auth,
481 const cryptohome::MountRequest& request,
482 const ProtobufMethodCallback& callback) {
483 ReturnProtobufMethodCallback(id.email(), callback);
486 void FakeCryptohomeClient::AddKeyEx(
487 const cryptohome::AccountIdentifier& id,
488 const cryptohome::AuthorizationRequest& auth,
489 const cryptohome::AddKeyRequest& request,
490 const ProtobufMethodCallback& callback) {
491 ReturnProtobufMethodCallback(id.email(), callback);
494 void FakeCryptohomeClient::RemoveKeyEx(
495 const cryptohome::AccountIdentifier& id,
496 const cryptohome::AuthorizationRequest& auth,
497 const cryptohome::RemoveKeyRequest& request,
498 const ProtobufMethodCallback& callback) {
499 ReturnProtobufMethodCallback(id.email(), 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 ReturnProtobufMethodCallback(id.email(), callback);
510 void FakeCryptohomeClient::SetServiceIsAvailable(bool is_available) {
511 service_is_available_ = is_available;
512 if (is_available) {
513 std::vector<WaitForServiceToBeAvailableCallback> callbacks;
514 callbacks.swap(pending_wait_for_service_to_be_available_callbacks_);
515 for (size_t i = 0; i < callbacks.size(); ++i)
516 callbacks[i].Run(is_available);
520 // static
521 std::vector<uint8> FakeCryptohomeClient::GetStubSystemSalt() {
522 const char kStubSystemSalt[] = "stub_system_salt";
523 return std::vector<uint8>(kStubSystemSalt,
524 kStubSystemSalt + arraysize(kStubSystemSalt) - 1);
527 void FakeCryptohomeClient::ReturnProtobufMethodCallback(
528 const std::string& userid,
529 const ProtobufMethodCallback& callback) {
530 cryptohome::BaseReply reply;
531 reply.set_error(cryptohome::CRYPTOHOME_ERROR_NOT_SET);
532 cryptohome::MountReply* mount =
533 reply.MutableExtension(cryptohome::MountReply::reply);
534 mount->set_sanitized_username(GetStubSanitizedUsername(userid));
535 base::MessageLoop::current()->PostTask(
536 FROM_HERE,
537 base::Bind(callback,
538 DBUS_METHOD_CALL_SUCCESS,
539 true,
540 reply));
543 void FakeCryptohomeClient::ReturnAsyncMethodResult(
544 const AsyncMethodCallback& callback,
545 bool returns_data) {
546 base::MessageLoop::current()->PostTask(
547 FROM_HERE,
548 base::Bind(&FakeCryptohomeClient::ReturnAsyncMethodResultInternal,
549 weak_ptr_factory_.GetWeakPtr(),
550 callback,
551 returns_data));
554 void FakeCryptohomeClient::ReturnAsyncMethodResultInternal(
555 const AsyncMethodCallback& callback,
556 bool returns_data) {
557 callback.Run(async_call_id_);
558 if (!returns_data && !async_call_status_handler_.is_null()) {
559 base::MessageLoop::current()->PostTask(
560 FROM_HERE,
561 base::Bind(async_call_status_handler_,
562 async_call_id_,
563 true,
564 cryptohome::MOUNT_ERROR_NONE));
565 } else if (returns_data && !async_call_status_data_handler_.is_null()) {
566 base::MessageLoop::current()->PostTask(
567 FROM_HERE,
568 base::Bind(async_call_status_data_handler_,
569 async_call_id_,
570 true,
571 std::string()));
573 ++async_call_id_;
576 } // namespace chromeos