summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAppaRao Puli <apparao.puli@intel.com>2022-06-28 02:09:03 +0300
committerEd Tanous <edtanous@google.com>2022-08-24 00:47:32 +0300
commite38778a5035eaccf642159c3ef3d70ce837d046a (patch)
tree64cca46a4112de93351555b4b46799a4d96c7261
parentce9694379a3d495b8e0719990050856642a212fe (diff)
downloadbmcweb-e38778a5035eaccf642159c3ef3d70ce837d046a.tar.xz
Add SSL support for http_client (EventService)
This commit adds the initial SSL support for http_client which can be used for sending asynchronous Events/MetricReports to subscribed Event Listener servers over secure channel. Current implementation of http client only works for http protocol. With current implementation, http client can be configured to work with secure http (HTTPS). As part of implementation it adds the SSL handshake mechanism and enforces the peer ceritificate verification. The http-client uses the cipher suites which are supported by mozilla browser and as recommended by OWASP. For better security enforcement its disables the SSLv2, SSLv3, TLSv1, TLSv1.1 as described in below OWASP cheetsheet. It is validated with RootCA certificate(PEM) for now. Adding support for different certificates can be looked in future as need arises. [1]: https://cheatsheetseries.owasp.org/cheatsheets/TLS_Cipher_String_Cheat_Sheet.html Tested: - Created new subscription with SSL destination(https) and confirmed that events are seen on EventListener side. URI: /redfish/v1/EventService/Subscriptions Method: POST Body: { "Context": "CustomText", "Destination": "https://<IP>:4000/service/collector/event_logs", "EventFormatType": "Event", "DeliveryRetryPolicy": "RetryForever", "Protocol": "Redfish" } - Unit tested the non-SSL connection by disabling the check in code (Note: EventService blocks all Non-SSL destinations). Verified that all events are properly shown on EventListener. URI: /redfish/v1/EventService/Subscriptions Method: POST Body: { "Context": "CustomText", "Destination": "http://<IP>:4001/service/collector/event_logs", "EventFormatType": "Event", "Protocol": "Redfish" } - Combined above two tests and verified both SSL & Non-SSL work fine in congention. - Created subscription with different URI paths on same IP, Port and protocol and verified that events sent as expected. Change-Id: I13b2fc942c9ce6c55cd7348aae1e088a3f3d7fd9 Signed-off-by: AppaRao Puli <apparao.puli@intel.com> Signed-off-by: Ed Tanous <edtanous@google.com>
-rw-r--r--http/http_client.hpp399
-rw-r--r--include/ssl_key_handler.hpp61
-rw-r--r--redfish-core/include/event_service_manager.hpp3
-rw-r--r--redfish-core/include/redfish_aggregator.hpp8
4 files changed, 343 insertions, 128 deletions
diff --git a/http/http_client.hpp b/http/http_client.hpp
index 491030cabc..d34fb2e582 100644
--- a/http/http_client.hpp
+++ b/http/http_client.hpp
@@ -18,6 +18,8 @@
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/basic_endpoint.hpp>
#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ssl/context.hpp>
+#include <boost/asio/ssl/error.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/beast/core/flat_static_buffer.hpp>
@@ -27,12 +29,14 @@
#include <boost/beast/http/read.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/beast/http/write.hpp>
+#include <boost/beast/ssl/ssl_stream.hpp>
#include <boost/beast/version.hpp>
#include <boost/container/devector.hpp>
#include <boost/system/error_code.hpp>
#include <http/http_response.hpp>
#include <include/async_resolve.hpp>
#include <logging.hpp>
+#include <ssl_key_handler.hpp>
#include <cstdlib>
#include <functional>
@@ -58,6 +62,8 @@ enum class ConnState
connectInProgress,
connectFailed,
connected,
+ handshakeInProgress,
+ handshakeFailed,
sendInProgress,
sendFailed,
recvInProgress,
@@ -67,6 +73,7 @@ enum class ConnState
suspended,
terminated,
abortConnection,
+ sslInitFailed,
retry
};
@@ -137,6 +144,8 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo>
std::function<void(bool, uint32_t, Response&)> callback;
crow::async_resolve::Resolver resolver;
boost::beast::tcp_stream conn;
+ std::optional<boost::beast::ssl_stream<boost::beast::tcp_stream&>> sslConn;
+
boost::asio::steady_timer timer;
friend class ConnectionPool;
@@ -180,26 +189,66 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo>
conn.expires_after(std::chrono::seconds(30));
conn.async_connect(endpointList,
- [self(shared_from_this())](
- const boost::beast::error_code ec,
- const boost::asio::ip::tcp::endpoint& endpoint) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "Connect " << endpoint.address().to_string()
- << ":" << std::to_string(endpoint.port())
- << ", id: " << std::to_string(self->connId)
- << " failed: " << ec.message();
- self->state = ConnState::connectFailed;
- self->waitAndRetry();
- return;
- }
- BMCWEB_LOG_DEBUG
- << "Connected to: " << endpoint.address().to_string() << ":"
- << std::to_string(endpoint.port())
- << ", id: " << std::to_string(self->connId);
- self->state = ConnState::connected;
- self->sendMessage();
- });
+ std::bind_front(&ConnectionInfo::afterConnect, this,
+ shared_from_this()));
+ }
+
+ void afterConnect(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ boost::beast::error_code ec,
+ const boost::asio::ip::tcp::endpoint& endpoint)
+ {
+
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "Connect " << endpoint.address().to_string()
+ << ":" << std::to_string(endpoint.port())
+ << ", id: " << std::to_string(connId)
+ << " failed: " << ec.message();
+ state = ConnState::connectFailed;
+ waitAndRetry();
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Connected to: " << endpoint.address().to_string()
+ << ":" << std::to_string(endpoint.port())
+ << ", id: " << std::to_string(connId);
+ if (sslConn)
+ {
+ doSSLHandshake();
+ return;
+ }
+ state = ConnState::connected;
+ sendMessage();
+ }
+
+ void doSSLHandshake()
+ {
+ if (!sslConn)
+ {
+ return;
+ }
+ state = ConnState::handshakeInProgress;
+ sslConn->async_handshake(
+ boost::asio::ssl::stream_base::client,
+ std::bind_front(&ConnectionInfo::afterSslHandshake, this,
+ shared_from_this()));
+ }
+
+ void afterSslHandshake(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ boost::beast::error_code ec)
+ {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "SSL Handshake failed -"
+ << " id: " << std::to_string(connId)
+ << " error: " << ec.message();
+ state = ConnState::handshakeFailed;
+ waitAndRetry();
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "SSL Handshake successful -"
+ << " id: " << std::to_string(connId);
+ state = ConnState::connected;
+ sendMessage();
}
void sendMessage()
@@ -210,23 +259,36 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo>
conn.expires_after(std::chrono::seconds(30));
// Send the HTTP request to the remote host
- boost::beast::http::async_write(
- conn, req,
- [self(shared_from_this())](const boost::beast::error_code& ec,
- const std::size_t& bytesTransferred) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "sendMessage() failed: " << ec.message();
- self->state = ConnState::sendFailed;
- self->waitAndRetry();
- return;
- }
- BMCWEB_LOG_DEBUG << "sendMessage() bytes transferred: "
- << bytesTransferred;
- boost::ignore_unused(bytesTransferred);
+ if (sslConn)
+ {
+ boost::beast::http::async_write(
+ *sslConn, req,
+ std::bind_front(&ConnectionInfo::afterWrite, this,
+ shared_from_this()));
+ }
+ else
+ {
+ boost::beast::http::async_write(
+ conn, req,
+ std::bind_front(&ConnectionInfo::afterWrite, this,
+ shared_from_this()));
+ }
+ }
- self->recvMessage();
- });
+ void afterWrite(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ const boost::beast::error_code& ec, size_t bytesTransferred)
+ {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "sendMessage() failed: " << ec.message();
+ state = ConnState::sendFailed;
+ waitAndRetry();
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "sendMessage() bytes transferred: "
+ << bytesTransferred;
+
+ recvMessage();
}
void recvMessage()
@@ -237,59 +299,73 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo>
parser->body_limit(httpReadBodyLimit);
// Receive the HTTP response
- boost::beast::http::async_read(
- conn, buffer, *parser,
- [self(shared_from_this())](const boost::beast::error_code& ec,
- const std::size_t& bytesTransferred) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "recvMessage() failed: " << ec.message();
- self->state = ConnState::recvFailed;
- self->waitAndRetry();
- return;
- }
- BMCWEB_LOG_DEBUG << "recvMessage() bytes transferred: "
- << bytesTransferred;
- BMCWEB_LOG_DEBUG << "recvMessage() data: "
- << self->parser->get().body();
+ if (sslConn)
+ {
+ boost::beast::http::async_read(
+ *sslConn, buffer, *parser,
+ std::bind_front(&ConnectionInfo::afterRead, this,
+ shared_from_this()));
+ }
+ else
+ {
+ boost::beast::http::async_read(
+ conn, buffer, *parser,
+ std::bind_front(&ConnectionInfo::afterRead, this,
+ shared_from_this()));
+ }
+ }
- unsigned int respCode = self->parser->get().result_int();
- BMCWEB_LOG_DEBUG << "recvMessage() Header Response Code: "
+ void afterRead(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ const boost::beast::error_code& ec,
+ const std::size_t& bytesTransferred)
+ {
+ if (ec && ec != boost::asio::ssl::error::stream_truncated)
+ {
+ BMCWEB_LOG_ERROR << "recvMessage() failed: " << ec.message();
+ state = ConnState::recvFailed;
+ waitAndRetry();
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "recvMessage() bytes transferred: "
+ << bytesTransferred;
+ BMCWEB_LOG_DEBUG << "recvMessage() data: " << parser->get().body();
+
+ unsigned int respCode = parser->get().result_int();
+ BMCWEB_LOG_DEBUG << "recvMessage() Header Response Code: " << respCode;
+
+ // Make sure the received response code is valid as defined by
+ // the associated retry policy
+ if (retryPolicy.invalidResp(respCode))
+ {
+ // The listener failed to receive the Sent-Event
+ BMCWEB_LOG_ERROR << "recvMessage() Listener Failed to "
+ "receive Sent-Event. Header Response Code: "
<< respCode;
+ state = ConnState::recvFailed;
+ waitAndRetry();
+ return;
+ }
- // Make sure the received response code is valid as defined by
- // the associated retry policy
- if (self->retryPolicy.invalidResp(respCode))
- {
- // The listener failed to receive the Sent-Event
- BMCWEB_LOG_ERROR << "recvMessage() Listener Failed to "
- "receive Sent-Event. Header Response Code: "
- << respCode;
- self->state = ConnState::recvFailed;
- self->waitAndRetry();
- return;
- }
+ // Send is successful
+ // Reset the counter just in case this was after retrying
+ retryCount = 0;
+
+ // Keep the connection alive if server supports it
+ // Else close the connection
+ BMCWEB_LOG_DEBUG << "recvMessage() keepalive : "
+ << parser->keep_alive();
- // Send is successful
- // Reset the counter just in case this was after retrying
- self->retryCount = 0;
-
- // Keep the connection alive if server supports it
- // Else close the connection
- BMCWEB_LOG_DEBUG << "recvMessage() keepalive : "
- << self->parser->keep_alive();
-
- // Copy the response into a Response object so that it can be
- // processed by the callback function.
- self->res.clear();
- self->res.stringResponse = self->parser->release();
- self->callback(self->parser->keep_alive(), self->connId, self->res);
- });
+ // Copy the response into a Response object so that it can be
+ // processed by the callback function.
+ res.clear();
+ res.stringResponse = parser->release();
+ callback(parser->keep_alive(), connId, res);
}
void waitAndRetry()
{
- if (retryCount >= retryPolicy.maxRetryAttempts)
+ if ((retryCount >= retryPolicy.maxRetryAttempts) ||
+ (state == ConnState::sslInitFailed))
{
BMCWEB_LOG_ERROR << "Maximum number of retries reached.";
BMCWEB_LOG_DEBUG << "Retry policy: "
@@ -348,11 +424,11 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo>
self->runningTimer = false;
// Let's close the connection and restart from resolve.
- self->doCloseAndRetry();
+ self->doClose(true);
});
}
- void doClose()
+ void shutdownConn(bool retry)
{
boost::beast::error_code ec;
conn.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
@@ -372,21 +448,43 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo>
<< " closed gracefully";
}
- state = ConnState::closed;
+ if ((state != ConnState::suspended) && (state != ConnState::terminated))
+ {
+ if (retry)
+ {
+ // Now let's try to resend the data
+ state = ConnState::retry;
+ this->doResolve();
+ }
+ else
+ {
+ state = ConnState::closed;
+ }
+ }
}
- void doCloseAndRetry()
+ void doClose(bool retry = false)
{
- boost::beast::error_code ec;
- conn.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
- conn.close();
+ if (!sslConn)
+ {
+ shutdownConn(retry);
+ return;
+ }
- // not_connected happens sometimes so don't bother reporting it.
- if (ec && ec != boost::beast::errc::not_connected)
+ sslConn->async_shutdown(
+ std::bind_front(&ConnectionInfo::afterSslShutdown, this,
+ shared_from_this(), retry));
+ }
+
+ void afterSslShutdown(const std::shared_ptr<ConnectionInfo>& /*self*/,
+ bool retry, const boost::system::error_code& ec)
+ {
+
+ if (ec)
{
BMCWEB_LOG_ERROR << host << ":" << std::to_string(port)
<< ", id: " << std::to_string(connId)
- << "shutdown failed: " << ec.message();
+ << " shutdown failed: " << ec.message();
}
else
{
@@ -394,29 +492,82 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo>
<< ", id: " << std::to_string(connId)
<< " closed gracefully";
}
+ shutdownConn(retry);
+ }
- // Now let's try to resend the data
- state = ConnState::retry;
- doResolve();
+ void setCipherSuiteTLSext()
+ {
+ if (!sslConn)
+ {
+ return;
+ }
+ // NOTE: The SSL_set_tlsext_host_name is defined in tlsv1.h header
+ // file but its having old style casting (name is cast to void*).
+ // Since bmcweb compiler treats all old-style-cast as error, its
+ // causing the build failure. So replaced the same macro inline and
+ // did corrected the code by doing static_cast to viod*. This has to
+ // be fixed in openssl library in long run. Set SNI Hostname (many
+ // hosts need this to handshake successfully)
+ if (SSL_ctrl(sslConn->native_handle(), SSL_CTRL_SET_TLSEXT_HOSTNAME,
+ TLSEXT_NAMETYPE_host_name,
+ static_cast<void*>(&host.front())) == 0)
+
+ {
+ boost::beast::error_code ec{static_cast<int>(::ERR_get_error()),
+ boost::asio::error::get_ssl_category()};
+
+ BMCWEB_LOG_ERROR << "SSL_set_tlsext_host_name " << host << ":"
+ << port << ", id: " << std::to_string(connId)
+ << " failed: " << ec.message();
+ // Set state as sslInit failed so that we close the connection
+ // and take appropriate action as per retry configuration.
+ state = ConnState::sslInitFailed;
+ waitAndRetry();
+ return;
+ }
}
public:
- explicit ConnectionInfo(boost::asio::io_context& ioc,
- const std::string& idIn, const std::string& destIP,
- const uint16_t destPort,
- const unsigned int connIdIn) :
+ explicit ConnectionInfo(boost::asio::io_context& iocIn,
+ const std::string& idIn,
+ const std::string& destIPIn, uint16_t destPortIn,
+ bool useSSL, unsigned int connIdIn) :
subId(idIn),
- host(destIP), port(destPort), connId(connIdIn), conn(ioc), timer(ioc)
- {}
+ host(destIPIn), port(destPortIn), connId(connIdIn), conn(iocIn),
+ timer(iocIn)
+ {
+ if (useSSL)
+ {
+ std::optional<boost::asio::ssl::context> sslCtx =
+ ensuressl::getSSLClientContext();
+
+ if (!sslCtx)
+ {
+ BMCWEB_LOG_ERROR << "prepareSSLContext failed - " << host << ":"
+ << port << ", id: " << std::to_string(connId);
+ // Don't retry if failure occurs while preparing SSL context
+ // such as certificate is invalid or set cipher failure or set
+ // host name failure etc... Setting conn state to sslInitFailed
+ // and connection state will be transitioned to next state
+ // depending on retry policy set by subscription.
+ state = ConnState::sslInitFailed;
+ waitAndRetry();
+ return;
+ }
+ sslConn.emplace(conn, *sslCtx);
+ setCipherSuiteTLSext();
+ }
+ }
};
class ConnectionPool : public std::enable_shared_from_this<ConnectionPool>
{
private:
boost::asio::io_context& ioc;
- const std::string id;
- const std::string destIP;
- const uint16_t destPort;
+ std::string id;
+ std::string destIP;
+ uint16_t destPort;
+ bool useSSL;
std::vector<std::shared_ptr<ConnectionInfo>> connections;
boost::container::devector<PendingRequest> requestQueue;
@@ -600,8 +751,8 @@ class ConnectionPool : public std::enable_shared_from_this<ConnectionPool>
{
unsigned int newId = static_cast<unsigned int>(connections.size());
- auto& ret = connections.emplace_back(
- std::make_shared<ConnectionInfo>(ioc, id, destIP, destPort, newId));
+ auto& ret = connections.emplace_back(std::make_shared<ConnectionInfo>(
+ ioc, id, destIP, destPort, useSSL, newId));
BMCWEB_LOG_DEBUG << "Added connection "
<< std::to_string(connections.size() - 1)
@@ -614,10 +765,10 @@ class ConnectionPool : public std::enable_shared_from_this<ConnectionPool>
public:
explicit ConnectionPool(boost::asio::io_context& iocIn,
const std::string& idIn,
- const std::string& destIPIn,
- const uint16_t destPortIn) :
+ const std::string& destIPIn, uint16_t destPortIn,
+ bool useSSLIn) :
ioc(iocIn),
- id(idIn), destIP(destIPIn), destPort(destPortIn)
+ id(idIn), destIP(destIPIn), destPort(destPortIn), useSSL(useSSLIn)
{
BMCWEB_LOG_DEBUG << "Initializing connection pool for " << destIP << ":"
<< std::to_string(destPort);
@@ -661,37 +812,39 @@ class HttpClient
// Send a request to destIP:destPort where additional processing of the
// result is not required
void sendData(std::string& data, const std::string& id,
- const std::string& destIP, const uint16_t destPort,
- const std::string& destUri,
+ const std::string& destIP, uint16_t destPort,
+ const std::string& destUri, bool useSSL,
const boost::beast::http::fields& httpHeader,
const boost::beast::http::verb verb,
const std::string& retryPolicyName)
{
- const std::function<void(const Response&)> cb = genericResHandler;
- sendDataWithCallback(data, id, destIP, destPort, destUri, httpHeader,
- verb, retryPolicyName, cb);
+ const std::function<void(Response&)> cb = genericResHandler;
+ sendDataWithCallback(data, id, destIP, destPort, destUri, useSSL,
+ httpHeader, verb, retryPolicyName, cb);
}
// Send request to destIP:destPort and use the provided callback to
// handle the response
void sendDataWithCallback(std::string& data, const std::string& id,
- const std::string& destIP,
- const uint16_t destPort,
- const std::string& destUri,
+ const std::string& destIP, uint16_t destPort,
+ const std::string& destUri, bool useSSL,
const boost::beast::http::fields& httpHeader,
const boost::beast::http::verb verb,
const std::string& retryPolicyName,
const std::function<void(Response&)>& resHandler)
{
- std::string clientKey = destIP + ":" + std::to_string(destPort);
+ std::string clientKey = useSSL ? "https" : "http";
+ clientKey += destIP;
+ clientKey += ":";
+ clientKey += std::to_string(destPort);
// Use nullptr to avoid creating a ConnectionPool each time
- auto result = connectionPools.try_emplace(clientKey, nullptr);
- if (result.second)
+ std::shared_ptr<ConnectionPool>& conn = connectionPools[clientKey];
+ if (conn == nullptr)
{
// Now actually create the ConnectionPool shared_ptr since it does
// not already exist
- result.first->second =
- std::make_shared<ConnectionPool>(ioc, id, destIP, destPort);
+ conn = std::make_shared<ConnectionPool>(ioc, id, destIP, destPort,
+ useSSL);
BMCWEB_LOG_DEBUG << "Created connection pool for " << clientKey;
}
else
@@ -710,8 +863,8 @@ class HttpClient
// Send the data using either the existing connection pool or the newly
// created connection pool
- result.first->second->sendData(data, destUri, httpHeader, verb,
- policy.first->second, resHandler);
+ conn->sendData(data, destUri, httpHeader, verb, policy.first->second,
+ resHandler);
}
void setRetryConfig(
diff --git a/include/ssl_key_handler.hpp b/include/ssl_key_handler.hpp
index 431dd84d3a..c6ceb83c2a 100644
--- a/include/ssl_key_handler.hpp
+++ b/include/ssl_key_handler.hpp
@@ -474,4 +474,65 @@ inline std::shared_ptr<boost::asio::ssl::context>
}
return mSslContext;
}
+
+inline std::optional<boost::asio::ssl::context> getSSLClientContext()
+{
+ boost::asio::ssl::context sslCtx(boost::asio::ssl::context::tls_client);
+
+ boost::system::error_code ec;
+
+ // Support only TLS v1.2 & v1.3
+ sslCtx.set_options(boost::asio::ssl::context::default_workarounds |
+ boost::asio::ssl::context::no_sslv2 |
+ boost::asio::ssl::context::no_sslv3 |
+ boost::asio::ssl::context::single_dh_use |
+ boost::asio::ssl::context::no_tlsv1 |
+ boost::asio::ssl::context::no_tlsv1_1,
+ ec);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "SSL context set_options failed";
+ return std::nullopt;
+ }
+
+ // Add a directory containing certificate authority files to be used
+ // for performing verification.
+ sslCtx.set_default_verify_paths(ec);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "SSL context set_default_verify failed";
+ return std::nullopt;
+ }
+
+ // Verify the remote server's certificate
+ sslCtx.set_verify_mode(boost::asio::ssl::verify_peer, ec);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "SSL context set_verify_mode failed";
+ return std::nullopt;
+ }
+
+ // All cipher suites are set as per OWASP datasheet.
+ // https://cheatsheetseries.owasp.org/cheatsheets/TLS_Cipher_String_Cheat_Sheet.html
+ constexpr const char* sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:"
+ "ECDHE-RSA-AES128-GCM-SHA256:"
+ "ECDHE-ECDSA-AES256-GCM-SHA384:"
+ "ECDHE-RSA-AES256-GCM-SHA384:"
+ "ECDHE-ECDSA-CHACHA20-POLY1305:"
+ "ECDHE-RSA-CHACHA20-POLY1305:"
+ "DHE-RSA-AES128-GCM-SHA256:"
+ "DHE-RSA-AES256-GCM-SHA384"
+ "TLS_AES_128_GCM_SHA256:"
+ "TLS_AES_256_GCM_SHA384:"
+ "TLS_CHACHA20_POLY1305_SHA256";
+
+ if (SSL_CTX_set_cipher_list(sslCtx.native_handle(), sslCiphers) != 1)
+ {
+ BMCWEB_LOG_ERROR << "SSL_CTX_set_cipher_list failed";
+ return std::nullopt;
+ }
+
+ return sslCtx;
+}
+
} // namespace ensuressl
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 3add4f15f1..dadeb2281b 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -396,9 +396,10 @@ class Subscription : public persistent_data::UserSubscription
return false;
}
+ bool useSSL = (uriProto == "https");
// A connection pool will be created if one does not already exist
crow::HttpClient::getInstance().sendData(
- msg, id, host, port, path, httpHeaders,
+ msg, id, host, port, path, useSSL, httpHeaders,
boost::beast::http::verb::post, retryPolicyName);
eventSeqNum++;
diff --git a/redfish-core/include/redfish_aggregator.hpp b/redfish-core/include/redfish_aggregator.hpp
index 24b42d95e4..622bb5b459 100644
--- a/redfish-core/include/redfish_aggregator.hpp
+++ b/redfish-core/include/redfish_aggregator.hpp
@@ -490,8 +490,8 @@ class RedfishAggregator
std::string data = thisReq.req.body();
crow::HttpClient::getInstance().sendDataWithCallback(
data, id, std::string(sat->second.host()),
- sat->second.port_number(), targetURI, thisReq.fields,
- thisReq.method(), retryPolicyName, cb);
+ sat->second.port_number(), targetURI, false /*useSSL*/,
+ thisReq.fields, thisReq.method(), retryPolicyName, cb);
}
// Forward a request for a collection URI to each known satellite BMC
@@ -509,8 +509,8 @@ class RedfishAggregator
std::string data = thisReq.req.body();
crow::HttpClient::getInstance().sendDataWithCallback(
data, id, std::string(sat.second.host()),
- sat.second.port_number(), targetURI, thisReq.fields,
- thisReq.method(), retryPolicyName, cb);
+ sat.second.port_number(), targetURI, false /*useSSL*/,
+ thisReq.fields, thisReq.method(), retryPolicyName, cb);
}
}