From: Fred Morcos Date: Fri, 8 Apr 2022 12:32:22 +0000 (+0200) Subject: Libdecaf impl of Ed448 PEM import and export X-Git-Tag: auth-4.8.0-alpha0~124^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8dd202d51e4a8c968dabea035b37fd938a10b95c;p=thirdparty%2Fpdns.git Libdecaf impl of Ed448 PEM import and export --- diff --git a/pdns/decafsigners.cc b/pdns/decafsigners.cc index f8376289e6..9f3bd1bda3 100644 --- a/pdns/decafsigners.cc +++ b/pdns/decafsigners.cc @@ -224,6 +224,40 @@ public: } string getName() const override { return "Decaf ED448"; } void create(unsigned int bits) override; + +#if defined(HAVE_LIBCRYPTO_ED448) + /** + * \brief Creates an ED448 key engine from a PEM file. + * + * Receives an open file handle with PEM contents and creates an ED448 + * 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 ED448 PEM + * contents. + * + * \return An ED448 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. + * + * Receives an open file handle and writes this key's contents to the + * file. + * + * \param[in] fp An open file handle for writing. + * + * \exception std::runtime_error In case of OpenSSL errors. + */ + void convertToPEM(std::FILE& fp) const override; +#endif + storvector_t convertToISCVector() const override; std::string getPubKeyHash() const override; std::string sign(const std::string& msg) const override; @@ -258,6 +292,42 @@ void DecafED448DNSCryptoKeyEngine::create(unsigned int bits) pub.serialize_into(d_pubkey); } +#if defined(HAVE_LIBCRYPTO_ED448) +void DecafED448DNSCryptoKeyEngine::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 = DECAF_EDDSA_448_PRIVATE_BYTES; + 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 = DECAF_EDDSA_448_PUBLIC_BYTES; + 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 DecafED448DNSCryptoKeyEngine::convertToPEM(std::FILE& fp) const +{ + auto key = std::unique_ptr(EVP_PKEY_new_raw_private_key(EVP_PKEY_ED448, nullptr, d_seckey, DECAF_EDDSA_448_PRIVATE_BYTES), EVP_PKEY_free); + if (key == nullptr) { + throw runtime_error(getName() + ": Could not create private key from buffer"); + } + + auto ret = PEM_write_PrivateKey(&fp, key.get(), nullptr, nullptr, 0, nullptr, nullptr); + if (ret == 0) { + throw runtime_error(getName() + ": Could not convert private key to PEM"); + } +} +#endif + int DecafED448DNSCryptoKeyEngine::getBits() const { return DECAF_EDDSA_448_PRIVATE_BYTES << 3;