diff options
Diffstat (limited to 'http/http_connection.hpp')
-rw-r--r-- | http/http_connection.hpp | 181 |
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() |