Просматривая различные документы OpenSSL 3.0
Мне удалось собрать решение для включения режима FIPS в OpenSSL со следующей целью:
Акцент делается на том факте, что как только в OpenSSL включен режим FIPS, все криптографические операции, выполняемые через OpenSSL, включая те, которые используются C++ Boost.Asio для соединений SSL/TLS, будут использовать Алгоритмы, одобренные FIPS, обеспечивающие соответствие стандартам FIPS. во всем приложении Boost C++.
Это действительная функция enableFIPS()
для включения режима OpenSSL FIPS для Boost C++?
main.cpp
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <openssl/provider.h>
bool PrintErrorSSL(const std::string& err)
{
std::cerr << err << std::endl;
unsigned long err_code;
while ((err_code = ERR_get_error()) != 0)
{
char err_msg[256];
ERR_error_string_n(err_code, err_msg, sizeof(err_msg));
std::cerr << "OpenSSL error: " << err_msg << std::endl;
}
// FIPS mode not enabled.
return false;
}
bool enableFIPS()
{
std::string ConfigPath;
std::string TestPath = "C:/Projects/sys-openssl-fips/Test/";
#ifdef _WIN32
ConfigPath = TestPath + "openssl-fips.cnf";
#else
ConfigPath = TestPath + "openssl-fips-linux.cnf";
#endif
if (!OSSL_PROVIDER_set_default_search_path(nullptr, TestPath.c_str()))
{
return PrintErrorSSL("OSSL_PROVIDER_set_default_search_path() Failed");
}
if (!OSSL_LIB_CTX_load_config(nullptr, ConfigPath.c_str()))
{
return PrintErrorSSL("OSSL_LIB_CTX_load_config() Failed");
}
if (!OSSL_PROVIDER_available(nullptr, "fips") || !OSSL_PROVIDER_available(nullptr, "base"))
{
return PrintErrorSSL("OSSL_PROVIDER_available() Failed");
}
if (!EVP_default_properties_is_fips_enabled(nullptr))
{
return PrintErrorSSL("EVP_default_properties_is_fips_enabled() Failed");
}
// FIPS mode enabled.
return true;
}
int main(int argc, char* argv[])
{
if (enableFIPS())
{
using boost::asio::ip::tcp;
boost::asio::io_context io_context;
boost::asio::ssl::context ssl_context(boost::asio::ssl::context::tlsv12);
boost::asio::ssl::stream<tcp::socket> socket(io_context, ssl_context);
tcp::resolver resolver(io_context);
auto endpoints = resolver.resolve("www.google.com", "443");
boost::asio::connect(socket.lowest_layer(), endpoints);
socket.handshake(boost::asio::ssl::stream_base::client);
std::string request = "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n";
boost::asio::write(socket, boost::asio::buffer(request));
boost::asio::streambuf response;
boost::system::error_code ec;
boost::asio::read_until(socket, response, "\r\n", ec);
std::istream response_stream(&response);
std::string http_status;
std::getline(response_stream, http_status);
if (http_status.find("200 OK") != std::string::npos)
return 0;
}
return 1;
}
openssl-fips.cnf
config_diagnostics = 1
openssl_conf = openssl_init
[fips_sect]
activate = 1
conditional-errors = 1
security-checks = 1
module-mac = D9:AB:CC:37:8A:4C:06:BF:E9:E3:A8:F7:B9:B5:02:48:58:71:76:EB:5E:71:8A:0F:87:AA:52:46:7D:60:B0:EB
[openssl_init]
providers = provider_sect
alg_section = algorithm_sect
[provider_sect]
fips = fips_sect
base = base_sect
[base_sect]
activate = 1
[algorithm_sect]
default_properties = fips=yes
Режим OpenSSL FIPS: ВЫКЛ.
В проектах будут использоваться алгоритмы, не одобренные FIPS, предоставляемые этими статическими библиотеками openssl.
Режим OpenSSL FIPS: ВКЛ.
В проектах будут использоваться одобренные FIPS алгоритмы, предоставляемые этими общими библиотеками openssl.
С помощью Process Explorer загружается fips.dll
:
Это выглядит близко.
Я бы сказал, что нужно быть осторожным с использованием конкретного конструктора для asio::ssl::context
. Похоже, что enableFIPS
в основном устанавливает значения по умолчанию, поэтому, возможно, для безопасности вы также можете вручную создать экземпляр SSL_CTX* и построить asio::ssl::context
на его основе, используя https://live.boost.org/doc/libs/1_84_0/doc/html/boost_asio /reference/ssl__context/context/overload2.html
Помимо этого, я всегда ручаюсь за тесты на соответствие. Конечно, вы можете начать с некоторых внутренних модульных/интеграционных тестов, которые проверят, что неправильные конфигурации активно отклоняются.
Спасибо, я потратил несколько дней, чтобы добраться до этой минимальной репродукции. Что касается контекстов, я сначала пытался использовать OSSL_LIB_CTX_new()
, но это требовало обслуживания, чтобы использовать и освободить его позже, затем я понял, что контекст OpenSSL по умолчанию существует, поэтому я пошел с ним. Но я также рассмотрю ваше предложение о создании экземпляра SSL_CTX*
вручную. :)
Да. И конструктор, который я связал, становится владельцем, так что вам даже не потребуется управление/освобождение позже.
Да, кстати, я понимаю, что это всего лишь пример программы, но ручной анализ HTTP, подобный этому, — это рецепт проблем с безопасностью, которые не компенсирует никакая сертификация FIPS. Всегда используйте существующие технологии, такие как Boost Beast или libcurl.