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

#include "pk11pub.h"
#include "pk11pqg.h"
#include "prerror.h"

#include "gtest/gtest.h"

namespace nss_test {

class ParamHolder {
 public:
  virtual void* get() = 0;
  virtual ~ParamHolder() = default;

 protected:
  ParamHolder() = default;
};

void Pkcs11KeyPairGenerator::GenerateKey(ScopedSECKEYPrivateKey* priv_key,
                                         ScopedSECKEYPublicKey* pub_key,
                                         bool sensitive) const {
  // This function returns if an assertion fails, so don't leak anything.
  priv_key->reset(nullptr);
  pub_key->reset(nullptr);

  auto params = MakeParams();
  ASSERT_NE(nullptr, params);

  ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
  ASSERT_TRUE(slot);

  SECKEYPublicKey* pub_tmp;
  ScopedSECKEYPrivateKey priv_tmp(
      PK11_GenerateKeyPair(slot.get(), mech_, params->get(), &pub_tmp, PR_FALSE,
                           sensitive ? PR_TRUE : PR_FALSE, nullptr));
  ASSERT_NE(nullptr, priv_tmp) << "PK11_GenerateKeyPair failed: "
                               << PORT_ErrorToName(PORT_GetError());
  ASSERT_NE(nullptr, pub_tmp);

  priv_key->swap(priv_tmp);
  pub_key->reset(pub_tmp);
}

class RsaParamHolder : public ParamHolder {
 public:
  RsaParamHolder() : params_({1024, 0x010001}) {}
  ~RsaParamHolder() = default;

  void* get() override { return &params_; }

 private:
  PK11RSAGenParams params_;
};

class PqgParamHolder : public ParamHolder {
 public:
  PqgParamHolder(PQGParams* params) : params_(params) {}
  ~PqgParamHolder() = default;

  void* get() override { return params_.get(); }

 private:
  ScopedPQGParams params_;
};

class DhParamHolder : public PqgParamHolder {
 public:
  DhParamHolder(PQGParams* params)
      : PqgParamHolder(params),
        params_({nullptr, params->prime, params->base}) {}
  ~DhParamHolder() = default;

  void* get() override { return &params_; }

 private:
  SECKEYDHParams params_;
};

class EcParamHolder : public ParamHolder {
 public:
  EcParamHolder(SECOidTag curve_oid) {
    SECOidData* curve = SECOID_FindOIDByTag(curve_oid);
    EXPECT_NE(nullptr, curve);

    size_t plen = curve->oid.len + 2;
    extra_.reset(new uint8_t[plen]);
    extra_[0] = SEC_ASN1_OBJECT_ID;
    extra_[1] = static_cast<uint8_t>(curve->oid.len);
    memcpy(&extra_[2], curve->oid.data, curve->oid.len);

    ec_params_ = {siBuffer, extra_.get(), static_cast<unsigned int>(plen)};
  }
  ~EcParamHolder() = default;

  void* get() override { return &ec_params_; }

 private:
  SECKEYECParams ec_params_;
  std::unique_ptr<uint8_t[]> extra_;
};

std::unique_ptr<ParamHolder> Pkcs11KeyPairGenerator::MakeParams() const {
  switch (mech_) {
    case CKM_RSA_PKCS_KEY_PAIR_GEN:
      std::cerr << "Generate RSA pair" << std::endl;
      return std::unique_ptr<ParamHolder>(new RsaParamHolder());

    case CKM_DSA_KEY_PAIR_GEN:
    case CKM_DH_PKCS_KEY_PAIR_GEN: {
      PQGParams* pqg_params = nullptr;
      PQGVerify* pqg_verify = nullptr;
      const unsigned int key_size = 1024;
      SECStatus rv = PK11_PQG_ParamGenV2(key_size, 0, key_size / 16,
                                         &pqg_params, &pqg_verify);
      if (rv != SECSuccess) {
        ADD_FAILURE() << "PK11_PQG_ParamGenV2 failed";
        return nullptr;
      }
      EXPECT_NE(nullptr, pqg_verify);
      EXPECT_NE(nullptr, pqg_params);
      PK11_PQG_DestroyVerify(pqg_verify);
      if (mech_ == CKM_DSA_KEY_PAIR_GEN) {
        std::cerr << "Generate DSA pair" << std::endl;
        return std::unique_ptr<ParamHolder>(new PqgParamHolder(pqg_params));
      }
      std::cerr << "Generate DH pair" << std::endl;
      return std::unique_ptr<ParamHolder>(new DhParamHolder(pqg_params));
    }

    case CKM_EC_KEY_PAIR_GEN:
      std::cerr << "Generate EC pair on " << curve_ << std::endl;
      return std::unique_ptr<ParamHolder>(new EcParamHolder(curve_));

    default:
      ADD_FAILURE() << "unknown OID " << mech_;
  }
  return nullptr;
}

}  // namespace nss_test
