blob: a82096527407051a20bdbb3beab1847111e4e9fd [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_QUICK_UNLOCK_PIN_BACKEND_H_
#define CHROME_BROWSER_CHROMEOS_LOGIN_QUICK_UNLOCK_PIN_BACKEND_H_
#include <string>
#include "base/callback.h"
#include "chromeos/login/auth/key.h"
class AccountId;
class Profile;
class ScopedKeepAlive;
namespace chromeos {
namespace quick_unlock {
class PinStorageCryptohome;
// Provides high-level access to the user's PIN. The underlying storage can be
// either cryptohome or prefs.
class PinBackend {
public:
using BoolCallback = base::OnceCallback<void(bool)>;
// Fetch the PinBackend instance.
static PinBackend* GetInstance();
// Computes a new salt.
static std::string ComputeSalt();
// Computes the secret for a given |pin| and |salt|.
static std::string ComputeSecret(const std::string& pin,
const std::string& salt,
Key::KeyType key_type);
// Use GetInstance().
PinBackend();
~PinBackend();
// Check to see if the PinBackend supports login. This is true when the
// cryptohome backend is available.
void HasLoginSupport(BoolCallback result);
// Try to migrate a prefs-based PIN to cryptohome.
void MigrateToCryptohome(Profile* profile, const Key& key);
// Check if the given account_id has a PIN registered.
void IsSet(const AccountId& account_id, BoolCallback result);
// Set the PIN for the given user.
void Set(const AccountId& account_id,
const std::string& auth_token,
const std::string& pin,
BoolCallback did_set);
// Remove the given user's PIN.
void Remove(const AccountId& account_id,
const std::string& auth_token,
BoolCallback did_remove);
// Is PIN authentication available for the given account? Even if PIN is set,
// it may not be available for authentication due to some additional
// restrictions.
void CanAuthenticate(const AccountId& account_id, BoolCallback result);
// Try to authenticate.
void TryAuthenticate(const AccountId& account_id,
const Key& key,
BoolCallback result);
// Returns true if the cryptohome backend should be used. Sometimes the prefs
// backend should be used even when cryptohome is available, ie, when there is
// an non-migrated PIN key.
bool ShouldUseCryptohome(const AccountId& account_id);
// Resets any cached state for testing purposes.
static void ResetForTesting();
private:
// Called when we know if the cryptohome supports PIN.
void OnIsCryptohomeBackendSupported(bool is_supported);
// Called when a migration attempt has completed. If |success| is true the PIN
// should be cleared from prefs.
void OnPinMigrationAttemptComplete(Profile* profile, bool success);
// True if still trying to determine which backend should be used.
bool resolving_backend_ = true;
// Determining if the device supports cryptohome-based keys requires an async
// dbus call to cryptohome. If we receive a request before we know which
// backend to use, the request will be pushed to this list and invoked once
// the backend configuration is determined.
std::vector<base::OnceClosure> on_cryptohome_support_received_;
// Non-null if we should use the cryptohome backend. If null, the prefs
// backend should be used.
std::unique_ptr<PinStorageCryptohome> cryptohome_backend_;
// Blocks chrome from restarting while migrating from prefs to cryptohome PIN.
std::unique_ptr<ScopedKeepAlive> scoped_keep_alive_;
DISALLOW_COPY_AND_ASSIGN(PinBackend);
};
} // namespace quick_unlock
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_LOGIN_QUICK_UNLOCK_PIN_BACKEND_H_