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: 30 CryptohomeClientImpl() : proxy_(NULL), weak_ptr_factory_(this) {} 31 32 // CryptohomeClient override. 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. 41 virtual void ResetAsyncCallStatusHandlers() OVERRIDE { 42 async_call_status_handler_.Reset(); 43 async_call_status_data_handler_.Reset(); 44 } 45 46 // CryptohomeClient override. 47 virtual void WaitForServiceToBeAvailable( 48 const WaitForServiceToBeAvailableCallback& callback) OVERRIDE { 49 proxy_->WaitForServiceToBeAvailable(callback); 50 } 51 52 // CryptohomeClient override. 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. 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. 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. 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. 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. 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, 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. 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. 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. 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. 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. 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. 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. 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 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. 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. 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 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. 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 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. 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. 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 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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: 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. 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(). 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. 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 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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 943 CryptohomeClient::CryptohomeClient() {} 944 945 CryptohomeClient::~CryptohomeClient() {} 946 947 // static 948 CryptohomeClient* CryptohomeClient::Create() { 949 return new CryptohomeClientImpl(); 950 } 951 952 // static 953 std::string CryptohomeClient::GetStubSanitizedUsername( 954 const std::string& username) { 955 return username + kUserIdStubHashSuffix; 956 } 957 958 } // namespace chromeos 959