This is an automated email from the ASF dual-hosted git repository.
bneradt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 9ddf262451 TLS curve/group name logging for Ticket Resumption (#12393)
9ddf262451 is described below
commit 9ddf2624516541ca08c482a849e21abbf5a44fe6
Author: Brian Neradt <[email protected]>
AuthorDate: Mon Sep 22 08:53:07 2025 -0500
TLS curve/group name logging for Ticket Resumption (#12393)
This applies to the cqssu (curve) and cqssg (group name) TLS log fields.
This does two things:
* Updates server session caching logic to provide the TLS group name on
resumption.
* Updates the logging of the curve and group name for ticket resumption
logic so that the TLS curve and group names are properly retrieved
from the SSL object. For ticket resumption, there is no curve/group
name stored to retrieve. It is properly retrieved from the SSL object.
Before this change: (1) the SSL group was always retrieved from the SSL
object when it should have been retrieved from the server session cache
ex_data for session cache resumption and (2) the curve value for cqssu
was alway "-" for TLS ticket resumption because there was no cached
value to retrieve like there is with server session caching.
Fixes: #12398
---
CMakeLists.txt | 2 +
include/iocore/net/TLSBasicSupport.h | 20 +++---
include/iocore/net/TLSSessionResumptionSupport.h | 87 +++++++++++++++++++++---
include/proxy/http/HttpUserAgent.h | 10 +--
include/tscore/ink_config.h.cmake.in | 2 +
src/api/InkAPI.cc | 2 +-
src/iocore/net/P_QUICNetVConnection.h | 7 +-
src/iocore/net/P_SSLNetVConnection.h | 5 +-
src/iocore/net/P_SSLUtils.h | 5 +-
src/iocore/net/QUICNetVConnection.cc | 18 ++++-
src/iocore/net/SSLNetVConnection.cc | 18 ++++-
src/iocore/net/SSLSessionCache.cc | 18 ++++-
src/iocore/net/SSLSessionCache.h | 20 +++++-
src/iocore/net/SSLUtils.cc | 26 +++++++
src/iocore/net/TLSBasicSupport.cc | 17 ++---
src/iocore/net/TLSSessionResumptionSupport.cc | 65 +++++++++++++-----
src/proxy/http/HttpSM.cc | 2 +-
17 files changed, 255 insertions(+), 69 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 010d74fc70..65c6ca278b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -476,8 +476,10 @@ check_symbol_exists(SSL_set1_verify_cert_store
"openssl/ssl.h" TS_HAS_VERIFY_CER
check_symbol_exists(SSL_get_shared_curve "openssl/ssl.h"
HAVE_SSL_GET_SHARED_CURVE)
check_symbol_exists(SSL_get_curve_name "openssl/ssl.h" HAVE_SSL_GET_CURVE_NAME)
check_symbol_exists(SSL_get0_group_name "openssl/ssl.h"
HAVE_SSL_GET0_GROUP_NAME)
+check_symbol_exists(SSL_get_negotiated_group "openssl/ssl.h"
HAVE_SSL_GET_NEGOTIATED_GROUP)
check_symbol_exists(SSL_get_group_id "openssl/ssl.h" HAVE_SSL_GET_GROUP_ID)
check_symbol_exists(SSL_get_group_name "openssl/ssl.h" HAVE_SSL_GET_GROUP_NAME)
+check_symbol_exists(SSL_group_to_name "openssl/ssl.h" HAVE_SSL_GROUP_TO_NAME)
check_symbol_exists(SSL_set_max_early_data "openssl/ssl.h"
HAVE_SSL_SET_MAX_EARLY_DATA)
check_symbol_exists(SSL_read_early_data "openssl/ssl.h"
HAVE_SSL_READ_EARLY_DATA)
check_symbol_exists(SSL_write_early_data "openssl/ssl.h"
HAVE_SSL_WRITE_EARLY_DATA)
diff --git a/include/iocore/net/TLSBasicSupport.h
b/include/iocore/net/TLSBasicSupport.h
index a0b17bae3d..015633607b 100644
--- a/include/iocore/net/TLSBasicSupport.h
+++ b/include/iocore/net/TLSBasicSupport.h
@@ -25,6 +25,7 @@
#pragma once
#include <string>
+#include <string_view>
#include <openssl/ssl.h>
@@ -43,13 +44,13 @@ public:
static void bind(SSL *ssl, TLSBasicSupport *srs);
static void unbind(SSL *ssl);
- TLSHandle get_tls_handle() const;
- const char *get_tls_protocol_name() const;
- const char *get_tls_cipher_suite() const;
- const char *get_tls_curve() const;
- const char *get_tls_group() const;
- ink_hrtime get_tls_handshake_begin_time() const;
- ink_hrtime get_tls_handshake_end_time() const;
+ TLSHandle get_tls_handle() const;
+ const char *get_tls_protocol_name() const;
+ const char *get_tls_cipher_suite() const;
+ const char *get_tls_curve() const;
+ std::string_view get_tls_group() const;
+ ink_hrtime get_tls_handshake_begin_time() const;
+ ink_hrtime get_tls_handshake_end_time() const;
/**
* Returns a certificate that need to be verified.
*
@@ -80,8 +81,9 @@ public:
protected:
void clear();
- virtual SSL *_get_ssl_object() const = 0;
- virtual ssl_curve_id _get_tls_curve() const = 0;
+ virtual SSL *_get_ssl_object() const = 0;
+ virtual ssl_curve_id _get_tls_curve() const = 0;
+ virtual std::string_view _get_tls_group() const = 0;
void _record_tls_handshake_begin_time();
void _record_tls_handshake_end_time();
diff --git a/include/iocore/net/TLSSessionResumptionSupport.h
b/include/iocore/net/TLSSessionResumptionSupport.h
index 6955528096..80c25d96d6 100644
--- a/include/iocore/net/TLSSessionResumptionSupport.h
+++ b/include/iocore/net/TLSSessionResumptionSupport.h
@@ -1,7 +1,8 @@
/** @file
TLSSessionResumptionSupport implements common methods and members to
- support TLS Ssssion Resumption
+ support TLS Ssssion Resumption, either via server session caching or
+ TLS session tickets.
@section license License
@@ -25,6 +26,7 @@
#pragma once
#include <openssl/ssl.h>
+#include <string_view>
#include "tscore/ink_inet.h"
#include "iocore/net/SSLTypes.h"
@@ -36,11 +38,34 @@ class TLSSessionResumptionSupport
public:
virtual ~TLSSessionResumptionSupport() = default;
+ //
---------------------------------------------------------------------------
+ // Binding of the TLSSessionResumptionSupport object to the SSL object
+ //
---------------------------------------------------------------------------
+
static void initialize();
static TLSSessionResumptionSupport *getInstance(SSL *ssl);
static void bind(SSL *ssl,
TLSSessionResumptionSupport *srs);
static void unbind(SSL *ssl);
+ //
---------------------------------------------------------------------------
+ // TLS Session Resumption Support Via Session Tickets
+ //
---------------------------------------------------------------------------
+
+ /** Handles TLS session ticket processing for session resumption.
+ *
+ * This function is called by OpenSSL to either encrypt (create) or decrypt
(resume) a session ticket,
+ * depending on the value of the @p enc parameter. It selects the
appropriate ticket key block based on
+ * the local endpoint and certificate context, and then either generates a
new session ticket or attempts
+ * to decrypt and validate an existing one.
+ *
+ * @param[in] ssl The SSL connection object.
+ * @param[out] keyname Buffer for the session ticket key name.
+ * @param[out] iv Buffer for the initialization vector.
+ * @param[in,out] cipher_ctx Cipher context for encryption/decryption.
+ * @param[in,out] hctx HMAC or MAC context for integrity protection.
+ * @param[in] enc Indicates operation: 1 for encrypt (create
ticket), 0 for decrypt (resume session).
+ * @return 1 on success, 0 if key not found, negative value on
error, or 2 if ticket should be renewed.
+ */
#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
int processSessionTicket(SSL *ssl, unsigned char *keyname, unsigned char
*iv, EVP_CIPHER_CTX *cipher_ctx, EVP_MAC_CTX *hctx,
int enc);
@@ -48,24 +73,63 @@ public:
int processSessionTicket(SSL *ssl, unsigned char *keyname, unsigned char
*iv, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx,
int enc);
#endif
- bool getSSLSessionCacheHit() const;
- bool getSSLOriginSessionCacheHit() const;
- ssl_curve_id getSSLCurveNID() const;
- SSL_SESSION *getSession(SSL *ssl, const unsigned char *id,
int len, int *copy);
+ //
---------------------------------------------------------------------------
+ // TLS Session Resumption Support Via Server Session Caching
+ //
---------------------------------------------------------------------------
+
+ /** Retrieves a cached SSL session from the session cache.
+ *
+ * This function is used to retrieve a cached SSL session from the session
cache.
+ *
+ * @param[in] ssl The SSL connection object.
+ * @param[in] id The session ID to lookup.
+ * @param[in] len The length of the session ID.
+ * @param[out] copy Pointer to an integer indicating if the session
ID should be copied.
+ * @return A pointer to the cached SSL session, or nullptr if
not found.
+ */
+ SSL_SESSION *getSession(SSL *ssl, const unsigned char *id, int len, int
*copy);
+
+ /**
+ * @brief Retrieves a cached SSL session from the origin session cache.
+ *
+ * This function is used to retrieve a cached SSL session from the origin
session cache.
+ *
+ * @param[in] lookup_key The key to lookup the session in the cache.
+ * @return A pointer to the cached SSL session, or nullptr if
not found.
+ */
std::shared_ptr<SSL_SESSION> getOriginSession(const std::string &lookup_key);
+ //
---------------------------------------------------------------------------
+ // Getters used for both ticket and session caching
+ //
---------------------------------------------------------------------------
+
+ bool getIsResumedSSLSession() const;
+ bool getIsResumedOriginSSLSession() const;
+ bool getIsResumedFromSessionCache() const;
+ bool getIsResumedFromSessionTicket() const;
+ ssl_curve_id getSSLCurveNID() const;
+ std::string_view getSSLGroupName() const;
+
protected:
void clear();
virtual const IpEndpoint &_getLocalEndpoint() = 0;
private:
+ enum class ResumptionType {
+ NOT_RESUMED,
+ RESUMED_FROM_SESSION_CACHE,
+ RESUMED_FROM_SESSION_TICKET,
+ };
+
static int _ex_data_index;
- bool _sslSessionCacheHit = false;
- bool _sslOriginSessionCacheHit = false;
- int _sslCurveNID = NID_undef;
+ ResumptionType _resumptionType = ResumptionType::NOT_RESUMED;
+ bool _isResumedOriginSession = false;
+ int _sslCurveNID = NID_undef;
+ std::string _sslGroupName;
+private:
#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
int _setSessionInformation(ssl_ticket_key_block *keyblock, unsigned char
*keyname, unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx,
EVP_MAC_CTX *hctx);
@@ -78,7 +142,8 @@ private:
EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx);
#endif
- void _setSSLSessionCacheHit(bool state);
- void _setSSLOriginSessionCacheHit(bool state);
- void _setSSLCurveNID(ssl_curve_id curve_nid);
+ constexpr static bool IS_RESUMED_ORIGIN_SESSION = true;
+ void _setResumptionType(ResumptionType type, bool isOrigin);
+ void _setSSLCurveNID(ssl_curve_id curve_nid);
+ void _setSSLGroupName(std::string_view group_name);
};
diff --git a/include/proxy/http/HttpUserAgent.h
b/include/proxy/http/HttpUserAgent.h
index a1e22b9515..1dacea0587 100644
--- a/include/proxy/http/HttpUserAgent.h
+++ b/include/proxy/http/HttpUserAgent.h
@@ -33,6 +33,8 @@
#include "iocore/net/TLSBasicSupport.h"
#include "iocore/net/TLSSessionResumptionSupport.h"
+#include <string>
+
struct ClientTransactionInfo {
int id{-1};
int priority_weight{-1};
@@ -48,7 +50,7 @@ struct ClientConnectionInfo {
char const *sec_protocol{"-"};
char const *cipher_suite{"-"};
char const *curve{"-"};
- char const *security_group{"-"};
+ std::string security_group{"-"};
int alpn_id{SessionProtocolNameRegistry::INVALID};
};
@@ -169,7 +171,7 @@ HttpUserAgent::set_txn(ProxyTransaction *txn,
TransactionMilestones &milestones)
m_conn_info.curve = "-";
}
- if (auto group{tbs->get_tls_group()}; group) {
+ if (auto group{tbs->get_tls_group()}; !group.empty()) {
m_conn_info.security_group = group;
} else {
m_conn_info.security_group = "-";
@@ -187,7 +189,7 @@ HttpUserAgent::set_txn(ProxyTransaction *txn,
TransactionMilestones &milestones)
}
if (auto tsrs = netvc->get_service<TLSSessionResumptionSupport>()) {
- m_conn_info.ssl_reused = tsrs->getSSLSessionCacheHit();
+ m_conn_info.ssl_reused = tsrs->getIsResumedSSLSession();
}
if (auto protocol_str{txn->get_protocol_string()}; protocol_str) {
@@ -266,7 +268,7 @@ HttpUserAgent::get_client_curve() const
inline char const *
HttpUserAgent::get_client_security_group() const
{
- return m_conn_info.security_group;
+ return m_conn_info.security_group.c_str();
}
inline int
diff --git a/include/tscore/ink_config.h.cmake.in
b/include/tscore/ink_config.h.cmake.in
index fcbd98a582..02cc203422 100644
--- a/include/tscore/ink_config.h.cmake.in
+++ b/include/tscore/ink_config.h.cmake.in
@@ -176,8 +176,10 @@ const int DEFAULT_STACKSIZE = @DEFAULT_STACK_SIZE@;
#cmakedefine01 HAVE_SSL_GET_SHARED_CURVE
#cmakedefine01 HAVE_SSL_GET_CURVE_NAME
#cmakedefine01 HAVE_SSL_GET0_GROUP_NAME
+#cmakedefine01 HAVE_SSL_GET_NEGOTIATED_GROUP
#cmakedefine01 HAVE_SSL_GET_GROUP_ID
#cmakedefine01 HAVE_SSL_GET_GROUP_NAME
+#cmakedefine01 HAVE_SSL_GROUP_TO_NAME
#cmakedefine01 HAVE_SSL_ERROR_DESCRIPTION
#cmakedefine01 HAVE_OSSL_PARAM_CONSTRUCT_END
#cmakedefine01 TS_USE_TLS_SET_CIPHERSUITES
diff --git a/src/api/InkAPI.cc b/src/api/InkAPI.cc
index 647d04e1e5..41d8fc198a 100644
--- a/src/api/InkAPI.cc
+++ b/src/api/InkAPI.cc
@@ -5467,7 +5467,7 @@ TSVConnIsSslReused(TSVConn sslp)
NetVConnection *vc = reinterpret_cast<NetVConnection *>(sslp);
SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc);
- return ssl_vc ? ssl_vc->getSSLSessionCacheHit() : 0;
+ return ssl_vc ? ssl_vc->getIsResumedSSLSession() : 0;
}
const char *
diff --git a/src/iocore/net/P_QUICNetVConnection.h
b/src/iocore/net/P_QUICNetVConnection.h
index 9869d9d619..4f30e3ba74 100644
--- a/src/iocore/net/P_QUICNetVConnection.h
+++ b/src/iocore/net/P_QUICNetVConnection.h
@@ -157,9 +157,10 @@ protected:
bool _isReadyToTransferData() const override;
// TLSBasicSupport
- SSL *_get_ssl_object() const override;
- ssl_curve_id _get_tls_curve() const override;
- int _verify_certificate(X509_STORE_CTX *ctx) override;
+ SSL *_get_ssl_object() const override;
+ ssl_curve_id _get_tls_curve() const override;
+ std::string_view _get_tls_group() const override;
+ int _verify_certificate(X509_STORE_CTX *ctx) override;
// TLSSNISupport
in_port_t _get_local_port() override;
diff --git a/src/iocore/net/P_SSLNetVConnection.h
b/src/iocore/net/P_SSLNetVConnection.h
index dea3328f68..7417477480 100644
--- a/src/iocore/net/P_SSLNetVConnection.h
+++ b/src/iocore/net/P_SSLNetVConnection.h
@@ -320,8 +320,9 @@ protected:
{
return this->ssl;
}
- ssl_curve_id _get_tls_curve() const override;
- int _verify_certificate(X509_STORE_CTX *ctx) override;
+ ssl_curve_id _get_tls_curve() const override;
+ std::string_view _get_tls_group() const override;
+ int _verify_certificate(X509_STORE_CTX *ctx) override;
// TLSSessionResumptionSupport
const IpEndpoint &
diff --git a/src/iocore/net/P_SSLUtils.h b/src/iocore/net/P_SSLUtils.h
index c7a4cad19c..b9d48cbc91 100644
--- a/src/iocore/net/P_SSLUtils.h
+++ b/src/iocore/net/P_SSLUtils.h
@@ -36,9 +36,12 @@ class SSLNetVConnection;
using ssl_error_t = int;
-// Return the SSL Curve ID associated to the specified SSL connection
+/// Return the SSL Curve ID associated with the specified SSL connection
ssl_curve_id SSLGetCurveNID(SSL *ssl);
+/// Return the TLS Group Name associated with the specified SSL connection.
+std::string_view SSLGetGroupName(SSL *ssl);
+
SSL_SESSION *SSLSessionDup(SSL_SESSION *sess);
enum class SSLCertContextType;
diff --git a/src/iocore/net/QUICNetVConnection.cc
b/src/iocore/net/QUICNetVConnection.cc
index e63fbdebaa..d3bc4a76d1 100644
--- a/src/iocore/net/QUICNetVConnection.cc
+++ b/src/iocore/net/QUICNetVConnection.cc
@@ -808,13 +808,29 @@ QUICNetVConnection::_get_ssl_object() const
ssl_curve_id
QUICNetVConnection::_get_tls_curve() const
{
- if (getSSLSessionCacheHit()) {
+ // For resumed server side session caching, we have to retrieve the
curve/group
+ // from our stored data. For non-resumed sessions or from ticket based
resumption,
+ // simply query the SSL object.
+ if (getIsResumedFromSessionCache()) {
return getSSLCurveNID();
} else {
return SSLGetCurveNID(this->_ssl);
}
}
+std::string_view
+QUICNetVConnection::_get_tls_group() const
+{
+ // For resumed server side session caching, we have to retrieve the
curve/group
+ // from our stored data. For non-resumed sessions or from ticket based
resumption,
+ // simply query the SSL object.
+ if (getIsResumedFromSessionCache()) {
+ return getSSLGroupName();
+ } else {
+ return SSLGetGroupName(this->_ssl);
+ }
+}
+
int
QUICNetVConnection::_verify_certificate(X509_STORE_CTX * /* ctx ATS_UNUSED */)
{
diff --git a/src/iocore/net/SSLNetVConnection.cc
b/src/iocore/net/SSLNetVConnection.cc
index 4d174d258c..2e24233462 100644
--- a/src/iocore/net/SSLNetVConnection.cc
+++ b/src/iocore/net/SSLNetVConnection.cc
@@ -2102,13 +2102,29 @@ SSLNetVConnection::_migrateFromSSL()
ssl_curve_id
SSLNetVConnection::_get_tls_curve() const
{
- if (getSSLSessionCacheHit()) {
+ // For resumed server side session caching, we have to retrieve the
curve/group
+ // from our stored data. For non-resumed sessions or from ticket based
resumption,
+ // simply query the SSL object.
+ if (getIsResumedFromSessionCache()) {
return getSSLCurveNID();
} else {
return SSLGetCurveNID(ssl);
}
}
+std::string_view
+SSLNetVConnection::_get_tls_group() const
+{
+ // For resumed server side session caching, we have to retrieve the
curve/group
+ // from our stored data. For non-resumed sessions or from ticket based
resumption,
+ // simply query the SSL object.
+ if (getIsResumedFromSessionCache()) {
+ return getSSLGroupName();
+ } else {
+ return SSLGetGroupName(ssl);
+ }
+}
+
int
SSLNetVConnection::_verify_certificate(X509_STORE_CTX * /* ctx ATS_UNUSED */)
{
diff --git a/src/iocore/net/SSLSessionCache.cc
b/src/iocore/net/SSLSessionCache.cc
index ee36095d5c..7fe5ae9eaf 100644
--- a/src/iocore/net/SSLSessionCache.cc
+++ b/src/iocore/net/SSLSessionCache.cc
@@ -174,6 +174,14 @@ SSLSessionBucket::insertSession(const SSLSessionID &id,
SSL_SESSION *sess, SSL *
// This could be moved to a function in charge of populating exdata
exdata->curve = (ssl == nullptr) ? 0 : SSLGetCurveNID(ssl);
+ if (ssl == nullptr) {
+ exdata->group_name[0] = '\0';
+ } else {
+ std::string_view group_name = SSLGetGroupName(ssl);
+ ink_release_assert(group_name.size() < sizeof(exdata->group_name));
+ strcpy(exdata->group_name, group_name.data());
+ }
+
std::unique_ptr<SSLSession> ssl_session(new SSLSession(id, buf, len,
buf_exdata));
std::unique_lock w_lock(mutex, std::try_to_lock);
@@ -352,9 +360,11 @@ SSLOriginSessionCache::insert_session(const std::string
&lookup_key, SSL_SESSION
Dbg(dbg_ctl_ssl_origin_session_cache, "insert session: %s = %p",
lookup_key.c_str(), sess_ptr);
- ssl_curve_id curve = (ssl == nullptr) ? 0 :
SSLGetCurveNID(ssl);
+ ssl_curve_id curve = (ssl == nullptr) ? 0 : SSLGetCurveNID(ssl);
+ std::string group_name = (ssl == nullptr) ? "" :
std::string{SSLGetGroupName(ssl)};
+
std::unique_ptr<SSLOriginSession> ssl_orig_session(
- new SSLOriginSession(lookup_key, curve,
std::shared_ptr<SSL_SESSION>{sess_ptr, SSLSessDeleter}));
+ new SSLOriginSession(lookup_key, curve, group_name,
std::shared_ptr<SSL_SESSION>{sess_ptr, SSLSessDeleter}));
auto new_node = ssl_orig_session.release();
std::unique_lock lock(mutex);
@@ -376,7 +386,7 @@ SSLOriginSessionCache::insert_session(const std::string
&lookup_key, SSL_SESSION
}
std::shared_ptr<SSL_SESSION>
-SSLOriginSessionCache::get_session(const std::string &lookup_key, ssl_curve_id
*curve)
+SSLOriginSessionCache::get_session(const std::string &lookup_key, ssl_curve_id
*curve, std::string &group_name)
{
Dbg(dbg_ctl_ssl_origin_session_cache, "get session: %s", lookup_key.c_str());
@@ -390,6 +400,8 @@ SSLOriginSessionCache::get_session(const std::string
&lookup_key, ssl_curve_id *
*curve = entry->second->curve_id;
}
+ group_name = entry->second->group_name;
+
return entry->second->shared_sess;
}
diff --git a/src/iocore/net/SSLSessionCache.h b/src/iocore/net/SSLSessionCache.h
index a2a6535c65..769c20adf1 100644
--- a/src/iocore/net/SSLSessionCache.h
+++ b/src/iocore/net/SSLSessionCache.h
@@ -30,13 +30,25 @@
#include <openssl/ssl.h>
#include <mutex>
+#include <string>
+#include <string_view>
#include <utility>
+/** Looking at OpenSSL's providers/common/capabilities.c, the current maximum
+ * length of a group name is 20 characters (brainpoolP256r1tls13 and the like).
+ * Reserving 64 characters should be more than enough. If someday we are
+ * surprised and this turns out to be too small, there is an assertion gaurd to
+ * make sure we do not overrun the buffer in SSLSessionCache.cc.
+ */
+#define SSL_MAX_GROUP_NAME_SIZE 64
#define SSL_MAX_SESSION_SIZE 256
#define SSL_MAX_ORIG_SESSION_SIZE 4096
struct ssl_session_cache_exdata {
ssl_curve_id curve = 0;
+
+ /** The TLS group name, gauranteed to be null-terminated. */
+ char group_name[SSL_MAX_GROUP_NAME_SIZE] = {'\0'};
};
inline void
@@ -193,10 +205,12 @@ class SSLOriginSession
public:
std::string key;
ssl_curve_id curve_id;
+ std::string group_name;
std::shared_ptr<SSL_SESSION> shared_sess = nullptr;
- SSLOriginSession(const std::string &lookup_key, ssl_curve_id curve,
std::shared_ptr<SSL_SESSION> session)
- : key(lookup_key), curve_id(curve), shared_sess(std::move(session))
+ SSLOriginSession(const std::string &lookup_key, ssl_curve_id curve,
std::string_view group_name,
+ std::shared_ptr<SSL_SESSION> session)
+ : key(lookup_key), curve_id(curve), group_name(group_name),
shared_sess(std::move(session))
{
}
@@ -210,7 +224,7 @@ public:
~SSLOriginSessionCache();
void insert_session(const std::string &lookup_key,
SSL_SESSION *sess, SSL *ssl);
- std::shared_ptr<SSL_SESSION> get_session(const std::string &lookup_key,
ssl_curve_id *curve);
+ std::shared_ptr<SSL_SESSION> get_session(const std::string &lookup_key,
ssl_curve_id *curve, std::string &group_name);
void remove_session(const std::string &lookup_key);
private:
diff --git a/src/iocore/net/SSLUtils.cc b/src/iocore/net/SSLUtils.cc
index 59e6f00a7d..0b7bc982ad 100644
--- a/src/iocore/net/SSLUtils.cc
+++ b/src/iocore/net/SSLUtils.cc
@@ -57,6 +57,7 @@
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/evp.h>
+#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
@@ -2521,6 +2522,31 @@ SSLGetCurveNID(SSL *ssl)
#endif
}
+std::string_view
+SSLGetGroupName([[maybe_unused]] SSL *ssl)
+{
+#if HAVE_SSL_GET0_GROUP_NAME // OpenSSL 3.2+
+ char const *group_name = SSL_get0_group_name(ssl);
+ return group_name != nullptr ? std::string_view(group_name) : "";
+#elif HAVE_SSL_GET_NEGOTIATED_GROUP && HAVE_SSL_GROUP_TO_NAME // OpenSSL
3.0/3.1
+ int const group_id = SSL_get_negotiated_group(ssl);
+ if (group_id != NID_undef) {
+ char const *group_name = SSL_group_to_name(ssl, group_id);
+ return group_name != nullptr ? std::string_view(group_name) : "";
+ }
+ return "";
+#elif HAVE_SSL_GET_GROUP_ID && HAVE_SSL_GET_GROUP_NAME // BoringSSL
+ uint16_t const group_id = SSL_get_group_id(ssl);
+ if (group_id == 0) {
+ return "";
+ }
+ char const *group_name = SSL_get_group_name(group_id);
+ return group_name != nullptr ? std::string_view(group_name) : "";
+#else
+ return "";
+#endif // HAVE_SSL_GET0_GROUP_NAME
+}
+
SSL_SESSION *
SSLSessionDup(SSL_SESSION *sess)
{
diff --git a/src/iocore/net/TLSBasicSupport.cc
b/src/iocore/net/TLSBasicSupport.cc
index 17adaa42dd..bb77dab836 100644
--- a/src/iocore/net/TLSBasicSupport.cc
+++ b/src/iocore/net/TLSBasicSupport.cc
@@ -123,25 +123,16 @@ TLSBasicSupport::get_tls_curve() const
#endif
}
-const char *
+std::string_view
TLSBasicSupport::get_tls_group() const
{
auto ssl = this->_get_ssl_object();
if (!ssl) {
- return nullptr;
- }
-#if HAVE_SSL_GET0_GROUP_NAME // OpenSSL
- return SSL_get0_group_name(ssl);
-#elif HAVE_SSL_GET_GROUP_ID && HAVE_SSL_GET_GROUP_NAME // BoringSSL
- uint16_t const group_id = SSL_get_group_id(ssl);
- if (group_id == 0) {
- return nullptr;
+ return "";
}
- return SSL_get_group_name(group_id);
-#else
- return nullptr;
-#endif // HAVE_SSL_GET0_GROUP_NAME
+
+ return this->_get_tls_group();
}
ink_hrtime
diff --git a/src/iocore/net/TLSSessionResumptionSupport.cc
b/src/iocore/net/TLSSessionResumptionSupport.cc
index af78aba176..68d8607617 100644
--- a/src/iocore/net/TLSSessionResumptionSupport.cc
+++ b/src/iocore/net/TLSSessionResumptionSupport.cc
@@ -26,6 +26,7 @@
#include "iocore/net/TLSSessionResumptionSupport.h"
#include "P_SSLCertLookup.h"
+#include "P_SSLUtils.h"
#include "iocore/net/SSLAPIHooks.h"
#include "P_SSLConfig.h"
@@ -124,15 +125,31 @@ TLSSessionResumptionSupport::processSessionTicket(SSL
*ssl, unsigned char *keyna
}
bool
-TLSSessionResumptionSupport::getSSLSessionCacheHit() const
+TLSSessionResumptionSupport::getIsResumedSSLSession() const
{
- return this->_sslSessionCacheHit;
+ return (this->_resumptionType == ResumptionType::RESUMED_FROM_SESSION_CACHE
||
+ this->_resumptionType ==
ResumptionType::RESUMED_FROM_SESSION_TICKET) &&
+ !this->_isResumedOriginSession;
}
bool
-TLSSessionResumptionSupport::getSSLOriginSessionCacheHit() const
+TLSSessionResumptionSupport::getIsResumedOriginSSLSession() const
{
- return this->_sslOriginSessionCacheHit;
+ return (this->_resumptionType == ResumptionType::RESUMED_FROM_SESSION_CACHE
||
+ this->_resumptionType ==
ResumptionType::RESUMED_FROM_SESSION_TICKET) &&
+ this->_isResumedOriginSession;
+}
+
+bool
+TLSSessionResumptionSupport::getIsResumedFromSessionCache() const
+{
+ return this->_resumptionType == ResumptionType::RESUMED_FROM_SESSION_CACHE;
+}
+
+bool
+TLSSessionResumptionSupport::getIsResumedFromSessionTicket() const
+{
+ return this->_resumptionType == ResumptionType::RESUMED_FROM_SESSION_TICKET;
}
ssl_curve_id
@@ -141,6 +158,12 @@ TLSSessionResumptionSupport::getSSLCurveNID() const
return this->_sslCurveNID;
}
+std::string_view
+TLSSessionResumptionSupport::getSSLGroupName() const
+{
+ return this->_sslGroupName;
+}
+
SSL_SESSION *
TLSSessionResumptionSupport::getSession(SSL *ssl, const unsigned char *id, int
len, int *copy)
{
@@ -180,8 +203,9 @@ TLSSessionResumptionSupport::getSession(SSL *ssl, const
unsigned char *id, int l
session = nullptr;
} else {
Metrics::Counter::increment(ssl_rsb.session_cache_hit);
- this->_setSSLSessionCacheHit(true);
+ this->_setResumptionType(ResumptionType::RESUMED_FROM_SESSION_CACHE,
!IS_RESUMED_ORIGIN_SESSION);
this->_setSSLCurveNID(exdata->curve);
+ this->_setSSLGroupName(exdata->group_name);
}
} else {
Metrics::Counter::increment(ssl_rsb.session_cache_miss);
@@ -192,8 +216,9 @@ TLSSessionResumptionSupport::getSession(SSL *ssl, const
unsigned char *id, int l
std::shared_ptr<SSL_SESSION>
TLSSessionResumptionSupport::getOriginSession(const std::string &lookup_key)
{
- ssl_curve_id curve = 0;
- std::shared_ptr<SSL_SESSION> shared_sess =
origin_sess_cache->get_session(lookup_key, &curve);
+ ssl_curve_id curve = 0;
+ std::string group_name;
+ std::shared_ptr<SSL_SESSION> shared_sess =
origin_sess_cache->get_session(lookup_key, &curve, group_name);
if (shared_sess != nullptr) {
// Double check the timeout
@@ -203,8 +228,9 @@ TLSSessionResumptionSupport::getOriginSession(const
std::string &lookup_key)
shared_sess.reset();
} else {
Metrics::Counter::increment(ssl_rsb.origin_session_cache_hit);
- this->_setSSLOriginSessionCacheHit(true);
+ this->_setResumptionType(ResumptionType::RESUMED_FROM_SESSION_CACHE,
IS_RESUMED_ORIGIN_SESSION);
this->_setSSLCurveNID(curve);
+ this->_setSSLGroupName(group_name);
}
} else {
Metrics::Counter::increment(ssl_rsb.origin_session_cache_miss);
@@ -215,7 +241,10 @@ TLSSessionResumptionSupport::getOriginSession(const
std::string &lookup_key)
void
TLSSessionResumptionSupport::clear()
{
- this->_sslSessionCacheHit = false;
+ this->_resumptionType = ResumptionType::NOT_RESUMED;
+ this->_isResumedOriginSession = false;
+ this->_sslCurveNID = NID_undef;
+ this->_sslGroupName.clear();
}
#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
@@ -297,7 +326,10 @@
TLSSessionResumptionSupport::_getSessionInformation(ssl_ticket_key_block *keyblo
Metrics::Counter::increment(ssl_rsb.total_tickets_verified_old_key);
}
- this->_setSSLSessionCacheHit(true);
+ this->_setResumptionType(ResumptionType::RESUMED_FROM_SESSION_TICKET,
!IS_RESUMED_ORIGIN_SESSION);
+ // Do not call _setSSLCurveNID() and _setSSLGroupName() here because the
+ // SSL object is not fully configured for this yet and the curve/group
+ // info is not available. OpenSSL will crash.
#ifdef TLS1_3_VERSION
if (SSL_version(ssl) >= TLS1_3_VERSION) {
@@ -317,19 +349,20 @@
TLSSessionResumptionSupport::_getSessionInformation(ssl_ticket_key_block *keyblo
}
void
-TLSSessionResumptionSupport::_setSSLSessionCacheHit(bool state)
+TLSSessionResumptionSupport::_setResumptionType(ResumptionType type, bool
isOrigin)
{
- this->_sslSessionCacheHit = state;
+ this->_resumptionType = type;
+ this->_isResumedOriginSession = isOrigin;
}
void
-TLSSessionResumptionSupport::_setSSLOriginSessionCacheHit(bool state)
+TLSSessionResumptionSupport::_setSSLCurveNID(ssl_curve_id curve_nid)
{
- this->_sslOriginSessionCacheHit = state;
+ this->_sslCurveNID = curve_nid;
}
void
-TLSSessionResumptionSupport::_setSSLCurveNID(ssl_curve_id curve_nid)
+TLSSessionResumptionSupport::_setSSLGroupName(std::string_view group_name)
{
- this->_sslCurveNID = curve_nid;
+ this->_sslGroupName = std::string{group_name};
}
diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc
index cc39104926..434044bd75 100644
--- a/src/proxy/http/HttpSM.cc
+++ b/src/proxy/http/HttpSM.cc
@@ -6651,7 +6651,7 @@ HttpSM::attach_server_session()
}
if (auto tsrs = server_vc->get_service<TLSSessionResumptionSupport>(); tsrs)
{
- server_ssl_reused = tsrs->getSSLOriginSessionCacheHit();
+ server_ssl_reused = tsrs->getIsResumedOriginSSLSession();
}
server_protocol = server_txn->get_protocol_string();