You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2020/12/04 00:34:06 UTC

[trafficserver] branch master updated: Use EVP MAC API if available (#7363)

This is an automated email from the ASF dual-hosted git repository.

maskit 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 c6f1ea6  Use EVP MAC API if available (#7363)
c6f1ea6 is described below

commit c6f1ea6dc19fba3b13cac526d4af2f90c640766a
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Fri Dec 4 09:33:57 2020 +0900

    Use EVP MAC API if available (#7363)
    
    HMAC_Init_ex is going to be deprecated since OpenSSL 3.0
---
 build/crypto.m4                           | 47 ++++++++++++++++++++++++++++
 configure.ac                              |  3 ++
 include/tscore/ink_config.h.in            |  1 +
 iocore/net/SSLCertLookup.cc               |  7 +++--
 iocore/net/SSLConfig.cc                   |  7 +++--
 iocore/net/SSLSessionTicket.cc            |  9 ++++--
 iocore/net/SSLSessionTicket.h             | 14 ++++-----
 iocore/net/SSLUtils.cc                    | 13 +++++---
 iocore/net/TLSSessionResumptionSupport.cc | 51 ++++++++++++++++++++++++++-----
 iocore/net/TLSSessionResumptionSupport.h  | 12 ++++++++
 10 files changed, 137 insertions(+), 27 deletions(-)

diff --git a/build/crypto.m4 b/build/crypto.m4
index 331be06..8a4d8fe 100644
--- a/build/crypto.m4
+++ b/build/crypto.m4
@@ -318,3 +318,50 @@ AC_DEFUN([TS_CHECK_EARLY_DATA], [
 
   AC_SUBST(has_tls_early_data)
 ])
+
+dnl
+dnl Since OpenSSL 1.1.1
+dnl
+dnl SSL_CTX_set_tlsext_ticket_key_evp_cb function is for OpenSSL 3.0
+dnl SSL_CTX_set_tlsext_ticket_key_cb macro is for OpenSSL 1.1.1
+dnl SSL_CTX_set_tlsext_ticket_key_cb function is for BoringSSL
+AC_DEFUN([TS_CHECK_SESSION_TICKET], [
+  _set_ssl_ctx_set_tlsext_ticket_key_evp_cb_saved_LIBS=$LIBS
+
+  TS_ADDTO(LIBS, [$OPENSSL_LIBS])
+  AC_CHECK_HEADERS(openssl/ssl.h)
+  session_ticket_check=no
+  has_tls_session_ticket=0
+  AC_MSG_CHECKING([for SSL_CTX_set_tlsext_ticket_key_cb macro])
+  AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM([[#include <openssl/ssl.h>]],
+                     [[
+                     #ifndef SSL_CTX_set_tlsext_ticket_key_cb
+                     #error
+                     #endif
+                     ]])
+    ],
+    [
+      AC_DEFINE(HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB, 1, [Whether SSL_CTX_set_tlsext_ticket_key_cb is available])
+      session_ticket_check=yes
+      has_tls_session_ticket=1
+    ],
+    []
+  )
+  AC_MSG_RESULT([$session_ticket_check])
+  AC_CHECK_FUNCS(
+    SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_tlsext_ticket_key_cb,
+    [
+      session_ticket_check=yes
+      has_tls_session_ticket=1
+    ],
+    []
+  )
+
+  LIBS=$_set_ssl_ctx_set_tlsext_ticket_key_evp_cb_saved_LIBS
+
+  AC_MSG_CHECKING([for session ticket support])
+  AC_MSG_RESULT([$session_ticket_check])
+
+  AC_SUBST(has_tls_session_ticket)
+])
diff --git a/configure.ac b/configure.ac
index d7ab893..b9b99c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1298,6 +1298,9 @@ TS_CHECK_CRYPTO_SET_CIPHERSUITES
 # Check for openssl early data support
 TS_CHECK_EARLY_DATA
 
+# Check for openssl session ticket support
+TS_CHECK_SESSION_TICKET
+
 saved_LIBS="$LIBS"
 TS_ADDTO([LIBS], ["$OPENSSL_LIBS"])
 
diff --git a/include/tscore/ink_config.h.in b/include/tscore/ink_config.h.in
index d633990..49135ee 100644
--- a/include/tscore/ink_config.h.in
+++ b/include/tscore/ink_config.h.in
@@ -79,6 +79,7 @@
 #define TS_USE_REMOTE_UNWINDING @use_remote_unwinding@
 #define TS_USE_TLS_OCSP @use_tls_ocsp@
 #define TS_HAS_TLS_EARLY_DATA @has_tls_early_data@
+#define TS_HAS_TLS_SESSION_TICKET @has_tls_session_ticket@
 
 #define TS_HAS_SO_PEERCRED @has_so_peercred@
 
diff --git a/iocore/net/SSLCertLookup.cc b/iocore/net/SSLCertLookup.cc
index e6385b4..9b887e5 100644
--- a/iocore/net/SSLCertLookup.cc
+++ b/iocore/net/SSLCertLookup.cc
@@ -28,6 +28,7 @@
 #include "tscore/MatcherUtils.h"
 #include "tscore/Regex.h"
 #include "tscore/Trie.h"
+#include "tscore/ink_config.h"
 #include "tscore/BufferWriter.h"
 #include "tscore/bwf_std_format.h"
 #include "tscore/TestBox.h"
@@ -216,7 +217,7 @@ fail:
 ssl_ticket_key_block *
 ssl_create_ticket_keyblock(const char *ticket_key_path)
 {
-#if TS_HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAS_TLS_SESSION_TICKET
   ats_scoped_str ticket_key_data;
   int ticket_key_len;
   ssl_ticket_key_block *keyblock = nullptr;
@@ -241,10 +242,10 @@ fail:
   ticket_block_free(keyblock);
   return nullptr;
 
-#else  /* !TS_HAVE_OPENSSL_SESSION_TICKETS */
+#else  /* !TS_HAS_TLS_SESSION_TICKET */
   (void)ticket_key_path;
   return nullptr;
-#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
+#endif /* TS_HAS_TLS_SESSION_TICKET */
 }
 
 SSLCertContext::SSLCertContext(SSLCertContext const &other)
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index cbe7855..4c34d67 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -34,6 +34,7 @@
 #include <cstring>
 #include <cmath>
 
+#include "tscore/ink_config.h"
 #include "tscore/ink_platform.h"
 #include "tscore/I_Layout.h"
 #include "records/I_RecHttp.h"
@@ -529,7 +530,7 @@ SSLTicketParams::LoadTicket(bool &nochange)
   cleanup();
   nochange = true;
 
-#if TS_HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAS_TLS_SESSION_TICKET
   ssl_ticket_key_block *keyblock = nullptr;
 
   SSLConfig::scoped_config params;
@@ -577,15 +578,15 @@ SSLTicketParams::LoadTicket(bool &nochange)
   load_time               = time(nullptr);
 
   Debug("ssl", "ticket key reloaded from %s", ticket_key_filename);
-  return true;
 #endif
+  return true;
 }
 
 void
 SSLTicketParams::LoadTicketData(char *ticket_data, int ticket_data_len)
 {
   cleanup();
-#if TS_HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAS_TLS_SESSION_TICKET
   if (ticket_data != nullptr && ticket_data_len > 0) {
     default_global_keyblock = ticket_block_create(ticket_data, ticket_data_len);
   } else {
diff --git a/iocore/net/SSLSessionTicket.cc b/iocore/net/SSLSessionTicket.cc
index 2e7d397..395fd8d 100644
--- a/iocore/net/SSLSessionTicket.cc
+++ b/iocore/net/SSLSessionTicket.cc
@@ -23,7 +23,7 @@
 
 #include "SSLSessionTicket.h"
 
-#if TS_HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAS_TLS_SESSION_TICKET
 
 #include "P_SSLCertLookup.h"
 #include "TLSSessionResumptionSupport.h"
@@ -40,8 +40,13 @@ ssl_session_ticket_free(void * /*parent*/, void *ptr, CRYPTO_EX_DATA * /*ad*/, i
  * a mechanism to present the ticket back to the server.
  * */
 int
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+ssl_callback_session_ticket(SSL *ssl, unsigned char *keyname, unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx, EVP_MAC_CTX *hctx,
+                            int enc)
+#else
 ssl_callback_session_ticket(SSL *ssl, unsigned char *keyname, unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx,
                             int enc)
+#endif
 {
   TLSSessionResumptionSupport *srs = TLSSessionResumptionSupport::getInstance(ssl);
 
@@ -57,4 +62,4 @@ ssl_callback_session_ticket(SSL *ssl, unsigned char *keyname, unsigned char *iv,
   }
 }
 
-#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
+#endif /* TS_HAS_TLS_SESSION_TICKET */
diff --git a/iocore/net/SSLSessionTicket.h b/iocore/net/SSLSessionTicket.h
index 71edbb6..4fc3518 100644
--- a/iocore/net/SSLSessionTicket.h
+++ b/iocore/net/SSLSessionTicket.h
@@ -23,21 +23,21 @@
 
 #pragma once
 
+#include "tscore/ink_config.h"
 #include <openssl/safestack.h>
 #include <openssl/tls1.h>
 #include <openssl/ssl.h>
 
-// Check if the ticket_key callback #define is available, and if so, enable session tickets.
-#ifdef SSL_CTX_set_tlsext_ticket_key_cb
-#define TS_HAVE_OPENSSL_SESSION_TICKETS 1
-#endif
-
-#ifdef TS_HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAS_TLS_SESSION_TICKET
 
 #include <openssl/crypto.h>
 #include <openssl/hmac.h>
 
 void ssl_session_ticket_free(void *, void *, CRYPTO_EX_DATA *, int, long, void *);
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+int ssl_callback_session_ticket(SSL *, unsigned char *, unsigned char *, EVP_CIPHER_CTX *, EVP_MAC_CTX *, int);
+#else
 int ssl_callback_session_ticket(SSL *, unsigned char *, unsigned char *, EVP_CIPHER_CTX *, HMAC_CTX *, int);
+#endif
 
-#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
+#endif /* TS_HAS_TLS_SESSION_TICKET */
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index 79be614..dabf3ad 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -22,6 +22,7 @@
 #include "P_SSLUtils.h"
 
 #include "tscpp/util/TextView.h"
+#include "tscore/ink_config.h"
 #include "tscore/ink_platform.h"
 #include "tscore/SimpleTokenizer.h"
 #include "tscore/I_Layout.h"
@@ -296,10 +297,14 @@ set_context_cert(SSL *ssl)
 
   if (ctx != nullptr) {
     SSL_set_SSL_CTX(ssl, ctx.get());
-#if TS_HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAS_TLS_SESSION_TICKET
     // Reset the ticket callback if needed
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+    SSL_CTX_set_tlsext_ticket_key_evp_cb(ctx.get(), ssl_callback_session_ticket);
+#else
     SSL_CTX_set_tlsext_ticket_key_cb(ctx.get(), ssl_callback_session_ticket);
 #endif
+#endif
     // After replacing the SSL_CTX, make sure the overriden ca_cert_file is still set
     setClientCertCACerts(ssl, netvc->get_ca_cert_file(), netvc->get_ca_cert_dir());
   } else {
@@ -597,7 +602,7 @@ ssl_context_enable_ecdh(SSL_CTX *ctx)
 static ssl_ticket_key_block *
 ssl_context_enable_tickets(SSL_CTX *ctx, const char *ticket_key_path)
 {
-#if TS_HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAS_TLS_SESSION_TICKET
   ssl_ticket_key_block *keyblock = nullptr;
 
   keyblock = ssl_create_ticket_keyblock(ticket_key_path);
@@ -619,10 +624,10 @@ ssl_context_enable_tickets(SSL_CTX *ctx, const char *ticket_key_path)
   SSL_CTX_clear_options(ctx, SSL_OP_NO_TICKET);
   return keyblock;
 
-#else  /* !TS_HAVE_OPENSSL_SESSION_TICKETS */
+#else  /* !TS_HAS_TLS_SESSION_TICKET */
   (void)ticket_key_path;
   return nullptr;
-#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
+#endif /* TS_HAS_TLS_SESSION_TICKET */
 }
 
 struct passphrase_cb_userdata {
diff --git a/iocore/net/TLSSessionResumptionSupport.cc b/iocore/net/TLSSessionResumptionSupport.cc
index ab6f38e..a11ceb3 100644
--- a/iocore/net/TLSSessionResumptionSupport.cc
+++ b/iocore/net/TLSSessionResumptionSupport.cc
@@ -26,23 +26,23 @@
 
 #include "TLSSessionResumptionSupport.h"
 
-#ifdef SSL_CTX_set_tlsext_ticket_key_cb
-#define TS_HAVE_OPENSSL_SESSION_TICKETS 1
-#endif
-
-#ifdef TS_HAVE_OPENSSL_SESSION_TICKETS
-
 #include "P_SSLConfig.h"
 #include "SSLStats.h"
 #include <openssl/evp.h>
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+#include <openssl/core_names.h>
+#endif
 #include "InkAPIInternal.h"
+#include "tscore/ink_config.h"
 
 // Remove this when drop OpenSSL 1.0.2 support
 #ifndef evp_md_func
 #ifdef OPENSSL_NO_SHA256
 #define evp_md_func EVP_sha1()
+char mac_param_digest[] = "sha1";
 #else
 #define evp_md_func EVP_sha256()
+char mac_param_digest[] = "sha256";
 #endif
 #endif
 
@@ -81,9 +81,15 @@ TLSSessionResumptionSupport::unbind(SSL *ssl)
   SSL_set_ex_data(ssl, _ex_data_index, nullptr);
 }
 
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+int
+TLSSessionResumptionSupport::processSessionTicket(SSL *ssl, unsigned char *keyname, unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx,
+                                                  EVP_MAC_CTX *hctx, int enc)
+#else
 int
 TLSSessionResumptionSupport::processSessionTicket(SSL *ssl, unsigned char *keyname, unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx,
                                                   HMAC_CTX *hctx, int enc)
+#endif
 {
   SSLConfig::scoped_config config;
   SSLCertificateConfig::scoped_config lookup;
@@ -172,29 +178,60 @@ TLSSessionResumptionSupport::clear()
   this->_sslSessionCacheHit = false;
 }
 
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+int
+TLSSessionResumptionSupport::_setSessionInformation(ssl_ticket_key_block *keyblock, SSL *ssl, unsigned char *keyname,
+                                                    unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx, EVP_MAC_CTX *hctx)
+#else
 int
 TLSSessionResumptionSupport::_setSessionInformation(ssl_ticket_key_block *keyblock, SSL *ssl, unsigned char *keyname,
                                                     unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx)
+#endif
 {
   const ssl_ticket_key_t &most_recent_key = keyblock->keys[0];
   memcpy(keyname, most_recent_key.key_name, sizeof(most_recent_key.key_name));
   RAND_bytes(iv, EVP_MAX_IV_LENGTH);
   EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), nullptr, most_recent_key.aes_key, iv);
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+  const OSSL_PARAM params[] = {
+    OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, const_cast<unsigned char *>(most_recent_key.hmac_secret),
+                                      sizeof(most_recent_key.hmac_secret)),
+    OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, mac_param_digest, 0),
+    OSSL_PARAM_construct_end(),
+  };
+  EVP_MAC_CTX_set_params(hctx, params);
+#else
   HMAC_Init_ex(hctx, most_recent_key.hmac_secret, sizeof(most_recent_key.hmac_secret), evp_md_func, nullptr);
+#endif
 
   Debug("ssl_session_ticket", "create ticket for a new session.");
   SSL_INCREMENT_DYN_STAT(ssl_total_tickets_created_stat);
   return 1;
 }
 
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+int
+TLSSessionResumptionSupport::_getSessionInformation(ssl_ticket_key_block *keyblock, SSL *ssl, unsigned char *keyname,
+                                                    unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx, EVP_MAC_CTX *hctx)
+#else
 int
 TLSSessionResumptionSupport::_getSessionInformation(ssl_ticket_key_block *keyblock, SSL *ssl, unsigned char *keyname,
                                                     unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx)
+#endif
 {
   for (unsigned i = 0; i < keyblock->num_keys; ++i) {
     if (memcmp(keyname, keyblock->keys[i].key_name, sizeof(keyblock->keys[i].key_name)) == 0) {
       EVP_DecryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), nullptr, keyblock->keys[i].aes_key, iv);
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+      const OSSL_PARAM params[] = {
+        OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, keyblock->keys[i].hmac_secret, sizeof(keyblock->keys[i].hmac_secret)),
+        OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, mac_param_digest, 0),
+        OSSL_PARAM_construct_end(),
+      };
+      EVP_MAC_CTX_set_params(hctx, params);
+#else
       HMAC_Init_ex(hctx, keyblock->keys[i].hmac_secret, sizeof(keyblock->keys[i].hmac_secret), evp_md_func, nullptr);
+#endif
 
       Debug("ssl_session_ticket", "verify the ticket for an existing session.");
       // Increase the total number of decrypted tickets.
@@ -234,5 +271,3 @@ TLSSessionResumptionSupport::_setSSLCurveNID(ssl_curve_id curve_nid)
 {
   this->_sslCurveNID = curve_nid;
 }
-
-#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
diff --git a/iocore/net/TLSSessionResumptionSupport.h b/iocore/net/TLSSessionResumptionSupport.h
index f1e61c9..26504c3 100644
--- a/iocore/net/TLSSessionResumptionSupport.h
+++ b/iocore/net/TLSSessionResumptionSupport.h
@@ -40,8 +40,13 @@ public:
   static void bind(SSL *ssl, TLSSessionResumptionSupport *srs);
   static void unbind(SSL *ssl);
 
+#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);
+#else
   int processSessionTicket(SSL *ssl, unsigned char *keyname, unsigned char *iv, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx,
                            int enc);
+#endif
   bool getSSLSessionCacheHit() const;
   ssl_curve_id getSSLCurveNID() const;
 
@@ -57,10 +62,17 @@ private:
   bool _sslSessionCacheHit = false;
   int _sslCurveNID         = NID_undef;
 
+#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
+  int _setSessionInformation(ssl_ticket_key_block *keyblock, SSL *ssl, unsigned char *keyname, unsigned char *iv,
+                             EVP_CIPHER_CTX *cipher_ctx, EVP_MAC_CTX *hctx);
+  int _getSessionInformation(ssl_ticket_key_block *keyblock, SSL *ssl, unsigned char *keyname, unsigned char *iv,
+                             EVP_CIPHER_CTX *cipher_ctx, EVP_MAC_CTX *hctx);
+#else
   int _setSessionInformation(ssl_ticket_key_block *keyblock, SSL *ssl, unsigned char *keyname, unsigned char *iv,
                              EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx);
   int _getSessionInformation(ssl_ticket_key_block *keyblock, SSL *ssl, unsigned char *keyname, unsigned char *iv,
                              EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx);
+#endif
 
   void _setSSLSessionCacheHit(bool state);
   void _setSSLCurveNID(ssl_curve_id curve_nid);