This is an automated email from the ASF dual-hosted git repository.
masaori 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 b8d546c Cleanup: Separate TLS SessionTicket from SSLUtils
b8d546c is described below
commit b8d546c131495bde56dfc1ff7449604c6d3385da
Author: Masaori Koshiba <[email protected]>
AuthorDate: Mon Feb 25 11:03:16 2019 +0900
Cleanup: Separate TLS SessionTicket from SSLUtils
---
iocore/net/Makefile.am | 5 +-
iocore/net/SSLCertLookup.cc | 26 ++++-----
iocore/net/SSLConfig.cc | 14 ++---
iocore/net/SSLSessionTicket.cc | 117 +++++++++++++++++++++++++++++++++++++++++
iocore/net/SSLSessionTicket.h | 42 +++++++++++++++
iocore/net/SSLUtils.cc | 107 ++++---------------------------------
6 files changed, 186 insertions(+), 125 deletions(-)
diff --git a/iocore/net/Makefile.am b/iocore/net/Makefile.am
index 0971d5f..7e27fe5 100644
--- a/iocore/net/Makefile.am
+++ b/iocore/net/Makefile.am
@@ -134,7 +134,7 @@ libinknet_a_SOURCES = \
ProxyProtocol.cc \
Socks.cc \
SSLCertLookup.cc \
- SSLSessionCache.cc \
+ SSLClientUtils.cc \
SSLConfig.cc \
SSLDiags.cc \
SSLInternal.cc \
@@ -145,8 +145,9 @@ libinknet_a_SOURCES = \
SSLNextProtocolSet.cc \
SSLSNIConfig.cc \
SSLStats.cc \
+ SSLSessionCache.cc \
+ SSLSessionTicket.cc \
SSLUtils.cc \
- SSLClientUtils.cc \
OCSPStapling.cc \
Socks.cc \
UDPIOEvent.cc \
diff --git a/iocore/net/SSLCertLookup.cc b/iocore/net/SSLCertLookup.cc
index f94f515..2b6e91d 100644
--- a/iocore/net/SSLCertLookup.cc
+++ b/iocore/net/SSLCertLookup.cc
@@ -21,12 +21,9 @@
limitations under the License.
*/
-#include "tscore/ink_config.h"
-
#include "P_SSLCertLookup.h"
-#include "P_SSLUtils.h"
-#include "P_SSLConfig.h"
-#include "I_EventSystem.h"
+
+#include "tscore/ink_config.h"
#include "tscore/I_Layout.h"
#include "tscore/MatcherUtils.h"
#include "tscore/Regex.h"
@@ -35,17 +32,16 @@
#include "tscore/bwf_std_format.h"
#include "tscore/TestBox.h"
+#include "I_EventSystem.h"
+
+#include "P_SSLUtils.h"
+#include "P_SSLConfig.h"
+#include "SSLSessionTicket.h"
+
#include <unordered_map>
#include <vector>
#include <algorithm>
-// Check if the ticket_key callback #define is available, and if so, enable
session tickets.
-#ifdef SSL_CTX_set_tlsext_ticket_key_cb
-
-#define HAVE_OPENSSL_SESSION_TICKETS 1
-
-#endif /* SSL_CTX_set_tlsext_ticket_key_cb */
-
struct SSLAddressLookupKey {
explicit SSLAddressLookupKey(const IpEndpoint &ip)
{
@@ -201,7 +197,7 @@ fail:
ssl_ticket_key_block *
ssl_create_ticket_keyblock(const char *ticket_key_path)
{
-#if HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAVE_OPENSSL_SESSION_TICKETS
ats_scoped_str ticket_key_data;
int ticket_key_len;
ssl_ticket_key_block *keyblock = nullptr;
@@ -226,10 +222,10 @@ fail:
ticket_block_free(keyblock);
return nullptr;
-#else /* !HAVE_OPENSSL_SESSION_TICKETS */
+#else /* !TS_HAVE_OPENSSL_SESSION_TICKETS */
(void)ticket_key_path;
return nullptr;
-#endif /* HAVE_OPENSSL_SESSION_TICKETS */
+#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
}
void
SSLCertContext::release()
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index 26a65a4..d822ce4 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -43,8 +43,9 @@
#include "P_Net.h"
#include "P_SSLUtils.h"
#include "P_SSLCertLookup.h"
-#include "SSLSessionCache.h"
#include "SSLDiags.h"
+#include "SSLSessionCache.h"
+#include "SSLSessionTicket.h"
#include "YamlSNIConfig.h"
int SSLConfig::configid = 0;
@@ -71,13 +72,6 @@ static
std::unique_ptr<ConfigUpdateHandler<SSLCertificateConfig>> sslCertUpdate;
static std::unique_ptr<ConfigUpdateHandler<SSLConfig>> sslConfigUpdate;
static std::unique_ptr<ConfigUpdateHandler<SSLTicketKeyConfig>> sslTicketKey;
-// Check if the ticket_key callback #define is available, and if so, enable
session tickets.
-#ifdef SSL_CTX_set_tlsext_ticket_key_cb
-
-#define HAVE_OPENSSL_SESSION_TICKETS 1
-
-#endif /* SSL_CTX_set_tlsext_ticket_key_cb */
-
SSLConfigParams::SSLConfigParams()
{
ink_mutex_init(&ctxMapLock);
@@ -563,7 +557,7 @@ SSLTicketParams::LoadTicket()
{
cleanup();
-#if HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAVE_OPENSSL_SESSION_TICKETS
ssl_ticket_key_block *keyblock = nullptr;
SSLConfig::scoped_config params;
@@ -611,7 +605,7 @@ void
SSLTicketParams::LoadTicketData(char *ticket_data, int ticket_data_len)
{
cleanup();
-#if HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAVE_OPENSSL_SESSION_TICKETS
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
new file mode 100644
index 0000000..151c64a
--- /dev/null
+++ b/iocore/net/SSLSessionTicket.cc
@@ -0,0 +1,117 @@
+/** @file
+
+ SessionTicket TLS Extension
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include "SSLSessionTicket.h"
+
+#if TS_HAVE_OPENSSL_SESSION_TICKETS
+
+#include "tscore/MatcherUtils.h"
+
+#include "P_Net.h"
+#include "SSLStats.h"
+#include "P_SSLConfig.h"
+
+// Remvoe this when drop OpenSSL 1.0.2 support
+#ifndef evp_md_func
+#ifdef OPENSSL_NO_SHA256
+#define evp_md_func EVP_sha1()
+#else
+#define evp_md_func EVP_sha256()
+#endif
+#endif
+
+void
+ssl_session_ticket_free(void * /*parent*/, void *ptr, CRYPTO_EX_DATA * /*ad*/,
int /*idx*/, long /*argl*/, void * /*argp*/)
+{
+ ticket_block_free((struct ssl_ticket_key_block *)ptr);
+}
+
+/*
+ * RFC 5077. Create session ticket to resume SSL session without requiring
session-specific state at the TLS server.
+ * Specifically, it distributes the encrypted session-state information to the
client in the form of a ticket and
+ * a mechanism to present the ticket back to the server.
+ * */
+int
+ssl_callback_session_ticket(SSL *ssl, unsigned char *keyname, unsigned char
*iv, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx,
+ int enc)
+{
+ SSLCertificateConfig::scoped_config lookup;
+ SSLTicketKeyConfig::scoped_config params;
+ SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
+
+ // Get the IP address to look up the keyblock
+ IpEndpoint ip;
+ int namelen = sizeof(ip);
+ SSLCertContext *cc = nullptr;
+ if (0 == safe_getsockname(netvc->get_socket(), &ip.sa, &namelen)) {
+ cc = lookup->find(ip);
+ }
+ ssl_ticket_key_block *keyblock = nullptr;
+ if (cc == nullptr || cc->keyblock == nullptr) {
+ // Try the default
+ keyblock = params->default_global_keyblock;
+ } else {
+ keyblock = cc->keyblock;
+ }
+ ink_release_assert(keyblock != nullptr && keyblock->num_keys > 0);
+
+ if (enc == 1) {
+ 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);
+ HMAC_Init_ex(hctx, most_recent_key.hmac_secret,
sizeof(most_recent_key.hmac_secret), evp_md_func, nullptr);
+
+ Debug("ssl", "create ticket for a new session.");
+ SSL_INCREMENT_DYN_STAT(ssl_total_tickets_created_stat);
+ return 1;
+ } else if (enc == 0) {
+ 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);
+ HMAC_Init_ex(hctx, keyblock->keys[i].hmac_secret,
sizeof(keyblock->keys[i].hmac_secret), evp_md_func, nullptr);
+
+ Debug("ssl", "verify the ticket for an existing session.");
+ // Increase the total number of decrypted tickets.
+ SSL_INCREMENT_DYN_STAT(ssl_total_tickets_verified_stat);
+
+ if (i != 0) { // The number of tickets decrypted with "older" keys.
+ SSL_INCREMENT_DYN_STAT(ssl_total_tickets_verified_old_key_stat);
+ }
+
+ SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
+ netvc->setSSLSessionCacheHit(true);
+ // When we decrypt with an "older" key, encrypt the ticket again with
the most recent key.
+ return (i == 0) ? 1 : 2;
+ }
+ }
+
+ Debug("ssl", "keyname is not consistent.");
+ SSL_INCREMENT_DYN_STAT(ssl_total_tickets_not_found_stat);
+ return 0;
+ }
+
+ return -1;
+}
+
+#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
diff --git a/iocore/net/SSLSessionTicket.h b/iocore/net/SSLSessionTicket.h
new file mode 100644
index 0000000..be520cb
--- /dev/null
+++ b/iocore/net/SSLSessionTicket.h
@@ -0,0 +1,42 @@
+/** @file
+
+ SessionTicket TLS Extension
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#pragma once
+
+#include <openssl/safestack.h>
+#include <openssl/tls1.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
+
+#include <openssl/crypto.h>
+#include <openssl/hmac.h>
+
+void ssl_session_ticket_free(void *, void *, CRYPTO_EX_DATA *, int, long, void
*);
+int ssl_callback_session_ticket(SSL *, unsigned char *, unsigned char *,
EVP_CIPHER_CTX *, HMAC_CTX *, int);
+
+#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index c2e7061..1e48bf2 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -36,6 +36,7 @@
#include "P_SSLSNI.h"
#include "P_SSLConfig.h"
#include "SSLSessionCache.h"
+#include "SSLSessionTicket.h"
#include "SSLDynlock.h"
#include "SSLDiags.h"
#include "SSLStats.h"
@@ -59,10 +60,6 @@
#include <openssl/evp.h>
#endif
-#if HAVE_OPENSSL_HMAC_H
-#include <openssl/hmac.h>
-#endif
-
#if HAVE_OPENSSL_TS_H
#include <openssl/ts.h>
#endif
@@ -130,16 +127,7 @@ struct ssl_user_config {
SSLSessionCache *session_cache; // declared extern in P_SSLConfig.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 HAVE_OPENSSL_SESSION_TICKETS 1
-
-static void session_ticket_free(void *, void *, CRYPTO_EX_DATA *, int, long,
void *);
-static int ssl_callback_session_ticket(SSL *, unsigned char *, unsigned char
*, EVP_CIPHER_CTX *, HMAC_CTX *, int);
-#endif /* SSL_CTX_set_tlsext_ticket_key_cb */
-
-#if HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAVE_OPENSSL_SESSION_TICKETS
static int ssl_session_ticket_index = -1;
#endif
@@ -376,7 +364,7 @@ set_context_cert(SSL *ssl)
if (ctx != nullptr) {
SSL_set_SSL_CTX(ssl, ctx);
-#if HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAVE_OPENSSL_SESSION_TICKETS
// Reset the ticket callback if needed
SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_callback_session_ticket);
#endif
@@ -714,7 +702,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 HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAVE_OPENSSL_SESSION_TICKETS
ssl_ticket_key_block *keyblock = nullptr;
keyblock = ssl_create_ticket_keyblock(ticket_key_path);
@@ -736,10 +724,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 /* !HAVE_OPENSSL_SESSION_TICKETS */
+#else /* !TS_HAVE_OPENSSL_SESSION_TICKETS */
(void)ticket_key_path;
return nullptr;
-#endif /* HAVE_OPENSSL_SESSION_TICKETS */
+#endif /* TS_HAVE_OPENSSL_SESSION_TICKETS */
}
struct passphrase_cb_userdata {
@@ -1015,8 +1003,8 @@ SSLInitializeLibrary()
CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_callback);
}
-#ifdef SSL_CTX_set_tlsext_ticket_key_cb
- ssl_session_ticket_index = SSL_CTX_get_ex_new_index(0, nullptr, nullptr,
nullptr, session_ticket_free);
+#ifdef TS_HAVE_OPENSSL_SESSION_TICKETS
+ ssl_session_ticket_index = SSL_CTX_get_ex_new_index(0, nullptr, nullptr,
nullptr, ssl_session_ticket_free);
if (ssl_session_ticket_index == -1) {
SSLError("failed to create session ticket index");
}
@@ -1705,7 +1693,7 @@ ssl_store_ssl_context(const SSLConfigParams *params,
SSLCertLookup *lookup, cons
}
}
if (!inserted) {
-#if HAVE_OPENSSL_SESSION_TICKETS
+#if TS_HAVE_OPENSSL_SESSION_TICKETS
if (keyblock != nullptr) {
ticket_block_free(keyblock);
}
@@ -1879,83 +1867,6 @@ SSLParseCertificateConfiguration(const SSLConfigParams
*params, SSLCertLookup *l
return true;
}
-#if HAVE_OPENSSL_SESSION_TICKETS
-
-static void
-session_ticket_free(void * /*parent*/, void *ptr, CRYPTO_EX_DATA * /*ad*/, int
/*idx*/, long /*argl*/, void * /*argp*/)
-{
- ticket_block_free((struct ssl_ticket_key_block *)ptr);
-}
-
-/*
- * RFC 5077. Create session ticket to resume SSL session without requiring
session-specific state at the TLS server.
- * Specifically, it distributes the encrypted session-state information to the
client in the form of a ticket and
- * a mechanism to present the ticket back to the server.
- * */
-static int
-ssl_callback_session_ticket(SSL *ssl, unsigned char *keyname, unsigned char
*iv, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hctx,
- int enc)
-{
- SSLCertificateConfig::scoped_config lookup;
- SSLTicketKeyConfig::scoped_config params;
- SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
-
- // Get the IP address to look up the keyblock
- IpEndpoint ip;
- int namelen = sizeof(ip);
- SSLCertContext *cc = nullptr;
- if (0 == safe_getsockname(netvc->get_socket(), &ip.sa, &namelen)) {
- cc = lookup->find(ip);
- }
- ssl_ticket_key_block *keyblock = nullptr;
- if (cc == nullptr || cc->keyblock == nullptr) {
- // Try the default
- keyblock = params->default_global_keyblock;
- } else {
- keyblock = cc->keyblock;
- }
- ink_release_assert(keyblock != nullptr && keyblock->num_keys > 0);
-
- if (enc == 1) {
- 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);
- HMAC_Init_ex(hctx, most_recent_key.hmac_secret,
sizeof(most_recent_key.hmac_secret), evp_md_func, nullptr);
-
- Debug("ssl", "create ticket for a new session.");
- SSL_INCREMENT_DYN_STAT(ssl_total_tickets_created_stat);
- return 1;
- } else if (enc == 0) {
- 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);
- HMAC_Init_ex(hctx, keyblock->keys[i].hmac_secret,
sizeof(keyblock->keys[i].hmac_secret), evp_md_func, nullptr);
-
- Debug("ssl", "verify the ticket for an existing session.");
- // Increase the total number of decrypted tickets.
- SSL_INCREMENT_DYN_STAT(ssl_total_tickets_verified_stat);
-
- if (i != 0) { // The number of tickets decrypted with "older" keys.
- SSL_INCREMENT_DYN_STAT(ssl_total_tickets_verified_old_key_stat);
- }
-
- SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
- netvc->setSSLSessionCacheHit(true);
- // When we decrypt with an "older" key, encrypt the ticket again with
the most recent key.
- return (i == 0) ? 1 : 2;
- }
- }
-
- Debug("ssl", "keyname is not consistent.");
- SSL_INCREMENT_DYN_STAT(ssl_total_tickets_not_found_stat);
- return 0;
- }
-
- return -1;
-}
-#endif /* HAVE_OPENSSL_SESSION_TICKETS */
-
// Release SSL_CTX and the associated data. This works for both
// client and server contexts and gracefully accepts nullptr.
void