blob: 103d00931e2ab2acf4f823f9534da0090d6bf8f1 [file] [log] [blame]
// Copyright 2019 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_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_PARENT_ACCESS_CODE_AUTHENTICATOR_H_
#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_PARENT_ACCESS_CODE_AUTHENTICATOR_H_
#include <memory>
#include <ostream>
#include <string>
#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "crypto/hmac.h"
namespace chromeos {
// Configuration used to generate and verify Parent Access Code.
class ParentAccessCodeConfig {
public:
// To create valid ParentAccessCodeConfig:
// * |shared_secret| cannot be empty
// * |code_validity| needs to be in between 30s and 3600s
// * |clock_drift_tolerance| needs to be between 0 and 1800s
// The above restrictions are applied to ParentAccessCodeConfig policy that is
// the main source of this configuration.
ParentAccessCodeConfig(const std::string& shared_secret,
base::TimeDelta code_validity,
base::TimeDelta clock_drift_tolerance);
ParentAccessCodeConfig(const ParentAccessCodeConfig& rhs);
ParentAccessCodeConfig& operator=(const ParentAccessCodeConfig&);
~ParentAccessCodeConfig();
// Secret shared between child and parent devices.
const std::string& shared_secret() const { return shared_secret_; }
// Time that access code is valid for.
base::TimeDelta code_validity() const { return code_validity_; }
// The allowed difference between the clock on child and parent devices.
base::TimeDelta clock_drift_tolerance() const {
return clock_drift_tolerance_;
}
private:
std::string shared_secret_;
base::TimeDelta code_validity_;
base::TimeDelta clock_drift_tolerance_;
};
// Parent Access Code that can be used to authorize various actions on child
// user's device.
// Typical lifetime of the code is 10 minutes and clock difference between
// generating and validating device is half of the code lifetime. Clock
// difference is accounted for during code validation.
class ParentAccessCode {
public:
// To create valid ParentAccessCode:
// * |code| needs to be 6 characters long
// * |valid_to| needs to be greater than |valid_from|
ParentAccessCode(const std::string& code,
base::Time valid_from,
base::Time valid_to);
ParentAccessCode(const ParentAccessCode&);
ParentAccessCode& operator=(const ParentAccessCode&);
~ParentAccessCode();
// Parent access code.
const std::string& code() const { return code_; }
// Code validity start time.
base::Time valid_from() const { return valid_from_; }
// Code expiration time.
base::Time valid_to() const { return valid_to_; }
bool operator==(const ParentAccessCode&) const;
bool operator!=(const ParentAccessCode&) const;
friend std::ostream& operator<<(std::ostream&, const ParentAccessCode&);
private:
std::string code_;
base::Time valid_from_;
base::Time valid_to_;
};
// Generates and validates ParentAccessCodes.
// Does not support timestamp from before Unix Epoch.
class ParentAccessCodeAuthenticator {
public:
// Granularity of which generation and verification are carried out. Should
// not exceed code validity period.
static constexpr base::TimeDelta kCodeGranularity =
base::TimeDelta::FromMinutes(1);
explicit ParentAccessCodeAuthenticator(const ParentAccessCodeConfig& config);
~ParentAccessCodeAuthenticator();
// Generates Parent Access Code from the given |timestamp|. Returns the code
// if generation was successful. |timestamp| needs to be greater or equal Unix
// Epoch.
base::Optional<ParentAccessCode> Generate(base::Time timestamp);
// Returns ParentAccessCode structure with validity information, if |code| is
// valid for the given timestamp. |timestamp| needs to be greater or equal
// Unix Epoch.
base::Optional<ParentAccessCode> Validate(const std::string& code,
base::Time timestamp);
private:
// Returns ParentAccessCode structure with validity information, if |code| is
// valid for the range [|valid_from|, |valid_to|). |valid_to| needs to be
// greater or equal to |valid_from|. |valid_from| needs to be greater or equal
// Unix Epoch.
base::Optional<ParentAccessCode> ValidateInRange(const std::string& code,
base::Time valid_from,
base::Time valid_to);
// Configuration used to generate and validate parent access code.
const ParentAccessCodeConfig config_;
// Keyed-hash message authentication generator.
crypto::HMAC hmac_{crypto::HMAC::SHA1};
DISALLOW_COPY_AND_ASSIGN(ParentAccessCodeAuthenticator);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_PARENT_ACCESS_CODE_AUTHENTICATOR_H_