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_remove_keys_operation.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/cryptohome/homedir_methods.h"
1034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "chromeos/cryptohome/system_salt_getter.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "google_apis/gaia/gaia_auth_util.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace chromeos {
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockRemoveKeysOperation::EasyUnlockRemoveKeysOperation(
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const UserContext& user_context,
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t start_index,
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const RemoveKeysCallback& callback)
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : user_context_(user_context),
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      callback_(callback),
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      key_index_(start_index),
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_ptr_factory_(this) {
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Must have the secret and callback.
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!user_context_.GetKey()->GetSecret().empty());
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!callback_.is_null());
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEasyUnlockRemoveKeysOperation::~EasyUnlockRemoveKeysOperation() {
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockRemoveKeysOperation::Start() {
3234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (user_context_.GetKey()->GetKeyType() == Key::KEY_TYPE_PASSWORD_PLAIN) {
3334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    SystemSaltGetter::Get()->GetSystemSalt(
3434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)        base::Bind(&EasyUnlockRemoveKeysOperation::OnGetSystemSalt,
3534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
3634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
3734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  }
3834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
3934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  RemoveKey();
4034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
4134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
4234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)void EasyUnlockRemoveKeysOperation::OnGetSystemSalt(
4334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    const std::string& system_salt) {
4434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  user_context_.GetKey()->Transform(Key::KEY_TYPE_SALTED_SHA256_TOP_HALF,
4534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)                                    system_salt);
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RemoveKey();
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockRemoveKeysOperation::RemoveKey() {
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string canonicalized =
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      gaia::CanonicalizeEmail(user_context_.GetUserID());
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  cryptohome::Identification id(canonicalized);
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const Key* const auth_key = user_context_.GetKey();
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  cryptohome::Authorization auth(auth_key->GetSecret(), auth_key->GetLabel());
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  // TODO(xiyuan): Use ListKeyEx and delete by label instead of by index.
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  cryptohome::HomedirMethods::GetInstance()->RemoveKeyEx(
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      id,
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      auth,
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EasyUnlockKeyManager::GetKeyLabel(key_index_),
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&EasyUnlockRemoveKeysOperation::OnKeyRemoved,
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 weak_ptr_factory_.GetWeakPtr()));
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EasyUnlockRemoveKeysOperation::OnKeyRemoved(
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool success,
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    cryptohome::MountError return_code) {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (success) {
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ++key_index_;
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RemoveKey();
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // MOUNT_ERROR_KEY_FAILURE is considered as success. Other error codes are
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // treated as failures.
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (return_code == cryptohome::MOUNT_ERROR_KEY_FAILURE) {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    callback_.Run(true);
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(ERROR) << "Easy unlock remove keys operation failed, code="
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               << return_code;
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    callback_.Run(false);
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace chromeos
86