// 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 "net/cert/ct_serialization.h"

#include "base/logging.h"
#include "crypto/sha2.h"
#include "net/cert/merkle_tree_leaf.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/signed_tree_head.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"

namespace net {

namespace ct {

namespace {

const size_t kLogIdLength = crypto::kSHA256Length;

enum SignatureType {
  SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP = 0,
  TREE_HASH = 1,
};

// Reads a variable-length SCT list that has been TLS encoded.
// The bytes read from |in| are discarded (i.e. |in|'s prefix removed)
// |max_list_length| contains the overall length of the encoded list.
// |max_item_length| contains the maximum length of a single item.
// On success, returns true and updates |*out| with the encoded list.
bool ReadSCTList(CBS* in, std::vector<base::StringPiece>* out) {
  std::vector<base::StringPiece> result;

  CBS sct_list_data;

  if (!CBS_get_u16_length_prefixed(in, &sct_list_data))
    return false;

  while (CBS_len(&sct_list_data) != 0) {
    CBS sct_list_item;
    if (!CBS_get_u16_length_prefixed(&sct_list_data, &sct_list_item)) {
      DVLOG(1) << "Failed to read item in list.";
      return false;
    }
    if (CBS_len(&sct_list_item) == 0) {
      DVLOG(1) << "Empty item in list";
      return false;
    }

    result.emplace_back(reinterpret_cast<const char*>(CBS_data(&sct_list_item)),
                        CBS_len(&sct_list_item));
  }

  result.swap(*out);
  return true;
}

// Checks and converts a hash algorithm.
// |in| is the numeric representation of the algorithm.
// If the hash algorithm value is in a set of known values, fills in |out| and
// returns true. Otherwise, returns false.
bool ConvertHashAlgorithm(unsigned in, DigitallySigned::HashAlgorithm* out) {
  switch (in) {
    case DigitallySigned::HASH_ALGO_NONE:
    case DigitallySigned::HASH_ALGO_MD5:
    case DigitallySigned::HASH_ALGO_SHA1:
    case DigitallySigned::HASH_ALGO_SHA224:
    case DigitallySigned::HASH_ALGO_SHA256:
    case DigitallySigned::HASH_ALGO_SHA384:
    case DigitallySigned::HASH_ALGO_SHA512:
      break;
    default:
      return false;
  }
  *out = static_cast<DigitallySigned::HashAlgorithm>(in);
  return true;
}

// Checks and converts a signing algorithm.
// |in| is the numeric representation of the algorithm.
// If the signing algorithm value is in a set of known values, fills in |out|
// and returns true. Otherwise, returns false.
bool ConvertSignatureAlgorithm(
    unsigned in,
    DigitallySigned::SignatureAlgorithm* out) {
  switch (in) {
    case DigitallySigned::SIG_ALGO_ANONYMOUS:
    case DigitallySigned::SIG_ALGO_RSA:
    case DigitallySigned::SIG_ALGO_DSA:
    case DigitallySigned::SIG_ALGO_ECDSA:
      break;
    default:
      return false;
  }
  *out = static_cast<DigitallySigned::SignatureAlgorithm>(in);
  return true;
}

// Writes a SignedEntryData of type X.509 cert to |*output|.
// |input| is the SignedEntryData containing the certificate.
// Returns true if the leaf_certificate in the SignedEntryData does not exceed
// kMaxAsn1CertificateLength and so can be written to |output|.
bool EncodeAsn1CertSignedEntry(const SignedEntryData& input, CBB* output) {
  CBB child;
  return CBB_add_u24_length_prefixed(output, &child) &&
         CBB_add_bytes(
             &child,
             reinterpret_cast<const uint8_t*>(input.leaf_certificate.data()),
             input.leaf_certificate.size()) &&
         CBB_flush(output);
}

// Writes a SignedEntryData of type PreCertificate to |*output|.
// |input| is the SignedEntryData containing the TBSCertificate and issuer key
// hash. Returns true if the TBSCertificate component in the SignedEntryData
// does not exceed kMaxTbsCertificateLength and so can be written to |output|.
bool EncodePrecertSignedEntry(const SignedEntryData& input, CBB* output) {
  CBB child;
  return CBB_add_bytes(
             output,
             reinterpret_cast<const uint8_t*>(input.issuer_key_hash.data),
             kLogIdLength) &&
         CBB_add_u24_length_prefixed(output, &child) &&
         CBB_add_bytes(
             &child,
             reinterpret_cast<const uint8_t*>(input.tbs_certificate.data()),
             input.tbs_certificate.size()) &&
         CBB_flush(output);
}

}  // namespace

bool EncodeDigitallySigned(const DigitallySigned& input, CBB* output_cbb) {
  CBB child;
  return CBB_add_u8(output_cbb, input.hash_algorithm) &&
         CBB_add_u8(output_cbb, input.signature_algorithm) &&
         CBB_add_u16_length_prefixed(output_cbb, &child) &&
         CBB_add_bytes(
             &child,
             reinterpret_cast<const uint8_t*>(input.signature_data.data()),
             input.signature_data.size()) &&
         CBB_flush(output_cbb);
}

bool EncodeDigitallySigned(const DigitallySigned& input,
                           std::string* output) {
  bssl::ScopedCBB output_cbb;
  if (!CBB_init(output_cbb.get(), 64) ||
      !EncodeDigitallySigned(input, output_cbb.get()) ||
      !CBB_flush(output_cbb.get())) {
    return false;
  }

  output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
                 CBB_len(output_cbb.get()));
  return true;
}

bool DecodeDigitallySigned(CBS* input, DigitallySigned* output) {
  uint8_t hash_algo;
  uint8_t sig_algo;
  CBS sig_data;

  if (!CBS_get_u8(input, &hash_algo) || !CBS_get_u8(input, &sig_algo) ||
      !CBS_get_u16_length_prefixed(input, &sig_data)) {
    return false;
  }

  DigitallySigned result;
  if (!ConvertHashAlgorithm(hash_algo, &result.hash_algorithm)) {
    DVLOG(1) << "Invalid hash algorithm " << hash_algo;
    return false;
  }
  if (!ConvertSignatureAlgorithm(sig_algo, &result.signature_algorithm)) {
    DVLOG(1) << "Invalid signature algorithm " << sig_algo;
    return false;
  }
  result.signature_data.assign(
      reinterpret_cast<const char*>(CBS_data(&sig_data)), CBS_len(&sig_data));

  *output = result;
  return true;
}

bool DecodeDigitallySigned(base::StringPiece* input, DigitallySigned* output) {
  CBS input_cbs;
  CBS_init(&input_cbs, reinterpret_cast<const uint8_t*>(input->data()),
           input->size());
  bool result = DecodeDigitallySigned(&input_cbs, output);
  input->remove_prefix(input->size() - CBS_len(&input_cbs));
  return result;
}

static bool EncodeSignedEntry(const SignedEntryData& input, CBB* output) {
  if (!CBB_add_u16(output, input.type)) {
    return false;
  }
  switch (input.type) {
    case SignedEntryData::LOG_ENTRY_TYPE_X509:
      return EncodeAsn1CertSignedEntry(input, output);
    case SignedEntryData::LOG_ENTRY_TYPE_PRECERT:
      return EncodePrecertSignedEntry(input, output);
  }
  return false;
}

bool EncodeSignedEntry(const SignedEntryData& input, std::string* output) {
  bssl::ScopedCBB output_cbb;

  if (!CBB_init(output_cbb.get(), 64) ||
      !EncodeSignedEntry(input, output_cbb.get()) ||
      !CBB_flush(output_cbb.get())) {
    return false;
  }

  output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
                 CBB_len(output_cbb.get()));
  return true;
}

static bool ReadTimeSinceEpoch(CBS* input, base::Time* output) {
  uint64_t time_since_epoch = 0;
  if (!CBS_get_u64(input, &time_since_epoch))
    return false;

  base::CheckedNumeric<int64_t> time_since_epoch_signed = time_since_epoch;

  if (!time_since_epoch_signed.IsValid()) {
    DVLOG(1) << "Timestamp value too big to cast to int64_t: "
             << time_since_epoch;
    return false;
  }

  *output =
      base::Time::UnixEpoch() +
      base::TimeDelta::FromMilliseconds(time_since_epoch_signed.ValueOrDie());

  return true;
}

static bool WriteTimeSinceEpoch(const base::Time& timestamp, CBB* output) {
  base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch();
  return CBB_add_u64(output, time_since_epoch.InMilliseconds());
}

bool EncodeTreeLeaf(const MerkleTreeLeaf& leaf, std::string* output) {
  bssl::ScopedCBB output_cbb;
  CBB child;
  if (!CBB_init(output_cbb.get(), 64) ||
      !CBB_add_u8(output_cbb.get(), 0) ||  // version: 1
      !CBB_add_u8(output_cbb.get(), 0) ||  // type: timestamped entry
      !WriteTimeSinceEpoch(leaf.timestamp, output_cbb.get()) ||
      !EncodeSignedEntry(leaf.signed_entry, output_cbb.get()) ||
      !CBB_add_u16_length_prefixed(output_cbb.get(), &child) ||
      !CBB_add_bytes(&child,
                     reinterpret_cast<const uint8_t*>(leaf.extensions.data()),
                     leaf.extensions.size()) ||
      !CBB_flush(output_cbb.get())) {
    return false;
  }
  output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
                 CBB_len(output_cbb.get()));
  return true;
}

bool EncodeV1SCTSignedData(const base::Time& timestamp,
                           const std::string& serialized_log_entry,
                           const std::string& extensions,
                           std::string* output) {
  bssl::ScopedCBB output_cbb;
  CBB child;
  if (!CBB_init(output_cbb.get(), 64) ||
      !CBB_add_u8(output_cbb.get(), SignedCertificateTimestamp::V1) ||
      !CBB_add_u8(output_cbb.get(), SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP) ||
      !WriteTimeSinceEpoch(timestamp, output_cbb.get()) ||
      // NOTE: serialized_log_entry must already be serialized and contain the
      // length as the prefix.
      !CBB_add_bytes(
          output_cbb.get(),
          reinterpret_cast<const uint8_t*>(serialized_log_entry.data()),
          serialized_log_entry.size()) ||
      !CBB_add_u16_length_prefixed(output_cbb.get(), &child) ||
      !CBB_add_bytes(&child,
                     reinterpret_cast<const uint8_t*>(extensions.data()),
                     extensions.size()) ||
      !CBB_flush(output_cbb.get())) {
    return false;
  }
  output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
                 CBB_len(output_cbb.get()));
  return true;
}

bool EncodeTreeHeadSignature(const SignedTreeHead& signed_tree_head,
                             std::string* output) {
  bssl::ScopedCBB output_cbb;
  if (!CBB_init(output_cbb.get(), 64) ||
      !CBB_add_u8(output_cbb.get(), signed_tree_head.version) ||
      !CBB_add_u8(output_cbb.get(), TREE_HASH) ||
      !WriteTimeSinceEpoch(signed_tree_head.timestamp, output_cbb.get()) ||
      !CBB_add_u64(output_cbb.get(), signed_tree_head.tree_size) ||
      !CBB_add_bytes(
          output_cbb.get(),
          reinterpret_cast<const uint8_t*>(signed_tree_head.sha256_root_hash),
          kSthRootHashLength)) {
    return false;
  }
  output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
                 CBB_len(output_cbb.get()));
  return true;
}

bool DecodeSCTList(base::StringPiece input,
                   std::vector<base::StringPiece>* output) {
  std::vector<base::StringPiece> result;
  CBS input_cbs;
  CBS_init(&input_cbs, reinterpret_cast<const uint8_t*>(input.data()),
           input.size());
  if (!ReadSCTList(&input_cbs, &result) || CBS_len(&input_cbs) != 0 ||
      result.empty()) {
    return false;
  }

  output->swap(result);
  return true;
}

bool DecodeSignedCertificateTimestamp(
    base::StringPiece* input,
    scoped_refptr<SignedCertificateTimestamp>* output) {
  scoped_refptr<SignedCertificateTimestamp> result(
      new SignedCertificateTimestamp());
  uint8_t version;
  CBS input_cbs;
  CBS_init(&input_cbs, reinterpret_cast<const uint8_t*>(input->data()),
           input->size());
  if (!CBS_get_u8(&input_cbs, &version))
    return false;
  if (version != SignedCertificateTimestamp::V1) {
    DVLOG(1) << "Unsupported/invalid version " << version;
    return false;
  }

  result->version = SignedCertificateTimestamp::V1;
  CBS log_id;
  CBS extensions;
  if (!CBS_get_bytes(&input_cbs, &log_id, kLogIdLength) ||
      !ReadTimeSinceEpoch(&input_cbs, &result->timestamp) ||
      !CBS_get_u16_length_prefixed(&input_cbs, &extensions) ||
      !DecodeDigitallySigned(&input_cbs, &result->signature)) {
    return false;
  }

  result->log_id.assign(reinterpret_cast<const char*>(CBS_data(&log_id)),
                        CBS_len(&log_id));
  result->extensions.assign(
      reinterpret_cast<const char*>(CBS_data(&extensions)),
      CBS_len(&extensions));
  output->swap(result);
  input->remove_prefix(input->size() - CBS_len(&input_cbs));
  return true;
}

bool EncodeSignedCertificateTimestamp(
    const scoped_refptr<ct::SignedCertificateTimestamp>& input,
    std::string* output) {
  // This function only supports serialization of V1 SCTs.
  DCHECK_EQ(SignedCertificateTimestamp::V1, input->version);
  DCHECK_EQ(kLogIdLength, input->log_id.size());

  bssl::ScopedCBB output_cbb;
  CBB child;
  if (!CBB_init(output_cbb.get(), 64) ||
      !CBB_add_u8(output_cbb.get(), input->version) ||
      !CBB_add_bytes(output_cbb.get(),
                     reinterpret_cast<const uint8_t*>(input->log_id.data()),
                     kLogIdLength) ||
      !WriteTimeSinceEpoch(input->timestamp, output_cbb.get()) ||
      !CBB_add_u16_length_prefixed(output_cbb.get(), &child) ||
      !CBB_add_bytes(&child,
                     reinterpret_cast<const uint8_t*>(input->extensions.data()),
                     input->extensions.size()) ||
      !EncodeDigitallySigned(input->signature, output_cbb.get()) ||
      !CBB_flush(output_cbb.get())) {
    return false;
  }
  output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
                 CBB_len(output_cbb.get()));
  return true;
}

bool EncodeSCTListForTesting(const base::StringPiece& sct,
                             std::string* output) {
  bssl::ScopedCBB encoded_sct, output_cbb;
  CBB encoded_sct_child, output_child;
  if (!CBB_init(encoded_sct.get(), 64) || !CBB_init(output_cbb.get(), 64) ||
      !CBB_add_u16_length_prefixed(encoded_sct.get(), &encoded_sct_child) ||
      !CBB_add_bytes(&encoded_sct_child,
                     reinterpret_cast<const uint8_t*>(sct.data()),
                     sct.size()) ||
      !CBB_flush(encoded_sct.get()) ||
      !CBB_add_u16_length_prefixed(output_cbb.get(), &output_child) ||
      !CBB_add_bytes(&output_child, CBB_data(encoded_sct.get()),
                     CBB_len(encoded_sct.get())) ||
      !CBB_flush(output_cbb.get())) {
    return false;
  }

  output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
                 CBB_len(output_cbb.get()));
  return true;
}

}  // namespace ct

}  // namespace net
