// Copyright 2014 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 "extensions/browser/verified_contents.h"

#include <stddef.h>

#include "base/base64url.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "components/crx_file/id_util.h"
#include "crypto/signature_verifier.h"
#include "extensions/common/extension.h"

using base::DictionaryValue;
using base::ListValue;
using base::Value;

namespace {

const char kBlockSizeKey[] = "block_size";
const char kContentHashesKey[] = "content_hashes";
const char kDescriptionKey[] = "description";
const char kFilesKey[] = "files";
const char kFormatKey[] = "format";
const char kHashBlockSizeKey[] = "hash_block_size";
const char kHeaderKidKey[] = "header.kid";
const char kItemIdKey[] = "item_id";
const char kItemVersionKey[] = "item_version";
const char kPathKey[] = "path";
const char kPayloadKey[] = "payload";
const char kProtectedKey[] = "protected";
const char kRootHashKey[] = "root_hash";
const char kSignatureKey[] = "signature";
const char kSignaturesKey[] = "signatures";
const char kSignedContentKey[] = "signed_content";
const char kTreeHashPerFile[] = "treehash per file";
const char kTreeHash[] = "treehash";
const char kWebstoreKId[] = "webstore";

// Helper function to iterate over a list of dictionaries, returning the
// dictionary that has |key| -> |value| in it, if any, or NULL.
const DictionaryValue* FindDictionaryWithValue(const ListValue* list,
                                               const std::string& key,
                                               const std::string& value) {
  for (const auto& i : *list) {
    const DictionaryValue* dictionary;
    if (!i.GetAsDictionary(&dictionary))
      continue;
    std::string found_value;
    if (dictionary->GetString(key, &found_value) && found_value == value)
      return dictionary;
  }
  return NULL;
}

}  // namespace

namespace extensions {

VerifiedContents::VerifiedContents(const uint8_t* public_key,
                                   size_t public_key_size)
    : public_key_(public_key),
      public_key_size_(public_key_size),
      valid_signature_(false),  // Guilty until proven innocent.
      block_size_(0) {}

VerifiedContents::~VerifiedContents() {
}

// The format of the payload json is:
// {
//   "item_id": "<extension id>",
//   "item_version": "<extension version>",
//   "content_hashes": [
//     {
//       "block_size": 4096,
//       "hash_block_size": 4096,
//       "format": "treehash",
//       "files": [
//         {
//           "path": "foo/bar",
//           "root_hash": "<base64url encoded bytes>"
//         },
//         ...
//       ]
//     }
//   ]
// }
bool VerifiedContents::InitFrom(const base::FilePath& path) {
  std::string payload;
  if (!GetPayload(path, &payload))
    return false;

  std::unique_ptr<base::Value> value(base::JSONReader::Read(payload));
  if (!value.get() || !value->IsType(Value::Type::DICTIONARY))
    return false;
  DictionaryValue* dictionary = static_cast<DictionaryValue*>(value.get());

  std::string item_id;
  if (!dictionary->GetString(kItemIdKey, &item_id) ||
      !crx_file::id_util::IdIsValid(item_id))
    return false;
  extension_id_ = item_id;

  std::string version_string;
  if (!dictionary->GetString(kItemVersionKey, &version_string))
    return false;
  version_ = base::Version(version_string);
  if (!version_.IsValid())
    return false;

  ListValue* hashes_list = NULL;
  if (!dictionary->GetList(kContentHashesKey, &hashes_list))
    return false;

  for (size_t i = 0; i < hashes_list->GetSize(); i++) {
    DictionaryValue* hashes = NULL;
    if (!hashes_list->GetDictionary(i, &hashes))
      return false;
    std::string format;
    if (!hashes->GetString(kFormatKey, &format) || format != kTreeHash)
      continue;

    int block_size = 0;
    int hash_block_size = 0;
    if (!hashes->GetInteger(kBlockSizeKey, &block_size) ||
        !hashes->GetInteger(kHashBlockSizeKey, &hash_block_size))
      return false;
    block_size_ = block_size;

    // We don't support using a different block_size and hash_block_size at
    // the moment.
    if (block_size_ != hash_block_size)
      return false;

    ListValue* files = NULL;
    if (!hashes->GetList(kFilesKey, &files))
      return false;

    for (size_t j = 0; j < files->GetSize(); j++) {
      DictionaryValue* data = NULL;
      if (!files->GetDictionary(j, &data))
        return false;
      std::string file_path_string;
      std::string encoded_root_hash;
      std::string root_hash;
      if (!data->GetString(kPathKey, &file_path_string) ||
          !base::IsStringUTF8(file_path_string) ||
          !data->GetString(kRootHashKey, &encoded_root_hash) ||
          !base::Base64UrlDecode(encoded_root_hash,
                                 base::Base64UrlDecodePolicy::IGNORE_PADDING,
                                 &root_hash))
        return false;
      base::FilePath file_path =
          base::FilePath::FromUTF8Unsafe(file_path_string);
      RootHashes::iterator i = root_hashes_.insert(std::make_pair(
          base::ToLowerASCII(file_path.value()), std::string()));
      i->second.swap(root_hash);
    }

    break;
  }
  return true;
}

bool VerifiedContents::HasTreeHashRoot(
    const base::FilePath& relative_path) const {
  base::FilePath::StringType path = base::ToLowerASCII(
      relative_path.NormalizePathSeparatorsTo('/').value());
  return root_hashes_.find(path) != root_hashes_.end();
}

bool VerifiedContents::TreeHashRootEquals(const base::FilePath& relative_path,
                                          const std::string& expected) const {
  base::FilePath::StringType path = base::ToLowerASCII(
      relative_path.NormalizePathSeparatorsTo('/').value());
  for (RootHashes::const_iterator i = root_hashes_.find(path);
       i != root_hashes_.end();
       ++i) {
    if (expected == i->second)
      return true;
  }
  return false;
}

// We're loosely following the "JSON Web Signature" draft spec for signing
// a JSON payload:
//
//   http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-26
//
// The idea is that you have some JSON that you want to sign, so you
// base64-encode that and put it as the "payload" field in a containing
// dictionary. There might be signatures of it done with multiple
// algorithms/parameters, so the payload is followed by a list of one or more
// signature sections. Each signature section specifies the
// algorithm/parameters in a JSON object which is base64url encoded into one
// string and put into a "protected" field in the signature. Then the encoded
// "payload" and "protected" strings are concatenated with a "." in between
// them and those bytes are signed and the resulting signature is base64url
// encoded and placed in the "signature" field. To allow for extensibility, we
// wrap this, so we can include additional kinds of payloads in the future. E.g.
// [
//   {
//     "description": "treehash per file",
//     "signed_content": {
//       "payload": "<base64url encoded JSON to sign>",
//       "signatures": [
//         {
//           "protected": "<base64url encoded JSON with algorithm/parameters>",
//           "header": {
//             <object with metadata about this signature, eg a key identifier>
//           }
//           "signature":
//              "<base64url encoded signature over payload || . || protected>"
//         },
//         ... <zero or more additional signatures> ...
//       ]
//     }
//   }
// ]
// There might be both a signature generated with a webstore private key and a
// signature generated with the extension's private key - for now we only
// verify the webstore one (since the id is in the payload, so we can trust
// that it is for a given extension), but in the future we may validate using
// the extension's key too (eg for non-webstore hosted extensions such as
// enterprise installs).
bool VerifiedContents::GetPayload(const base::FilePath& path,
                                  std::string* payload) {
  std::string contents;
  if (!base::ReadFileToString(path, &contents))
    return false;
  std::unique_ptr<base::Value> value(base::JSONReader::Read(contents));
  if (!value.get() || !value->IsType(Value::Type::LIST))
    return false;
  ListValue* top_list = static_cast<ListValue*>(value.get());

  // Find the "treehash per file" signed content, e.g.
  // [
  //   {
  //     "description": "treehash per file",
  //     "signed_content": {
  //       "signatures": [ ... ],
  //       "payload": "..."
  //     }
  //   }
  // ]
  const DictionaryValue* dictionary =
      FindDictionaryWithValue(top_list, kDescriptionKey, kTreeHashPerFile);
  const DictionaryValue* signed_content = NULL;
  if (!dictionary ||
      !dictionary->GetDictionaryWithoutPathExpansion(kSignedContentKey,
                                                     &signed_content)) {
    return false;
  }

  const ListValue* signatures = NULL;
  if (!signed_content->GetList(kSignaturesKey, &signatures))
    return false;

  const DictionaryValue* signature_dict =
      FindDictionaryWithValue(signatures, kHeaderKidKey, kWebstoreKId);
  if (!signature_dict)
    return false;

  std::string protected_value;
  std::string encoded_signature;
  std::string decoded_signature;
  if (!signature_dict->GetString(kProtectedKey, &protected_value) ||
      !signature_dict->GetString(kSignatureKey, &encoded_signature) ||
      !base::Base64UrlDecode(encoded_signature,
                             base::Base64UrlDecodePolicy::IGNORE_PADDING,
                             &decoded_signature))
    return false;

  std::string encoded_payload;
  if (!signed_content->GetString(kPayloadKey, &encoded_payload))
    return false;

  valid_signature_ =
      VerifySignature(protected_value, encoded_payload, decoded_signature);
  if (!valid_signature_)
    return false;

  if (!base::Base64UrlDecode(encoded_payload,
                             base::Base64UrlDecodePolicy::IGNORE_PADDING,
                             payload))
    return false;

  return true;
}

bool VerifiedContents::VerifySignature(const std::string& protected_value,
                                       const std::string& payload,
                                       const std::string& signature_bytes) {
  crypto::SignatureVerifier signature_verifier;
  if (!signature_verifier.VerifyInit(
          crypto::SignatureVerifier::RSA_PKCS1_SHA256,
          reinterpret_cast<const uint8_t*>(signature_bytes.data()),
          signature_bytes.size(), public_key_, public_key_size_)) {
    VLOG(1) << "Could not verify signature - VerifyInit failure";
    return false;
  }

  signature_verifier.VerifyUpdate(
      reinterpret_cast<const uint8_t*>(protected_value.data()),
      protected_value.size());

  std::string dot(".");
  signature_verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(dot.data()),
                                  dot.size());

  signature_verifier.VerifyUpdate(
      reinterpret_cast<const uint8_t*>(payload.data()), payload.size());

  if (!signature_verifier.VerifyFinal()) {
    VLOG(1) << "Could not verify signature - VerifyFinal failure";
    return false;
  }
  return true;
}

}  // namespace extensions
