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