/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <memory>
#include "nss.h"
#include "pk11pub.h"

#include "cpputil.h"
#include "nss_scoped_ptrs.h"

#include "testvectors/p256ecdh-vectors.h"
#include "testvectors/p384ecdh-vectors.h"
#include "testvectors/p521ecdh-vectors.h"
#include "gtest/gtest.h"

namespace nss_test {

class Pkcs11EcdhTest : public ::testing::TestWithParam<EcdhTestVector> {
 protected:
  void Derive(const EcdhTestVector vec) {
    std::string err = "Test #" + std::to_string(vec.id) + " failed";

    SECItem expect_item = {siBuffer, toUcharPtr(vec.secret.data()),
                           static_cast<unsigned int>(vec.secret.size())};

    ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    ASSERT_TRUE(slot);

    SECItem priv_item = {siBuffer, toUcharPtr(vec.private_key.data()),
                         static_cast<unsigned int>(vec.private_key.size())};
    SECKEYPrivateKey* key = nullptr;
    SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
        slot.get(), &priv_item, nullptr, nullptr, false, false, KU_ALL, &key,
        nullptr);
    EXPECT_EQ(SECSuccess, rv) << err;

    ScopedSECKEYPrivateKey priv_key(key);
    ASSERT_TRUE(priv_key) << err;

    SECItem spki_item = {siBuffer, toUcharPtr(vec.public_key.data()),
                         static_cast<unsigned int>(vec.public_key.size())};

    ScopedCERTSubjectPublicKeyInfo cert_spki(
        SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
    if (vec.valid) {
      ASSERT_TRUE(!!cert_spki) << err;
    } else if (!cert_spki) {
      ASSERT_TRUE(vec.invalid_asn) << err;
      return;
    }

    ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get()));
    if (vec.valid) {
      ASSERT_TRUE(!!pub_key) << err;
    } else if (!pub_key) {
      ASSERT_FALSE(vec.valid) << err;
      return;
    }

    ScopedPK11SymKey sym_key(
        PK11_PubDeriveWithKDF(priv_key.get(), pub_key.get(), false, nullptr,
                              nullptr, CKM_ECDH1_DERIVE, CKM_SHA512_HMAC,
                              CKA_DERIVE, 0, CKD_NULL, nullptr, nullptr));
    ASSERT_EQ(vec.valid, !!sym_key) << err;

    if (vec.valid) {
      rv = PK11_ExtractKeyValue(sym_key.get());
      EXPECT_EQ(SECSuccess, rv) << err;

      SECItem* derived_key = PK11_GetKeyData(sym_key.get());
      EXPECT_EQ(0, SECITEM_CompareItem(derived_key, &expect_item)) << err;
    }
  };
};

TEST_P(Pkcs11EcdhTest, TestVectors) { Derive(GetParam()); }

INSTANTIATE_TEST_SUITE_P(WycheproofP256EcdhTest, Pkcs11EcdhTest,
                         ::testing::ValuesIn(kP256EcdhWycheproofVectors));
INSTANTIATE_TEST_SUITE_P(WycheproofP384EcdhTest, Pkcs11EcdhTest,
                         ::testing::ValuesIn(kP384EcdhWycheproofVectors));
INSTANTIATE_TEST_SUITE_P(WycheproofP521EcdhTest, Pkcs11EcdhTest,
                         ::testing::ValuesIn(kP521EcdhWycheproofVectors));

}  // namespace nss_test
