// 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 <algorithm>
#include <limits>

#include "base/logging.h"
#include "base/numerics/safe_math.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 "starboard/types.h"

namespace net {

namespace ct {

namespace {

// Note: length is always specified in bytes.
// CT protocol version length
const size_t kVersionLength = 1;

// Common V1 struct members
const size_t kTimestampLength = 8;
const size_t kSignedEntryTypeLength = 2;
const size_t kAsn1CertificateLengthBytes = 3;
const size_t kTbsCertificateLengthBytes = 3;
const size_t kExtensionsLengthBytes = 2;

// Members of a V1 SCT
const size_t kLogIdLength = crypto::kSHA256Length;
const size_t kHashAlgorithmLength = 1;
const size_t kSigAlgorithmLength = 1;
const size_t kSignatureLengthBytes = 2;

// Members of the digitally-signed struct of a V1 SCT
const size_t kSignatureTypeLength = 1;

const size_t kSCTListLengthBytes = 2;
const size_t kSerializedSCTLengthBytes = 2;

// Members of digitally-signed struct of a STH
const size_t kTreeSizeLength = 8;

// Members of a V1 MerkleTreeLeaf
const size_t kMerkleLeafTypeLength = 1;
const size_t kIssuerKeyHashLength = crypto::kSHA256Length;

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

// Reads a TLS-encoded variable length unsigned integer from |in|.
// The integer is expected to be in big-endian order, which is used by TLS.
// The bytes read from |in| are discarded (i.e. |in|'s prefix removed)
// |length| indicates the size (in bytes) of the integer. On success, returns
// true and stores the result in |*out|.
template <typename T>
bool ReadUint(size_t length, base::StringPiece* in, T* out) {
  if (in->size() < length)
    return false;
  DCHECK_NE(length, 0u);
  DCHECK_LE(length, sizeof(T));

  T result = static_cast<uint8_t>((*in)[0]);
  // This loop only executes if sizeof(T) > 1, because the first operation is
  // to shift left by 1 byte, which is undefined behaviour if T is a 1 byte
  // integer.
  for (size_t i = 1; i < length; ++i) {
    result = (result << 8) | static_cast<uint8_t>((*in)[i]);
  }
  in->remove_prefix(length);
  *out = result;
  return true;
}

// Reads a TLS-encoded field length from |in|.
// The bytes read from |in| are discarded (i.e. |in|'s prefix removed).
// |prefix_length| indicates the bytes needed to represent the length (e.g. 3).
// Max |prefix_length| is 8.
// success, returns true and stores the result in |*out|.
bool ReadLength(size_t prefix_length, base::StringPiece* in, size_t* out) {
  uint64_t length = 0;
  if (!ReadUint(prefix_length, in, &length))
    return false;
  base::CheckedNumeric<size_t> checked_length = length;
  if (!checked_length.IsValid())
    return false;
  *out = checked_length.ValueOrDie();
  return true;
}

// Reads |length| bytes from |*in|. If |*in| is too small, returns false.
// The bytes read from |in| are discarded (i.e. |in|'s prefix removed)
bool ReadFixedBytes(size_t length,
                    base::StringPiece* in,
                    base::StringPiece* out) {
  if (in->length() < length)
    return false;
  out->set(in->data(), length);
  in->remove_prefix(length);
  return true;
}

// Reads a length-prefixed variable amount of bytes from |in|, updating |out|
// on success. |prefix_length| indicates the number of bytes needed to represent
// the length.
// The bytes read from |in| are discarded (i.e. |in|'s prefix removed)
bool ReadVariableBytes(size_t prefix_length,
                       base::StringPiece* in,
                       base::StringPiece* out) {
  size_t length = 0;
  if (!ReadLength(prefix_length, in, &length))
    return false;
  return ReadFixedBytes(length, in, out);
}

// Reads a variable-length 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 ReadList(size_t max_list_length,
              size_t max_item_length,
              base::StringPiece* in,
              std::vector<base::StringPiece>* out) {
  std::vector<base::StringPiece> result;

  base::StringPiece list_data;
  if (!ReadVariableBytes(max_list_length, in, &list_data))
    return false;

  while (!list_data.empty()) {
    base::StringPiece list_item;
    if (!ReadVariableBytes(max_item_length, &list_data, &list_item)) {
      return false;
    }
    if (list_item.empty()) {
      return false;
    }
    result.push_back(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 TLS-encoded variable length unsigned integer to |output|.
// |length| indicates the size (in bytes) of the integer. This must be able to
// accomodate |value|.
// |value| the value itself to be written.
void WriteUint(size_t length, uint64_t value, std::string* output) {
  // Check that |value| fits into |length| bytes.
  DCHECK(length >= sizeof(value) || value >> (length * 8) == 0);

  for (; length > 0; --length) {
    output->push_back((value >> ((length - 1) * 8)) & 0xFF);
  }
}

// Writes an array to |output| from |input|.
// Should be used in one of two cases:
// * The length of |input| has already been encoded into the |output| stream.
// * The length of |input| is fixed and the reader is expected to specify that
// length when reading.
// If the length of |input| is dynamic and data is expected to follow it,
// WriteVariableBytes must be used.
// Returns the number of bytes written (the length of |input|).
size_t WriteEncodedBytes(const base::StringPiece& input, std::string* output) {
  input.AppendToString(output);
  return input.size();
}

// Writes a variable-length array to |output|.
// |prefix_length| indicates the number of bytes needed to represent the length.
// |input| is the array itself.
// If 1 <= |prefix_length| <= 8 and the size of |input| is less than
// 2^|prefix_length| - 1, encode the length and data and return true.
// Otherwise, return false.
bool WriteVariableBytes(size_t prefix_length,
                        const base::StringPiece& input,
                        std::string* output) {
  DCHECK_GE(prefix_length, 1u);
  DCHECK_LE(prefix_length, 8u);

  uint64_t input_size = input.size();
  uint64_t max_input_size = (prefix_length == 8)
                                ? UINT64_MAX
                                : ((UINT64_C(1) << (prefix_length * 8)) - 1);

  if (input_size > max_input_size)
    return false;

  WriteUint(prefix_length, input_size, output);
  WriteEncodedBytes(input, output);

  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,
                               std::string* output) {
  return WriteVariableBytes(kAsn1CertificateLengthBytes,
                            input.leaf_certificate, 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,
                              std::string* output) {
  WriteEncodedBytes(
      base::StringPiece(
          reinterpret_cast<const char*>(input.issuer_key_hash.data),
          kIssuerKeyHashLength),
      output);
  return WriteVariableBytes(kTbsCertificateLengthBytes,
                            input.tbs_certificate, output);
}

}  // namespace

bool EncodeDigitallySigned(const DigitallySigned& input,
                           std::string* output) {
  WriteUint(kHashAlgorithmLength, input.hash_algorithm, output);
  WriteUint(kSigAlgorithmLength, input.signature_algorithm,
            output);
  return WriteVariableBytes(kSignatureLengthBytes, input.signature_data,
                            output);
}

bool DecodeDigitallySigned(base::StringPiece* input,
                           DigitallySigned* output) {
  unsigned hash_algo;
  unsigned sig_algo;
  base::StringPiece sig_data;

  if (!ReadUint(kHashAlgorithmLength, input, &hash_algo) ||
      !ReadUint(kSigAlgorithmLength, input, &sig_algo) ||
      !ReadVariableBytes(kSignatureLengthBytes, input, &sig_data)) {
    return false;
  }

  DigitallySigned result;
  if (!ConvertHashAlgorithm(hash_algo, &result.hash_algorithm) ||
      !ConvertSignatureAlgorithm(sig_algo, &result.signature_algorithm)) {
    return false;
  }
  sig_data.CopyToString(&result.signature_data);

  *output = result;
  return true;
}

bool EncodeSignedEntry(const SignedEntryData& input, std::string* output) {
  WriteUint(kSignedEntryTypeLength, input.type, output);
  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;
}

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

  base::CheckedNumeric<int64_t> time_since_epoch_signed = time_since_epoch;

  if (!time_since_epoch_signed.IsValid()) {
    return false;
  }

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

  return true;
}

static void WriteTimeSinceEpoch(const base::Time& timestamp,
                                std::string* output) {
  base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch();
  WriteUint(kTimestampLength, time_since_epoch.InMilliseconds(), output);
}

bool EncodeTreeLeaf(const MerkleTreeLeaf& leaf, std::string* output) {
  WriteUint(kVersionLength, 0, output);         // version: 1
  WriteUint(kMerkleLeafTypeLength, 0, output);  // type: timestamped entry
  WriteTimeSinceEpoch(leaf.timestamp, output);
  if (!EncodeSignedEntry(leaf.signed_entry, output))
    return false;
  if (!WriteVariableBytes(kExtensionsLengthBytes, leaf.extensions, output))
    return false;

  return true;
}

bool EncodeV1SCTSignedData(const base::Time& timestamp,
                           const std::string& serialized_log_entry,
                           const std::string& extensions,
                           std::string* output) {
  WriteUint(kVersionLength, SignedCertificateTimestamp::V1,
            output);
  WriteUint(kSignatureTypeLength, SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP,
            output);
  WriteTimeSinceEpoch(timestamp, output);
  // NOTE: serialized_log_entry must already be serialized and contain the
  // length as the prefix.
  WriteEncodedBytes(serialized_log_entry, output);
  return WriteVariableBytes(kExtensionsLengthBytes, extensions, output);
}

void EncodeTreeHeadSignature(const SignedTreeHead& signed_tree_head,
                             std::string* output) {
  WriteUint(kVersionLength, signed_tree_head.version, output);
  WriteUint(kSignatureTypeLength, TREE_HASH, output);
  WriteTimeSinceEpoch(signed_tree_head.timestamp, output);
  WriteUint(kTreeSizeLength, signed_tree_head.tree_size, output);
  WriteEncodedBytes(
      base::StringPiece(signed_tree_head.sha256_root_hash, kSthRootHashLength),
      output);
}

bool DecodeSCTList(base::StringPiece input,
                   std::vector<base::StringPiece>* output) {
  std::vector<base::StringPiece> result;
  if (!ReadList(kSCTListLengthBytes, kSerializedSCTLengthBytes, &input,
                &result)) {
    return false;
  }

  if (!input.empty() || result.empty())
    return false;
  output->swap(result);
  return true;
}

bool DecodeSignedCertificateTimestamp(
    base::StringPiece* input,
    scoped_refptr<SignedCertificateTimestamp>* output) {
  scoped_refptr<SignedCertificateTimestamp> result(
      new SignedCertificateTimestamp());
  unsigned version;
  if (!ReadUint(kVersionLength, input, &version))
    return false;
  if (version != SignedCertificateTimestamp::V1) {
    return false;
  }

  result->version = SignedCertificateTimestamp::V1;
  base::StringPiece log_id;
  base::StringPiece extensions;
  if (!ReadFixedBytes(kLogIdLength, input, &log_id) ||
      !ReadTimeSinceEpoch(input, &result->timestamp) ||
      !ReadVariableBytes(kExtensionsLengthBytes, input, &extensions) ||
      !DecodeDigitallySigned(input, &result->signature)) {
    return false;
  }

  log_id.CopyToString(&result->log_id);
  extensions.CopyToString(&result->extensions);
  output->swap(result);
  return true;
}

void EncodeSignedCertificateTimestamp(
    const scoped_refptr<ct::SignedCertificateTimestamp>& input,
    std::string* output) {
  // This function only supports serialization of V1 SCTs.
  DCHECK_EQ(SignedCertificateTimestamp::V1, input->version);
  WriteUint(kVersionLength, input->version, output);
  DCHECK_EQ(kLogIdLength, input->log_id.size());
  WriteEncodedBytes(
      base::StringPiece(reinterpret_cast<const char*>(input->log_id.data()),
                        kLogIdLength),
      output);
  WriteTimeSinceEpoch(input->timestamp, output);
  WriteVariableBytes(kExtensionsLengthBytes, input->extensions, output);
  EncodeDigitallySigned(input->signature, output);
}

bool EncodeSCTListForTesting(const base::StringPiece& sct,
                             std::string* output) {
  std::string encoded_sct;
  return WriteVariableBytes(kSerializedSCTLengthBytes, sct, &encoded_sct) &&
         WriteVariableBytes(kSCTListLengthBytes, encoded_sct, output);
}

}  // namespace ct

}  // namespace net
