11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_get_keys_operation.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/logging.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "google_apis/gaia/gaia_auth_util.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace chromeos {
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockGetKeysOperation::EasyUnlockGetKeysOperation(
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const UserContext& user_context,
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GetKeysCallback& callback)
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : user_context_(user_context),
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      callback_(callback),
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      key_index_(0),
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_ptr_factory_(this) {
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockGetKeysOperation::~EasyUnlockGetKeysOperation() {
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockGetKeysOperation::Start() {
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(xiyuan): Use ListKeyEx.
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  key_index_ = 0;
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetKeyData();
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockGetKeysOperation::GetKeyData() {
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string canonicalized =
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      gaia::CanonicalizeEmail(user_context_.GetUserID());
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  cryptohome::Identification id(canonicalized);
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  cryptohome::HomedirMethods::GetInstance()->GetKeyDataEx(
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      id,
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EasyUnlockKeyManager::GetKeyLabel(key_index_),
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&EasyUnlockGetKeysOperation::OnGetKeyData,
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 weak_ptr_factory_.GetWeakPtr()));
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockGetKeysOperation::OnGetKeyData(
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool success,
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    cryptohome::MountError return_code,
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::vector<cryptohome::KeyDefinition>& key_definitions) {
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!success || key_definitions.empty()) {
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // MOUNT_ERROR_KEY_FAILURE is considered as success. Other error codes are
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // treated as failures.
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (return_code == cryptohome::MOUNT_ERROR_NONE ||
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return_code == cryptohome::MOUNT_ERROR_KEY_FAILURE) {
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      callback_.Run(true, devices_);
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return;
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(ERROR) << "Easy unlock failed to get key data, code=" << return_code;
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    callback_.Run(false, EasyUnlockDeviceKeyDataList());
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(1u, key_definitions.size());
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const std::vector<cryptohome::KeyDefinition::ProviderData>& provider_data =
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      key_definitions.front().provider_data;
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EasyUnlockDeviceKeyData device;
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < provider_data.size(); ++i) {
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const cryptohome::KeyDefinition::ProviderData& entry = provider_data[i];
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (entry.name == kEasyUnlockKeyMetaNameBluetoothAddress) {
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (entry.bytes)
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        device.bluetooth_address = *entry.bytes;
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      else
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        NOTREACHED();
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (entry.name == kEasyUnlockKeyMetaNamePubKey) {
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (entry.bytes)
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        device.public_key = *entry.bytes;
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      else
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        NOTREACHED();
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (entry.name == kEasyUnlockKeyMetaNamePsk) {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (entry.bytes)
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        device.psk = *entry.bytes;
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      else
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        NOTREACHED();
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (entry.name == kEasyUnlockKeyMetaNameChallenge) {
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (entry.bytes)
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        device.challenge = *entry.bytes;
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      else
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        NOTREACHED();
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (entry.name == kEasyUnlockKeyMetaNameWrappedSecret) {
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (entry.bytes)
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        device.wrapped_secret = *entry.bytes;
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      else
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        NOTREACHED();
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      LOG(WARNING) << "Unknown Easy unlock key data entry, name="
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   << entry.name;
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  devices_.push_back(device);
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ++key_index_;
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetKeyData();
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace chromeos
109