- add sources.
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / cryptohome_client.cc
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.
4
5 #include "chromeos/dbus/cryptohome_client.h"
6
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/fake_cryptohome_client.h"
14 #include "dbus/bus.h"
15 #include "dbus/message.h"
16 #include "dbus/object_path.h"
17 #include "dbus/object_proxy.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
19
20 namespace chromeos {
21
22 namespace {
23
24 // This suffix is appended to user_id to get hash in stub implementation:
25 // stub_hash = "[user_id]-hash";
26 static const char kUserIdStubHashSuffix[] = "-hash";
27
28 // The CryptohomeClient implementation.
29 class CryptohomeClientImpl : public CryptohomeClient {
30  public:
31   CryptohomeClientImpl() : proxy_(NULL), weak_ptr_factory_(this) {}
32
33   // CryptohomeClient override.
34   virtual void SetAsyncCallStatusHandlers(
35       const AsyncCallStatusHandler& handler,
36       const AsyncCallStatusWithDataHandler& data_handler) OVERRIDE {
37     async_call_status_handler_ = handler;
38     async_call_status_data_handler_ = data_handler;
39   }
40
41   // CryptohomeClient override.
42   virtual void ResetAsyncCallStatusHandlers() OVERRIDE {
43     async_call_status_handler_.Reset();
44     async_call_status_data_handler_.Reset();
45   }
46
47   // CryptohomeClient override.
48   virtual void WaitForServiceToBeAvailable(
49       const WaitForServiceToBeAvailableCallback& callback) OVERRIDE {
50     proxy_->WaitForServiceToBeAvailable(callback);
51   }
52
53   // CryptohomeClient override.
54   virtual void IsMounted(const BoolDBusMethodCallback& callback) OVERRIDE {
55     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
56                                  cryptohome::kCryptohomeIsMounted);
57     CallBoolMethod(&method_call, callback);
58   }
59
60   // CryptohomeClient override.
61   virtual bool Unmount(bool *success) OVERRIDE {
62     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
63                                  cryptohome::kCryptohomeUnmount);
64     return CallBoolMethodAndBlock(&method_call, success);
65   }
66
67   // CryptohomeClient override.
68   virtual void AsyncCheckKey(const std::string& username,
69                              const std::string& key,
70                              const AsyncMethodCallback& callback) OVERRIDE {
71     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
72                                  cryptohome::kCryptohomeAsyncCheckKey);
73     dbus::MessageWriter writer(&method_call);
74     writer.AppendString(username);
75     writer.AppendString(key);
76     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
77                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
78                                   weak_ptr_factory_.GetWeakPtr(),
79                                   callback));
80   }
81
82   // CryptohomeClient override.
83   virtual void AsyncMigrateKey(const std::string& username,
84                                const std::string& from_key,
85                                const std::string& to_key,
86                                const AsyncMethodCallback& callback) OVERRIDE {
87     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
88                                  cryptohome::kCryptohomeAsyncMigrateKey);
89     dbus::MessageWriter writer(&method_call);
90     writer.AppendString(username);
91     writer.AppendString(from_key);
92     writer.AppendString(to_key);
93     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
94                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
95                                   weak_ptr_factory_.GetWeakPtr(),
96                                   callback));
97   }
98
99   // CryptohomeClient override.
100   virtual void AsyncRemove(const std::string& username,
101                            const AsyncMethodCallback& callback) OVERRIDE {
102     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
103                                  cryptohome::kCryptohomeAsyncRemove);
104     dbus::MessageWriter writer(&method_call);
105     writer.AppendString(username);
106     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
107                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
108                                   weak_ptr_factory_.GetWeakPtr(),
109                                   callback));
110   }
111
112   // CryptohomeClient override.
113   virtual void GetSystemSalt(const GetSystemSaltCallback& callback) OVERRIDE {
114     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
115                                  cryptohome::kCryptohomeGetSystemSalt);
116     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
117                        base::Bind(&CryptohomeClientImpl::OnGetSystemSalt,
118                                   weak_ptr_factory_.GetWeakPtr(),
119                                   callback));
120   }
121
122   // CryptohomeClient override,
123   virtual void GetSanitizedUsername(
124       const std::string& username,
125       const StringDBusMethodCallback& callback) OVERRIDE {
126     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
127                                  cryptohome::kCryptohomeGetSanitizedUsername);
128     dbus::MessageWriter writer(&method_call);
129     writer.AppendString(username);
130     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
131                        base::Bind(&CryptohomeClientImpl::OnStringMethod,
132                                   weak_ptr_factory_.GetWeakPtr(),
133                                   callback));
134   }
135
136   // CryptohomeClient override.
137   virtual std::string BlockingGetSanitizedUsername(
138       const std::string& username) OVERRIDE {
139     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
140                                  cryptohome::kCryptohomeGetSanitizedUsername);
141     dbus::MessageWriter writer(&method_call);
142     writer.AppendString(username);
143
144     scoped_ptr<dbus::Response> response =
145         blocking_method_caller_->CallMethodAndBlock(&method_call);
146
147     std::string sanitized_username;
148     if (response) {
149       dbus::MessageReader reader(response.get());
150       reader.PopString(&sanitized_username);
151     }
152
153     return sanitized_username;
154   }
155
156   // CryptohomeClient override.
157   virtual void AsyncMount(const std::string& username,
158                           const std::string& key,
159                           int flags,
160                           const AsyncMethodCallback& callback) OVERRIDE {
161     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
162                                  cryptohome::kCryptohomeAsyncMount);
163     dbus::MessageWriter writer(&method_call);
164     writer.AppendString(username);
165     writer.AppendString(key);
166     writer.AppendBool(flags & cryptohome::CREATE_IF_MISSING);
167     writer.AppendBool(flags & cryptohome::ENSURE_EPHEMERAL);
168     // deprecated_tracked_subdirectories
169     writer.AppendArrayOfStrings(std::vector<std::string>());
170     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
171                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
172                                   weak_ptr_factory_.GetWeakPtr(),
173                                   callback));
174   }
175
176   // CryptohomeClient override.
177   virtual void AsyncAddKey(const std::string& username,
178                            const std::string& key,
179                            const std::string& new_key,
180                            const AsyncMethodCallback& callback) OVERRIDE {
181     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
182                                  cryptohome::kCryptohomeAsyncAddKey);
183     dbus::MessageWriter writer(&method_call);
184     writer.AppendString(username);
185     writer.AppendString(key);
186     writer.AppendString(new_key);
187     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
188                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
189                                   weak_ptr_factory_.GetWeakPtr(),
190                                   callback));
191   }
192
193   // CryptohomeClient override.
194   virtual void AsyncMountGuest(const AsyncMethodCallback& callback) OVERRIDE {
195     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
196                                  cryptohome::kCryptohomeAsyncMountGuest);
197     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
198                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
199                                   weak_ptr_factory_.GetWeakPtr(),
200                                   callback));
201   }
202
203   // CryptohomeClient override.
204   virtual void AsyncMountPublic(const std::string& public_mount_id,
205                                 int flags,
206                                 const AsyncMethodCallback& callback) OVERRIDE {
207     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
208                                  cryptohome::kCryptohomeAsyncMountPublic);
209     dbus::MessageWriter writer(&method_call);
210     writer.AppendString(public_mount_id);
211     writer.AppendBool(flags & cryptohome::CREATE_IF_MISSING);
212     writer.AppendBool(flags & cryptohome::ENSURE_EPHEMERAL);
213     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
214                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
215                                   weak_ptr_factory_.GetWeakPtr(),
216                                   callback));
217   }
218
219   // CryptohomeClient override.
220   virtual void TpmIsReady(const BoolDBusMethodCallback& callback) OVERRIDE {
221     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
222                                  cryptohome::kCryptohomeTpmIsReady);
223     CallBoolMethod(&method_call, callback);
224   }
225
226   // CryptohomeClient override.
227   virtual void TpmIsEnabled(const BoolDBusMethodCallback& callback) OVERRIDE {
228     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
229                                  cryptohome::kCryptohomeTpmIsEnabled);
230     CallBoolMethod(&method_call, callback);
231   }
232
233   // CryptohomeClient override.
234   // TODO(hashimoto): Remove this method. crbug.com/141006
235   virtual bool CallTpmIsEnabledAndBlock(bool* enabled) OVERRIDE {
236     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
237                                  cryptohome::kCryptohomeTpmIsEnabled);
238     return CallBoolMethodAndBlock(&method_call, enabled);
239   }
240
241   // CryptohomeClient override.
242   virtual void TpmGetPassword(
243       const StringDBusMethodCallback& callback) OVERRIDE {
244     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
245                                  cryptohome::kCryptohomeTpmGetPassword);
246     proxy_->CallMethod(
247         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
248         base::Bind(&CryptohomeClientImpl::OnStringMethod,
249                    weak_ptr_factory_.GetWeakPtr(),
250                    callback));
251   }
252
253   // CryptohomeClient override.
254   virtual void TpmIsOwned(const BoolDBusMethodCallback& callback) OVERRIDE {
255     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
256                                  cryptohome::kCryptohomeTpmIsOwned);
257     CallBoolMethod(&method_call, callback);
258   }
259
260   // CryptohomeClient override.
261   // TODO(hashimoto): Remove this method. crbug.com/141012
262   virtual bool CallTpmIsOwnedAndBlock(bool* owned) OVERRIDE {
263     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
264                                  cryptohome::kCryptohomeTpmIsOwned);
265     return CallBoolMethodAndBlock(&method_call, owned);
266   }
267
268   // CryptohomeClient override.
269   virtual void TpmIsBeingOwned(const BoolDBusMethodCallback& callback)
270       OVERRIDE {
271     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
272                                  cryptohome::kCryptohomeTpmIsBeingOwned);
273     CallBoolMethod(&method_call, callback);
274   }
275
276   // CryptohomeClient override.
277   // TODO(hashimoto): Remove this method. crbug.com/141011
278   virtual bool CallTpmIsBeingOwnedAndBlock(bool* owning) OVERRIDE {
279     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
280                                  cryptohome::kCryptohomeTpmIsBeingOwned);
281     return CallBoolMethodAndBlock(&method_call, owning);
282   }
283
284   // CryptohomeClient override.
285   virtual void TpmCanAttemptOwnership(
286       const VoidDBusMethodCallback& callback) OVERRIDE {
287     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
288                                  cryptohome::kCryptohomeTpmCanAttemptOwnership);
289     CallVoidMethod(&method_call, callback);
290   }
291
292   // CryptohomeClient overrides.
293   virtual void TpmClearStoredPassword(const VoidDBusMethodCallback& callback)
294       OVERRIDE {
295     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
296                                  cryptohome::kCryptohomeTpmClearStoredPassword);
297     CallVoidMethod(&method_call, callback);
298   }
299
300   // CryptohomeClient override.
301   // TODO(hashimoto): Remove this method. crbug.com/141010
302   virtual bool CallTpmClearStoredPasswordAndBlock() OVERRIDE {
303     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
304                                  cryptohome::kCryptohomeTpmClearStoredPassword);
305     scoped_ptr<dbus::Response> response(
306         blocking_method_caller_->CallMethodAndBlock(&method_call));
307     return response.get() != NULL;
308   }
309
310   // CryptohomeClient override.
311   virtual void Pkcs11IsTpmTokenReady(const BoolDBusMethodCallback& callback)
312       OVERRIDE {
313     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
314                                  cryptohome::kCryptohomePkcs11IsTpmTokenReady);
315     CallBoolMethod(&method_call, callback);
316   }
317
318   // CryptohomeClient override.
319   virtual void Pkcs11GetTpmTokenInfo(
320       const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE {
321     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
322                                  cryptohome::kCryptohomePkcs11GetTpmTokenInfo);
323     proxy_->CallMethod(
324         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
325         base::Bind(
326             &CryptohomeClientImpl::OnPkcs11GetTpmTokenInfo,
327             weak_ptr_factory_.GetWeakPtr(),
328             callback));
329   }
330
331   // CryptohomeClient override.
332   virtual void Pkcs11GetTpmTokenInfoForUser(
333       const std::string& user_email,
334       const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE {
335     dbus::MethodCall method_call(
336         cryptohome::kCryptohomeInterface,
337         cryptohome::kCryptohomePkcs11GetTpmTokenInfoForUser);
338     dbus::MessageWriter writer(&method_call);
339     writer.AppendString(user_email);
340     proxy_->CallMethod(
341         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
342         base::Bind(
343             &CryptohomeClientImpl::OnPkcs11GetTpmTokenInfoForUser,
344             weak_ptr_factory_.GetWeakPtr(),
345             callback));
346   }
347
348   // CryptohomeClient override.
349   virtual bool InstallAttributesGet(const std::string& name,
350                                     std::vector<uint8>* value,
351                                     bool* successful) OVERRIDE {
352     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
353                                  cryptohome::kCryptohomeInstallAttributesGet);
354     dbus::MessageWriter writer(&method_call);
355     writer.AppendString(name);
356     scoped_ptr<dbus::Response> response(
357         blocking_method_caller_->CallMethodAndBlock(&method_call));
358     if (!response.get())
359       return false;
360     dbus::MessageReader reader(response.get());
361     uint8* bytes = NULL;
362     size_t length = 0;
363     if (!reader.PopArrayOfBytes(&bytes, &length) ||
364         !reader.PopBool(successful))
365       return false;
366     value->assign(bytes, bytes + length);
367     return true;
368   }
369
370   // CryptohomeClient override.
371   virtual bool InstallAttributesSet(const std::string& name,
372                                     const std::vector<uint8>& value,
373                                     bool* successful) OVERRIDE {
374     dbus::MethodCall method_call(cryptohome::kCryptohomeInterface,
375                                  cryptohome::kCryptohomeInstallAttributesSet);
376     dbus::MessageWriter writer(&method_call);
377     writer.AppendString(name);
378     writer.AppendArrayOfBytes(value.data(), value.size());
379     return CallBoolMethodAndBlock(&method_call, successful);
380   }
381
382   // CryptohomeClient override.
383   virtual bool InstallAttributesFinalize(bool* successful) OVERRIDE {
384     dbus::MethodCall method_call(
385         cryptohome::kCryptohomeInterface,
386         cryptohome::kCryptohomeInstallAttributesFinalize);
387     return CallBoolMethodAndBlock(&method_call, successful);
388   }
389
390   // CryptohomeClient override.
391   virtual void InstallAttributesIsReady(const BoolDBusMethodCallback& callback)
392       OVERRIDE {
393     dbus::MethodCall method_call(
394         cryptohome::kCryptohomeInterface,
395         cryptohome::kCryptohomeInstallAttributesIsReady);
396     return CallBoolMethod(&method_call, callback);
397   }
398
399   // CryptohomeClient override.
400   virtual bool InstallAttributesIsInvalid(bool* is_invalid) OVERRIDE {
401     dbus::MethodCall method_call(
402         cryptohome::kCryptohomeInterface,
403         cryptohome::kCryptohomeInstallAttributesIsInvalid);
404     return CallBoolMethodAndBlock(&method_call, is_invalid);
405   }
406
407   // CryptohomeClient override.
408   virtual bool InstallAttributesIsFirstInstall(
409       bool* is_first_install) OVERRIDE {
410     dbus::MethodCall method_call(
411         cryptohome::kCryptohomeInterface,
412         cryptohome::kCryptohomeInstallAttributesIsFirstInstall);
413     return CallBoolMethodAndBlock(&method_call, is_first_install);
414   }
415
416   // CryptohomeClient override.
417   virtual void TpmAttestationIsPrepared(
418         const BoolDBusMethodCallback& callback) OVERRIDE {
419     dbus::MethodCall method_call(
420         cryptohome::kCryptohomeInterface,
421         cryptohome::kCryptohomeTpmIsAttestationPrepared);
422     return CallBoolMethod(&method_call, callback);
423   }
424
425   // CryptohomeClient override.
426   virtual void TpmAttestationIsEnrolled(
427         const BoolDBusMethodCallback& callback) OVERRIDE {
428     dbus::MethodCall method_call(
429         cryptohome::kCryptohomeInterface,
430         cryptohome::kCryptohomeTpmIsAttestationEnrolled);
431     return CallBoolMethod(&method_call, callback);
432   }
433
434   // CryptohomeClient override.
435   virtual void AsyncTpmAttestationCreateEnrollRequest(
436       const AsyncMethodCallback& callback) OVERRIDE {
437     dbus::MethodCall method_call(
438         cryptohome::kCryptohomeInterface,
439         cryptohome::kCryptohomeAsyncTpmAttestationCreateEnrollRequest);
440     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
441                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
442                                   weak_ptr_factory_.GetWeakPtr(),
443                                   callback));
444   }
445
446   // CryptohomeClient override.
447   virtual void AsyncTpmAttestationEnroll(
448       const std::string& pca_response,
449       const AsyncMethodCallback& callback) OVERRIDE {
450     dbus::MethodCall method_call(
451         cryptohome::kCryptohomeInterface,
452         cryptohome::kCryptohomeAsyncTpmAttestationEnroll);
453     dbus::MessageWriter writer(&method_call);
454     writer.AppendArrayOfBytes(
455         reinterpret_cast<const uint8*>(pca_response.data()),
456         pca_response.size());
457     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
458                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
459                                   weak_ptr_factory_.GetWeakPtr(),
460                                   callback));
461   }
462
463   // CryptohomeClient override.
464   virtual void AsyncTpmAttestationCreateCertRequest(
465       attestation::AttestationCertificateProfile certificate_profile,
466       const std::string& user_id,
467       const std::string& request_origin,
468       const AsyncMethodCallback& callback) OVERRIDE {
469     dbus::MethodCall method_call(
470         cryptohome::kCryptohomeInterface,
471         cryptohome::kCryptohomeAsyncTpmAttestationCreateCertRequestByProfile);
472     dbus::MessageWriter writer(&method_call);
473     writer.AppendInt32(certificate_profile);
474     writer.AppendString(user_id);
475     writer.AppendString(request_origin);
476     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
477                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
478                                   weak_ptr_factory_.GetWeakPtr(),
479                                   callback));
480   }
481
482   // CryptohomeClient override.
483   virtual void AsyncTpmAttestationFinishCertRequest(
484       const std::string& pca_response,
485       attestation::AttestationKeyType key_type,
486       const std::string& user_id,
487       const std::string& key_name,
488       const AsyncMethodCallback& callback) OVERRIDE {
489     dbus::MethodCall method_call(
490         cryptohome::kCryptohomeInterface,
491         cryptohome::kCryptohomeAsyncTpmAttestationFinishCertRequest);
492     dbus::MessageWriter writer(&method_call);
493     writer.AppendArrayOfBytes(
494         reinterpret_cast<const uint8*>(pca_response.data()),
495         pca_response.size());
496     bool is_user_specific = (key_type == attestation::KEY_USER);
497     writer.AppendBool(is_user_specific);
498     writer.AppendString(user_id);
499     writer.AppendString(key_name);
500     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
501                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
502                                   weak_ptr_factory_.GetWeakPtr(),
503                                   callback));
504   }
505
506   // CryptohomeClient override.
507   virtual void TpmAttestationDoesKeyExist(
508       attestation::AttestationKeyType key_type,
509       const std::string& user_id,
510       const std::string& key_name,
511       const BoolDBusMethodCallback& callback) OVERRIDE {
512     dbus::MethodCall method_call(
513         cryptohome::kCryptohomeInterface,
514         cryptohome::kCryptohomeTpmAttestationDoesKeyExist);
515     dbus::MessageWriter writer(&method_call);
516     bool is_user_specific = (key_type == attestation::KEY_USER);
517     writer.AppendBool(is_user_specific);
518     writer.AppendString(user_id);
519     writer.AppendString(key_name);
520     CallBoolMethod(&method_call, callback);
521   }
522
523   // CryptohomeClient override.
524   virtual void TpmAttestationGetCertificate(
525       attestation::AttestationKeyType key_type,
526       const std::string& user_id,
527       const std::string& key_name,
528       const DataMethodCallback& callback) OVERRIDE {
529     dbus::MethodCall method_call(
530         cryptohome::kCryptohomeInterface,
531         cryptohome::kCryptohomeTpmAttestationGetCertificate);
532     dbus::MessageWriter writer(&method_call);
533     bool is_user_specific = (key_type == attestation::KEY_USER);
534     writer.AppendBool(is_user_specific);
535     writer.AppendString(user_id);
536     writer.AppendString(key_name);
537     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
538                        base::Bind(&CryptohomeClientImpl::OnDataMethod,
539                                   weak_ptr_factory_.GetWeakPtr(),
540                                   callback));
541   }
542
543   // CryptohomeClient override.
544   virtual void TpmAttestationGetPublicKey(
545       attestation::AttestationKeyType key_type,
546       const std::string& user_id,
547       const std::string& key_name,
548       const DataMethodCallback& callback) OVERRIDE {
549     dbus::MethodCall method_call(
550         cryptohome::kCryptohomeInterface,
551         cryptohome::kCryptohomeTpmAttestationGetPublicKey);
552     dbus::MessageWriter writer(&method_call);
553     bool is_user_specific = (key_type == attestation::KEY_USER);
554     writer.AppendBool(is_user_specific);
555     writer.AppendString(user_id);
556     writer.AppendString(key_name);
557     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
558                        base::Bind(&CryptohomeClientImpl::OnDataMethod,
559                                   weak_ptr_factory_.GetWeakPtr(),
560                                   callback));
561   }
562
563   // CryptohomeClient override.
564   virtual void TpmAttestationRegisterKey(
565       attestation::AttestationKeyType key_type,
566       const std::string& user_id,
567       const std::string& key_name,
568       const AsyncMethodCallback& callback) OVERRIDE {
569     dbus::MethodCall method_call(
570         cryptohome::kCryptohomeInterface,
571         cryptohome::kCryptohomeTpmAttestationRegisterKey);
572     dbus::MessageWriter writer(&method_call);
573     bool is_user_specific = (key_type == attestation::KEY_USER);
574     writer.AppendBool(is_user_specific);
575     writer.AppendString(user_id);
576     writer.AppendString(key_name);
577     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
578                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
579                                   weak_ptr_factory_.GetWeakPtr(),
580                                   callback));
581   }
582
583   // CryptohomeClient override.
584   virtual void TpmAttestationSignEnterpriseChallenge(
585       attestation::AttestationKeyType key_type,
586       const std::string& user_id,
587       const std::string& key_name,
588       const std::string& domain,
589       const std::string& device_id,
590       attestation::AttestationChallengeOptions options,
591       const std::string& challenge,
592       const AsyncMethodCallback& callback) OVERRIDE {
593     dbus::MethodCall method_call(
594         cryptohome::kCryptohomeInterface,
595         cryptohome::kCryptohomeTpmAttestationSignEnterpriseChallenge);
596     dbus::MessageWriter writer(&method_call);
597     bool is_user_specific = (key_type == attestation::KEY_USER);
598     writer.AppendBool(is_user_specific);
599     writer.AppendString(user_id);
600     writer.AppendString(key_name);
601     writer.AppendString(domain);
602     writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(device_id.data()),
603                               device_id.size());
604     bool include_signed_public_key =
605         (options & attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY);
606     writer.AppendBool(include_signed_public_key);
607     writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(challenge.data()),
608                               challenge.size());
609     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
610                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
611                                   weak_ptr_factory_.GetWeakPtr(),
612                                   callback));
613   }
614
615   // CryptohomeClient override.
616   virtual void TpmAttestationSignSimpleChallenge(
617       attestation::AttestationKeyType key_type,
618       const std::string& user_id,
619       const std::string& key_name,
620       const std::string& challenge,
621       const AsyncMethodCallback& callback) OVERRIDE {
622     dbus::MethodCall method_call(
623         cryptohome::kCryptohomeInterface,
624         cryptohome::kCryptohomeTpmAttestationSignSimpleChallenge);
625     dbus::MessageWriter writer(&method_call);
626     bool is_user_specific = (key_type == attestation::KEY_USER);
627     writer.AppendBool(is_user_specific);
628     writer.AppendString(user_id);
629     writer.AppendString(key_name);
630     writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(challenge.data()),
631                               challenge.size());
632     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
633                        base::Bind(&CryptohomeClientImpl::OnAsyncMethodCall,
634                                   weak_ptr_factory_.GetWeakPtr(),
635                                   callback));
636   }
637
638   // CryptohomeClient override.
639   virtual void TpmAttestationGetKeyPayload(
640       attestation::AttestationKeyType key_type,
641       const std::string& user_id,
642       const std::string& key_name,
643       const DataMethodCallback& callback) OVERRIDE {
644     dbus::MethodCall method_call(
645         cryptohome::kCryptohomeInterface,
646         cryptohome::kCryptohomeTpmAttestationGetKeyPayload);
647     dbus::MessageWriter writer(&method_call);
648     bool is_user_specific = (key_type == attestation::KEY_USER);
649     writer.AppendBool(is_user_specific);
650     writer.AppendString(user_id);
651     writer.AppendString(key_name);
652     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
653                        base::Bind(&CryptohomeClientImpl::OnDataMethod,
654                                   weak_ptr_factory_.GetWeakPtr(),
655                                   callback));
656   }
657
658   // CryptohomeClient override.
659   virtual void TpmAttestationSetKeyPayload(
660       attestation::AttestationKeyType key_type,
661       const std::string& user_id,
662       const std::string& key_name,
663       const std::string& payload,
664       const BoolDBusMethodCallback& callback) OVERRIDE {
665     dbus::MethodCall method_call(
666         cryptohome::kCryptohomeInterface,
667         cryptohome::kCryptohomeTpmAttestationSetKeyPayload);
668     dbus::MessageWriter writer(&method_call);
669     bool is_user_specific = (key_type == attestation::KEY_USER);
670     writer.AppendBool(is_user_specific);
671     writer.AppendString(user_id);
672     writer.AppendString(key_name);
673     writer.AppendArrayOfBytes(reinterpret_cast<const uint8*>(payload.data()),
674                               payload.size());
675     CallBoolMethod(&method_call, callback);
676   }
677
678   // CryptohomeClient override.
679   virtual void TpmAttestationDeleteKeys(
680       attestation::AttestationKeyType key_type,
681       const std::string& user_id,
682       const std::string& key_prefix,
683       const BoolDBusMethodCallback& callback) OVERRIDE {
684     dbus::MethodCall method_call(
685         cryptohome::kCryptohomeInterface,
686         cryptohome::kCryptohomeTpmAttestationDeleteKeys);
687     dbus::MessageWriter writer(&method_call);
688     bool is_user_specific = (key_type == attestation::KEY_USER);
689     writer.AppendBool(is_user_specific);
690     writer.AppendString(user_id);
691     writer.AppendString(key_prefix);
692     CallBoolMethod(&method_call, callback);
693   }
694
695  protected:
696   virtual void Init(dbus::Bus* bus) OVERRIDE {
697     proxy_ = bus->GetObjectProxy(
698         cryptohome::kCryptohomeServiceName,
699         dbus::ObjectPath(cryptohome::kCryptohomeServicePath));
700
701     blocking_method_caller_.reset(new BlockingMethodCaller(bus, proxy_));
702
703     proxy_->ConnectToSignal(cryptohome::kCryptohomeInterface,
704                             cryptohome::kSignalAsyncCallStatus,
705                             base::Bind(&CryptohomeClientImpl::OnAsyncCallStatus,
706                                        weak_ptr_factory_.GetWeakPtr()),
707                             base::Bind(&CryptohomeClientImpl::OnSignalConnected,
708                                        weak_ptr_factory_.GetWeakPtr()));
709     proxy_->ConnectToSignal(
710         cryptohome::kCryptohomeInterface,
711         cryptohome::kSignalAsyncCallStatusWithData,
712         base::Bind(&CryptohomeClientImpl::OnAsyncCallStatusWithData,
713                    weak_ptr_factory_.GetWeakPtr()),
714         base::Bind(&CryptohomeClientImpl::OnSignalConnected,
715                    weak_ptr_factory_.GetWeakPtr()));
716   }
717
718  private:
719   // Handles the result of AsyncXXX methods.
720   void OnAsyncMethodCall(const AsyncMethodCallback& callback,
721                          dbus::Response* response) {
722     if (!response)
723       return;
724     dbus::MessageReader reader(response);
725     int async_id = 0;
726     if (!reader.PopInt32(&async_id)) {
727       LOG(ERROR) << "Invalid response: " << response->ToString();
728       return;
729     }
730     callback.Run(async_id);
731   }
732
733   // Handles the result of GetSystemSalt().
734   void OnGetSystemSalt(const GetSystemSaltCallback& callback,
735                        dbus::Response* response) {
736     if (!response) {
737       callback.Run(DBUS_METHOD_CALL_FAILURE, std::vector<uint8>());
738       return;
739     }
740     dbus::MessageReader reader(response);
741     uint8* bytes = NULL;
742     size_t length = 0;
743     if (!reader.PopArrayOfBytes(&bytes, &length)) {
744       callback.Run(DBUS_METHOD_CALL_FAILURE, std::vector<uint8>());
745       return;
746     }
747     callback.Run(DBUS_METHOD_CALL_SUCCESS,
748                  std::vector<uint8>(bytes, bytes + length));
749   }
750
751   // Calls a method without result values.
752   void CallVoidMethod(dbus::MethodCall* method_call,
753                       const VoidDBusMethodCallback& callback) {
754     proxy_->CallMethod(method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
755                        base::Bind(&CryptohomeClientImpl::OnVoidMethod,
756                                   weak_ptr_factory_.GetWeakPtr(),
757                                   callback));
758   }
759
760   void OnVoidMethod(const VoidDBusMethodCallback& callback,
761                     dbus::Response* response) {
762     if (!response) {
763       callback.Run(DBUS_METHOD_CALL_FAILURE);
764       return;
765     }
766     callback.Run(DBUS_METHOD_CALL_SUCCESS);
767   }
768
769   // Calls a method with a bool value reult and block.
770   bool CallBoolMethodAndBlock(dbus::MethodCall* method_call,
771                               bool* result) {
772     scoped_ptr<dbus::Response> response(
773         blocking_method_caller_->CallMethodAndBlock(method_call));
774     if (!response.get())
775       return false;
776     dbus::MessageReader reader(response.get());
777     return reader.PopBool(result);
778   }
779
780   // Calls a method with a bool value result.
781   void CallBoolMethod(dbus::MethodCall* method_call,
782                       const BoolDBusMethodCallback& callback) {
783     proxy_->CallMethod(method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
784                        base::Bind(
785                            &CryptohomeClientImpl::OnBoolMethod,
786                            weak_ptr_factory_.GetWeakPtr(),
787                            callback));
788   }
789
790   // Handles responses for methods with a bool value result.
791   void OnBoolMethod(const BoolDBusMethodCallback& callback,
792                     dbus::Response* response) {
793     if (!response) {
794       callback.Run(DBUS_METHOD_CALL_FAILURE, false);
795       return;
796     }
797     dbus::MessageReader reader(response);
798     bool result = false;
799     if (!reader.PopBool(&result)) {
800       callback.Run(DBUS_METHOD_CALL_FAILURE, false);
801       LOG(ERROR) << "Invalid response: " << response->ToString();
802       return;
803     }
804     callback.Run(DBUS_METHOD_CALL_SUCCESS, result);
805   }
806
807   // Handles responses for methods with a string value result.
808   void OnStringMethod(const StringDBusMethodCallback& callback,
809                       dbus::Response* response) {
810     if (!response) {
811       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string());
812       return;
813     }
814     dbus::MessageReader reader(response);
815     std::string result;
816     if (!reader.PopString(&result)) {
817       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string());
818       return;
819     }
820     callback.Run(DBUS_METHOD_CALL_SUCCESS, result);
821   }
822
823   // Handles responses for methods with a bool result and data.
824   void OnDataMethod(const DataMethodCallback& callback,
825                     dbus::Response* response) {
826     if (!response) {
827       callback.Run(DBUS_METHOD_CALL_FAILURE, false, std::string());
828       return;
829     }
830     dbus::MessageReader reader(response);
831     uint8* data_buffer = NULL;
832     size_t data_length = 0;
833     bool result = false;
834     if (!reader.PopArrayOfBytes(&data_buffer, &data_length) ||
835         !reader.PopBool(&result)) {
836       callback.Run(DBUS_METHOD_CALL_FAILURE, false, std::string());
837       return;
838     }
839     std::string data(reinterpret_cast<char*>(data_buffer), data_length);
840     callback.Run(DBUS_METHOD_CALL_SUCCESS, result, data);
841   }
842
843   // Handles responses for Pkcs11GetTpmTokenInfo.
844   void OnPkcs11GetTpmTokenInfo(const Pkcs11GetTpmTokenInfoCallback& callback,
845                                dbus::Response* response) {
846     if (!response) {
847       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
848       return;
849     }
850     dbus::MessageReader reader(response);
851     std::string label;
852     std::string user_pin;
853     if (!reader.PopString(&label) || !reader.PopString(&user_pin)) {
854       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
855       LOG(ERROR) << "Invalid response: " << response->ToString();
856       return;
857     }
858     const int kDefaultSlot = 0;
859     callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, kDefaultSlot);
860   }
861
862   // Handles responses for Pkcs11GetTpmTokenInfoForUser.
863   void OnPkcs11GetTpmTokenInfoForUser(
864       const Pkcs11GetTpmTokenInfoCallback& callback,
865       dbus::Response* response) {
866     if (!response) {
867       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
868       return;
869     }
870     dbus::MessageReader reader(response);
871     std::string label;
872     std::string user_pin;
873     int slot = 0;
874     if (!reader.PopString(&label) || !reader.PopString(&user_pin) ||
875         !reader.PopInt32(&slot)) {
876       callback.Run(DBUS_METHOD_CALL_FAILURE, std::string(), std::string(), -1);
877       LOG(ERROR) << "Invalid response: " << response->ToString();
878       return;
879     }
880     callback.Run(DBUS_METHOD_CALL_SUCCESS, label, user_pin, slot);
881   }
882
883   // Handles AsyncCallStatus signal.
884   void OnAsyncCallStatus(dbus::Signal* signal) {
885     dbus::MessageReader reader(signal);
886     int async_id = 0;
887     bool return_status = false;
888     int return_code = 0;
889     if (!reader.PopInt32(&async_id) ||
890         !reader.PopBool(&return_status) ||
891         !reader.PopInt32(&return_code)) {
892       LOG(ERROR) << "Invalid signal: " << signal->ToString();
893       return;
894     }
895     if (!async_call_status_handler_.is_null())
896       async_call_status_handler_.Run(async_id, return_status, return_code);
897   }
898
899   // Handles AsyncCallStatusWithData signal.
900   void OnAsyncCallStatusWithData(dbus::Signal* signal) {
901     dbus::MessageReader reader(signal);
902     int async_id = 0;
903     bool return_status = false;
904     uint8* return_data_buffer = NULL;
905     size_t return_data_length = 0;
906     if (!reader.PopInt32(&async_id) ||
907         !reader.PopBool(&return_status) ||
908         !reader.PopArrayOfBytes(&return_data_buffer, &return_data_length)) {
909       LOG(ERROR) << "Invalid signal: " << signal->ToString();
910       return;
911     }
912     if (!async_call_status_data_handler_.is_null()) {
913       std::string return_data(reinterpret_cast<char*>(return_data_buffer),
914                               return_data_length);
915       async_call_status_data_handler_.Run(async_id, return_status, return_data);
916     }
917   }
918
919   // Handles the result of signal connection setup.
920   void OnSignalConnected(const std::string& interface,
921                          const std::string& signal,
922                          bool succeeded) {
923     LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
924         signal << " failed.";
925   }
926
927   dbus::ObjectProxy* proxy_;
928   scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
929   AsyncCallStatusHandler async_call_status_handler_;
930   AsyncCallStatusWithDataHandler async_call_status_data_handler_;
931
932   // Note: This should remain the last member so it'll be destroyed and
933   // invalidate its weak pointers before any other members are destroyed.
934   base::WeakPtrFactory<CryptohomeClientImpl> weak_ptr_factory_;
935
936   DISALLOW_COPY_AND_ASSIGN(CryptohomeClientImpl);
937 };
938
939 }  // namespace
940
941 ////////////////////////////////////////////////////////////////////////////////
942 // CryptohomeClient
943
944 CryptohomeClient::CryptohomeClient() {}
945
946 CryptohomeClient::~CryptohomeClient() {}
947
948 // static
949 CryptohomeClient* CryptohomeClient::Create(DBusClientImplementationType type) {
950   if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
951     return new CryptohomeClientImpl();
952   DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
953   return new FakeCryptohomeClient();
954 }
955
956 // static
957 std::string CryptohomeClient::GetStubSanitizedUsername(
958     const std::string& username) {
959   return username + kUserIdStubHashSuffix;
960 }
961
962 }  // namespace chromeos