// Copyright 2015 The Weave 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 "src/privet/security_manager.h"

#include <algorithm>
#include <limits>
#include <memory>
#include <set>

#include <base/bind.h>
#include <base/guid.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <weave/provider/task_runner.h>

#include "src/data_encoding.h"
#include "src/privet/auth_manager.h"
#include "src/privet/constants.h"
#include "src/privet/openssl_utils.h"
#include "src/string_utils.h"
#include "third_party/chromium/crypto/p224_spake.h"

namespace weave {
namespace privet {

namespace {

const int kSessionExpirationTimeMinutes = 5;
const int kPairingExpirationTimeMinutes = 5;
const int kMaxAllowedPairingAttemts = 3;
const int kPairingBlockingTimeMinutes = 1;

const int kAccessTokenExpirationSeconds = 3600;

class Spakep224Exchanger : public SecurityManager::KeyExchanger {
 public:
  explicit Spakep224Exchanger(const std::string& password)
      : spake_(crypto::P224EncryptedKeyExchange::kPeerTypeServer, password) {}
  ~Spakep224Exchanger() override = default;

  // SecurityManager::KeyExchanger methods.
  const std::string& GetMessage() override { return spake_.GetNextMessage(); }

  bool ProcessMessage(const std::string& message, ErrorPtr* error) override {
    switch (spake_.ProcessMessage(message)) {
      case crypto::P224EncryptedKeyExchange::kResultPending:
        return true;
      case crypto::P224EncryptedKeyExchange::kResultFailed:
        Error::AddTo(error, FROM_HERE, errors::kInvalidClientCommitment,
                     spake_.error());
        return false;
      default:
        LOG(FATAL) << "SecurityManager uses only one round trip";
    }
    return false;
  }

  const std::string& GetKey() const override {
    return spake_.GetUnverifiedKey();
  }

 private:
  crypto::P224EncryptedKeyExchange spake_;
};

class UnsecureKeyExchanger : public SecurityManager::KeyExchanger {
 public:
  explicit UnsecureKeyExchanger(const std::string& password)
      : password_(password) {}
  ~UnsecureKeyExchanger() override = default;

  // SecurityManager::KeyExchanger methods.
  const std::string& GetMessage() override { return password_; }

  bool ProcessMessage(const std::string& message, ErrorPtr* error) override {
    return true;
  }

  const std::string& GetKey() const override { return password_; }

 private:
  std::string password_;
};

}  // namespace

SecurityManager::SecurityManager(const Config* config,
                                 AuthManager* auth_manager,
                                 provider::TaskRunner* task_runner)
    : config_{config}, auth_manager_{auth_manager}, task_runner_{task_runner} {
  CHECK(auth_manager_);
  CHECK_EQ(GetSettings().embedded_code.empty(),
           std::find(GetSettings().pairing_modes.begin(),
                     GetSettings().pairing_modes.end(),
                     PairingType::kEmbeddedCode) ==
               GetSettings().pairing_modes.end());
}

SecurityManager::~SecurityManager() {
  while (!pending_sessions_.empty())
    ClosePendingSession(pending_sessions_.begin()->first);
}

bool SecurityManager::CreateAccessTokenImpl(AuthType auth_type,
                                            AuthScope desired_scope,
                                            std::vector<uint8_t>* access_token,
                                            AuthScope* access_token_scope,
                                            base::TimeDelta* access_token_ttl) {
  UserInfo user_info{desired_scope,
                     std::to_string(static_cast<int>(auth_type)) + "/" +
                         std::to_string(++last_user_id_)};

  const base::TimeDelta kTtl =
      base::TimeDelta::FromSeconds(kAccessTokenExpirationSeconds);

  if (access_token)
    *access_token = auth_manager_->CreateAccessToken(user_info, kTtl);

  if (access_token_scope)
    *access_token_scope = user_info.scope();

  if (access_token_ttl)
    *access_token_ttl = kTtl;

  return true;
}

bool SecurityManager::CreateAccessTokenImpl(
    AuthType auth_type,
    const std::vector<uint8_t>& auth_code,
    AuthScope desired_scope,
    std::vector<uint8_t>* access_token,
    AuthScope* access_token_scope,
    base::TimeDelta* access_token_ttl,
    ErrorPtr* error) {
  auto disabled_mode = [](ErrorPtr* error) {
    Error::AddTo(error, FROM_HERE, errors::kInvalidAuthMode,
                 "Mode is not available");
    return false;
  };

  switch (auth_type) {
    case AuthType::kAnonymous:
      if (!IsAnonymousAuthSupported())
        return disabled_mode(error);
      return CreateAccessTokenImpl(auth_type, desired_scope, access_token,
                                   access_token_scope, access_token_ttl);
    case AuthType::kPairing:
      if (!IsPairingAuthSupported())
        return disabled_mode(error);
      if (!IsValidPairingCode(auth_code)) {
        Error::AddTo(error, FROM_HERE, errors::kInvalidAuthCode,
                     "Invalid authCode");
        return false;
      }
      return CreateAccessTokenImpl(auth_type, desired_scope, access_token,
                                   access_token_scope, access_token_ttl);
    case AuthType::kLocal:
      if (!IsLocalAuthSupported())
        return disabled_mode(error);
      const base::TimeDelta kTtl =
          base::TimeDelta::FromSeconds(kAccessTokenExpirationSeconds);
      return auth_manager_->CreateAccessTokenFromAuth(
          auth_code, kTtl, access_token, access_token_scope, access_token_ttl,
          error);
  }

  Error::AddTo(error, FROM_HERE, errors::kInvalidAuthMode,
               "Unsupported auth mode");
  return false;
}

bool SecurityManager::CreateAccessToken(AuthType auth_type,
                                        const std::string& auth_code,
                                        AuthScope desired_scope,
                                        std::string* access_token,
                                        AuthScope* access_token_scope,
                                        base::TimeDelta* access_token_ttl,
                                        ErrorPtr* error) {
  std::vector<uint8_t> auth_decoded;
  if (auth_type != AuthType::kAnonymous &&
      !Base64Decode(auth_code, &auth_decoded)) {
    Error::AddToPrintf(error, FROM_HERE, errors::kInvalidAuthorization,
                       "Invalid auth_code encoding: %s", auth_code.c_str());
    return false;
  }

  std::vector<uint8_t> access_token_decoded;
  if (!CreateAccessTokenImpl(auth_type, auth_decoded, desired_scope,
                             &access_token_decoded, access_token_scope,
                             access_token_ttl, error)) {
    return false;
  }

  if (access_token)
    *access_token = Base64Encode(access_token_decoded);

  return true;
}

bool SecurityManager::ParseAccessToken(const std::string& token,
                                       UserInfo* user_info,
                                       ErrorPtr* error) const {
  std::vector<uint8_t> decoded;
  if (!Base64Decode(token, &decoded)) {
    Error::AddToPrintf(error, FROM_HERE, errors::kInvalidAuthorization,
                       "Invalid token encoding: %s", token.c_str());
    return false;
  }

  return auth_manager_->ParseAccessToken(decoded, user_info, error);
}

std::set<PairingType> SecurityManager::GetPairingTypes() const {
  return GetSettings().pairing_modes;
}

std::set<CryptoType> SecurityManager::GetCryptoTypes() const {
  std::set<CryptoType> result{CryptoType::kSpake_p224};
  if (GetSettings().disable_security)
    result.insert(CryptoType::kNone);
  return result;
}

std::set<AuthType> SecurityManager::GetAuthTypes() const {
  std::set<AuthType> result;
  if (IsAnonymousAuthSupported())
    result.insert(AuthType::kAnonymous);

  if (IsPairingAuthSupported())
    result.insert(AuthType::kPairing);

  if (IsLocalAuthSupported())
    result.insert(AuthType::kLocal);

  return result;
}

std::string SecurityManager::ClaimRootClientAuthToken(ErrorPtr* error) {
  return Base64Encode(auth_manager_->ClaimRootClientAuthToken(
      RootClientTokenOwner::kClient, error));
}

bool SecurityManager::ConfirmClientAuthToken(const std::string& token,
                                             ErrorPtr* error) {
  std::vector<uint8_t> token_decoded;
  if (!Base64Decode(token, &token_decoded)) {
    Error::AddToPrintf(error, FROM_HERE, errors::kInvalidFormat,
                       "Invalid auth token string: '%s'", token.c_str());
    return false;
  }
  return auth_manager_->ConfirmClientAuthToken(token_decoded, error);
}

const Config::Settings& SecurityManager::GetSettings() const {
  return config_->GetSettings();
}

bool SecurityManager::IsValidPairingCode(
    const std::vector<uint8_t>& auth_code) const {
  if (GetSettings().disable_security)
    return true;
  for (const auto& session : confirmed_sessions_) {
    const std::string& key = session.second->GetKey();
    const std::string& id = session.first;
    if (auth_code == HmacSha256(std::vector<uint8_t>(key.begin(), key.end()),
                                std::vector<uint8_t>(id.begin(), id.end()))) {
      pairing_attemts_ = 0;
      block_pairing_until_ = base::Time{};
      return true;
    }
  }
  LOG(ERROR) << "Attempt to authenticate with invalide code.";
  return false;
}

bool SecurityManager::StartPairing(PairingType mode,
                                   CryptoType crypto,
                                   std::string* session_id,
                                   std::string* device_commitment,
                                   ErrorPtr* error) {
  if (!CheckIfPairingAllowed(error))
    return false;

  const auto& pairing_modes = GetSettings().pairing_modes;
  if (std::find(pairing_modes.begin(), pairing_modes.end(), mode) ==
      pairing_modes.end()) {
    Error::AddTo(error, FROM_HERE, errors::kInvalidParams,
                 "Pairing mode is not enabled");
    return false;
  }

  std::string code;
  switch (mode) {
    case PairingType::kEmbeddedCode:
      CHECK(!GetSettings().embedded_code.empty());
      code = GetSettings().embedded_code;
      break;
    case PairingType::kPinCode:
      code = base::StringPrintf("%04i", base::RandInt(0, 9999));
      break;
    default:
      Error::AddTo(error, FROM_HERE, errors::kInvalidParams,
                   "Unsupported pairing mode");
      return false;
  }

  std::unique_ptr<KeyExchanger> spake;
  switch (crypto) {
    case CryptoType::kSpake_p224:
      spake.reset(new Spakep224Exchanger(code));
      break;
    case CryptoType::kNone:
      if (GetSettings().disable_security) {
        spake.reset(new UnsecureKeyExchanger(code));
        break;
      }
    // Fall through...
    default:
      Error::AddTo(error, FROM_HERE, errors::kInvalidParams,
                   "Unsupported crypto");
      return false;
  }

  // Allow only a single session at a time for now.
  while (!pending_sessions_.empty())
    ClosePendingSession(pending_sessions_.begin()->first);

  std::string session;
  do {
    session = base::GenerateGUID();
  } while (confirmed_sessions_.find(session) != confirmed_sessions_.end() ||
           pending_sessions_.find(session) != pending_sessions_.end());
  std::string commitment = spake->GetMessage();
  pending_sessions_.insert(std::make_pair(session, std::move(spake)));

  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::Bind(base::IgnoreResult(&SecurityManager::ClosePendingSession),
                 weak_ptr_factory_.GetWeakPtr(), session),
      base::TimeDelta::FromMinutes(kPairingExpirationTimeMinutes));

  *session_id = session;
  *device_commitment = Base64Encode(commitment);
  LOG(INFO) << "Pairing code for session " << *session_id << " is " << code;
  // TODO(vitalybuka): Handle case when device can't start multiple pairing
  // simultaneously and implement throttling to avoid brute force attack.
  if (!on_start_.is_null()) {
    on_start_.Run(session, mode,
                  std::vector<uint8_t>{code.begin(), code.end()});
  }

  return true;
}

bool SecurityManager::ConfirmPairing(const std::string& session_id,
                                     const std::string& client_commitment,
                                     std::string* fingerprint,
                                     std::string* signature,
                                     ErrorPtr* error) {
  auto session = pending_sessions_.find(session_id);
  if (session == pending_sessions_.end()) {
    Error::AddToPrintf(error, FROM_HERE, errors::kUnknownSession,
                       "Unknown session id: '%s'", session_id.c_str());
    return false;
  }

  std::vector<uint8_t> commitment;
  if (!Base64Decode(client_commitment, &commitment)) {
    ClosePendingSession(session_id);
    Error::AddToPrintf(error, FROM_HERE, errors::kInvalidFormat,
                       "Invalid commitment string: '%s'",
                       client_commitment.c_str());
    return false;
  }

  if (!session->second->ProcessMessage(
          std::string(commitment.begin(), commitment.end()), error)) {
    ClosePendingSession(session_id);
    Error::AddTo(error, FROM_HERE, errors::kCommitmentMismatch,
                 "Pairing code or crypto implementation mismatch");
    return false;
  }

  const std::string& key = session->second->GetKey();
  VLOG(3) << "KEY " << base::HexEncode(key.data(), key.size());

  const auto& certificate_fingerprint =
      auth_manager_->GetCertificateFingerprint();
  *fingerprint = Base64Encode(certificate_fingerprint);
  std::vector<uint8_t> cert_hmac = HmacSha256(
      std::vector<uint8_t>(key.begin(), key.end()), certificate_fingerprint);
  *signature = Base64Encode(cert_hmac);
  confirmed_sessions_.insert(
      std::make_pair(session->first, std::move(session->second)));
  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::Bind(base::IgnoreResult(&SecurityManager::CloseConfirmedSession),
                 weak_ptr_factory_.GetWeakPtr(), session_id),
      base::TimeDelta::FromMinutes(kSessionExpirationTimeMinutes));
  ClosePendingSession(session_id);
  return true;
}

bool SecurityManager::CancelPairing(const std::string& session_id,
                                    ErrorPtr* error) {
  bool confirmed = CloseConfirmedSession(session_id);
  bool pending = ClosePendingSession(session_id);
  if (pending) {
    CHECK_GE(pairing_attemts_, 1);
    --pairing_attemts_;
  }
  CHECK(!confirmed || !pending);
  if (confirmed || pending)
    return true;
  Error::AddToPrintf(error, FROM_HERE, errors::kUnknownSession,
                     "Unknown session id: '%s'", session_id.c_str());
  return false;
}

std::string SecurityManager::CreateSessionId() {
  return Base64Encode(auth_manager_->CreateSessionId());
}

void SecurityManager::RegisterPairingListeners(
    const PairingStartListener& on_start,
    const PairingEndListener& on_end) {
  CHECK(on_start_.is_null() && on_end_.is_null());
  on_start_ = on_start;
  on_end_ = on_end;
}

bool SecurityManager::CheckIfPairingAllowed(ErrorPtr* error) {
  if (GetSettings().disable_security)
    return true;

  if (block_pairing_until_ > auth_manager_->Now()) {
    Error::AddTo(error, FROM_HERE, errors::kDeviceBusy,
                 "Too many pairing attempts");
    return false;
  }

  if (++pairing_attemts_ >= kMaxAllowedPairingAttemts) {
    LOG(INFO) << "Pairing blocked for" << kPairingBlockingTimeMinutes
              << "minutes.";
    block_pairing_until_ = auth_manager_->Now();
    block_pairing_until_ +=
        base::TimeDelta::FromMinutes(kPairingBlockingTimeMinutes);
  }

  return true;
}

bool SecurityManager::ClosePendingSession(const std::string& session_id) {
  // The most common source of these session_id values is the map containing
  // the sessions, which we're about to clear out.  Make a local copy.
  const std::string safe_session_id{session_id};
  const size_t num_erased = pending_sessions_.erase(safe_session_id);
  if (num_erased > 0 && !on_end_.is_null())
    on_end_.Run(safe_session_id);
  return num_erased != 0;
}

bool SecurityManager::CloseConfirmedSession(const std::string& session_id) {
  return confirmed_sessions_.erase(session_id) != 0;
}

bool SecurityManager::IsAnonymousAuthSupported() const {
  return GetSettings().local_anonymous_access_role != AuthScope::kNone;
}

bool SecurityManager::IsPairingAuthSupported() const {
  return GetSettings().local_pairing_enabled;
}

bool SecurityManager::IsLocalAuthSupported() const {
  return GetSettings().root_client_token_owner != RootClientTokenOwner::kNone;
}

}  // namespace privet
}  // namespace weave
