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

#include "chrome/browser/extensions/install_signer.h"

#include <stddef.h>
#include <stdint.h>
#include <utility>

#include "base/base64.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/process.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
#include "crypto/random.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
#include "crypto/signature_verifier.h"
#include "extensions/common/extension.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "rlz/buildflags/buildflags.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"

#if BUILDFLAG(ENABLE_RLZ)
#include "rlz/lib/machine_id.h"
#endif

namespace {

using extensions::ExtensionIdSet;

const char kExpireDateKey[] = "expire_date";
const char kExpiryKey[] = "expiry";
const char kHashKey[] = "hash";
const char kIdsKey[] = "ids";
const char kInvalidIdsKey[] = "invalid_ids";
const char kProtocolVersionKey[] = "protocol_version";
const char kSaltKey[] = "salt";
const char kSignatureKey[] = "signature";
const char kSignatureFormatVersionKey[] = "signature_format_version";
const char kTimestampKey[] = "timestamp";

const char kContentTypeJSON[] = "application/json";

// This allows us to version the format of what we write into the prefs,
// allowing for forward migration, as well as detecting forwards/backwards
// incompatabilities, etc.
const int kSignatureFormatVersion = 2;

const size_t kSaltBytes = 32;

const char kBackendUrl[] =
    "https://www.googleapis.com/chromewebstore/v1.1/items/verify";

const char kPublicKeyPEM[] =                                            \
    "-----BEGIN PUBLIC KEY-----"                                        \
    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj/u/XDdjlDyw7gHEtaaa"  \
    "sZ9GdG8WOKAyJzXd8HFrDtz2Jcuy7er7MtWvHgNDA0bwpznbI5YdZeV4UfCEsA4S"  \
    "rA5b3MnWTHwA1bgbiDM+L9rrqvcadcKuOlTeN48Q0ijmhHlNFbTzvT9W0zw/GKv8"  \
    "LgXAHggxtmHQ/Z9PP2QNF5O8rUHHSL4AJ6hNcEKSBVSmbbjeVm4gSXDuED5r0nwx"  \
    "vRtupDxGYp8IZpP5KlExqNu1nbkPc+igCTIB6XsqijagzxewUHCdovmkb2JNtskx"  \
    "/PMIEv+TvWIx2BzqGp71gSh/dV7SJ3rClvWd2xj8dtxG8FfAWDTIIi0qZXWn2Qhi"  \
    "zQIDAQAB"                                                          \
    "-----END PUBLIC KEY-----";

GURL GetBackendUrl() {
  return GURL(kBackendUrl);
}

// Hashes |salt| with the machine id, base64-encodes it and returns it in
// |result|.
bool HashWithMachineId(const std::string& salt, std::string* result) {
  std::string machine_id;
#if BUILDFLAG(ENABLE_RLZ)
  if (!rlz_lib::GetMachineId(&machine_id))
    return false;
#else
  machine_id = "unknown";
#endif

  std::unique_ptr<crypto::SecureHash> hash(
      crypto::SecureHash::Create(crypto::SecureHash::SHA256));

  hash->Update(machine_id.data(), machine_id.size());
  hash->Update(salt.data(), salt.size());

  std::string result_bytes(crypto::kSHA256Length, 0);
  hash->Finish(base::data(result_bytes), result_bytes.size());

  base::Base64Encode(result_bytes, result);
  return true;
}

// Validates that |input| is a string of the form "YYYY-MM-DD".
bool ValidateExpireDateFormat(const std::string& input) {
  if (input.length() != 10)
    return false;
  for (int i = 0; i < 10; i++) {
    if (i == 4 ||  i == 7) {
      if (input[i] != '-')
        return false;
    } else if (!base::IsAsciiDigit(input[i])) {
      return false;
    }
  }
  return true;
}

// Sets the value of |key| in |dictionary| to be a list with the contents of
// |ids|.
void SetExtensionIdSet(base::DictionaryValue* dictionary,
                       const char* key,
                       const ExtensionIdSet& ids) {
  auto id_list = std::make_unique<base::ListValue>();
  for (auto i = ids.begin(); i != ids.end(); ++i)
    id_list->AppendString(*i);
  dictionary->Set(key, std::move(id_list));
}

// Tries to fetch a list of strings from |dictionay| for |key|, and inserts
// them into |ids|. The return value indicates success/failure. Note: on
// failure, |ids| might contain partial results, for instance if some of the
// members of the list were not strings.
bool GetExtensionIdSet(const base::DictionaryValue& dictionary,
                       const char* key,
                       ExtensionIdSet* ids) {
  const base::ListValue* id_list = NULL;
  if (!dictionary.GetList(key, &id_list))
    return false;
  for (auto i = id_list->begin(); i != id_list->end(); ++i) {
    std::string id;
    if (!i->GetAsString(&id)) {
      return false;
    }
    ids->insert(id);
  }
  return true;
}

}  // namespace

namespace extensions {

InstallSignature::InstallSignature() {
}
InstallSignature::InstallSignature(const InstallSignature& other) = default;
InstallSignature::~InstallSignature() {
}

void InstallSignature::ToValue(base::DictionaryValue* value) const {
  CHECK(value);

  value->SetInteger(kSignatureFormatVersionKey, kSignatureFormatVersion);
  SetExtensionIdSet(value, kIdsKey, ids);
  SetExtensionIdSet(value, kInvalidIdsKey, invalid_ids);
  value->SetString(kExpireDateKey, expire_date);
  std::string salt_base64;
  std::string signature_base64;
  base::Base64Encode(salt, &salt_base64);
  base::Base64Encode(signature, &signature_base64);
  value->SetString(kSaltKey, salt_base64);
  value->SetString(kSignatureKey, signature_base64);
  value->SetString(kTimestampKey,
                   base::NumberToString(timestamp.ToInternalValue()));
}

// static
std::unique_ptr<InstallSignature> InstallSignature::FromValue(
    const base::DictionaryValue& value) {
  std::unique_ptr<InstallSignature> result(new InstallSignature);

  // For now we don't want to support any backwards compability, but in the
  // future if we do, we would want to put the migration code here.
  int format_version = 0;
  if (!value.GetInteger(kSignatureFormatVersionKey, &format_version) ||
      format_version != kSignatureFormatVersion) {
    result.reset();
    return result;
  }

  std::string salt_base64;
  std::string signature_base64;
  if (!value.GetString(kExpireDateKey, &result->expire_date) ||
      !value.GetString(kSaltKey, &salt_base64) ||
      !value.GetString(kSignatureKey, &signature_base64) ||
      !base::Base64Decode(salt_base64, &result->salt) ||
      !base::Base64Decode(signature_base64, &result->signature)) {
    result.reset();
    return result;
  }

  // Note: earlier versions of the code did not write out a timestamp value
  // so older entries will not necessarily have this.
  if (value.HasKey(kTimestampKey)) {
    std::string timestamp;
    int64_t timestamp_value = 0;
    if (!value.GetString(kTimestampKey, &timestamp) ||
        !base::StringToInt64(timestamp, &timestamp_value)) {
      result.reset();
      return result;
    }
    result->timestamp = base::Time::FromInternalValue(timestamp_value);
  }

  if (!GetExtensionIdSet(value, kIdsKey, &result->ids) ||
      !GetExtensionIdSet(value, kInvalidIdsKey, &result->invalid_ids)) {
    result.reset();
    return result;
  }

  return result;
}

InstallSigner::InstallSigner(
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    const ExtensionIdSet& ids)
    : ids_(ids), url_loader_factory_(std::move(url_loader_factory)) {}

InstallSigner::~InstallSigner() {
}

// static
bool InstallSigner::VerifySignature(const InstallSignature& signature) {
  if (signature.ids.empty())
    return true;

  std::string signed_data;
  for (auto i = signature.ids.begin(); i != signature.ids.end(); ++i)
    signed_data.append(*i);

  std::string hash_base64;
  if (!HashWithMachineId(signature.salt, &hash_base64))
    return false;
  signed_data.append(hash_base64);

  signed_data.append(signature.expire_date);

  std::string public_key;
  if (!Extension::ParsePEMKeyBytes(kPublicKeyPEM, &public_key))
    return false;

  crypto::SignatureVerifier verifier;
  if (!verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
                           base::as_bytes(base::make_span(signature.signature)),
                           base::as_bytes(base::make_span(public_key))))
    return false;

  verifier.VerifyUpdate(base::as_bytes(base::make_span(signed_data)));
  return verifier.VerifyFinal();
}

// static
ExtensionIdSet InstallSigner::GetForcedNotFromWebstore() {
  std::string value =
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          ::switches::kExtensionsNotWebstore);
  if (value.empty())
    return ExtensionIdSet();

  std::vector<std::string> ids = base::SplitString(
      value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  return ExtensionIdSet(ids.begin(), ids.end());
}

namespace {

int g_request_count = 0;

base::LazyInstance<base::TimeTicks>::DestructorAtExit g_last_request_time =
    LAZY_INSTANCE_INITIALIZER;

base::LazyInstance<base::ThreadChecker>::DestructorAtExit
    g_single_thread_checker = LAZY_INSTANCE_INITIALIZER;

void LogRequestStartHistograms() {
  // Make sure we only ever call this from one thread, so that we don't have to
  // worry about race conditions setting g_last_request_time.
  DCHECK(g_single_thread_checker.Get().CalledOnValidThread());

  // Process::Current().CreationTime is only defined on some platforms.
#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)
  const base::Time process_creation_time =
      base::Process::Current().CreationTime();
  UMA_HISTOGRAM_COUNTS_1M(
      "ExtensionInstallSigner.UptimeAtTimeOfRequest",
      (base::Time::Now() - process_creation_time).InSeconds());
#endif  // defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)

  base::TimeDelta delta;
  base::TimeTicks now = base::TimeTicks::Now();
  if (!g_last_request_time.Get().is_null())
    delta = now - g_last_request_time.Get();
  g_last_request_time.Get() = now;
  UMA_HISTOGRAM_COUNTS_1M("ExtensionInstallSigner.SecondsSinceLastRequest",
                          delta.InSeconds());

  g_request_count += 1;
  UMA_HISTOGRAM_COUNTS_100("ExtensionInstallSigner.RequestCount",
                           g_request_count);
}

}  // namespace

void InstallSigner::GetSignature(SignatureCallback callback) {
  CHECK(!simple_loader_.get());
  CHECK(callback_.is_null());
  CHECK(salt_.empty());
  callback_ = std::move(callback);

  // If the set of ids is empty, just return an empty signature and skip the
  // call to the server.
  if (ids_.empty()) {
    if (!callback_.is_null())
      std::move(callback_).Run(std::make_unique<InstallSignature>());
    return;
  }

  salt_ = std::string(kSaltBytes, 0);
  crypto::RandBytes(base::data(salt_), salt_.size());

  std::string hash_base64;
  if (!HashWithMachineId(salt_, &hash_base64)) {
    ReportErrorViaCallback();
    return;
  }

  if (!url_loader_factory_) {
    ReportErrorViaCallback();
    return;
  }

  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("extension_install_signer", R"(
        semantics {
          sender: "Extension Install Signer"
          description: "Fetches the signatures for installed extensions."
          trigger:
            "Chrome detects an extension that requires installation "
            "verification."
          data:
            "The ids of the extensions that need to be verified, as well as a "
            "non-revertable salted hash of the user's machine id provided by "
            "RLZ library, which varies between different installs. This id is "
            "only used to verify the validity of the response."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
          cookies_allowed: YES
          cookies_store: "user"
          setting:
            "This feature cannot be disabled, but it is only activated if "
            "extensions are installed."
          chrome_policy {
            ExtensionInstallBlacklist {
              policy_options {mode: MANDATORY}
              ExtensionInstallBlacklist: {
                entries: '*'
              }
            }
          }
        })");

  // The request protocol is JSON of the form:
  // {
  //   "protocol_version": "1",
  //   "hash": "<base64-encoded hash value here>",
  //   "ids": [ "<id1>", "id2" ]
  // }
  base::DictionaryValue dictionary;
  dictionary.SetInteger(kProtocolVersionKey, 1);
  dictionary.SetString(kHashKey, hash_base64);
  std::unique_ptr<base::ListValue> id_list(new base::ListValue);
  for (auto i = ids_.begin(); i != ids_.end(); ++i) {
    id_list->AppendString(*i);
  }
  dictionary.Set(kIdsKey, std::move(id_list));
  std::string json;
  base::JSONWriter::Write(dictionary, &json);
  if (json.empty()) {
    ReportErrorViaCallback();
    return;
  }

  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = GetBackendUrl();
  resource_request->method = "POST";

  simple_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
                                                    traffic_annotation);
  simple_loader_->AttachStringForUpload(json, kContentTypeJSON);

  LogRequestStartHistograms();
  request_start_time_ = base::Time::Now();
  VLOG(1) << "Sending request: " << json;

  // TODO: Set a cap value to the expected content to be loaded, and use
  // DownloadToString instead.
  simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
      url_loader_factory_.get(),
      base::BindOnce(&InstallSigner::ParseFetchResponse,
                     base::Unretained(this)));
}

void InstallSigner::ReportErrorViaCallback() {
  if (!callback_.is_null())
    std::move(callback_).Run(nullptr);
}

void InstallSigner::ParseFetchResponse(
    std::unique_ptr<std::string> response_body) {
  UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.FetchSuccess", !!response_body);
  UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.GetResponseSuccess",
                        !!response_body && !response_body->empty());
  if (!response_body || response_body->empty()) {
    ReportErrorViaCallback();
    return;
  }
  VLOG(1) << "Got response: " << *response_body;

  // The response is JSON of the form:
  // {
  //   "protocol_version": "1",
  //   "signature": "<base64-encoded signature>",
  //   "expiry": "<date in YYYY-MM-DD form>",
  //   "invalid_ids": [ "<id3>", "<id4>" ]
  // }
  // where |invalid_ids| is a list of ids from the original request that
  // could not be verified to be in the webstore.

  base::DictionaryValue* dictionary = NULL;
  std::unique_ptr<base::Value> parsed =
      base::JSONReader::ReadDeprecated(*response_body);
  bool json_success = parsed.get() && parsed->GetAsDictionary(&dictionary);
  UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ParseJsonSuccess",
                        json_success);
  if (!json_success) {
    ReportErrorViaCallback();
    return;
  }

  int protocol_version = 0;
  std::string signature_base64;
  std::string signature;
  std::string expire_date;

  dictionary->GetInteger(kProtocolVersionKey, &protocol_version);
  dictionary->GetString(kSignatureKey, &signature_base64);
  dictionary->GetString(kExpiryKey, &expire_date);

  bool fields_success =
      protocol_version == 1 && !signature_base64.empty() &&
      ValidateExpireDateFormat(expire_date) &&
      base::Base64Decode(signature_base64, &signature);
  UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ParseFieldsSuccess",
                        fields_success);
  if (!fields_success) {
    ReportErrorViaCallback();
    return;
  }

  ExtensionIdSet invalid_ids;
  const base::ListValue* invalid_ids_list = NULL;
  if (dictionary->GetList(kInvalidIdsKey, &invalid_ids_list)) {
    for (size_t i = 0; i < invalid_ids_list->GetSize(); i++) {
      std::string id;
      if (!invalid_ids_list->GetString(i, &id)) {
        ReportErrorViaCallback();
        return;
      }
      invalid_ids.insert(id);
    }
  }

  HandleSignatureResult(signature, expire_date, invalid_ids);
}

void InstallSigner::HandleSignatureResult(const std::string& signature,
                                          const std::string& expire_date,
                                          const ExtensionIdSet& invalid_ids) {
  ExtensionIdSet valid_ids =
      base::STLSetDifference<ExtensionIdSet>(ids_, invalid_ids);

  std::unique_ptr<InstallSignature> result;
  if (!signature.empty()) {
    result.reset(new InstallSignature);
    result->ids = valid_ids;
    result->invalid_ids = invalid_ids;
    result->salt = salt_;
    result->signature = signature;
    result->expire_date = expire_date;
    result->timestamp = request_start_time_;
    bool verified = VerifySignature(*result);
    UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ResultWasValid", verified);
    UMA_HISTOGRAM_COUNTS_100("ExtensionInstallSigner.InvalidCount",
                             invalid_ids.size());
    if (!verified)
      result.reset();
  }

  if (!callback_.is_null())
    std::move(callback_).Run(std::move(result));
}


}  // namespace extensions
