// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

// This is an implementation of DiceGenerateCertificate and the crypto
// operations that uses mbedtls. The algorithms used are SHA512, HKDF-SHA512,
// and deterministic ECDSA-P256-SHA512.

#include <stdint.h>
#include <string.h>

#include "dice/dice.h"
#include "dice/ops.h"
#include "dice/utils.h"
#include "mbedtls/asn1.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/bignum.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/ecp.h"
#include "mbedtls/hkdf.h"
#include "mbedtls/hmac_drbg.h"
#include "mbedtls/md.h"
#include "mbedtls/oid.h"
#include "mbedtls/pk.h"
#include "mbedtls/x509.h"
#include "mbedtls/x509_crt.h"

static const size_t kMaxCertificateSize = 2048;
static const size_t kMaxExtensionSize = 2048;
static const size_t kMaxKeyIdSize = 40;

static DiceResult SetupKeyPair(
    const uint8_t private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
    mbedtls_pk_context* context) {
  if (0 !=
      mbedtls_pk_setup(context, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY))) {
    return kDiceResultPlatformError;
  }
  // Use the |private_key_seed| directly to seed a PRNG which is then in turn
  // used to generate the private key. This implementation uses HMAC_DRBG in a
  // loop with no reduction, like RFC6979.
  DiceResult result = kDiceResultOk;
  mbedtls_hmac_drbg_context rng_context;
  mbedtls_hmac_drbg_init(&rng_context);
  if (0 != mbedtls_hmac_drbg_seed_buf(
               &rng_context, mbedtls_md_info_from_type(MBEDTLS_MD_SHA512),
               private_key_seed, DICE_PRIVATE_KEY_SEED_SIZE)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (0 != mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1,
                               mbedtls_pk_ec(*context),
                               mbedtls_hmac_drbg_random, &rng_context)) {
    result = kDiceResultPlatformError;
    goto out;
  }

out:
  mbedtls_hmac_drbg_free(&rng_context);
  return result;
}

static DiceResult GetIdFromKey(void* context,
                               const mbedtls_pk_context* pk_context,
                               uint8_t id[DICE_ID_SIZE]) {
  uint8_t raw_public_key[33];
  size_t raw_public_key_size = 0;
  mbedtls_ecp_keypair* key = mbedtls_pk_ec(*pk_context);

  if (0 != mbedtls_ecp_point_write_binary(
               &key->grp, &key->Q, MBEDTLS_ECP_PF_COMPRESSED,
               &raw_public_key_size, raw_public_key, sizeof(raw_public_key))) {
    return kDiceResultPlatformError;
  }
  return DiceDeriveCdiCertificateId(context, raw_public_key,
                                    raw_public_key_size, id);
}

// 54 byte name is prefix (13), hex id (40), and a null terminator.
static void GetNameFromId(const uint8_t id[DICE_ID_SIZE], char name[54]) {
  strcpy(name, "serialNumber=");
  DiceHexEncode(id, /*num_bytes=*/DICE_ID_SIZE, (uint8_t*)&name[13],
                /*out_size=*/40);
  name[53] = '\0';
}

static DiceResult GetSubjectKeyIdFromId(const uint8_t id[DICE_ID_SIZE],
                                        size_t buffer_size, uint8_t* buffer,
                                        size_t* actual_size) {
  uint8_t* pos = buffer + buffer_size;
  int length_or_error =
      mbedtls_asn1_write_octet_string(&pos, buffer, id, DICE_ID_SIZE);
  if (length_or_error < 0) {
    return kDiceResultPlatformError;
  }
  *actual_size = length_or_error;
  memmove(buffer, pos, *actual_size);
  return kDiceResultOk;
}

static int AddAuthorityKeyIdEncoding(uint8_t** pos, uint8_t* start,
                                     int length) {
  // From RFC 5280 4.2.1.1.
  const int kKeyIdentifierTag = 0;

  int ret = 0;  // Used by MBEDTLS_ASN1_CHK_ADD.
  MBEDTLS_ASN1_CHK_ADD(length, mbedtls_asn1_write_len(pos, start, length));
  MBEDTLS_ASN1_CHK_ADD(
      length,
      mbedtls_asn1_write_tag(
          pos, start, MBEDTLS_ASN1_CONTEXT_SPECIFIC | kKeyIdentifierTag));

  MBEDTLS_ASN1_CHK_ADD(length, mbedtls_asn1_write_len(pos, start, length));
  MBEDTLS_ASN1_CHK_ADD(
      length,
      mbedtls_asn1_write_tag(pos, start,
                             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
  return length;
}

static DiceResult GetAuthorityKeyIdFromId(const uint8_t id[DICE_ID_SIZE],
                                          size_t buffer_size, uint8_t* buffer,
                                          size_t* actual_size) {
  uint8_t* pos = buffer + buffer_size;
  int length_or_error =
      mbedtls_asn1_write_raw_buffer(&pos, buffer, id, DICE_ID_SIZE);
  if (length_or_error < 0) {
    return kDiceResultPlatformError;
  }
  length_or_error = AddAuthorityKeyIdEncoding(&pos, buffer, length_or_error);
  if (length_or_error < 0) {
    return kDiceResultPlatformError;
  }
  *actual_size = length_or_error;
  memmove(buffer, pos, *actual_size);
  return kDiceResultOk;
}

static uint8_t GetFieldTag(uint8_t tag) {
  return MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
}

// Can be used with MBEDTLS_ASN1_CHK_ADD.
static int WriteExplicitOctetStringField(uint8_t tag, const uint8_t* value,
                                         size_t value_size, uint8_t** pos,
                                         uint8_t* start) {
  int ret = 0;  // Used by MBEDTLS_ASN1_CHK_ADD.
  int field_length = 0;
  MBEDTLS_ASN1_CHK_ADD(field_length, mbedtls_asn1_write_octet_string(
                                         pos, start, value, value_size));
  // Explicitly tagged, so add the field tag too.
  MBEDTLS_ASN1_CHK_ADD(field_length,
                       mbedtls_asn1_write_len(pos, start, field_length));
  MBEDTLS_ASN1_CHK_ADD(field_length,
                       mbedtls_asn1_write_tag(pos, start, GetFieldTag(tag)));
  return field_length;
}

static int GetDiceExtensionDataHelper(const DiceInputValues* input_values,
                                      uint8_t** pos, uint8_t* start) {
  // ASN.1 constants not defined by mbedtls.
  const uint8_t kEnumTypeTag = 10;
  // ASN.1 tags for extension fields.
  const uint8_t kDiceFieldCodeHash = 0;
  const uint8_t kDiceFieldCodeDescriptor = 1;
  const uint8_t kDiceFieldConfigHash = 2;
  const uint8_t kDiceFieldConfigDescriptor = 3;
  const uint8_t kDiceFieldAuthorityHash = 4;
  const uint8_t kDiceFieldAuthorityDescriptor = 5;
  const uint8_t kDiceFieldMode = 6;

  // Build up the extension ASN.1 in reverse order.
  int ret = 0;  // Used by MBEDTLS_ASN1_CHK_ADD.
  int length = 0;

  // Add the mode field.
  MBEDTLS_ASN1_CHK_ADD(length,
                       mbedtls_asn1_write_int(pos, start, input_values->mode));
  // Overwrite the 'int' type.
  ++(*pos);
  --length;
  MBEDTLS_ASN1_CHK_ADD(length,
                       mbedtls_asn1_write_tag(pos, start, kEnumTypeTag));

  // Explicitly tagged, so add the field tag too.
  MBEDTLS_ASN1_CHK_ADD(length, mbedtls_asn1_write_len(pos, start, length));
  MBEDTLS_ASN1_CHK_ADD(
      length, mbedtls_asn1_write_tag(pos, start, GetFieldTag(kDiceFieldMode)));

  // Add the authorityDescriptor field, if applicable.
  if (input_values->authority_descriptor_size > 0) {
    MBEDTLS_ASN1_CHK_ADD(
        length,
        WriteExplicitOctetStringField(
            kDiceFieldAuthorityDescriptor, input_values->authority_descriptor,
            input_values->authority_descriptor_size, pos, start));
  }

  // Add the authorityHash field.
  MBEDTLS_ASN1_CHK_ADD(
      length, WriteExplicitOctetStringField(kDiceFieldAuthorityHash,
                                            input_values->authority_hash,
                                            DICE_HASH_SIZE, pos, start));

  // Add the configurationDescriptor field (and configurationHash field, if
  // applicable).
  if (input_values->config_type == kDiceConfigTypeDescriptor) {
    uint8_t hash[DICE_HASH_SIZE];
    int result = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512),
                            input_values->config_descriptor,
                            input_values->config_descriptor_size, hash);
    if (result) {
      return result;
    }
    MBEDTLS_ASN1_CHK_ADD(
        length, WriteExplicitOctetStringField(
                    kDiceFieldConfigDescriptor, input_values->config_descriptor,
                    input_values->config_descriptor_size, pos, start));
    MBEDTLS_ASN1_CHK_ADD(
        length, WriteExplicitOctetStringField(kDiceFieldConfigHash, hash,
                                              DICE_HASH_SIZE, pos, start));
  } else if (input_values->config_type == kDiceConfigTypeInline) {
    MBEDTLS_ASN1_CHK_ADD(
        length, WriteExplicitOctetStringField(
                    kDiceFieldConfigDescriptor, input_values->config_value,
                    DICE_INLINE_CONFIG_SIZE, pos, start));
  }

  // Add the code descriptor field, if applicable.
  if (input_values->code_descriptor_size > 0) {
    MBEDTLS_ASN1_CHK_ADD(
        length, WriteExplicitOctetStringField(
                    kDiceFieldCodeDescriptor, input_values->code_descriptor,
                    input_values->code_descriptor_size, pos, start));
  }

  // Add the code hash field.
  MBEDTLS_ASN1_CHK_ADD(length, WriteExplicitOctetStringField(
                                   kDiceFieldCodeHash, input_values->code_hash,
                                   DICE_HASH_SIZE, pos, start));

  // Add the sequence length and tag.
  MBEDTLS_ASN1_CHK_ADD(length, mbedtls_asn1_write_len(pos, start, length));
  MBEDTLS_ASN1_CHK_ADD(
      length,
      mbedtls_asn1_write_tag(pos, start,
                             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
  return length;
}

static DiceResult GetDiceExtensionData(const DiceInputValues* input_values,
                                       size_t buffer_size, uint8_t* buffer,
                                       size_t* actual_size) {
  uint8_t* pos = buffer + buffer_size;
  int length_or_error = GetDiceExtensionDataHelper(input_values, &pos, buffer);
  if (length_or_error == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
    return kDiceResultBufferTooSmall;
  } else if (length_or_error < 0) {
    return kDiceResultPlatformError;
  }
  *actual_size = length_or_error;
  memmove(buffer, pos, *actual_size);
  return kDiceResultOk;
}

DiceResult DiceHash(void* context_not_used, const uint8_t* input,
                    size_t input_size, uint8_t output[DICE_HASH_SIZE]) {
  (void)context_not_used;
  if (0 != mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), input,
                      input_size, output)) {
    return kDiceResultPlatformError;
  }
  return kDiceResultOk;
}

DiceResult DiceKdf(void* context_not_used, size_t length, const uint8_t* ikm,
                   size_t ikm_size, const uint8_t* salt, size_t salt_size,
                   const uint8_t* info, size_t info_size, uint8_t* output) {
  (void)context_not_used;
  if (0 != mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), salt,
                        salt_size, ikm, ikm_size, info, info_size, output,
                        length)) {
    return kDiceResultPlatformError;
  }
  return kDiceResultOk;
}

DiceResult DiceGenerateCertificate(
    void* context,
    const uint8_t subject_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
    const uint8_t authority_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
    const DiceInputValues* input_values, size_t certificate_buffer_size,
    uint8_t* certificate, size_t* certificate_actual_size) {
  // 1.3.6.1.4.1.11129.2.1.24
  // iso.org.dod.internet.private.enterprise.
  //   google.googleSecurity.certificateExtensions.diceAttestationData
  const char* kDiceExtensionOid =
      MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD
      "\x01\x04\x01\xd6\x79\x02\x01\x18";
  const size_t kDiceExtensionOidLength = 10;

  DiceResult result = kDiceResultOk;

  // Initialize variables cleaned up on 'goto out'.
  mbedtls_pk_context authority_key_context;
  mbedtls_pk_init(&authority_key_context);
  mbedtls_pk_context subject_key_context;
  mbedtls_pk_init(&subject_key_context);
  mbedtls_x509write_cert cert_context;
  mbedtls_x509write_crt_init(&cert_context);
  mbedtls_mpi serial_number;
  mbedtls_mpi_init(&serial_number);

  // These are 'variably modified' types so need to be declared upfront.
  uint8_t authority_key_id[kMaxKeyIdSize];
  uint8_t subject_key_id[kMaxKeyIdSize];
  uint8_t dice_extension[kMaxExtensionSize];
  uint8_t tmp_buffer[kMaxCertificateSize];

  // Derive key pairs and IDs.
  result = SetupKeyPair(authority_private_key_seed, &authority_key_context);
  if (result != kDiceResultOk) {
    goto out;
  }

  uint8_t authority_id[DICE_ID_SIZE];
  result = GetIdFromKey(context, &authority_key_context, authority_id);
  if (result != kDiceResultOk) {
    goto out;
  }

  char authority_name[54];
  GetNameFromId(authority_id, authority_name);

  size_t authority_key_id_size = 0;
  result = GetAuthorityKeyIdFromId(authority_id, sizeof(authority_key_id),
                                   authority_key_id, &authority_key_id_size);
  if (result != kDiceResultOk) {
    goto out;
  }
  result = SetupKeyPair(subject_private_key_seed, &subject_key_context);
  if (result != kDiceResultOk) {
    goto out;
  }

  uint8_t subject_id[DICE_ID_SIZE];
  result = GetIdFromKey(context, &subject_key_context, subject_id);
  if (result != kDiceResultOk) {
    goto out;
  }

  char subject_name[54];
  GetNameFromId(subject_id, subject_name);

  size_t subject_key_id_size = 0;
  result = GetSubjectKeyIdFromId(subject_id, sizeof(subject_key_id),
                                 subject_key_id, &subject_key_id_size);
  if (result != kDiceResultOk) {
    goto out;
  }

  size_t dice_extension_size = 0;
  result = GetDiceExtensionData(input_values, sizeof(dice_extension),
                                dice_extension, &dice_extension_size);
  if (result != kDiceResultOk) {
    goto out;
  }

  // Construct the certificate.
  mbedtls_x509write_crt_set_version(&cert_context, MBEDTLS_X509_CRT_VERSION_3);
  if (0 !=
      mbedtls_mpi_read_binary(&serial_number, subject_id, sizeof(subject_id))) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (0 != mbedtls_x509write_crt_set_serial(&cert_context, &serial_number)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  // '20180322235959' is the date of publication of the DICE specification. Here
  // it's used as a somewhat arbitrary backstop. '99991231235959' is suggested
  // by RFC 5280 in cases where expiry is not meaningful. Basically, the
  // certificate never expires.
  if (0 != mbedtls_x509write_crt_set_validity(&cert_context, "20180322235959",
                                              "99991231235959")) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (0 !=
      mbedtls_x509write_crt_set_issuer_name(&cert_context, authority_name)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (0 !=
      mbedtls_x509write_crt_set_subject_name(&cert_context, subject_name)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  mbedtls_x509write_crt_set_subject_key(&cert_context, &subject_key_context);
  mbedtls_x509write_crt_set_issuer_key(&cert_context, &authority_key_context);
  mbedtls_x509write_crt_set_md_alg(&cert_context, MBEDTLS_MD_SHA512);
  if (0 != mbedtls_x509write_crt_set_extension(
               &cert_context, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
               MBEDTLS_OID_SIZE(MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER),
               /*critical=*/0, authority_key_id, authority_key_id_size)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (0 != mbedtls_x509write_crt_set_extension(
               &cert_context, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
               MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER),
               /*critical=*/0, subject_key_id, subject_key_id_size)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (0 != mbedtls_x509write_crt_set_key_usage(&cert_context,
                                               MBEDTLS_X509_KU_KEY_CERT_SIGN)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (0 != mbedtls_x509write_crt_set_basic_constraints(&cert_context,
                                                       /*is_ca=*/1,
                                                       /*max_pathlen=*/-1)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (0 != mbedtls_x509write_crt_set_extension(
               &cert_context, kDiceExtensionOid, kDiceExtensionOidLength,
               /*critical=*/0, dice_extension, dice_extension_size)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  // This implementation is deterministic and assumes entropy is not available.
  // If this code is run where entropy is available, however, f_rng and p_rng
  // should be set appropriately.
  int length_or_error =
      mbedtls_x509write_crt_der(&cert_context, tmp_buffer, sizeof(tmp_buffer),
                                /*f_rng=*/NULL, /*p_rng=*/NULL);
  if (length_or_error < 0) {
    result = kDiceResultPlatformError;
    goto out;
  }
  *certificate_actual_size = length_or_error;
  if (*certificate_actual_size > certificate_buffer_size) {
    result = kDiceResultBufferTooSmall;
    goto out;
  }
  // The certificate has been written to the end of tmp_buffer. Skip unused
  // buffer when copying.
  memcpy(certificate,
         &tmp_buffer[sizeof(tmp_buffer) - *certificate_actual_size],
         *certificate_actual_size);

out:
  mbedtls_mpi_free(&serial_number);
  mbedtls_x509write_crt_free(&cert_context);
  mbedtls_pk_free(&authority_key_context);
  mbedtls_pk_free(&subject_key_context);
  return result;
}
