// 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_objects_extractor.h"

#include <string.h>

#include <openssl/bytestring.h>
#include <openssl/obj.h>
#include <openssl/x509.h>

#include "base/logging.h"
#include "base/sha1.h"
#include "base/strings/string_util.h"
#include "crypto/scoped_openssl_types.h"
#include "crypto/sha2.h"
#include "net/cert/asn1_util.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/ssl/scoped_openssl_types.h"

namespace net {

namespace ct {

namespace {

void FreeX509_EXTENSIONS(X509_EXTENSIONS* ptr) {
  sk_X509_EXTENSION_pop_free(ptr, X509_EXTENSION_free);
}

using ScopedX509_EXTENSIONS =
    crypto::ScopedOpenSSL<X509_EXTENSIONS, FreeX509_EXTENSIONS>;

// The wire form of the OID 1.3.6.1.4.1.11129.2.4.2. See Section 3.3 of
// RFC6962.
const uint8_t kEmbeddedSCTOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01,
                                   0xD6, 0x79, 0x02, 0x04, 0x02};

// The wire form of the OID 1.3.6.1.4.1.11129.2.4.5 - OCSP SingleExtension for
// X.509v3 Certificate Transparency Signed Certificate Timestamp List, see
// Section 3.3 of RFC6962.
const uint8_t kOCSPExtensionOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01,
                                     0xD6, 0x79, 0x02, 0x04, 0x05};

bool StringEqualToCBS(const std::string& value1, const CBS* value2) {
  if (CBS_len(value2) != value1.size())
    return false;
  return memcmp(value1.data(), CBS_data(value2), CBS_len(value2)) == 0;
}

ScopedX509 OSCertHandleToOpenSSL(X509Certificate::OSCertHandle os_handle) {
#if defined(USE_OPENSSL_CERTS)
  return ScopedX509(X509Certificate::DupOSCertHandle(os_handle));
#else
  std::string der_encoded;
  if (!X509Certificate::GetDEREncoded(os_handle, &der_encoded))
    return ScopedX509();
  const uint8_t* bytes = reinterpret_cast<const uint8_t*>(der_encoded.data());
  return ScopedX509(d2i_X509(NULL, &bytes, der_encoded.size()));
#endif
}

// Finds the SignedCertificateTimestampList in an extension with OID |oid| in
// |x509_exts|. If found, returns true and sets |*out_sct_list| to the encoded
// SCT list. |out_sct_list| may be NULL.
bool GetSCTListFromX509_EXTENSIONS(const X509_EXTENSIONS* x509_exts,
                                   const uint8_t* oid,
                                   size_t oid_len,
                                   std::string* out_sct_list) {
  for (size_t i = 0; i < sk_X509_EXTENSION_num(x509_exts); i++) {
    X509_EXTENSION* x509_ext = sk_X509_EXTENSION_value(x509_exts, i);
    if (static_cast<size_t>(x509_ext->object->length) == oid_len &&
        memcmp(x509_ext->object->data, oid, oid_len) == 0) {
      // The SCT list is an OCTET STRING inside the extension.
      CBS ext_value, sct_list;
      CBS_init(&ext_value, x509_ext->value->data, x509_ext->value->length);
      if (!CBS_get_asn1(&ext_value, &sct_list, CBS_ASN1_OCTETSTRING) ||
          CBS_len(&ext_value) != 0) {
        return false;
      }
      if (out_sct_list) {
        *out_sct_list =
            std::string(reinterpret_cast<const char*>(CBS_data(&sct_list)),
                        CBS_len(&sct_list));
      }
      return true;
    }
  }
  return false;
}

// Finds the SingleResponse in |responses| which matches |issuer| and
// |cert_serial_number|. On success, returns true and sets
// |*out_single_response| to the body of the SingleResponse starting at the
// |certStatus| field.
bool FindMatchingSingleResponse(CBS* responses,
                                X509Certificate::OSCertHandle issuer,
                                const std::string& cert_serial_number,
                                CBS* out_single_response) {
  std::string issuer_der;
  if (!X509Certificate::GetDEREncoded(issuer, &issuer_der))
    return false;

  base::StringPiece issuer_spki;
  if (!asn1::ExtractSPKIFromDERCert(issuer_der, &issuer_spki))
    return false;

  // In OCSP, only the key itself is under hash.
  base::StringPiece issuer_spk;
  if (!asn1::ExtractSubjectPublicKeyFromSPKI(issuer_spki, &issuer_spk))
    return false;

  // ExtractSubjectPublicKey... does not remove the initial octet encoding the
  // number of unused bits in the ASN.1 BIT STRING so we do it here. For public
  // keys, the bitstring is in practice always byte-aligned.
  if (issuer_spk.empty() || issuer_spk[0] != 0)
    return false;
  issuer_spk.remove_prefix(1);

  // TODO(ekasper): add SHA-384 to crypto/sha2.h and here if it proves
  // necessary.
  // TODO(ekasper): only compute the hashes on demand.
  std::string issuer_key_sha256_hash = crypto::SHA256HashString(issuer_spk);
  std::string issuer_key_sha1_hash =
      base::SHA1HashString(issuer_spk.as_string());

  while (CBS_len(responses) > 0) {
    CBS single_response, cert_id;
    if (!CBS_get_asn1(responses, &single_response, CBS_ASN1_SEQUENCE) ||
        !CBS_get_asn1(&single_response, &cert_id, CBS_ASN1_SEQUENCE)) {
      return false;
    }

    CBS hash_algorithm, hash, serial_number, issuer_name_hash, issuer_key_hash;
    if (!CBS_get_asn1(&cert_id, &hash_algorithm, CBS_ASN1_SEQUENCE) ||
        !CBS_get_asn1(&hash_algorithm, &hash, CBS_ASN1_OBJECT) ||
        !CBS_get_asn1(&cert_id, &issuer_name_hash, CBS_ASN1_OCTETSTRING) ||
        !CBS_get_asn1(&cert_id, &issuer_key_hash, CBS_ASN1_OCTETSTRING) ||
        !CBS_get_asn1(&cert_id, &serial_number, CBS_ASN1_INTEGER) ||
        CBS_len(&cert_id) != 0) {
      return false;
    }

    // Check the serial number matches.
    if (!StringEqualToCBS(cert_serial_number, &serial_number))
      continue;

    // Check if the issuer_key_hash matches.
    // TODO(ekasper): also use the issuer name hash in matching.
    switch (OBJ_cbs2nid(&hash)) {
      case NID_sha1:
        if (StringEqualToCBS(issuer_key_sha1_hash, &issuer_key_hash)) {
          *out_single_response = single_response;
          return true;
        }
        break;
      case NID_sha256:
        if (StringEqualToCBS(issuer_key_sha256_hash, &issuer_key_hash)) {
          *out_single_response = single_response;
          return true;
        }
        break;
    }
  }

  return false;
}

}  // namespace

bool ExtractEmbeddedSCTList(X509Certificate::OSCertHandle cert,
                            std::string* sct_list) {
  ScopedX509 x509(OSCertHandleToOpenSSL(cert));
  if (!x509)
    return false;
  X509_EXTENSIONS* x509_exts = x509->cert_info->extensions;
  if (!x509_exts)
    return false;
  return GetSCTListFromX509_EXTENSIONS(x509->cert_info->extensions,
                                       kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid),
                                       sct_list);
}

bool GetPrecertLogEntry(X509Certificate::OSCertHandle leaf,
                        X509Certificate::OSCertHandle issuer,
                        LogEntry* result) {
  result->Reset();

  ScopedX509 leaf_x509(OSCertHandleToOpenSSL(leaf));
  if (!leaf_x509)
    return false;

  // XXX(rsleevi): This check may be overkill, since we should be able to
  // generate precerts for certs without the extension. For now, just a sanity
  // check to match the reference implementation.
  if (!leaf_x509->cert_info->extensions ||
      !GetSCTListFromX509_EXTENSIONS(leaf_x509->cert_info->extensions,
                                     kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid),
                                     NULL)) {
    return false;
  }

  // The Precertificate log entry is the final certificate's TBSCertificate
  // without the SCT extension (RFC6962, section 3.2).
  ScopedX509 leaf_copy(X509_dup(leaf_x509.get()));
  if (!leaf_copy || !leaf_copy->cert_info->extensions) {
    NOTREACHED();
    return false;
  }
  X509_EXTENSIONS* leaf_copy_exts = leaf_copy->cert_info->extensions;
  for (size_t i = 0; i < sk_X509_EXTENSION_num(leaf_copy_exts); i++) {
    X509_EXTENSION* ext = sk_X509_EXTENSION_value(leaf_copy_exts, i);
    if (static_cast<size_t>(ext->object->length) == sizeof(kEmbeddedSCTOid) &&
        memcmp(ext->object->data, kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid)) ==
            0) {
      X509_EXTENSION_free(sk_X509_EXTENSION_delete(leaf_copy_exts, i));
      X509_CINF_set_modified(leaf_copy->cert_info);
      break;
    }
  }

  std::string to_be_signed;
  int len = i2d_X509_CINF(leaf_copy->cert_info, NULL);
  if (len < 0)
    return false;
  uint8_t* ptr =
      reinterpret_cast<uint8_t*>(base::WriteInto(&to_be_signed, len + 1));
  if (i2d_X509_CINF(leaf_copy->cert_info, &ptr) < 0)
    return false;

  // Extract the issuer's public key.
  std::string issuer_der;
  if (!X509Certificate::GetDEREncoded(issuer, &issuer_der))
    return false;
  base::StringPiece issuer_key;
  if (!asn1::ExtractSPKIFromDERCert(issuer_der, &issuer_key))
    return false;

  // Fill in the LogEntry.
  result->type = ct::LogEntry::LOG_ENTRY_TYPE_PRECERT;
  result->tbs_certificate.swap(to_be_signed);
  crypto::SHA256HashString(issuer_key, result->issuer_key_hash.data,
                           sizeof(result->issuer_key_hash.data));

  return true;
}

bool GetX509LogEntry(X509Certificate::OSCertHandle leaf, LogEntry* result) {
  DCHECK(leaf);

  std::string encoded;
  if (!X509Certificate::GetDEREncoded(leaf, &encoded))
    return false;

  result->Reset();
  result->type = ct::LogEntry::LOG_ENTRY_TYPE_X509;
  result->leaf_certificate.swap(encoded);
  return true;
}

bool ExtractSCTListFromOCSPResponse(X509Certificate::OSCertHandle issuer,
                                    const std::string& cert_serial_number,
                                    const std::string& ocsp_response,
                                    std::string* sct_list) {
  // The input is an OCSPResponse. See RFC2560, section 4.2.1. The SCT list is
  // in the extensions field of the SingleResponse which matches the input
  // certificate.
  CBS cbs;
  CBS_init(&cbs, reinterpret_cast<const uint8_t*>(ocsp_response.data()),
           ocsp_response.size());

  // Parse down to the ResponseBytes. The ResponseBytes is optional, but if it's
  // missing, this can't include an SCT list.
  CBS sequence, response_status, tagged_response_bytes, response_bytes;
  CBS response_type, response;
  if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE) || CBS_len(&cbs) != 0 ||
      !CBS_get_asn1(&sequence, &response_status, CBS_ASN1_ENUMERATED) ||
      !CBS_get_asn1(&sequence, &tagged_response_bytes,
                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
      CBS_len(&sequence) != 0 ||
      !CBS_get_asn1(&tagged_response_bytes, &response_bytes,
                    CBS_ASN1_SEQUENCE) ||
      CBS_len(&tagged_response_bytes) != 0 ||
      !CBS_get_asn1(&response_bytes, &response_type, CBS_ASN1_OBJECT) ||
      !CBS_get_asn1(&response_bytes, &response, CBS_ASN1_OCTETSTRING) ||
      CBS_len(&response_bytes) != 0) {
    return false;
  }

  // The only relevant ResponseType is id-pkix-ocsp-basic.
  if (OBJ_cbs2nid(&response_type) != NID_id_pkix_OCSP_basic)
    return false;

  // Parse the ResponseData out of the BasicOCSPResponse. Ignore the rest.
  CBS basic_response, response_data, responses;
  if (!CBS_get_asn1(&response, &basic_response, CBS_ASN1_SEQUENCE) ||
      CBS_len(&response) != 0 ||
      !CBS_get_asn1(&basic_response, &response_data, CBS_ASN1_SEQUENCE)) {
  }

  // Skip the optional version.
  const int kVersionTag = CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0;
  if (CBS_len(&response_data) > 0 &&
      CBS_data(&response_data)[0] == kVersionTag &&
      !CBS_get_asn1(&response_data, NULL /* version */, kVersionTag)) {
    return false;
  }

  // Extract the list of SingleResponses.
  if (!CBS_get_any_asn1_element(&response_data, NULL /* responderID */, NULL,
                                NULL) ||
      !CBS_get_any_asn1_element(&response_data, NULL /* producedAt */, NULL,
                                NULL) ||
      !CBS_get_asn1(&response_data, &responses, CBS_ASN1_SEQUENCE)) {
    return false;
  }

  CBS single_response;
  if (!FindMatchingSingleResponse(&responses, issuer, cert_serial_number,
                                  &single_response)) {
    return false;
  }

  // Skip the certStatus and thisUpdate fields.
  if (!CBS_get_any_asn1_element(&single_response, NULL /* certStatus */, NULL,
                                NULL) ||
      !CBS_get_any_asn1_element(&single_response, NULL /* thisUpdate */, NULL,
                                NULL)) {
    return false;
  }

  const int kNextUpdateTag =
      CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0;
  const int kSingleExtensionsTag =
      CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1;

  // Skip the optional nextUpdate field.
  if (CBS_len(&single_response) > 0 &&
      CBS_data(&single_response)[0] == kNextUpdateTag &&
      !CBS_get_asn1(&single_response, NULL /* nextUpdate */, kNextUpdateTag)) {
    return false;
  }

  CBS extensions;
  if (!CBS_get_asn1(&single_response, &extensions, kSingleExtensionsTag))
    return false;
  const uint8_t* ptr = CBS_data(&extensions);
  ScopedX509_EXTENSIONS x509_exts(
      d2i_X509_EXTENSIONS(NULL, &ptr, CBS_len(&extensions)));
  if (!x509_exts || ptr != CBS_data(&extensions) + CBS_len(&extensions))
    return false;

  return GetSCTListFromX509_EXTENSIONS(x509_exts.get(), kOCSPExtensionOid,
                                       sizeof(kOCSPExtensionOid), sct_list);
}

}  // namespace ct

}  // namespace net
