blob: f85f32c9babb515e4cf542d445d83e3a2d62af4f [file] [log] [blame]
// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/macros.h>
#include "login_manager/job_manager.h"
namespace login_manager {
class ChildOutputCollector;
class LoginMetrics;
class SystemUtils;
// Generates time-based opaque device identifiers used as keys in server-side
// device state storage. This allows persisting device-specific data on the
// server that survives device recovery and can be restored afterwards.
// Identifiers are generated by running a number of stable hardware identifiers
// along with a quantized time stamp through a cryptographic hash function. The
// resulting identifiers shouldn't be predictable by servers, so it's important
// to include hardware identifiers that are only known to the device.
// Quantized time is included in order to avoid sharing stable device
// identifiers with the server. This improves privacy, since the server will
// only be able to track the device within the validity time of the identifiers
// it has collected. Once the device stops sharing identifiers, it will
// eventually regain anonymity.
class ServerBackedStateKeyGenerator {
// Callback type for state key generation requests.
typedef base::Callback<void(const std::vector<std::vector<uint8_t>>&)>
// The power of two determining the size of the time quanta for device state
// keys, i.e. the quanta will be of size 2^kDeviceStateKeyTimeQuantumPower
// seconds. 2^23 seconds corresponds to 97.09 days.
static const int kDeviceStateKeyTimeQuantumPower = 23;
// The number of future time quanta to generate device state identifiers for.
// This determines the interval after which a device will no longer receive
// server-backed state information and thus corresponds to the delay until a
// device becomes anonymous to the server again.
// The goal here is to guarantee state key validity for 1 year into the
// future. 4 quanta are needed to cover a year, but the current quantum is
// clipped short in the general case. Hence, one buffer quantum is needed to
// make up for the clipping, yielding a total of 5 quanta.
static const int kDeviceStateKeyFutureQuanta = 5;
ServerBackedStateKeyGenerator(SystemUtils* system_utils,
LoginMetrics* metrics);
virtual ~ServerBackedStateKeyGenerator();
// Parses a machine information string containing newline-separated key=value
// pairs. Removes quoting from names and values. Returns true if parsing is
// successful.
static bool ParseMachineInfo(const std::string& data,
std::map<std::string, std::string>* params);
// Sets a machine information parameters. Returns false if a parameter is
// missing.
bool InitMachineInfo(const std::map<std::string, std::string>& params);
// Requests the currently-valid state keys to be computed based on system
// time. It is the responsibility of the caller to ensure that the system time
// is accurate before starting the request! The state keys (sorted by time
// quantum in ascending order) are returned via |callback|, potentially after
// waiting for machine info to become available. If the state keys can't be
// computed due to missing machine identifiers, |callback| will be invoked
// with an empty vector.
virtual void RequestStateKeys(const StateKeyCallback& callback);
// Computes the keys and stores them in |state_keys|. In case of error,
// |state_keys| will be cleared.
void ComputeKeys(std::vector<std::vector<uint8_t>>* state_keys);
SystemUtils* system_utils_;
LoginMetrics* metrics_;
// Pending state key generation callbacks.
std::vector<StateKeyCallback> pending_callbacks_;
// The data required to generate state keys.
bool machine_info_available_;
std::string stable_device_secret_;
// TODO(mnissler): Remove these and the corresponding code once the old way
// of generating state keys is no longer used in the wild, i.e. all devices
// can be assumed to have a stable device secret.
std::string machine_serial_number_;
std::string disk_serial_number_;
std::string group_code_key_;
} // namespace login_manager