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

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

#include "cose/cose.h"
#include "cose/cose_configure.h"
#include "cose_int.h"
#include "openssl/curve25519.h"
#include "openssl/is_boringssl.h"

// Gets the public key from a well-formed Ed25519 COSE_Key. On success populates
// |public_key| and returns true.
static bool GetPublicKeyFromCbor(const cn_cbor *key, uint8_t public_key[PUBLIC_KEY_SIZE]) {
  const int64_t kCoseKeyAlgLabel = 3;
  const int64_t kCoseKeyOpsLabel = 4;
  const uint64_t kCoseKeyOpsVerify = 2;
  const int64_t kCoseAlgEdDSA = -8;

  // Mandatory attributes.
  cn_cbor *type = cn_cbor_mapget_int(key, COSE_Key_Type);
  cn_cbor *curve = cn_cbor_mapget_int(key, COSE_Key_OPK_Curve);
  cn_cbor *x = cn_cbor_mapget_int(key, COSE_Key_OPK_X);
  if (!type || !curve || !x) {
    return false;
  }
  if (type->type != CN_CBOR_UINT || type->v.uint != COSE_Key_Type_OKP) {
    return false;
  }
  if (curve->type != CN_CBOR_UINT || curve->v.uint != COSE_Curve_Ed25519) {
    return false;
  }
  if (x->type != CN_CBOR_BYTES || x->length != PUBLIC_KEY_SIZE) {
    return false;
  }
  // Optional attributes.
  cn_cbor *alg = cn_cbor_mapget_int(key, kCoseKeyAlgLabel);
  if (alg) {
    if (alg->type != CN_CBOR_INT || alg->v.sint != kCoseAlgEdDSA) {
      return false;
    }
  }
  cn_cbor *ops = cn_cbor_mapget_int(key, kCoseKeyOpsLabel);
  if (ops) {
    if (ops->type != CN_CBOR_ARRAY || ops->length == 0) {
      return false;
    }
    bool found_verify = false;
    for (size_t i = 0; i < ops->length; ++i) {
      cn_cbor *item = cn_cbor_index(ops, i);
      if (!item || item->type != CN_CBOR_UINT) {
        return false;
      }
      if (item->v.uint == kCoseKeyOpsVerify) {
        found_verify = true;
      }
    }
    if (!found_verify) {
      return false;
    }
  }

  memcpy(public_key, x->v.bytes, PUBLIC_KEY_SIZE);
  return true;
}

// A simple implementation of 'EdDSA_Verify' using boringssl. This function is
// required by 'COSE_Sign1_validate'.
bool EdDSA_Verify(COSE *cose_signer, int signature_index, COSE_KEY *cose_key,
                  const byte *message, size_t message_size, cose_errback *) {
  cn_cbor *signature = _COSE_arrayget_int(cose_signer, signature_index);
  cn_cbor *key = cose_key->m_cborKey;
  if (!signature || !key) {
    return false;
  }
  if (signature->type != CN_CBOR_BYTES || signature->length != 64) {
    return false;
  }
  uint8_t public_key[PUBLIC_KEY_SIZE];
  if (!GetPublicKeyFromCbor(key, public_key)) {
    return false;
  }
  return (1 == ED25519_verify(message, message_size, signature->v.bytes,
                              public_key));
}

// A stub for 'EdDSA_Sign'. This is unused, but helps make linkers happy.
bool EdDSA_Sign(COSE * /*cose_signer*/, int /*signature_index*/,
                COSE_KEY * /*cose_key*/, const byte * /*message*/,
                size_t /*message_size*/, cose_errback *) {
  return false;
}
