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