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