mirror of
https://github.com/monero-project/monero.git
synced 2026-01-27 06:44:33 +01:00
core_rpc_server: new file: rpc_ssl.fingerprint
This commit is contained in:
@@ -641,6 +641,56 @@ bool ssl_options_t::handshake(
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string get_hr_ssl_fingerprint(const X509 *cert, const EVP_MD *fdig)
|
||||
{
|
||||
unsigned int j;
|
||||
unsigned int n;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
std::string fingerprint;
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(cert && fdig, "Pointer args to get_hr_ssl_fingerprint cannot be null");
|
||||
|
||||
if (!X509_digest(cert, fdig, md, &n))
|
||||
{
|
||||
const unsigned long ssl_err_val = static_cast<int>(ERR_get_error());
|
||||
const boost::system::error_code ssl_err_code = boost::asio::error::ssl_errors(static_cast<int>(ssl_err_val));
|
||||
MERROR("Failed to create SSL fingerprint: " << ERR_reason_error_string(ssl_err_val));
|
||||
throw boost::system::system_error(ssl_err_code, ERR_reason_error_string(ssl_err_val));
|
||||
}
|
||||
fingerprint.resize(n * 3 - 1);
|
||||
char *out = &fingerprint[0];
|
||||
for (j = 0; j < n; ++j)
|
||||
{
|
||||
snprintf(out, 3 + (j + 1 < n), "%02X%s", md[j], (j + 1 == n) ? "" : ":");
|
||||
out += 3;
|
||||
}
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
std::string get_hr_ssl_fingerprint_from_file(const std::string& cert_path, const EVP_MD *fdig) {
|
||||
// Open file for reading
|
||||
FILE* fp = fopen(cert_path.c_str(), "r");
|
||||
if (!fp)
|
||||
{
|
||||
const boost::system::error_code err_code(errno, boost::system::system_category());
|
||||
throw boost::system::system_error(err_code, "Failed to open certificate file '" + cert_path + "'");
|
||||
}
|
||||
std::unique_ptr<FILE, decltype(&fclose)> file(fp, &fclose);
|
||||
|
||||
// Extract certificate structure from file
|
||||
X509* ssl_cert_handle = PEM_read_X509(file.get(), NULL, NULL, NULL);
|
||||
if (!ssl_cert_handle) {
|
||||
const unsigned long ssl_err_val = static_cast<int>(ERR_get_error());
|
||||
const boost::system::error_code ssl_err_code = boost::asio::error::ssl_errors(static_cast<int>(ssl_err_val));
|
||||
MERROR("OpenSSL error occurred while loading certificate at '" + cert_path + "'");
|
||||
throw boost::system::system_error(ssl_err_code, ERR_reason_error_string(ssl_err_val));
|
||||
}
|
||||
std::unique_ptr<X509, decltype(&X509_free)> ssl_cert(ssl_cert_handle, &X509_free);
|
||||
|
||||
// Get the fingerprint from X509 structure
|
||||
return get_hr_ssl_fingerprint(ssl_cert.get(), fdig);
|
||||
}
|
||||
|
||||
bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s)
|
||||
{
|
||||
if (s == "enabled")
|
||||
@@ -705,6 +755,29 @@ boost::system::error_code store_ssl_keys(boost::asio::ssl::context& ssl, const b
|
||||
return boost::asio::error::ssl_errors(ERR_get_error());
|
||||
if (std::fclose(file.release()) != 0)
|
||||
return {errno, boost::system::system_category()};
|
||||
|
||||
// write SHA-256 fingerprint file
|
||||
const boost::filesystem::path fp_file{base.string() + ".fingerprint"};
|
||||
file.reset(std::fopen(fp_file.string().c_str(), "w"));
|
||||
if (!file)
|
||||
return {errno, boost::system::system_category()};
|
||||
const auto fp_perms = (boost::filesystem::owner_read | boost::filesystem::group_read | boost::filesystem::others_read);
|
||||
boost::filesystem::permissions(fp_file, fp_perms, error);
|
||||
if (error)
|
||||
return error;
|
||||
try
|
||||
{
|
||||
const std::string fingerprint = get_hr_ssl_fingerprint(ssl_cert);
|
||||
if (fingerprint.length() != fwrite(fingerprint.c_str(), sizeof(char), fingerprint.length(), file.get()))
|
||||
return {errno, boost::system::system_category()};
|
||||
}
|
||||
catch (const boost::system::system_error& fperr)
|
||||
{
|
||||
return fperr.code();
|
||||
}
|
||||
if (std::fclose(file.release()) != 0)
|
||||
return {errno, boost::system::system_category()};
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user