diff --git a/include/opendht/dht_proxy_server.h b/include/opendht/dht_proxy_server.h index 8be073ac958af602eeb7f41acb050f40d9ae587e..c98ca30dcb88ca42f6bf51f9a1a8321c52d6bccc 100644 --- a/include/opendht/dht_proxy_server.h +++ b/include/opendht/dht_proxy_server.h @@ -31,7 +31,11 @@ #include <memory> #include <mutex> + #include <restinio/all.hpp> +#ifdef OPENDHT_PROXY_OPENSSL +#include <restinio/tls.hpp> +#endif #include "http.h" #ifdef OPENDHT_JSONCPP @@ -51,7 +55,12 @@ namespace restinio { } using RestRouter = restinio::router::express_router_t<>; + +#ifdef OPENDHT_PROXY_OPENSSL +struct RestRouterTraits : public restinio::default_tls_traits_t +#else struct RestRouterTraits : public restinio::default_traits_t +#endif { using timer_manager_t = restinio::asio_timer_manager_t; using http_methods_mapper_t = restinio::custom_http_methods_t; @@ -88,10 +97,10 @@ public: */ DhtProxyServer( #ifdef OPENDHT_PROXY_OPENSSL - dht::crypto::Identity& identity, + dht::crypto::Identity& identity, #endif - std::shared_ptr<DhtRunner> dht, in_port_t port = 8000, - const std::string& pushServer = "", std::shared_ptr<dht::Logger> logger = {}); + std::shared_ptr<DhtRunner> dht, in_port_t port = 8000, const std::string& pushServer = "", + std::shared_ptr<dht::Logger> logger = {}); virtual ~DhtProxyServer(); @@ -337,6 +346,10 @@ private: // http server std::thread httpServerThread_; std::unique_ptr<restinio::http_server_t<RestRouterTraits>> httpServer_; +#ifdef OPENDHT_PROXY_OPENSSL + std::unique_ptr<const asio::const_buffer> pk_; + std::unique_ptr<const asio::const_buffer> cc_; +#endif // http client std::pair<std::string, std::string> pushHostPort_; diff --git a/src/dht_proxy_server.cpp b/src/dht_proxy_server.cpp index 8db78805b8217880d6d428cb38fb9be690673e3f..977952ab52f76582faae45e8e6c01e6f50072d98 100644 --- a/src/dht_proxy_server.cpp +++ b/src/dht_proxy_server.cpp @@ -48,15 +48,14 @@ constexpr const std::chrono::minutes PRINT_STATS_PERIOD {2}; DhtProxyServer::DhtProxyServer( #ifdef OPENDHT_PROXY_OPENSSL - dht::crypto::Identity& identity, + dht::crypto::Identity& identity, #endif - std::shared_ptr<DhtRunner> dht, in_port_t port, - const std::string& pushServer, std::shared_ptr<dht::Logger> logger + std::shared_ptr<DhtRunner> dht, in_port_t port, const std::string& pushServer, + std::shared_ptr<dht::Logger> logger ): dht_(dht), logger_(logger), lockListener_(std::make_shared<std::mutex>()), listeners_(std::make_shared<std::map<restinio::connection_id_t, http::ListenerSession>>()), - connListener_(std::make_shared<http::ConnectionListener>( - dht, listeners_, lockListener_, logger)), + connListener_(std::make_shared<http::ConnectionListener>(dht, listeners_, lockListener_, logger)), pushServer_(pushServer) { if (not dht_) @@ -80,6 +79,33 @@ DhtProxyServer::DhtProxyServer( // build http server auto settings = makeHttpServerSettings(); settings.port(port); + +#ifdef OPENDHT_PROXY_OPENSSL + // define tls context + asio::ssl::context tls_context { asio::ssl::context::sslv23 }; + tls_context.set_options(asio::ssl::context::default_workarounds + | asio::ssl::context::no_sslv2 + | asio::ssl::context::single_dh_use); + // save keys in memory & set in tls context + asio::error_code ec; + // node private key + auto pk = identity.first->serialize(); // returns Blob + pk_ = std::make_unique<const asio::const_buffer>(static_cast<void*>(pk.data()), + (std::size_t) pk.size()); + tls_context.use_private_key(*pk_, asio::ssl::context::file_format::pem, ec); + if (ec) + throw std::runtime_error("Error setting Node private key: " + ec.message()); + // certificate chain + auto cc = identity.second->toString(true/*chain*/); + auto ccb = dht::Blob(cc.begin(), cc.end()); + cc_ = std::make_unique<const asio::const_buffer>(static_cast<void*>(ccb.data()), + (std::size_t) ccb.size()); + tls_context.use_certificate_chain(*cc_, ec); + if (ec) + throw std::runtime_error("Error setting CA chain file: " + ec.message()); + settings.tls_context(std::move(tls_context)); +#endif + httpServer_.reset(new restinio::http_server_t<RestRouterTraits>( restinio::own_io_context(), std::forward<ServerSettings>(settings) diff --git a/tests/dhtproxytester.cpp b/tests/dhtproxytester.cpp index 459cffc4ce6b08e4a4a5469c8402a86b15384eb1..98bf654f1096e22e81c4925dda11f4e2681dc83f 100644 --- a/tests/dhtproxytester.cpp +++ b/tests/dhtproxytester.cpp @@ -41,15 +41,17 @@ DhtProxyTester::setUp() { nodeProxy->run(0, /*identity*/{}, /*threaded*/true); nodeProxy->bootstrap(nodePeer.getBound()); -#ifdef OPENDHT_PUSH_NOTIFICATIONS - auto ca_tmp = dht::crypto::generateEcIdentity("DHT Node CA"); - serverIdentity = dht::crypto::generateIdentity("DHT Node", ca_tmp); +#ifdef OPENDHT_PROXY_OPENSSL + serverCAIdentity = std::make_unique<dht::crypto::Identity>( + dht::crypto::generateEcIdentity("DHT Node CA")); + serverIdentity = std::make_unique<dht::crypto::Identity>( + dht::crypto::generateIdentity("DHT Node", *serverCAIdentity)); #endif serverProxy = std::unique_ptr<dht::DhtProxyServer>( new dht::DhtProxyServer( #ifdef OPENDHT_PUSH_NOTIFICATIONS - serverIdentity, + *serverIdentity, #endif nodeProxy, 8080, /*pushServer*/"127.0.0.1:8090", logger)); diff --git a/tests/dhtproxytester.h b/tests/dhtproxytester.h index a5078b7eae1db122449084a634446e15b9f68753..5739235d6bf83f8d500e583773f1ff2a15b98e42 100644 --- a/tests/dhtproxytester.h +++ b/tests/dhtproxytester.h @@ -68,7 +68,8 @@ class DhtProxyTester : public CppUnit::TestFixture { std::shared_ptr<dht::DhtRunner> nodeProxy; #ifdef OPENDHT_PUSH_NOTIFICATIONS - dht::crypto::Identity serverIdentity; + std::unique_ptr<dht::crypto::Identity> serverIdentity; + std::unique_ptr<dht::crypto::Identity> serverCAIdentity; #endif std::unique_ptr<dht::DhtProxyServer> serverProxy; diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp index 6bef49e3d91ef2ae4feb6f08aaf1bd8edee24dba..197515cce94849d10c6ba99daa4e58e7d0eff062 100644 --- a/tools/dhtnode.cpp +++ b/tools/dhtnode.cpp @@ -228,7 +228,7 @@ void cmd_loop(std::shared_ptr<DhtRunner>& node, dht_params& params proxies.emplace(port, std::unique_ptr<DhtProxyServer>( new DhtProxyServer( #ifdef OPENDHT_PROXY_OPENSSL - params.id, /* dht::crypto::Identity */ + params.id, #endif node, port #ifdef OPENDHT_PUSH_NOTIFICATIONS @@ -512,16 +512,19 @@ main(int argc, char **argv) setupSignals(); auto node = std::make_shared<DhtRunner>(); - try { +#ifndef OPENDHT_PROXY_SERVER if (not params.id.first and params.generate_identity) { - auto ca_tmp = dht::crypto::generateEcIdentity("DHT Node CA"); - params.id = dht::crypto::generateIdentity("DHT Node", ca_tmp); +#endif + auto node_ca = std::make_unique<dht::crypto::Identity>(dht::crypto::generateEcIdentity("DHT Node CA")); + params.id = dht::crypto::generateIdentity("DHT Node", *node_ca); if (not params.save_identity.empty()) { - dht::crypto::saveIdentity(ca_tmp, params.save_identity + "_ca", params.privkey_pwd); + dht::crypto::saveIdentity(*node_ca, params.save_identity + "_ca", params.privkey_pwd); dht::crypto::saveIdentity(params.id, params.save_identity, params.privkey_pwd); } +#ifndef OPENDHT_PROXY_SERVER } +#endif dht::DhtRunner::Config config {}; config.dht_config.node_config.network = params.network; @@ -562,7 +565,7 @@ main(int argc, char **argv) proxies.emplace(params.proxyserver, std::unique_ptr<DhtProxyServer>( new DhtProxyServer( #ifdef OPENDHT_PROXY_OPENSSL - params.id, /* dht::crypto::Identity */ + params.id, #endif node, params.proxyserver, params.pushserver, context.logger))); #else