Merge pull request #7366

9867a91 Store RPC SSL key/cert for consistent authentication between runs (Lee Clagett)
This commit is contained in:
luigi1111 2021-03-20 01:38:03 -04:00
commit 602926fe9d
No known key found for this signature in database
GPG key ID: F4ACA0183641E010
4 changed files with 80 additions and 2 deletions

View file

@ -265,6 +265,12 @@ namespace net_utils
template<class t_callback>
bool connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeot, const t_callback &cb, const std::string& bind_ip = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect);
boost::asio::ssl::context& get_ssl_context() noexcept
{
assert(m_state != nullptr);
return m_state->ssl_context;
}
typename t_protocol_handler::config_type& get_config_object()
{
assert(m_state != nullptr); // always set in constructor

View file

@ -36,6 +36,7 @@
#include <boost/utility/string_ref.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/error_code.hpp>
#define SSL_FINGERPRINT_SIZE 32
@ -144,6 +145,9 @@ namespace net_utils
bool create_ec_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
//! Store private key for `ssl` at `base + ".key"` unencrypted and certificate for `ssl` at `base + ".crt"`.
boost::system::error_code store_ssl_keys(boost::asio::ssl::context& ssl, const boost::filesystem::path& base);
}
}

View file

@ -29,6 +29,8 @@
#include <string.h>
#include <thread>
#include <boost/asio/ssl.hpp>
#include <boost/cerrno.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/lambda/lambda.hpp>
#include <openssl/ssl.h>
#include <openssl/pem.h>
@ -567,6 +569,51 @@ bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s)
return true;
}
boost::system::error_code store_ssl_keys(boost::asio::ssl::context& ssl, const boost::filesystem::path& base)
{
EVP_PKEY* ssl_key = nullptr;
X509* ssl_cert = nullptr;
const auto ctx = ssl.native_handle();
CHECK_AND_ASSERT_MES(ctx, boost::system::error_code(EINVAL, boost::system::system_category()), "Context is null");
CHECK_AND_ASSERT_MES(base.has_filename(), boost::system::error_code(EINVAL, boost::system::system_category()), "Need filename");
if (!(ssl_key = SSL_CTX_get0_privatekey(ctx)) || !(ssl_cert = SSL_CTX_get0_certificate(ctx)))
return {EINVAL, boost::system::system_category()};
using file_closer = int(std::FILE*);
boost::system::error_code error{};
std::unique_ptr<std::FILE, file_closer*> file{nullptr, std::fclose};
// write key file unencrypted
{
const boost::filesystem::path key_file{base.string() + ".key"};
file.reset(std::fopen(key_file.string().c_str(), "wb"));
if (!file)
return {errno, boost::system::system_category()};
boost::filesystem::permissions(key_file, boost::filesystem::owner_read, error);
if (error)
return error;
if (!PEM_write_PrivateKey(file.get(), ssl_key, nullptr, nullptr, 0, nullptr, nullptr))
return boost::asio::error::ssl_errors(ERR_get_error());
if (std::fclose(file.release()) != 0)
return {errno, boost::system::system_category()};
}
// write certificate file in standard SSL X.509 unencrypted
const boost::filesystem::path cert_file{base.string() + ".crt"};
file.reset(std::fopen(cert_file.string().c_str(), "wb"));
if (!file)
return {errno, boost::system::system_category()};
const auto cert_perms = (boost::filesystem::owner_read | boost::filesystem::group_read | boost::filesystem::others_read);
boost::filesystem::permissions(cert_file, cert_perms, error);
if (error)
return error;
if (!PEM_write_X509(file.get(), ssl_cert))
return boost::asio::error::ssl_errors(ERR_get_error());
if (std::fclose(file.release()) != 0)
return {errno, boost::system::system_category()};
return error;
}
} // namespace
} // namespace