| /* 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 ¶ms_; } |
| |
| 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 ¶ms_; } |
| |
| 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 |