// 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.

#ifndef LOGIN_MANAGER_SERVER_BACKED_STATE_KEY_GENERATOR_H_
#define LOGIN_MANAGER_SERVER_BACKED_STATE_KEY_GENERATOR_H_

#include <stdint.h>

#include <map>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/macros.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 {
 public:
  // Callback type for state key generation requests.
  typedef base::Callback<void(const std::vector<std::vector<uint8_t>>&)>
      StateKeyCallback;

  // 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);
  ServerBackedStateKeyGenerator(const ServerBackedStateKeyGenerator&) = delete;
  ServerBackedStateKeyGenerator& operator=(
      const ServerBackedStateKeyGenerator&) = delete;

  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);

 private:
  // 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_ = false;
  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

#endif  // LOGIN_MANAGER_SERVER_BACKED_STATE_KEY_GENERATOR_H_
