1 // Copyright 2014 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 "chrome/browser/chromeos/login/easy_unlock/easy_unlock_get_keys_operation.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/logging.h" 11 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h" 12 #include "google_apis/gaia/gaia_auth_util.h" 13 14 namespace chromeos { 15 16 EasyUnlockGetKeysOperation::EasyUnlockGetKeysOperation( 17 const UserContext& user_context, 18 const GetKeysCallback& callback) 19 : user_context_(user_context), 20 callback_(callback), 21 key_index_(0), 22 weak_ptr_factory_(this) { 23 } 24 25 EasyUnlockGetKeysOperation::~EasyUnlockGetKeysOperation() { 26 } 27 28 void EasyUnlockGetKeysOperation::Start() { 29 // TODO(xiyuan): Use ListKeyEx. 30 key_index_ = 0; 31 GetKeyData(); 32 } 33 34 void EasyUnlockGetKeysOperation::GetKeyData() { 35 std::string canonicalized = 36 gaia::CanonicalizeEmail(user_context_.GetUserID()); 37 cryptohome::Identification id(canonicalized); 38 cryptohome::HomedirMethods::GetInstance()->GetKeyDataEx( 39 id, 40 EasyUnlockKeyManager::GetKeyLabel(key_index_), 41 base::Bind(&EasyUnlockGetKeysOperation::OnGetKeyData, 42 weak_ptr_factory_.GetWeakPtr())); 43 44 } 45 46 void EasyUnlockGetKeysOperation::OnGetKeyData( 47 bool success, 48 cryptohome::MountError return_code, 49 const std::vector<cryptohome::KeyDefinition>& key_definitions) { 50 if (!success || key_definitions.empty()) { 51 // MOUNT_ERROR_KEY_FAILURE is considered as success. Other error codes are 52 // treated as failures. 53 if (return_code == cryptohome::MOUNT_ERROR_NONE || 54 return_code == cryptohome::MOUNT_ERROR_KEY_FAILURE) { 55 callback_.Run(true, devices_); 56 return; 57 } 58 59 LOG(ERROR) << "Easy unlock failed to get key data, code=" << return_code; 60 callback_.Run(false, EasyUnlockDeviceKeyDataList()); 61 return; 62 } 63 64 DCHECK_EQ(1u, key_definitions.size()); 65 66 const std::vector<cryptohome::KeyDefinition::ProviderData>& provider_data = 67 key_definitions.front().provider_data; 68 69 EasyUnlockDeviceKeyData device; 70 for (size_t i = 0; i < provider_data.size(); ++i) { 71 const cryptohome::KeyDefinition::ProviderData& entry = provider_data[i]; 72 if (entry.name == kEasyUnlockKeyMetaNameBluetoothAddress) { 73 if (entry.bytes) 74 device.bluetooth_address = *entry.bytes; 75 else 76 NOTREACHED(); 77 } else if (entry.name == kEasyUnlockKeyMetaNamePubKey) { 78 if (entry.bytes) 79 device.public_key = *entry.bytes; 80 else 81 NOTREACHED(); 82 } else if (entry.name == kEasyUnlockKeyMetaNamePsk) { 83 if (entry.bytes) 84 device.psk = *entry.bytes; 85 else 86 NOTREACHED(); 87 } else if (entry.name == kEasyUnlockKeyMetaNameChallenge) { 88 if (entry.bytes) 89 device.challenge = *entry.bytes; 90 else 91 NOTREACHED(); 92 } else if (entry.name == kEasyUnlockKeyMetaNameWrappedSecret) { 93 if (entry.bytes) 94 device.wrapped_secret = *entry.bytes; 95 else 96 NOTREACHED(); 97 } else { 98 LOG(WARNING) << "Unknown Easy unlock key data entry, name=" 99 << entry.name; 100 } 101 } 102 devices_.push_back(device); 103 104 ++key_index_; 105 GetKeyData(); 106 } 107 108 } // namespace chromeos 109