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