summaryrefslogtreecommitdiff
path: root/http/http_connection.hpp
diff options
context:
space:
mode:
authorEd Tanous <edtanous@google.com>2022-02-21 23:11:14 +0300
committerEd Tanous <ed@tanous.net>2023-01-12 02:44:24 +0300
commit7c8e064d33a1b9136b10f224d9ae9e9b066be012 (patch)
tree5f371962698da003ebffedb311245afbbf26ba45 /http/http_connection.hpp
parent218295dc3aa54e68a097f9ab305b9292e70793f7 (diff)
downloadbmcweb-7c8e064d33a1b9136b10f224d9ae9e9b066be012.tar.xz
Refactor mtls callbacks into their own file
Mutual TLS is non-trivial enough that it definitely shouldn't be done in an inline lambda method. This commit moves the code. Tested: WIP. This is a pretty negligible code move; Minimal touch testing should be good. Signed-off-by: Ed Tanous <edtanous@google.com> Change-Id: I7a15a6bc66f4d8fb090411509549628f6d1045a5
Diffstat (limited to 'http/http_connection.hpp')
-rw-r--r--http/http_connection.hpp181
1 files changed, 20 insertions, 161 deletions
diff --git a/http/http_connection.hpp b/http/http_connection.hpp
index efd4313eca..dc95b8e557 100644
--- a/http/http_connection.hpp
+++ b/http/http_connection.hpp
@@ -21,6 +21,7 @@
#include <boost/beast/websocket.hpp>
#include <boost/url/url_view.hpp>
#include <json_html_serializer.hpp>
+#include <mutual_tls.hpp>
#include <security_headers.hpp>
#include <ssl_key_handler.hpp>
@@ -53,6 +54,8 @@ template <typename Adaptor, typename Handler>
class Connection :
public std::enable_shared_from_this<Connection<Adaptor, Handler>>
{
+ using self_type = Connection<Adaptor, Handler>;
+
public:
Connection(Handler* handlerIn, boost::asio::steady_timer&& timerIn,
std::function<std::string()>& getCachedDateStrF,
@@ -90,6 +93,22 @@ class Connection :
Connection& operator=(const Connection&) = delete;
Connection& operator=(Connection&&) = delete;
+ bool tlsVerifyCallback(bool preverified,
+ boost::asio::ssl::verify_context& ctx)
+ {
+ // We always return true to allow full auth flow for resources that
+ // don't require auth
+ if (preverified)
+ {
+ userSession = verifyMtlsUser(req->ipAddress, ctx);
+ if (userSession)
+ {
+ sessionIsFromTransport = true;
+ }
+ }
+ return true;
+ }
+
void prepareMutualTls()
{
std::error_code error;
@@ -116,167 +135,7 @@ class Connection :
}
adaptor.set_verify_callback(
- [this](bool preverified, boost::asio::ssl::verify_context& ctx) {
- // do nothing if TLS is disabled
- if (!persistent_data::SessionStore::getInstance()
- .getAuthMethodsConfig()
- .tls)
- {
- BMCWEB_LOG_DEBUG << this << " TLS auth_config is disabled";
- return true;
- }
-
- // We always return true to allow full auth flow
- if (!preverified)
- {
- BMCWEB_LOG_DEBUG << this << " TLS preverification failed.";
- return true;
- }
-
- X509_STORE_CTX* cts = ctx.native_handle();
- if (cts == nullptr)
- {
- BMCWEB_LOG_DEBUG << this << " Cannot get native TLS handle.";
- return true;
- }
-
- // Get certificate
- X509* peerCert =
- X509_STORE_CTX_get_current_cert(ctx.native_handle());
- if (peerCert == nullptr)
- {
- BMCWEB_LOG_DEBUG << this
- << " Cannot get current TLS certificate.";
- return true;
- }
-
- // Check if certificate is OK
- int ctxError = X509_STORE_CTX_get_error(cts);
- if (ctxError != X509_V_OK)
- {
- BMCWEB_LOG_INFO << this << " Last TLS error is: " << ctxError;
- return true;
- }
- // Check that we have reached final certificate in chain
- int32_t depth = X509_STORE_CTX_get_error_depth(cts);
- if (depth != 0)
-
- {
- BMCWEB_LOG_DEBUG
- << this << " Certificate verification in progress (depth "
- << depth << "), waiting to reach final depth";
- return true;
- }
-
- BMCWEB_LOG_DEBUG << this
- << " Certificate verification of final depth";
-
- // Verify KeyUsage
- bool isKeyUsageDigitalSignature = false;
- bool isKeyUsageKeyAgreement = false;
-
- ASN1_BIT_STRING* usage = static_cast<ASN1_BIT_STRING*>(
- X509_get_ext_d2i(peerCert, NID_key_usage, nullptr, nullptr));
-
- if (usage == nullptr)
- {
- BMCWEB_LOG_DEBUG << this << " TLS usage is null";
- return true;
- }
-
- for (int i = 0; i < usage->length; i++)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
- unsigned char usageChar = usage->data[i];
- if (KU_DIGITAL_SIGNATURE & usageChar)
- {
- isKeyUsageDigitalSignature = true;
- }
- if (KU_KEY_AGREEMENT & usageChar)
- {
- isKeyUsageKeyAgreement = true;
- }
- }
- ASN1_BIT_STRING_free(usage);
-
- if (!isKeyUsageDigitalSignature || !isKeyUsageKeyAgreement)
- {
- BMCWEB_LOG_DEBUG << this
- << " Certificate ExtendedKeyUsage does "
- "not allow provided certificate to "
- "be used for user authentication";
- return true;
- }
-
- // Determine that ExtendedKeyUsage includes Client Auth
-
- stack_st_ASN1_OBJECT* extUsage =
- static_cast<stack_st_ASN1_OBJECT*>(X509_get_ext_d2i(
- peerCert, NID_ext_key_usage, nullptr, nullptr));
-
- if (extUsage == nullptr)
- {
- BMCWEB_LOG_DEBUG << this << " TLS extUsage is null";
- return true;
- }
-
- bool isExKeyUsageClientAuth = false;
- for (int i = 0; i < sk_ASN1_OBJECT_num(extUsage); i++)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
- int nid = OBJ_obj2nid(sk_ASN1_OBJECT_value(extUsage, i));
- if (NID_client_auth == nid)
- {
- isExKeyUsageClientAuth = true;
- break;
- }
- }
- sk_ASN1_OBJECT_free(extUsage);
-
- // Certificate has to have proper key usages set
- if (!isExKeyUsageClientAuth)
- {
- BMCWEB_LOG_DEBUG << this
- << " Certificate ExtendedKeyUsage does "
- "not allow provided certificate to "
- "be used for user authentication";
- return true;
- }
- std::string sslUser;
- // Extract username contained in CommonName
- sslUser.resize(256, '\0');
-
- int status = X509_NAME_get_text_by_NID(
- X509_get_subject_name(peerCert), NID_commonName, sslUser.data(),
- static_cast<int>(sslUser.size()));
-
- if (status == -1)
- {
- BMCWEB_LOG_DEBUG
- << this << " TLS cannot get username to create session";
- return true;
- }
-
- size_t lastChar = sslUser.find('\0');
- if (lastChar == std::string::npos || lastChar == 0)
- {
- BMCWEB_LOG_DEBUG << this << " Invalid TLS user name";
- return true;
- }
- sslUser.resize(lastChar);
- sessionIsFromTransport = true;
- userSession = persistent_data::SessionStore::getInstance()
- .generateUserSession(
- sslUser, req->ipAddress, std::nullopt,
- persistent_data::PersistenceType::TIMEOUT);
- if (userSession != nullptr)
- {
- BMCWEB_LOG_DEBUG
- << this
- << " Generating TLS session: " << userSession->uniqueId;
- }
- return true;
- });
+ std::bind_front(&self_type::tlsVerifyCallback, this));
}
Adaptor& socket()