Don't preload rarely seen large images
[chromium-blink-merge.git] / chromeos / dbus / cryptohome_client.cc
blobe816b91052eb0e67521d6a6039d92505b6344a07
1 // Copyright (c) 2012 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/cryptohome_client.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "chromeos/cryptohome/async_method_caller.h"
12 #include "chromeos/dbus/blocking_method_caller.h"
13 #include "chromeos/dbus/cryptohome/key.pb.h"
14 #include "chromeos/dbus/cryptohome/rpc.pb.h"
15 #include "dbus/bus.h"
16 #include "dbus/message.h"
17 #include "dbus/object_path.h"
18 #include "dbus/object_proxy.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
21 namespace chromeos {
23 const int CryptohomeClient::kNotReadyAsyncId = -1;
25 namespace {
27 // This suffix is appended to user_id to get hash in stub implementation:
28 // stub_hash = "[user_id]-hash";
29 static const char kUserIdStubHashSuffix[] = "-hash";
31 // Timeout for TPM operations. On slow machines it should be larger, than
32 // default DBus timeout. TPM operations can take up to 80 seconds, so limit
33 // is 2 minutes.
34 const int kTpmDBusTimeoutMs = 2 * 60 * 1000;
36 // The CryptohomeClient implementation.
37 class CryptohomeClientImpl : public CryptohomeClient {
38 public:
39 CryptohomeClientImpl() : proxy_(NULL), weak_ptr_factory_(this) {}
41 // CryptohomeClient override.
42 void SetAsyncCallStatusHandlers(
43 const AsyncCallStatusHandler& handler,
44 const AsyncCallStatusWithDataHandler& data_handler) override {
45 async_call_status_handler_ = handler;
46 async_call_status_data_handler_ = data_handler;
49 // CryptohomeClient override.
50 void ResetAsyncCallStatusHandlers() override {
51 async_call_status_handler_.Reset();
52 async_call_status_data_handler_.Reset();
55 // CryptohomeClient override.
56 void WaitForServiceToBeAvailable(
57 const WaitForServiceToBeAvailableCallback& callback) override {
58 proxy_->WaitForServiceToBeAvailable(callback);
61 // CryptohomeClient override.
62 void IsMounted(const BoolDBusMethodCallback& callback) override {
63 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
64 cryptohome::kCryptohomeIsMounted);
65 CallBoolMethod(&method_call, callback);
68 // CryptohomeClient override.
69 bool Unmount(bool* success) override {
70 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
71 cryptohome::kCryptohomeUnmount);
72 return CallBoolMethodAndBlock(&method_call, success);
75 // CryptohomeClient override.
76 void AsyncCheckKey(const std::string& username,
77 const std::string& key,
78 const AsyncMethodCallback& callback) override {
79 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
80 cryptohome::kCryptohomeAsyncCheckKey);
81 dbus::MessageWriter writer(&method_call);
82 writer.AppendString(username);
83 writer.AppendString(key);
84 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
85 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
86 weak_ptr_factory_.GetWeakPtr(),
87 callback));
90 // CryptohomeClient override.
91 void AsyncMigrateKey(const std::string& username,
92 const std::string& from_key,
93 const std::string& to_key,
94 const AsyncMethodCallback& callback) override {
95 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
96 cryptohome::kCryptohomeAsyncMigrateKey);
97 dbus::MessageWriter writer(&method_call);
98 writer.AppendString(username);
99 writer.AppendString(from_key);
100 writer.AppendString(to_key);
101 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
102 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
103 weak_ptr_factory_.GetWeakPtr(),
104 callback));
107 // CryptohomeClient override.
108 void AsyncRemove(const std::string& username,
109 const AsyncMethodCallback& callback) override {
110 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
111 cryptohome::kCryptohomeAsyncRemove);
112 dbus::MessageWriter writer(&method_call);
113 writer.AppendString(username);
114 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
115 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
116 weak_ptr_factory_.GetWeakPtr(),
117 callback));
120 // CryptohomeClient override.
121 void GetSystemSalt(const GetSystemSaltCallback& callback) override {
122 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
123 cryptohome::kCryptohomeGetSystemSalt);
124 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
125 base::Bind(&CryptohomeClientImpl::OnGetSystemSalt,
126 weak_ptr_factory_.GetWeakPtr(),
127 callback));
130 // CryptohomeClient override,
131 void GetSanitizedUsername(const std::string& username,
132 const StringDBusMethodCallback& callback) override {
133 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
134 cryptohome::kCryptohomeGetSanitizedUsername);
135 dbus::MessageWriter writer(&method_call);
136 writer.AppendString(username);
137 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
138 base::Bind(&CryptohomeClientImpl::OnStringMethod,
139 weak_ptr_factory_.GetWeakPtr(),
140 callback));
143 // CryptohomeClient override.
144 std::string BlockingGetSanitizedUsername(
145 const std::string& username) override {
146 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
147 cryptohome::kCryptohomeGetSanitizedUsername);
148 dbus::MessageWriter writer(&method_call);
149 writer.AppendString(username);
151 scoped_ptr<dbus::Response> response =
152 blocking_method_caller_->CallMethodAndBlock(&method_call);
154 std::string sanitized_username;
155 if (response) {
156 dbus::MessageReader reader(response.get());
157 reader.PopString(&sanitized_username);
160 return sanitized_username;
163 // CryptohomeClient override.
164 void AsyncMount(const std::string& username,
165 const std::string& key,
166 int flags,
167 const AsyncMethodCallback& callback) override {
168 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
169 cryptohome::kCryptohomeAsyncMount);
170 dbus::MessageWriter writer(&method_call);
171 writer.AppendString(username);
172 writer.AppendString(key);
173 writer.AppendBool(flags & cryptohome::CREATE_IF_MISSING);
174 writer.AppendBool(flags & cryptohome::ENSURE_EPHEMERAL);
175 // deprecated_tracked_subdirectories
176 writer.AppendArrayOfStrings(std::vector<std::string>());
177 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
178 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
179 weak_ptr_factory_.GetWeakPtr(),
180 callback));
183 // CryptohomeClient override.
184 void AsyncAddKey(const std::string& username,
185 const std::string& key,
186 const std::string& new_key,
187 const AsyncMethodCallback& callback) override {
188 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
189 cryptohome::kCryptohomeAsyncAddKey);
190 dbus::MessageWriter writer(&method_call);
191 writer.AppendString(username);
192 writer.AppendString(key);
193 writer.AppendString(new_key);
194 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
195 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
196 weak_ptr_factory_.GetWeakPtr(),
197 callback));
200 // CryptohomeClient override.
201 void AsyncMountGuest(const AsyncMethodCallback& callback) override {
202 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
203 cryptohome::kCryptohomeAsyncMountGuest);
204 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
205 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
206 weak_ptr_factory_.GetWeakPtr(),
207 callback));
210 // CryptohomeClient override.
211 void AsyncMountPublic(const std::string& public_mount_id,
212 int flags,
213 const AsyncMethodCallback& callback) override {
214 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
215 cryptohome::kCryptohomeAsyncMountPublic);
216 dbus::MessageWriter writer(&method_call);
217 writer.AppendString(public_mount_id);
218 writer.AppendBool(flags & cryptohome::CREATE_IF_MISSING);
219 writer.AppendBool(flags & cryptohome::ENSURE_EPHEMERAL);
220 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
221 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
222 weak_ptr_factory_.GetWeakPtr(),
223 callback));
226 // CryptohomeClient override.
227 void TpmIsReady(const BoolDBusMethodCallback& callback) override {
228 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
229 cryptohome::kCryptohomeTpmIsReady);
230 CallBoolMethod(&method_call, callback);
233 // CryptohomeClient override.
234 void TpmIsEnabled(const BoolDBusMethodCallback& callback) override {
235 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
236 cryptohome::kCryptohomeTpmIsEnabled);
237 CallBoolMethod(&method_call, callback);
240 // CryptohomeClient override.
241 // TODO(hashimoto): Remove this method. crbug.com/141006
242 bool CallTpmIsEnabledAndBlock(bool* enabled) override {
243 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
244 cryptohome::kCryptohomeTpmIsEnabled);
245 return CallBoolMethodAndBlock(&method_call, enabled);
248 // CryptohomeClient override.
249 void TpmGetPassword(const StringDBusMethodCallback& callback) override {
250 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
251 cryptohome::kCryptohomeTpmGetPassword);
252 proxy_->CallMethod(
253 &method_call, kTpmDBusTimeoutMs ,
254 base::Bind(&CryptohomeClientImpl::OnStringMethod,
255 weak_ptr_factory_.GetWeakPtr(),
256 callback));
259 // CryptohomeClient override.
260 void TpmIsOwned(const BoolDBusMethodCallback& callback) override {
261 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
262 cryptohome::kCryptohomeTpmIsOwned);
263 CallBoolMethod(&method_call, callback);
266 // CryptohomeClient override.
267 // TODO(hashimoto): Remove this method. crbug.com/141012
268 bool CallTpmIsOwnedAndBlock(bool* owned) override {
269 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
270 cryptohome::kCryptohomeTpmIsOwned);
271 return CallBoolMethodAndBlock(&method_call, owned);
274 // CryptohomeClient override.
275 void TpmIsBeingOwned(const BoolDBusMethodCallback& callback) override {
276 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
277 cryptohome::kCryptohomeTpmIsBeingOwned);
278 CallBoolMethod(&method_call, callback);
281 // CryptohomeClient override.
282 // TODO(hashimoto): Remove this method. crbug.com/141011
283 bool CallTpmIsBeingOwnedAndBlock(bool* owning) override {
284 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
285 cryptohome::kCryptohomeTpmIsBeingOwned);
286 return CallBoolMethodAndBlock(&method_call, owning);
289 // CryptohomeClient override.
290 void TpmCanAttemptOwnership(const VoidDBusMethodCallback& callback) override {
291 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
292 cryptohome::kCryptohomeTpmCanAttemptOwnership);
293 CallVoidMethod(&method_call, callback);
296 // CryptohomeClient overrides.
297 void TpmClearStoredPassword(const VoidDBusMethodCallback& callback) override {
298 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
299 cryptohome::kCryptohomeTpmClearStoredPassword);
300 CallVoidMethod(&method_call, callback);
303 // CryptohomeClient override.
304 // TODO(hashimoto): Remove this method. crbug.com/141010
305 bool CallTpmClearStoredPasswordAndBlock() override {
306 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
307 cryptohome::kCryptohomeTpmClearStoredPassword);
308 scoped_ptr<dbus::Response> response(
309 blocking_method_caller_->CallMethodAndBlock(&method_call));
310 return response.get() != NULL;
313 // CryptohomeClient override.
314 void Pkcs11IsTpmTokenReady(const BoolDBusMethodCallback& callback) override {
315 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
316 cryptohome::kCryptohomePkcs11IsTpmTokenReady);
317 CallBoolMethod(&method_call, callback);
320 // CryptohomeClient override.
321 void Pkcs11GetTpmTokenInfo(
322 const Pkcs11GetTpmTokenInfoCallback& callback) override {
323 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
324 cryptohome::kCryptohomePkcs11GetTpmTokenInfo);
325 proxy_->CallMethod(
326 &method_call, kTpmDBusTimeoutMs ,
327 base::Bind(
328 &CryptohomeClientImpl::OnPkcs11GetTpmTokenInfo,
329 weak_ptr_factory_.GetWeakPtr(),
330 callback));
333 // CryptohomeClient override.
334 void Pkcs11GetTpmTokenInfoForUser(
335 const std::string& user_email,
336 const Pkcs11GetTpmTokenInfoCallback& callback) override {
337 dbus::MethodCall method_call(
338 cryptohome::kCryptohomeInterface,
339 cryptohome::kCryptohomePkcs11GetTpmTokenInfoForUser);
340 dbus::MessageWriter writer(&method_call);
341 writer.AppendString(user_email);
342 proxy_->CallMethod(
343 &method_call, kTpmDBusTimeoutMs ,
344 base::Bind(
345 &CryptohomeClientImpl::OnPkcs11GetTpmTokenInfoForUser,
346 weak_ptr_factory_.GetWeakPtr(),
347 callback));
350 // CryptohomeClient override.
351 bool InstallAttributesGet(const std::string& name,
352 std::vector<uint8>* value,
353 bool* successful) override {
354 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
355 cryptohome::kCryptohomeInstallAttributesGet);
356 dbus::MessageWriter writer(&method_call);
357 writer.AppendString(name);
358 scoped_ptr<dbus::Response> response(
359 blocking_method_caller_->CallMethodAndBlock(&method_call));
360 if (!response.get())
361 return false;
362 dbus::MessageReader reader(response.get());
363 const uint8* bytes = NULL;
364 size_t length = 0;
365 if (!reader.PopArrayOfBytes(&bytes, &length) ||
366 !reader.PopBool(successful))
367 return false;
368 value->assign(bytes, bytes + length);
369 return true;
372 // CryptohomeClient override.
373 bool InstallAttributesSet(const std::string& name,
374 const std::vector<uint8>& value,
375 bool* successful) override {
376 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
377 cryptohome::kCryptohomeInstallAttributesSet);
378 dbus::MessageWriter writer(&method_call);
379 writer.AppendString(name);
380 writer.AppendArrayOfBytes(value.data(), value.size());
381 return CallBoolMethodAndBlock(&method_call, successful);
384 // CryptohomeClient override.
385 bool InstallAttributesFinalize(bool* successful) override {
386 dbus::MethodCall method_call(
387 cryptohome::kCryptohomeInterface,
388 cryptohome::kCryptohomeInstallAttributesFinalize);
389 return CallBoolMethodAndBlock(&method_call, successful);
392 // CryptohomeClient override.
393 void InstallAttributesIsReady(
394 const BoolDBusMethodCallback& callback) override {
395 dbus::MethodCall method_call(
396 cryptohome::kCryptohomeInterface,
397 cryptohome::kCryptohomeInstallAttributesIsReady);
398 return CallBoolMethod(&method_call, callback);
401 // CryptohomeClient override.
402 bool InstallAttributesIsInvalid(bool* is_invalid) override {
403 dbus::MethodCall method_call(
404 cryptohome::kCryptohomeInterface,
405 cryptohome::kCryptohomeInstallAttributesIsInvalid);
406 return CallBoolMethodAndBlock(&method_call, is_invalid);
409 // CryptohomeClient override.
410 bool InstallAttributesIsFirstInstall(bool* is_first_install) override {
411 dbus::MethodCall method_call(
412 cryptohome::kCryptohomeInterface,
413 cryptohome::kCryptohomeInstallAttributesIsFirstInstall);
414 return CallBoolMethodAndBlock(&method_call, is_first_install);
417 // CryptohomeClient override.
418 void TpmAttestationIsPrepared(
419 const BoolDBusMethodCallback& callback) override {
420 dbus::MethodCall method_call(
421 cryptohome::kCryptohomeInterface,
422 cryptohome::kCryptohomeTpmIsAttestationPrepared);
423 return CallBoolMethod(&method_call, callback);
426 // CryptohomeClient override.
427 void TpmAttestationIsEnrolled(
428 const BoolDBusMethodCallback& callback) override {
429 dbus::MethodCall method_call(
430 cryptohome::kCryptohomeInterface,
431 cryptohome::kCryptohomeTpmIsAttestationEnrolled);
432 return CallBoolMethod(&method_call, callback);
435 // CryptohomeClient override.
436 void AsyncTpmAttestationCreateEnrollRequest(
437 attestation::PrivacyCAType pca_type,
438 const AsyncMethodCallback& callback) override {
439 dbus::MethodCall method_call(
440 cryptohome::kCryptohomeInterface,
441 cryptohome::kCryptohomeAsyncTpmAttestationCreateEnrollRequest);
442 dbus::MessageWriter writer(&method_call);
443 writer.AppendInt32(pca_type);
444 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
445 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
446 weak_ptr_factory_.GetWeakPtr(),
447 callback));
450 // CryptohomeClient override.
451 void AsyncTpmAttestationEnroll(attestation::PrivacyCAType pca_type,
452 const std::string& pca_response,
453 const AsyncMethodCallback& callback) override {
454 dbus::MethodCall method_call(
455 cryptohome::kCryptohomeInterface,
456 cryptohome::kCryptohomeAsyncTpmAttestationEnroll);
457 dbus::MessageWriter writer(&method_call);
458 writer.AppendInt32(pca_type);
459 writer.AppendArrayOfBytes(
460 reinterpret_cast<const uint8*>(pca_response.data()),
461 pca_response.size());
462 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
463 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
464 weak_ptr_factory_.GetWeakPtr(),
465 callback));
468 // CryptohomeClient override.
469 void AsyncTpmAttestationCreateCertRequest(
470 attestation::PrivacyCAType pca_type,
471 attestation::AttestationCertificateProfile certificate_profile,
472 const std::string& user_id,
473 const std::string& request_origin,
474 const AsyncMethodCallback& callback) override {
475 dbus::MethodCall method_call(
476 cryptohome::kCryptohomeInterface,
477 cryptohome::kCryptohomeAsyncTpmAttestationCreateCertRequest);
478 dbus::MessageWriter writer(&method_call);
479 writer.AppendInt32(pca_type);
480 writer.AppendInt32(certificate_profile);
481 writer.AppendString(user_id);
482 writer.AppendString(request_origin);
483 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
484 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
485 weak_ptr_factory_.GetWeakPtr(),
486 callback));
489 // CryptohomeClient override.
490 void AsyncTpmAttestationFinishCertRequest(
491 const std::string& pca_response,
492 attestation::AttestationKeyType key_type,
493 const std::string& user_id,
494 const std::string& key_name,
495 const AsyncMethodCallback& callback) override {
496 dbus::MethodCall method_call(
497 cryptohome::kCryptohomeInterface,
498 cryptohome::kCryptohomeAsyncTpmAttestationFinishCertRequest);
499 dbus::MessageWriter writer(&method_call);
500 writer.AppendArrayOfBytes(
501 reinterpret_cast<const uint8*>(pca_response.data()),
502 pca_response.size());
503 bool is_user_specific = (key_type == attestation::KEY_USER);
504 writer.AppendBool(is_user_specific);
505 writer.AppendString(user_id);
506 writer.AppendString(key_name);
507 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
508 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
509 weak_ptr_factory_.GetWeakPtr(),
510 callback));
513 // CryptohomeClient override.
514 void TpmAttestationDoesKeyExist(
515 attestation::AttestationKeyType key_type,
516 const std::string& user_id,
517 const std::string& key_name,
518 const BoolDBusMethodCallback& callback) override {
519 dbus::MethodCall method_call(
520 cryptohome::kCryptohomeInterface,
521 cryptohome::kCryptohomeTpmAttestationDoesKeyExist);
522 dbus::MessageWriter writer(&method_call);
523 bool is_user_specific = (key_type == attestation::KEY_USER);
524 writer.AppendBool(is_user_specific);
525 writer.AppendString(user_id);
526 writer.AppendString(key_name);
527 CallBoolMethod(&method_call, callback);
530 // CryptohomeClient override.
531 void TpmAttestationGetCertificate(
532 attestation::AttestationKeyType key_type,
533 const std::string& user_id,
534 const std::string& key_name,
535 const DataMethodCallback& callback) override {
536 dbus::MethodCall method_call(
537 cryptohome::kCryptohomeInterface,
538 cryptohome::kCryptohomeTpmAttestationGetCertificate);
539 dbus::MessageWriter writer(&method_call);
540 bool is_user_specific = (key_type == attestation::KEY_USER);
541 writer.AppendBool(is_user_specific);
542 writer.AppendString(user_id);
543 writer.AppendString(key_name);
544 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
545 base::Bind(&CryptohomeClientImpl::OnDataMethod,
546 weak_ptr_factory_.GetWeakPtr(),
547 callback));
550 // CryptohomeClient override.
551 void TpmAttestationGetPublicKey(attestation::AttestationKeyType key_type,
552 const std::string& user_id,
553 const std::string& key_name,
554 const DataMethodCallback& callback) override {
555 dbus::MethodCall method_call(
556 cryptohome::kCryptohomeInterface,
557 cryptohome::kCryptohomeTpmAttestationGetPublicKey);
558 dbus::MessageWriter writer(&method_call);
559 bool is_user_specific = (key_type == attestation::KEY_USER);
560 writer.AppendBool(is_user_specific);
561 writer.AppendString(user_id);
562 writer.AppendString(key_name);
563 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
564 base::Bind(&CryptohomeClientImpl::OnDataMethod,
565 weak_ptr_factory_.GetWeakPtr(),
566 callback));
569 // CryptohomeClient override.
570 void TpmAttestationRegisterKey(attestation::AttestationKeyType key_type,
571 const std::string& user_id,
572 const std::string& key_name,
573 const AsyncMethodCallback& callback) override {
574 dbus::MethodCall method_call(
575 cryptohome::kCryptohomeInterface,
576 cryptohome::kCryptohomeTpmAttestationRegisterKey);
577 dbus::MessageWriter writer(&method_call);
578 bool is_user_specific = (key_type == attestation::KEY_USER);
579 writer.AppendBool(is_user_specific);
580 writer.AppendString(user_id);
581 writer.AppendString(key_name);
582 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
583 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
584 weak_ptr_factory_.GetWeakPtr(),
585 callback));
588 // CryptohomeClient override.
589 void TpmAttestationSignEnterpriseChallenge(
590 attestation::AttestationKeyType key_type,
591 const std::string& user_id,
592 const std::string& key_name,
593 const std::string& domain,
594 const std::string& device_id,
595 attestation::AttestationChallengeOptions options,
596 const std::string& challenge,
597 const AsyncMethodCallback& callback) override {
598 dbus::MethodCall method_call(
599 cryptohome::kCryptohomeInterface,
600 cryptohome::kCryptohomeTpmAttestationSignEnterpriseChallenge);
601 dbus::MessageWriter writer(&method_call);
602 bool is_user_specific = (key_type == attestation::KEY_USER);
603 writer.AppendBool(is_user_specific);
604 writer.AppendString(user_id);
605 writer.AppendString(key_name);
606 writer.AppendString(domain);
607 writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(device_id.data()),
608 device_id.size());
609 bool include_signed_public_key =
610 (options & attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY);
611 writer.AppendBool(include_signed_public_key);
612 writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(challenge.data()),
613 challenge.size());
614 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
615 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
616 weak_ptr_factory_.GetWeakPtr(),
617 callback));
620 // CryptohomeClient override.
621 void TpmAttestationSignSimpleChallenge(
622 attestation::AttestationKeyType key_type,
623 const std::string& user_id,
624 const std::string& key_name,
625 const std::string& challenge,
626 const AsyncMethodCallback& callback) override {
627 dbus::MethodCall method_call(
628 cryptohome::kCryptohomeInterface,
629 cryptohome::kCryptohomeTpmAttestationSignSimpleChallenge);
630 dbus::MessageWriter writer(&method_call);
631 bool is_user_specific = (key_type == attestation::KEY_USER);
632 writer.AppendBool(is_user_specific);
633 writer.AppendString(user_id);
634 writer.AppendString(key_name);
635 writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(challenge.data()),
636 challenge.size());
637 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
638 base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
639 weak_ptr_factory_.GetWeakPtr(),
640 callback));
643 // CryptohomeClient override.
644 void TpmAttestationGetKeyPayload(
645 attestation::AttestationKeyType key_type,
646 const std::string& user_id,
647 const std::string& key_name,
648 const DataMethodCallback& callback) override {
649 dbus::MethodCall method_call(
650 cryptohome::kCryptohomeInterface,
651 cryptohome::kCryptohomeTpmAttestationGetKeyPayload);
652 dbus::MessageWriter writer(&method_call);
653 bool is_user_specific = (key_type == attestation::KEY_USER);
654 writer.AppendBool(is_user_specific);
655 writer.AppendString(user_id);
656 writer.AppendString(key_name);
657 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
658 base::Bind(&CryptohomeClientImpl::OnDataMethod,
659 weak_ptr_factory_.GetWeakPtr(),
660 callback));
663 // CryptohomeClient override.
664 void TpmAttestationSetKeyPayload(
665 attestation::AttestationKeyType key_type,
666 const std::string& user_id,
667 const std::string& key_name,
668 const std::string& payload,
669 const BoolDBusMethodCallback& callback) override {
670 dbus::MethodCall method_call(
671 cryptohome::kCryptohomeInterface,
672 cryptohome::kCryptohomeTpmAttestationSetKeyPayload);
673 dbus::MessageWriter writer(&method_call);
674 bool is_user_specific = (key_type == attestation::KEY_USER);
675 writer.AppendBool(is_user_specific);
676 writer.AppendString(user_id);
677 writer.AppendString(key_name);
678 writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(payload.data()),
679 payload.size());
680 CallBoolMethod(&method_call, callback);
683 // CryptohomeClient override.
684 void TpmAttestationDeleteKeys(
685 attestation::AttestationKeyType key_type,
686 const std::string& user_id,
687 const std::string& key_prefix,
688 const BoolDBusMethodCallback& callback) override {
689 dbus::MethodCall method_call(
690 cryptohome::kCryptohomeInterface,
691 cryptohome::kCryptohomeTpmAttestationDeleteKeys);
692 dbus::MessageWriter writer(&method_call);
693 bool is_user_specific = (key_type == attestation::KEY_USER);
694 writer.AppendBool(is_user_specific);
695 writer.AppendString(user_id);
696 writer.AppendString(key_prefix);
697 CallBoolMethod(&method_call, callback);
700 void GetKeyDataEx(const cryptohome::AccountIdentifier& id,
701 const cryptohome::AuthorizationRequest& auth,
702 const cryptohome::GetKeyDataRequest& request,
703 const ProtobufMethodCallback& callback) override {
704 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
705 cryptohome::kCryptohomeGetKeyDataEx);
706 dbus::MessageWriter writer(&method_call);
707 writer.AppendProtoAsArrayOfBytes(id);
708 writer.AppendProtoAsArrayOfBytes(auth);
709 writer.AppendProtoAsArrayOfBytes(request);
711 proxy_->CallMethod(&method_call,
712 kTpmDBusTimeoutMs,
713 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
714 weak_ptr_factory_.GetWeakPtr(),
715 callback));
718 void CheckKeyEx(const cryptohome::AccountIdentifier& id,
719 const cryptohome::AuthorizationRequest& auth,
720 const cryptohome::CheckKeyRequest& request,
721 const ProtobufMethodCallback& callback) override {
722 const char* method_name = cryptohome::kCryptohomeCheckKeyEx;
723 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
724 method_name);
726 dbus::MessageWriter writer(&method_call);
727 writer.AppendProtoAsArrayOfBytes(id);
728 writer.AppendProtoAsArrayOfBytes(auth);
729 writer.AppendProtoAsArrayOfBytes(request);
731 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
732 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
733 weak_ptr_factory_.GetWeakPtr(),
734 callback));
737 void MountEx(const cryptohome::AccountIdentifier& id,
738 const cryptohome::AuthorizationRequest& auth,
739 const cryptohome::MountRequest& request,
740 const ProtobufMethodCallback& callback) override {
741 const char* method_name = cryptohome::kCryptohomeMountEx;
742 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
743 method_name);
745 dbus::MessageWriter writer(&method_call);
746 writer.AppendProtoAsArrayOfBytes(id);
747 writer.AppendProtoAsArrayOfBytes(auth);
748 writer.AppendProtoAsArrayOfBytes(request);
750 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs ,
751 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
752 weak_ptr_factory_.GetWeakPtr(),
753 callback));
756 void AddKeyEx(const cryptohome::AccountIdentifier& id,
757 const cryptohome::AuthorizationRequest& auth,
758 const cryptohome::AddKeyRequest& request,
759 const ProtobufMethodCallback& callback) override {
760 const char* method_name = cryptohome::kCryptohomeAddKeyEx;
761 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
762 method_name);
764 dbus::MessageWriter writer(&method_call);
765 writer.AppendProtoAsArrayOfBytes(id);
766 writer.AppendProtoAsArrayOfBytes(auth);
767 writer.AppendProtoAsArrayOfBytes(request);
769 proxy_->CallMethod(&method_call, kTpmDBusTimeoutMs,
770 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
771 weak_ptr_factory_.GetWeakPtr(),
772 callback));
775 void UpdateKeyEx(const cryptohome::AccountIdentifier& id,
776 const cryptohome::AuthorizationRequest& auth,
777 const cryptohome::UpdateKeyRequest& request,
778 const ProtobufMethodCallback& callback) override {
779 const char* method_name = cryptohome::kCryptohomeUpdateKeyEx;
780 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
781 method_name);
783 dbus::MessageWriter writer(&method_call);
784 writer.AppendProtoAsArrayOfBytes(id);
785 writer.AppendProtoAsArrayOfBytes(auth);
786 writer.AppendProtoAsArrayOfBytes(request);
788 proxy_->CallMethod(&method_call,
789 kTpmDBusTimeoutMs ,
790 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
791 weak_ptr_factory_.GetWeakPtr(),
792 callback));
795 void RemoveKeyEx(const cryptohome::AccountIdentifier& id,
796 const cryptohome::AuthorizationRequest& auth,
797 const cryptohome::RemoveKeyRequest& request,
798 const ProtobufMethodCallback& callback) override {
799 const char* method_name = cryptohome::kCryptohomeRemoveKeyEx;
800 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, method_name);
802 dbus::MessageWriter writer(&method_call);
803 writer.AppendProtoAsArrayOfBytes(id);
804 writer.AppendProtoAsArrayOfBytes(auth);
805 writer.AppendProtoAsArrayOfBytes(request);
807 proxy_->CallMethod(&method_call,
808 kTpmDBusTimeoutMs ,
809 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
810 weak_ptr_factory_.GetWeakPtr(),
811 callback));
814 void GetBootAttribute(const cryptohome::GetBootAttributeRequest& request,
815 const ProtobufMethodCallback& callback) override {
816 const char* method_name = cryptohome::kCryptohomeGetBootAttribute;
817 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, method_name);
819 dbus::MessageWriter writer(&method_call);
820 writer.AppendProtoAsArrayOfBytes(request);
822 proxy_->CallMethod(&method_call,
823 kTpmDBusTimeoutMs ,
824 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
825 weak_ptr_factory_.GetWeakPtr(),
826 callback));
829 void SetBootAttribute(const cryptohome::SetBootAttributeRequest& request,
830 const ProtobufMethodCallback& callback) override {
831 const char* method_name = cryptohome::kCryptohomeSetBootAttribute;
832 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, method_name);
834 dbus::MessageWriter writer(&method_call);
835 writer.AppendProtoAsArrayOfBytes(request);
837 proxy_->CallMethod(&method_call,
838 kTpmDBusTimeoutMs ,
839 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
840 weak_ptr_factory_.GetWeakPtr(),
841 callback));
844 void FlushAndSignBootAttributes(
845 const cryptohome::FlushAndSignBootAttributesRequest& request,
846 const ProtobufMethodCallback& callback) override {
847 const char* method_name = cryptohome::kCryptohomeFlushAndSignBootAttributes;
848 dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, method_name);
850 dbus::MessageWriter writer(&method_call);
851 writer.AppendProtoAsArrayOfBytes(request);
853 proxy_->CallMethod(&method_call,
854 kTpmDBusTimeoutMs ,
855 base::Bind(&CryptohomeClientImpl::OnBaseReplyMethod,
856 weak_ptr_factory_.GetWeakPtr(),
857 callback));
860 protected:
861 void Init(dbus::Bus* bus) override {
862 proxy_ = bus->GetObjectProxy(
863 cryptohome::kCryptohomeServiceName,
864 dbus::ObjectPath(cryptohome::kCryptohomeServicePath));
866 blocking_method_caller_.reset(new BlockingMethodCaller(bus, proxy_));
868 proxy_->ConnectToSignal(cryptohome::kCryptohomeInterface,
869 cryptohome::kSignalAsyncCallStatus,
870 base::Bind(&CryptohomeClientImpl::OnAsyncCallStatus,
871 weak_ptr_factory_.GetWeakPtr()),
872 base::Bind(&CryptohomeClientImpl::OnSignalConnected,
873 weak_ptr_factory_.GetWeakPtr()));
874 proxy_->ConnectToSignal(
875 cryptohome::kCryptohomeInterface,
876 cryptohome::kSignalAsyncCallStatusWithData,
877 base::Bind(&CryptohomeClientImpl::OnAsyncCallStatusWithData,
878 weak_ptr_factory_.GetWeakPtr()),
879 base::Bind(&CryptohomeClientImpl::OnSignalConnected,
880 weak_ptr_factory_.GetWeakPtr()));
883 private:
884 // Handles the result of AsyncXXX methods.
885 void OnAsyncMethodCall(const AsyncMethodCallback& callback,
886 dbus::Response* response) {
887 if (!response) {
888 callback.Run(kNotReadyAsyncId);
889 return;
891 dbus::MessageReader reader(response);
892 int async_id = 0;
893 if (!reader.PopInt32(&async_id)) {
894 LOG(ERROR) << "Invalid response: " << response->ToString();
895 return;
897 callback.Run(async_id);
900 // Handles the result of GetSystemSalt().
901 void OnGetSystemSalt(const GetSystemSaltCallback& callback,
902 dbus::Response* response) {
903 if (!response) {
904 callback.Run(DBUS_METHOD_CALL_FAILURE, std::vector<uint8>());
905 return;
907 dbus::MessageReader reader(response);
908 const uint8* bytes = NULL;
909 size_t length = 0;
910 if (!reader.PopArrayOfBytes(&bytes, &length)) {
911 callback.Run(DBUS_METHOD_CALL_FAILURE, std::vector<uint8>());
912 return;
914 callback.Run(DBUS_METHOD_CALL_SUCCESS,
915 std::vector<uint8>(bytes, bytes + length));
918 // Calls a method without result values.
919 void CallVoidMethod(dbus::MethodCall* method_call,
920 const VoidDBusMethodCallback& callback) {
921 proxy_->CallMethod(method_call, kTpmDBusTimeoutMs ,
922 base::Bind(&CryptohomeClientImpl::OnVoidMethod,
923 weak_ptr_factory_.GetWeakPtr(),
924 callback));
927 void OnVoidMethod(const VoidDBusMethodCallback& callback,
928 dbus::Response* response) {
929 if (!response) {
930 callback.Run(DBUS_METHOD_CALL_FAILURE);
931 return;
933 callback.Run(DBUS_METHOD_CALL_SUCCESS);
936 // Calls a method with a bool value reult and block.
937 bool CallBoolMethodAndBlock(dbus::MethodCall* method_call,
938 bool* result) {
939 scoped_ptr<dbus::Response> response(
940 blocking_method_caller_->CallMethodAndBlock(method_call));
941 if (!response.get())
942 return false;
943 dbus::MessageReader reader(response.get());
944 return reader.PopBool(result);
947 // Calls a method with a bool value result.
948 void CallBoolMethod(dbus::MethodCall* method_call,
949 const BoolDBusMethodCallback& callback) {
950 proxy_->CallMethod(method_call, kTpmDBusTimeoutMs ,
951 base::Bind(
952 &CryptohomeClientImpl::OnBoolMethod,
953 weak_ptr_factory_.GetWeakPtr(),
954 callback));
957 // Handles responses for methods with a bool value result.
958 void OnBoolMethod(const BoolDBusMethodCallback& callback,
959 dbus::Response* response) {
960 if (!response) {
961 callback.Run(DBUS_METHOD_CALL_FAILURE, false);
962 return;
964 dbus::MessageReader reader(response);
965 bool result = false;
966 if (!reader.PopBool(&result)) {
967 callback.Run(DBUS_METHOD_CALL_FAILURE, false);
968 LOG(ERROR) << "Invalid response: " << response->ToString();
969 return;
971 callback.Run(DBUS_METHOD_CALL_SUCCESS, result);
974 // Handles responses for methods with a string value result.
975 void OnStringMethod(const StringDBusMethodCallback& callback,
976 dbus::Response* response) {
977 if (!response) {
978 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string());
979 return;
981 dbus::MessageReader reader(response);
982 std::string result;
983 if (!reader.PopString(&result)) {
984 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string());
985 return;
987 callback.Run(DBUS_METHOD_CALL_SUCCESS, result);
990 // Handles responses for methods with a bool result and data.
991 void OnDataMethod(const DataMethodCallback& callback,
992 dbus::Response* response) {
993 if (!response) {
994 callback.Run(DBUS_METHOD_CALL_FAILURE, false, std::string());
995 return;
997 dbus::MessageReader reader(response);
998 const uint8* data_buffer = NULL;
999 size_t data_length = 0;
1000 bool result = false;
1001 if (!reader.PopArrayOfBytes(&data_buffer, &data_length) ||
1002 !reader.PopBool(&result)) {
1003 callback.Run(DBUS_METHOD_CALL_FAILURE, false, std::string());
1004 return;
1006 std::string data(reinterpret_cast<const char*>(data_buffer), data_length);
1007 callback.Run(DBUS_METHOD_CALL_SUCCESS, result, data);
1010 // Handles responses for methods with a BaseReply protobuf method.
1011 void OnBaseReplyMethod(const ProtobufMethodCallback& callback,
1012 dbus::Response* response) {
1013 cryptohome::BaseReply reply;
1014 if (!response) {
1015 callback.Run(DBUS_METHOD_CALL_FAILURE, false, reply);
1016 return;
1018 dbus::MessageReader reader(response);
1019 if (!reader.PopArrayOfBytesAsProto(&reply)) {
1020 callback.Run(DBUS_METHOD_CALL_FAILURE, false, reply);
1021 return;
1023 callback.Run(DBUS_METHOD_CALL_SUCCESS, true, reply);
1026 // Handles responses for Pkcs11GetTpmTokenInfo.
1027 void OnPkcs11GetTpmTokenInfo(const Pkcs11GetTpmTokenInfoCallback& callback,
1028 dbus::Response* response) {
1029 if (!response) {
1030 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
1031 return;
1033 dbus::MessageReader reader(response);
1034 std::string label;
1035 std::string user_pin;
1036 if (!reader.PopString(&label) || !reader.PopString(&user_pin)) {
1037 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
1038 LOG(ERROR) << "Invalid response: " << response->ToString();
1039 return;
1041 const int kDefaultSlot = 0;
1042 callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, kDefaultSlot);
1045 // Handles responses for Pkcs11GetTpmTokenInfoForUser.
1046 void OnPkcs11GetTpmTokenInfoForUser(
1047 const Pkcs11GetTpmTokenInfoCallback& callback,
1048 dbus::Response* response) {
1049 if (!response) {
1050 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
1051 return;
1053 dbus::MessageReader reader(response);
1054 std::string label;
1055 std::string user_pin;
1056 int slot = 0;
1057 if (!reader.PopString(&label) || !reader.PopString(&user_pin) ||
1058 !reader.PopInt32(&slot)) {
1059 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
1060 LOG(ERROR) << "Invalid response: " << response->ToString();
1061 return;
1063 callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, slot);
1066 // Handles AsyncCallStatus signal.
1067 void OnAsyncCallStatus(dbus::Signal* signal) {
1068 dbus::MessageReader reader(signal);
1069 int async_id = 0;
1070 bool return_status = false;
1071 int return_code = 0;
1072 if (!reader.PopInt32(&async_id) ||
1073 !reader.PopBool(&return_status) ||
1074 !reader.PopInt32(&return_code)) {
1075 LOG(ERROR) << "Invalid signal: " << signal->ToString();
1076 return;
1078 if (!async_call_status_handler_.is_null())
1079 async_call_status_handler_.Run(async_id, return_status, return_code);
1082 // Handles AsyncCallStatusWithData signal.
1083 void OnAsyncCallStatusWithData(dbus::Signal* signal) {
1084 dbus::MessageReader reader(signal);
1085 int async_id = 0;
1086 bool return_status = false;
1087 const uint8* return_data_buffer = NULL;
1088 size_t return_data_length = 0;
1089 if (!reader.PopInt32(&async_id) ||
1090 !reader.PopBool(&return_status) ||
1091 !reader.PopArrayOfBytes(&return_data_buffer, &return_data_length)) {
1092 LOG(ERROR) << "Invalid signal: " << signal->ToString();
1093 return;
1095 if (!async_call_status_data_handler_.is_null()) {
1096 std::string return_data(reinterpret_cast<const char*>(return_data_buffer),
1097 return_data_length);
1098 async_call_status_data_handler_.Run(async_id, return_status, return_data);
1102 // Handles the result of signal connection setup.
1103 void OnSignalConnected(const std::string& interface,
1104 const std::string& signal,
1105 bool succeeded) {
1106 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
1107 signal << " failed.";
1110 dbus::ObjectProxy* proxy_;
1111 scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
1112 AsyncCallStatusHandler async_call_status_handler_;
1113 AsyncCallStatusWithDataHandler async_call_status_data_handler_;
1115 // Note: This should remain the last member so it'll be destroyed and
1116 // invalidate its weak pointers before any other members are destroyed.
1117 base::WeakPtrFactory<CryptohomeClientImpl> weak_ptr_factory_;
1119 DISALLOW_COPY_AND_ASSIGN(CryptohomeClientImpl);
1122 } // namespace
1124 ////////////////////////////////////////////////////////////////////////////////
1125 // CryptohomeClient
1127 CryptohomeClient::CryptohomeClient() {}
1129 CryptohomeClient::~CryptohomeClient() {}
1131 // static
1132 CryptohomeClient* CryptohomeClient::Create() {
1133 return new CryptohomeClientImpl();
1136 // static
1137 std::string CryptohomeClient::GetStubSanitizedUsername(
1138 const std::string& username) {
1139 return username + kUserIdStubHashSuffix;
1142 } // namespace chromeos