]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Sodium impl of EDDSA PEM export
authorFred Morcos <fred.morcos@open-xchange.com>
Wed, 30 Mar 2022 08:39:03 +0000 (10:39 +0200)
committerFred Morcos <fred.morcos@open-xchange.com>
Wed, 20 Apr 2022 10:51:42 +0000 (12:51 +0200)
There's no real way to serialize keys in Sodium, so we fall-back to
using OpenSSL which is available in our Sodium-based builds.

pdns/sodiumsigners.cc

index d7c5bba38ca077faa1c8e552c43b46714f267ea1..c9190354cdac9f642aa26000998fedb8533156d6 100644 (file)
@@ -1,3 +1,5 @@
+#include <openssl/evp.h>
+#include <openssl/pem.h>
 extern "C" {
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -13,6 +15,19 @@ public:
   {}
   string getName() const override { return "Sodium ED25519"; }
   void create(unsigned int bits) 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;
+
   storvector_t convertToISCVector() const override;
   std::string getPubKeyHash() const override;
   std::string sign(const std::string& msg) const override;
@@ -40,6 +55,19 @@ void SodiumED25519DNSCryptoKeyEngine::create(unsigned int bits)
   crypto_sign_ed25519_keypair(d_pubkey, d_seckey);
 }
 
+void SodiumED25519DNSCryptoKeyEngine::convertToPEM(std::FILE& fp) const
+{
+  auto key = std::unique_ptr<EVP_PKEY, void (*)(EVP_PKEY*)>(EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, nullptr, d_seckey, crypto_sign_ed25519_SEEDBYTES), 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");
+  }
+}
+
 int SodiumED25519DNSCryptoKeyEngine::getBits() const
 {
   return crypto_sign_ed25519_SEEDBYTES * 8;