// Copyright 2021 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.

#include "dice/cbor_cert_op.h"

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

#include "dice/cbor_writer.h"
#include "dice/dice.h"
#include "dice/utils.h"
#include "openssl/curve25519.h"
#include "openssl/is_boringssl.h"
#include "openssl/sha.h"

// Max size of COSE_Sign1 including payload.
static const size_t kMaxCertificateSize = 2048;
// Max size of COSE_Key encoding.
static const size_t kMaxPublicKeySize = 64;
// Max size of the COSE_Sign1 protected attributes.
static const size_t kMaxProtectedAttributesSize = 16;

static DiceResult EncodeProtectedAttributes(size_t buffer_size, uint8_t* buffer,
                                            size_t* encoded_size) {
  // Constants per RFC 8152.
  const int64_t kCoseHeaderAlgLabel = 1;
  const int64_t kCoseAlgEdDSA = -8;

  struct CborOut out = {
      .buffer = buffer,
      .size = buffer_size,
  };
  if (!CborWriteMap(/*num_elements=*/1, &out) ||
      // Add the algorithm.
      !CborWriteInt(kCoseHeaderAlgLabel, &out) ||
      !CborWriteInt(kCoseAlgEdDSA, &out)) {
    return kDiceResultBufferTooSmall;
  }
  *encoded_size = out.offset;
  return kDiceResultOk;
}

static DiceResult EncodePublicKey(uint8_t subject_public_key[32],
                                  size_t buffer_size, uint8_t* buffer,
                                  size_t* encoded_size) {
  // Constants per RFC 8152.
  const int64_t kCoseKeyKtyLabel = 1;
  const int64_t kCoseKeyAlgLabel = 3;
  const int64_t kCoseKeyOpsLabel = 4;
  const int64_t kCoseOkpCrvLabel = -1;
  const int64_t kCoseOkpXLabel = -2;
  const int64_t kCoseKeyTypeOkp = 1;
  const int64_t kCoseAlgEdDSA = -8;
  const int64_t kCoseKeyOpsVerify = 2;
  const int64_t kCoseCrvEd25519 = 6;

  struct CborOut out = {
      .buffer = buffer,
      .size = buffer_size,
  };
  if (!CborWriteMap(/*num_pairs=*/5, &out) ||
      // Add the key type.
      !CborWriteInt(kCoseKeyKtyLabel, &out) ||
      !CborWriteInt(kCoseKeyTypeOkp, &out) ||
      // Add the algorithm.
      !CborWriteInt(kCoseKeyAlgLabel, &out) ||
      !CborWriteInt(kCoseAlgEdDSA, &out) ||
      // Add the KeyOps.
      !CborWriteInt(kCoseKeyOpsLabel, &out) ||
      !CborWriteArray(/*num_elements=*/1, &out) ||
      !CborWriteInt(kCoseKeyOpsVerify, &out) ||
      // Add the curve.
      !CborWriteInt(kCoseOkpCrvLabel, &out) ||
      !CborWriteInt(kCoseCrvEd25519, &out) ||
      // Add the subject public key.
      !CborWriteInt(kCoseOkpXLabel, &out) ||
      !CborWriteBstr(/*data_size=*/32, subject_public_key, &out)) {
    return kDiceResultBufferTooSmall;
  }
  *encoded_size = out.offset;
  return kDiceResultOk;
}

// Encodes a CBOR Web Token (CWT) with an issuer, subject, and additional
// fields.
static DiceResult EncodeCwt(const DiceInputValues* input_values,
                            const char* authority_id_hex,
                            const char* subject_id_hex,
                            const uint8_t* encoded_public_key,
                            size_t encoded_public_key_size, size_t buffer_size,
                            uint8_t* buffer, size_t* encoded_size) {
  // Constants per RFC 8392.
  const int64_t kCwtIssuerLabel = 1;
  const int64_t kCwtSubjectLabel = 2;
  // Constants per the Open Profile for DICE specification.
  const int64_t kCodeHashLabel = -4670545;
  const int64_t kCodeDescriptorLabel = -4670546;
  const int64_t kConfigHashLabel = -4670547;
  const int64_t kConfigDescriptorLabel = -4670548;
  const int64_t kAuthorityHashLabel = -4670549;
  const int64_t kAuthorityDescriptorLabel = -4670550;
  const int64_t kModeLabel = -4670551;
  const int64_t kSubjectPublicKeyLabel = -4670552;
  const int64_t kKeyUsageLabel = -4670553;
  // Key usage constant per RFC 5280.
  const uint8_t kKeyUsageCertSign = 32;

  // Count the number of entries.
  uint32_t map_pairs = 7;
  if (input_values->code_descriptor_size > 0) {
    map_pairs += 1;
  }
  if (input_values->config_type == kDiceConfigTypeDescriptor) {
    map_pairs += 2;
  } else {
    map_pairs += 1;
  }
  if (input_values->authority_descriptor_size > 0) {
    map_pairs += 1;
  }

  struct CborOut out = {
      .buffer = buffer,
      .size = buffer_size,
  };
  if (!CborWriteMap(map_pairs, &out) ||
      // Add the issuer.
      !CborWriteInt(kCwtIssuerLabel, &out) ||
      !CborWriteTstr(authority_id_hex, &out) ||
      // Add the subject.
      !CborWriteInt(kCwtSubjectLabel, &out) ||
      !CborWriteTstr(subject_id_hex, &out) ||
      // Add the code hash.
      !CborWriteInt(kCodeHashLabel, &out) ||
      !CborWriteBstr(DICE_HASH_SIZE, input_values->code_hash, &out)) {
    return kDiceResultBufferTooSmall;
  }
  // Add the code descriptor, if provided.
  if (input_values->code_descriptor_size > 0) {
    if (!CborWriteInt(kCodeDescriptorLabel, &out) ||
        !CborWriteBstr(input_values->code_descriptor_size,
                       input_values->code_descriptor, &out)) {
      return kDiceResultBufferTooSmall;
    }
  }
  // Add the config inputs.
  if (input_values->config_type == kDiceConfigTypeDescriptor) {
    uint8_t config_descriptor_hash[DICE_HASH_SIZE];
    SHA512(input_values->config_descriptor,
           input_values->config_descriptor_size, config_descriptor_hash);
    if (
        // Add the config descriptor.
        !CborWriteInt(kConfigDescriptorLabel, &out) ||
        !CborWriteBstr(input_values->config_descriptor_size,
                       input_values->config_descriptor, &out) ||
        // Add the Config hash.
        !CborWriteInt(kConfigHashLabel, &out) ||
        !CborWriteBstr(DICE_HASH_SIZE, config_descriptor_hash, &out)) {
      return kDiceResultBufferTooSmall;
    }
  } else if (input_values->config_type == kDiceConfigTypeInline) {
    // Add the inline config.
    if (!CborWriteInt(kConfigDescriptorLabel, &out) ||
        !CborWriteBstr(DICE_INLINE_CONFIG_SIZE, input_values->config_value,
                       &out)) {
      return kDiceResultBufferTooSmall;
    }
  }
  // Add the authority inputs.
  if (!CborWriteInt(kAuthorityHashLabel, &out) ||
      !CborWriteBstr(DICE_HASH_SIZE, input_values->authority_hash, &out)) {
    return kDiceResultBufferTooSmall;
  }
  if (input_values->authority_descriptor_size > 0) {
    if (!CborWriteInt(kAuthorityDescriptorLabel, &out) ||
        !CborWriteBstr(input_values->authority_descriptor_size,
                       input_values->authority_descriptor, &out)) {
      return kDiceResultBufferTooSmall;
    }
  }
  uint8_t mode_byte = input_values->mode;
  uint8_t key_usage = kKeyUsageCertSign;
  if (
      // Add the mode input.
      !CborWriteInt(kModeLabel, &out) ||
      !CborWriteBstr(/*data_sisze=*/1, &mode_byte, &out) ||
      // Add the subject public key.
      !CborWriteInt(kSubjectPublicKeyLabel, &out) ||
      !CborWriteBstr(encoded_public_key_size, encoded_public_key, &out) ||
      // Add the key usage.
      !CborWriteInt(kKeyUsageLabel, &out) ||
      !CborWriteBstr(/*data_size=*/1, &key_usage, &out)) {
    return kDiceResultBufferTooSmall;
  }

  *encoded_size = out.offset;
  return kDiceResultOk;
}

static DiceResult EncodeCoseTbs(const uint8_t* protected_attributes,
                                size_t protected_attributes_size,
                                const uint8_t* payload, size_t payload_size,
                                size_t buffer_size, uint8_t* buffer,
                                size_t* encoded_size) {
  struct CborOut out = {
      .buffer = buffer,
      .size = buffer_size,
  };
  if (
      // TBS is an array of four elements.
      !CborWriteArray(/*num_elements=*/4, &out) ||
      // Context string field.
      !CborWriteTstr("Signature1", &out) ||
      // Protected attributes from COSE_Sign1.
      !CborWriteBstr(protected_attributes_size, protected_attributes, &out) ||
      // Empty application data.
      !CborWriteBstr(/*data_size=*/0, /*data=*/NULL, &out) ||
      // Payload from COSE_Sign1.
      !CborWriteBstr(payload_size, payload, &out)) {
    return kDiceResultBufferTooSmall;
  }
  *encoded_size = out.offset;
  return kDiceResultOk;
}

static DiceResult EncodeCoseSign1(const uint8_t* protected_attributes,
                                  size_t protected_attributes_size,
                                  const uint8_t* payload, size_t payload_size,
                                  const uint8_t signature[64],
                                  size_t buffer_size, uint8_t* buffer,
                                  size_t* encoded_size) {
  struct CborOut out = {
      .buffer = buffer,
      .size = buffer_size,
  };
  if (
      // COSE_Sign1 is an array of four elements.
      !CborWriteArray(/*num_elements=*/4, &out) ||
      // Protected attributes.
      !CborWriteBstr(protected_attributes_size, protected_attributes, &out) ||
      // Empty map for unprotected attributes.
      !CborWriteMap(/*num_pairs=*/0, &out) ||
      // Payload.
      !CborWriteBstr(payload_size, payload, &out) ||
      // Signature.
      !CborWriteBstr(/*num_elements=*/64, signature, &out)) {
    return kDiceResultBufferTooSmall;
  }
  *encoded_size = out.offset;
  return kDiceResultOk;
}

DiceResult DiceGenerateCborCertificateOp(
    const DiceOps* ops,
    const uint8_t subject_private_key[DICE_PRIVATE_KEY_SIZE],
    const uint8_t authority_private_key[DICE_PRIVATE_KEY_SIZE],
    const DiceInputValues* input_values, size_t certificate_buffer_size,
    uint8_t* certificate, size_t* certificate_actual_size) {
  DiceResult result = kDiceResultOk;

  *certificate_actual_size = 0;
  if (input_values->config_type != kDiceConfigTypeDescriptor &&
      input_values->config_type != kDiceConfigTypeInline) {
    return kDiceResultInvalidInput;
  }

  // Declare buffers which are cleared on 'goto out'.
  uint8_t subject_bssl_private_key[64];
  uint8_t authority_bssl_private_key[64];

  // These are 'variably modified' types so need to be declared upfront.
  uint8_t encoded_public_key[kMaxPublicKeySize];
  uint8_t payload[kMaxCertificateSize];
  uint8_t protected_attributes[kMaxProtectedAttributesSize];

  // Derive public keys and IDs from the private keys. Note: the Boringssl
  // implementation refers to the raw private key as a seed.
  uint8_t subject_public_key[32];
  ED25519_keypair_from_seed(subject_public_key, subject_bssl_private_key,
                            subject_private_key);

  uint8_t subject_id[20];
  result = DiceDeriveCdiCertificateId(ops, subject_public_key, 32, subject_id);
  if (result != kDiceResultOk) {
    goto out;
  }
  char subject_id_hex[41];
  DiceHexEncode(subject_id, sizeof(subject_id), subject_id_hex,
                sizeof(subject_id_hex));
  subject_id_hex[sizeof(subject_id_hex) - 1] = '\0';

  uint8_t authority_public_key[32];
  ED25519_keypair_from_seed(authority_public_key, authority_bssl_private_key,
                            authority_private_key);

  uint8_t authority_id[20];
  result =
      DiceDeriveCdiCertificateId(ops, authority_public_key, 32, authority_id);
  if (result != kDiceResultOk) {
    goto out;
  }
  char authority_id_hex[41];
  DiceHexEncode(authority_id, sizeof(authority_id), authority_id_hex,
                sizeof(authority_id_hex));
  authority_id_hex[sizeof(authority_id_hex) - 1] = '\0';

  // The encoded protected attributes are used in the TBS and the final
  // COSE_Sign1 structure.
  size_t protected_attributes_size = 0;
  result = EncodeProtectedAttributes(sizeof(protected_attributes),
                                     protected_attributes,
                                     &protected_attributes_size);
  if (result != kDiceResultOk) {
    goto out;
  }

  // The public key encoded as a COSE_Key structure is embedded in the CWT.
  size_t encoded_public_key_size = 0;
  result = EncodePublicKey(subject_public_key, sizeof(encoded_public_key),
                           encoded_public_key, &encoded_public_key_size);
  if (result != kDiceResultOk) {
    goto out;
  }

  // The CWT is the payload in both the TBS and the final COSE_Sign1 structure.
  size_t payload_size = 0;
  result = EncodeCwt(input_values, authority_id_hex, subject_id_hex,
                     encoded_public_key, encoded_public_key_size,
                     sizeof(payload), payload, &payload_size);
  if (result != kDiceResultOk) {
    goto out;
  }

  // Construct a To-Be-Signed (TBS) structure based on the relevant fields of
  // the COSE_Sign1.
  result = EncodeCoseTbs(protected_attributes, protected_attributes_size,
                         payload, payload_size, certificate_buffer_size,
                         certificate, certificate_actual_size);
  if (result != kDiceResultOk) {
    goto out;
  }

  // Sign the TBS with the authority key.
  uint8_t signature[64];
  if (1 != ED25519_sign(signature, certificate, *certificate_actual_size,
                        authority_bssl_private_key)) {
    result = kDiceResultPlatformError;
    goto out;
  }
  if (1 != ED25519_verify(certificate, *certificate_actual_size, signature,
                          authority_public_key)) {
    result = kDiceResultPlatformError;
    goto out;
  }

  // The final certificate is an untagged COSE_Sign1 structure.
  result = EncodeCoseSign1(
      protected_attributes, protected_attributes_size, payload, payload_size,
      signature, certificate_buffer_size, certificate, certificate_actual_size);

out:
  ops->clear_memory(ops, sizeof(subject_bssl_private_key),
                    subject_bssl_private_key);
  ops->clear_memory(ops, sizeof(authority_bssl_private_key),
                    authority_bssl_private_key);

  return result;
}
