From: Fred Morcos Date: Fri, 1 Apr 2022 10:14:16 +0000 (+0200) Subject: Sodium impl of EDDSA PEM import X-Git-Tag: auth-4.8.0-alpha0~124^2~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e3421c9b7871e247dc0f478596dbd851a7501d6e;p=thirdparty%2Fpdns.git Sodium impl of EDDSA PEM import --- diff --git a/pdns/sodiumsigners.cc b/pdns/sodiumsigners.cc index c9190354cd..c4d68e29e2 100644 --- a/pdns/sodiumsigners.cc +++ b/pdns/sodiumsigners.cc @@ -16,6 +16,25 @@ public: string getName() const override { return "Sodium ED25519"; } void create(unsigned int bits) override; + /** + * \brief Creates an ED25519 key engine from a PEM file. + * + * Receives an open file handle with PEM contents and creates an + * ED25519 key engine. + * + * \param[in] drc Key record contents to be populated. + * + * \param[in] filename Only used for providing filename information in + * error messages. + * + * \param[in] fp An open file handle to a file containing ED25519 PEM + * contents. + * + * \return An ED25519 key engine populated with the contents of the + * PEM file. + */ + void createFromPEMFile(DNSKEYRecordContent& drc, const std::string& filename, std::FILE& fp) override; + /** * \brief Writes this key's contents to a file. * @@ -55,6 +74,27 @@ void SodiumED25519DNSCryptoKeyEngine::create(unsigned int bits) crypto_sign_ed25519_keypair(d_pubkey, d_seckey); } +void SodiumED25519DNSCryptoKeyEngine::createFromPEMFile(DNSKEYRecordContent& drc, const string& filename, std::FILE& fp) +{ + drc.d_algorithm = d_algorithm; + auto key = std::unique_ptr(PEM_read_PrivateKey(&fp, nullptr, nullptr, nullptr), &EVP_PKEY_free); + if (key == nullptr) { + throw runtime_error(getName() + ": Failed to read private key from PEM file `" + filename + "`"); + } + + std::size_t keylen = crypto_sign_ed25519_SECRETKEYBYTES; + int ret = EVP_PKEY_get_raw_private_key(key.get(), d_seckey, &keylen); + if (ret == 0) { + throw runtime_error(getName() + ": Failed to get private key from PEM file contents `" + filename + "`"); + } + + keylen = crypto_sign_ed25519_PUBLICKEYBYTES; + ret = EVP_PKEY_get_raw_public_key(key.get(), d_pubkey, &keylen); + if (ret == 0) { + throw runtime_error(getName() + ": Failed to get public key from PEM file contents `" + filename + "`"); + } +} + void SodiumED25519DNSCryptoKeyEngine::convertToPEM(std::FILE& fp) const { auto key = std::unique_ptr(EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, nullptr, d_seckey, crypto_sign_ed25519_SEEDBYTES), EVP_PKEY_free);