]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Reformat dnsdist-lua-bindings-dnscrypt.cc
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 21 May 2024 08:52:54 +0000 (10:52 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 21 May 2024 08:52:54 +0000 (10:52 +0200)
.not-formatted
pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc

index 74920fdcc5f5d2d20eb23e801a967c7d8d42f83a..696f65ed70d7fc0ffb892f52a0ad772c00153aaf 100644 (file)
@@ -39,7 +39,6 @@
 ./pdns/dnsdistdist/dnsdist-kvs.cc
 ./pdns/dnsdistdist/dnsdist-kvs.hh
 ./pdns/dnsdistdist/dnsdist-lbpolicies.cc
-./pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc
 ./pdns/dnsdistdist/dnsdist-lua-bindings-kvs.cc
 ./pdns/dnsdistdist/dnsdist-lua-bindings-packetcache.cc
 ./pdns/dnsdistdist/dnsdist-lua-bindings-protobuf.cc
index 6d6a61d6983bf794f1d414d0a0181b92c33bedf3..9c7775f19fc4578389b7132aff5a9e5e29b19797 100644 (file)
 void setupLuaBindingsDNSCrypt(LuaContext& luaCtx, bool client)
 {
 #ifdef HAVE_DNSCRYPT
-    /* DNSCryptContext bindings */
-    luaCtx.registerFunction<std::string(DNSCryptContext::*)()const>("getProviderName", [](const DNSCryptContext& ctx) { return ctx.getProviderName().toStringNoDot(); });
-    luaCtx.registerFunction("markActive", &DNSCryptContext::markActive);
-    luaCtx.registerFunction("markInactive", &DNSCryptContext::markInactive);
-    luaCtx.registerFunction("reloadCertificates", &DNSCryptContext::reloadCertificates);
-    luaCtx.registerFunction("removeInactiveCertificate", &DNSCryptContext::removeInactiveCertificate);
-    luaCtx.registerFunction<void(std::shared_ptr<DNSCryptContext>::*)(const std::string& certFile, const std::string& keyFile, boost::optional<bool> active)>("loadNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const std::string& certFile, const std::string& keyFile, boost::optional<bool> active) {
-
-      if (ctx == nullptr) {
-        throw std::runtime_error("DNSCryptContext::loadNewCertificate() called on a nil value");
-      }
-
-      ctx->loadNewCertificate(certFile, keyFile, active ? *active : true);
-    });
-    luaCtx.registerFunction<void(std::shared_ptr<DNSCryptContext>::*)(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active)>("addNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active) {
-
-      if (ctx == nullptr) {
-        throw std::runtime_error("DNSCryptContext::addNewCertificate() called on a nil value");
-      }
-
-      ctx->addNewCertificate(newCert, newKey, active ? *active : true);
-    });
-    luaCtx.registerFunction<LuaArray<std::shared_ptr<DNSCryptCertificatePair>>(std::shared_ptr<DNSCryptContext>::*)()>("getCertificatePairs", [](std::shared_ptr<DNSCryptContext> ctx) {
-      LuaArray<std::shared_ptr<DNSCryptCertificatePair>> result;
-
-      if (ctx != nullptr) {
-        size_t idx = 1;
-        for (const auto& pair : ctx->getCertificates()) {
-          result.push_back({idx++, pair});
-        }
-      }
-
-      return result;
-    });
-
-    luaCtx.registerFunction<std::shared_ptr<DNSCryptCertificatePair>(std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificatePair", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) {
-
-      if (ctx == nullptr) {
-        throw std::runtime_error("DNSCryptContext::getCertificatePair() called on a nil value");
-      }
-
-      std::shared_ptr<DNSCryptCertificatePair> result = nullptr;
-      auto pairs = ctx->getCertificates();
-      if (idx < pairs.size()) {
-        result = pairs.at(idx);
-      }
-
-      return result;
-    });
-
-    luaCtx.registerFunction<const DNSCryptCert(std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificate", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) {
-
-      if (ctx == nullptr) {
-        throw std::runtime_error("DNSCryptContext::getCertificate() called on a nil value");
-      }
-
-      auto pairs = ctx->getCertificates();
-      if (idx < pairs.size()) {
-        return pairs.at(idx)->cert;
-      }
-
-      throw std::runtime_error("This DNSCrypt context has no certificate at index " + std::to_string(idx));
-    });
-
-    luaCtx.registerFunction<std::string(std::shared_ptr<DNSCryptContext>::*)()const>("printCertificates", [](const std::shared_ptr<DNSCryptContext> ctx) {
-      ostringstream ret;
-
-      if (ctx != nullptr) {
-        size_t idx = 1;
-        boost::format fmt("%1$-3d %|5t|%2$-8d %|10t|%3$-7d %|20t|%4$-21.21s %|41t|%5$-21.21s");
-        ret << (fmt % "#" % "Serial" % "Version" % "From" % "To" ) << endl;
-
-        for (const auto& pair : ctx->getCertificates()) {
-          const auto& cert = pair->cert;
-          const DNSCryptExchangeVersion version = DNSCryptContext::getExchangeVersion(cert);
-
-          ret << (fmt % idx % cert.getSerial() % (version == DNSCryptExchangeVersion::VERSION1 ? 1 : 2) % DNSCryptContext::certificateDateToStr(cert.getTSStart()) % DNSCryptContext::certificateDateToStr(cert.getTSEnd())) << endl;
-        }
-      }
-
-      return ret.str();
-    });
-
-    luaCtx.registerFunction<void(DNSCryptContext::*)(const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version)>("generateAndLoadInMemoryCertificate", [](DNSCryptContext& ctx, const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version) {
-        DNSCryptPrivateKey privateKey;
-        DNSCryptCert cert;
-
-        try {
-          if (generateDNSCryptCertificate(providerPrivateKeyFile, serial, begin, end, version ? *version : DNSCryptExchangeVersion::VERSION1, cert, privateKey)) {
-            ctx.addNewCertificate(cert, privateKey);
-          }
-        }
-        catch (const std::exception& e) {
-          errlog("Error generating a DNSCrypt certificate: %s", e.what());
-          g_outputBuffer = "Error generating a DNSCrypt certificate: " + string(e.what()) + "\n";
-        }
-    });
-
-    /* DNSCryptCertificatePair */
-    luaCtx.registerFunction<const DNSCryptCert(std::shared_ptr<DNSCryptCertificatePair>::*)()const>("getCertificate", [](const std::shared_ptr<DNSCryptCertificatePair> pair) {
-      if (pair == nullptr) {
-        throw std::runtime_error("DNSCryptCertificatePair::getCertificate() called on a nil value");
-      }
-      return pair->cert;
-    });
-    luaCtx.registerFunction<bool(std::shared_ptr<DNSCryptCertificatePair>::*)()const>("isActive", [](const std::shared_ptr<DNSCryptCertificatePair> pair) {
-      if (pair == nullptr) {
-        throw std::runtime_error("DNSCryptCertificatePair::isActive() called on a nil value");
-      }
-      return pair->active;
-    });
-
-    /* DNSCryptCert */
-    luaCtx.registerFunction<std::string(DNSCryptCert::*)()const>("getMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.magic.data()), cert.magic.size()); });
-    luaCtx.registerFunction<std::string(DNSCryptCert::*)()const>("getEsVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.esVersion.data()), cert.esVersion.size()); });
-    luaCtx.registerFunction<std::string(DNSCryptCert::*)()const>("getProtocolMinorVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.protocolMinorVersion.data()), cert.protocolMinorVersion.size()); });
-    luaCtx.registerFunction<std::string(DNSCryptCert::*)()const>("getSignature", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signature.data()), cert.signature.size()); });
-    luaCtx.registerFunction<std::string(DNSCryptCert::*)()const>("getResolverPublicKey", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.resolverPK.data()), cert.signedData.resolverPK.size()); });
-    luaCtx.registerFunction<std::string(DNSCryptCert::*)()const>("getClientMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.clientMagic.data()), cert.signedData.clientMagic.size()); });
-    luaCtx.registerFunction<uint32_t(DNSCryptCert::*)()const>("getSerial", [](const DNSCryptCert& cert) { return cert.getSerial(); });
-    luaCtx.registerFunction<uint32_t(DNSCryptCert::*)()const>("getTSStart", [](const DNSCryptCert& cert) { return ntohl(cert.getTSStart()); });
-    luaCtx.registerFunction<uint32_t(DNSCryptCert::*)()const>("getTSEnd", [](const DNSCryptCert& cert) { return ntohl(cert.getTSEnd()); });
-
-    luaCtx.writeFunction("generateDNSCryptCertificate", [client](const std::string& providerPrivateKeyFile, const std::string& certificateFile, const std::string& privateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version) {
-      setLuaNoSideEffect();
-      if (client) {
-        return;
-      }
-      DNSCryptPrivateKey privateKey;
-      DNSCryptCert cert;
-
-      try {
-        if (generateDNSCryptCertificate(providerPrivateKeyFile, serial, begin, end, version ? *version : DNSCryptExchangeVersion::VERSION1, cert, privateKey)) {
-          privateKey.saveToFile(privateKeyFile);
-          DNSCryptContext::saveCertFromFile(cert, certificateFile);
-        }
-      }
-      catch (const std::exception& e) {
-        errlog("Error generating a DNSCrypt certificate: %s", e.what());
-        g_outputBuffer = "Error generating a DNSCrypt certificate: " + string(e.what()) + "\n";
-      }
-    });
-
-    luaCtx.writeFunction("generateDNSCryptProviderKeys", [client](const std::string& publicKeyFile, const std::string& privateKeyFile) {
-      setLuaNoSideEffect();
-      if (client) {
-        return;
-      }
-      DNSCryptCertSignedData::ResolverPublicKeyType publicKey;
-      DNSCryptCertSignedData::ResolverPrivateKeyType privateKey;
-      sodium_mlock(privateKey.data(), privateKey.size());
-
-      try {
-        DNSCryptContext::generateProviderKeys(publicKey, privateKey);
-
-        ofstream pubKStream(publicKeyFile);
-        pubKStream.write(reinterpret_cast<char*>(publicKey.data()), publicKey.size());
-        pubKStream.close();
-
-        ofstream privKStream(privateKeyFile);
-        privKStream.write(reinterpret_cast<char*>(privateKey.data()), privateKey.size());
-        privKStream.close();
-
-        g_outputBuffer = "Provider fingerprint is: " + DNSCryptContext::getProviderFingerprint(publicKey) + "\n";
-      }
-      catch (const std::exception& e) {
-        errlog("Error generating a DNSCrypt provider key: %s", e.what());
-        g_outputBuffer = "Error generating a DNSCrypt provider key: " + string(e.what()) + "\n";
-      }
-
-      sodium_memzero(privateKey.data(), privateKey.size());
-      sodium_munlock(privateKey.data(), privateKey.size());
-    });
-
-    luaCtx.writeFunction("printDNSCryptProviderFingerprint", [](const std::string& publicKeyFile) {
-      setLuaNoSideEffect();
-      DNSCryptCertSignedData::ResolverPublicKeyType publicKey;
-
-      try {
-        ifstream file(publicKeyFile);
-        file.read(reinterpret_cast<char*>(publicKey.data()), publicKey.size());
-
-        if (file.fail()) {
-          throw std::runtime_error("Invalid dnscrypt provider public key file " + publicKeyFile);
-        }
-
-        file.close();
-        g_outputBuffer = "Provider fingerprint is: " + DNSCryptContext::getProviderFingerprint(publicKey) + "\n";
-      }
-      catch (const std::exception& e) {
-        errlog("Error getting a DNSCrypt provider fingerprint: %s", e.what());
-        g_outputBuffer = "Error getting a DNSCrypt provider fingerprint: " + string(e.what()) + "\n";
-      }
-    });
+  /* DNSCryptContext bindings */
+  luaCtx.registerFunction<std::string (DNSCryptContext::*)() const>("getProviderName", [](const DNSCryptContext& ctx) { return ctx.getProviderName().toStringNoDot(); });
+  luaCtx.registerFunction("markActive", &DNSCryptContext::markActive);
+  luaCtx.registerFunction("markInactive", &DNSCryptContext::markInactive);
+  luaCtx.registerFunction("reloadCertificates", &DNSCryptContext::reloadCertificates);
+  luaCtx.registerFunction("removeInactiveCertificate", &DNSCryptContext::removeInactiveCertificate);
+  luaCtx.registerFunction<void (std::shared_ptr<DNSCryptContext>::*)(const std::string& certFile, const std::string& keyFile, boost::optional<bool> active)>("loadNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const std::string& certFile, const std::string& keyFile, boost::optional<bool> active) {
+    if (ctx == nullptr) {
+      throw std::runtime_error("DNSCryptContext::loadNewCertificate() called on a nil value");
+    }
+
+    ctx->loadNewCertificate(certFile, keyFile, active ? *active : true);
+  });
+  luaCtx.registerFunction<void (std::shared_ptr<DNSCryptContext>::*)(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active)>("addNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active) {
+    if (ctx == nullptr) {
+      throw std::runtime_error("DNSCryptContext::addNewCertificate() called on a nil value");
+    }
+
+    ctx->addNewCertificate(newCert, newKey, active ? *active : true);
+  });
+  luaCtx.registerFunction<LuaArray<std::shared_ptr<DNSCryptCertificatePair>> (std::shared_ptr<DNSCryptContext>::*)()>("getCertificatePairs", [](std::shared_ptr<DNSCryptContext> ctx) {
+    LuaArray<std::shared_ptr<DNSCryptCertificatePair>> result;
+
+    if (ctx != nullptr) {
+      size_t idx = 1;
+      for (const auto& pair : ctx->getCertificates()) {
+        result.push_back({idx++, pair});
+      }
+    }
+
+    return result;
+  });
+
+  luaCtx.registerFunction<std::shared_ptr<DNSCryptCertificatePair> (std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificatePair", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) {
+    if (ctx == nullptr) {
+      throw std::runtime_error("DNSCryptContext::getCertificatePair() called on a nil value");
+    }
+
+    std::shared_ptr<DNSCryptCertificatePair> result = nullptr;
+    auto pairs = ctx->getCertificates();
+    if (idx < pairs.size()) {
+      result = pairs.at(idx);
+    }
+
+    return result;
+  });
+
+  luaCtx.registerFunction<const DNSCryptCert (std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificate", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) {
+    if (ctx == nullptr) {
+      throw std::runtime_error("DNSCryptContext::getCertificate() called on a nil value");
+    }
+
+    auto pairs = ctx->getCertificates();
+    if (idx < pairs.size()) {
+      return pairs.at(idx)->cert;
+    }
+
+    throw std::runtime_error("This DNSCrypt context has no certificate at index " + std::to_string(idx));
+  });
+
+  luaCtx.registerFunction<std::string (std::shared_ptr<DNSCryptContext>::*)() const>("printCertificates", [](const std::shared_ptr<DNSCryptContext> ctx) {
+    ostringstream ret;
+
+    if (ctx != nullptr) {
+      size_t idx = 1;
+      boost::format fmt("%1$-3d %|5t|%2$-8d %|10t|%3$-7d %|20t|%4$-21.21s %|41t|%5$-21.21s");
+      ret << (fmt % "#" % "Serial" % "Version" % "From" % "To") << endl;
+
+      for (const auto& pair : ctx->getCertificates()) {
+        const auto& cert = pair->cert;
+        const DNSCryptExchangeVersion version = DNSCryptContext::getExchangeVersion(cert);
+
+        ret << (fmt % idx % cert.getSerial() % (version == DNSCryptExchangeVersion::VERSION1 ? 1 : 2) % DNSCryptContext::certificateDateToStr(cert.getTSStart()) % DNSCryptContext::certificateDateToStr(cert.getTSEnd())) << endl;
+      }
+    }
+
+    return ret.str();
+  });
+
+  luaCtx.registerFunction<void (DNSCryptContext::*)(const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version)>("generateAndLoadInMemoryCertificate", [](DNSCryptContext& ctx, const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version) {
+    DNSCryptPrivateKey privateKey;
+    DNSCryptCert cert;
+
+    try {
+      if (generateDNSCryptCertificate(providerPrivateKeyFile, serial, begin, end, version ? *version : DNSCryptExchangeVersion::VERSION1, cert, privateKey)) {
+        ctx.addNewCertificate(cert, privateKey);
+      }
+    }
+    catch (const std::exception& e) {
+      errlog("Error generating a DNSCrypt certificate: %s", e.what());
+      g_outputBuffer = "Error generating a DNSCrypt certificate: " + string(e.what()) + "\n";
+    }
+  });
+
+  /* DNSCryptCertificatePair */
+  luaCtx.registerFunction<const DNSCryptCert (std::shared_ptr<DNSCryptCertificatePair>::*)() const>("getCertificate", [](const std::shared_ptr<DNSCryptCertificatePair> pair) {
+    if (pair == nullptr) {
+      throw std::runtime_error("DNSCryptCertificatePair::getCertificate() called on a nil value");
+    }
+    return pair->cert;
+  });
+  luaCtx.registerFunction<bool (std::shared_ptr<DNSCryptCertificatePair>::*)() const>("isActive", [](const std::shared_ptr<DNSCryptCertificatePair> pair) {
+    if (pair == nullptr) {
+      throw std::runtime_error("DNSCryptCertificatePair::isActive() called on a nil value");
+    }
+    return pair->active;
+  });
+
+  /* DNSCryptCert */
+  luaCtx.registerFunction<std::string (DNSCryptCert::*)() const>("getMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.magic.data()), cert.magic.size()); });
+  luaCtx.registerFunction<std::string (DNSCryptCert::*)() const>("getEsVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.esVersion.data()), cert.esVersion.size()); });
+  luaCtx.registerFunction<std::string (DNSCryptCert::*)() const>("getProtocolMinorVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.protocolMinorVersion.data()), cert.protocolMinorVersion.size()); });
+  luaCtx.registerFunction<std::string (DNSCryptCert::*)() const>("getSignature", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signature.data()), cert.signature.size()); });
+  luaCtx.registerFunction<std::string (DNSCryptCert::*)() const>("getResolverPublicKey", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.resolverPK.data()), cert.signedData.resolverPK.size()); });
+  luaCtx.registerFunction<std::string (DNSCryptCert::*)() const>("getClientMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.clientMagic.data()), cert.signedData.clientMagic.size()); });
+  luaCtx.registerFunction<uint32_t (DNSCryptCert::*)() const>("getSerial", [](const DNSCryptCert& cert) { return cert.getSerial(); });
+  luaCtx.registerFunction<uint32_t (DNSCryptCert::*)() const>("getTSStart", [](const DNSCryptCert& cert) { return ntohl(cert.getTSStart()); });
+  luaCtx.registerFunction<uint32_t (DNSCryptCert::*)() const>("getTSEnd", [](const DNSCryptCert& cert) { return ntohl(cert.getTSEnd()); });
+
+  luaCtx.writeFunction("generateDNSCryptCertificate", [client](const std::string& providerPrivateKeyFile, const std::string& certificateFile, const std::string& privateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version) {
+    setLuaNoSideEffect();
+    if (client) {
+      return;
+    }
+    DNSCryptPrivateKey privateKey;
+    DNSCryptCert cert;
+
+    try {
+      if (generateDNSCryptCertificate(providerPrivateKeyFile, serial, begin, end, version ? *version : DNSCryptExchangeVersion::VERSION1, cert, privateKey)) {
+        privateKey.saveToFile(privateKeyFile);
+        DNSCryptContext::saveCertFromFile(cert, certificateFile);
+      }
+    }
+    catch (const std::exception& e) {
+      errlog("Error generating a DNSCrypt certificate: %s", e.what());
+      g_outputBuffer = "Error generating a DNSCrypt certificate: " + string(e.what()) + "\n";
+    }
+  });
+
+  luaCtx.writeFunction("generateDNSCryptProviderKeys", [client](const std::string& publicKeyFile, const std::string& privateKeyFile) {
+    setLuaNoSideEffect();
+    if (client) {
+      return;
+    }
+    DNSCryptCertSignedData::ResolverPublicKeyType publicKey;
+    DNSCryptCertSignedData::ResolverPrivateKeyType privateKey;
+    sodium_mlock(privateKey.data(), privateKey.size());
+
+    try {
+      DNSCryptContext::generateProviderKeys(publicKey, privateKey);
+
+      ofstream pubKStream(publicKeyFile);
+      pubKStream.write(reinterpret_cast<char*>(publicKey.data()), publicKey.size());
+      pubKStream.close();
+
+      ofstream privKStream(privateKeyFile);
+      privKStream.write(reinterpret_cast<char*>(privateKey.data()), privateKey.size());
+      privKStream.close();
+
+      g_outputBuffer = "Provider fingerprint is: " + DNSCryptContext::getProviderFingerprint(publicKey) + "\n";
+    }
+    catch (const std::exception& e) {
+      errlog("Error generating a DNSCrypt provider key: %s", e.what());
+      g_outputBuffer = "Error generating a DNSCrypt provider key: " + string(e.what()) + "\n";
+    }
+
+    sodium_memzero(privateKey.data(), privateKey.size());
+    sodium_munlock(privateKey.data(), privateKey.size());
+  });
+
+  luaCtx.writeFunction("printDNSCryptProviderFingerprint", [](const std::string& publicKeyFile) {
+    setLuaNoSideEffect();
+    DNSCryptCertSignedData::ResolverPublicKeyType publicKey;
+
+    try {
+      ifstream file(publicKeyFile);
+      file.read(reinterpret_cast<char*>(publicKey.data()), publicKey.size());
+
+      if (file.fail()) {
+        throw std::runtime_error("Invalid dnscrypt provider public key file " + publicKeyFile);
+      }
+
+      file.close();
+      g_outputBuffer = "Provider fingerprint is: " + DNSCryptContext::getProviderFingerprint(publicKey) + "\n";
+    }
+    catch (const std::exception& e) {
+      errlog("Error getting a DNSCrypt provider fingerprint: %s", e.what());
+      g_outputBuffer = "Error getting a DNSCrypt provider fingerprint: " + string(e.what()) + "\n";
+    }
+  });
 #endif
 }