You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2021/07/20 22:07:01 UTC
[trafficserver] branch 9.1.x updated: Adds OCSP support for
BoringSSL (#7298)
This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 9.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/9.1.x by this push:
new 3f53b15 Adds OCSP support for BoringSSL (#7298)
3f53b15 is described below
commit 3f53b15c7c07b137d26d2e230b47522ca2e4e74b
Author: Randall Meyer <rr...@apache.org>
AuthorDate: Tue Jul 20 10:19:27 2021 -0700
Adds OCSP support for BoringSSL (#7298)
Requires the external library boringocsp
(cherry picked from commit 5ddb462ea18603cba7b515c22d0b32bf94f50ac3)
---
build/boringocsp.m4 | 88 +++++++++++++++++++++++++++++++++++++++++
configure.ac | 3 ++
include/tscore/ink_config.h.in | 2 +
iocore/net/Makefile.am | 1 +
iocore/net/OCSPStapling.cc | 60 ++++++++++++++++++++++++----
iocore/net/P_OCSPStapling.h | 11 ++++++
src/traffic_quic/Makefile.inc | 4 +-
src/traffic_server/Makefile.inc | 7 +++-
8 files changed, 165 insertions(+), 11 deletions(-)
diff --git a/build/boringocsp.m4 b/build/boringocsp.m4
new file mode 100644
index 0000000..40fe3ac
--- /dev/null
+++ b/build/boringocsp.m4
@@ -0,0 +1,88 @@
+dnl -------------------------------------------------------- -*- autoconf -*-
+dnl Licensed to the Apache Software Foundation (ASF) under one or more
+dnl contributor license agreements. See the NOTICE file distributed with
+dnl this work for additional information regarding copyright ownership.
+dnl The ASF licenses this file to You under the Apache License, Version 2.0
+dnl (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
+
+dnl
+dnl TS_CHECK_BORINGOCSP: look for boringocsp libraries and headers
+dnl
+AC_DEFUN([TS_CHECK_BORINGOCSP], [
+has_boringocsp=no
+AC_ARG_WITH(boringocsp, [AS_HELP_STRING([--with-boringocsp=DIR], [use a specific BoringOCSP library])],
+[
+ if test "x$withval" != "xyes" && test "x$withval" != "x"; then
+ boringocsp_base_dir="$withval"
+ if test "$withval" != "no"; then
+ has_boringocsp=1
+ use_tls_ocsp=1
+ case "$withval" in
+ *":"*)
+ boringocsp_include="`echo $withval |sed -e 's/:.*$//'`"
+ boringocsp_ldflags="`echo $withval |sed -e 's/^.*://'`"
+ AC_MSG_CHECKING(checking for boringocsp includes in $boringocsp_include libs in $boringocsp_ldflags)
+ ;;
+ *)
+ boringocsp_include="$withval"
+ boringocsp_ldflags="$withval"
+ boringocsp_base_dir="$withval"
+ AC_MSG_CHECKING(boringocsp includes in $withval libs in $boringocsp_ldflags)
+ ;;
+ esac
+ fi
+ fi
+
+ if test -d $boringocsp_include && test -d $boringocsp_ldflags && test -f $boringocsp_include/ocsp.h; then
+ AC_MSG_RESULT([ok])
+ else
+ AC_MSG_RESULT([not found])
+ fi
+ AC_SUBST(use_boringocsp)
+
+if test "$has_boringocsp" != "0"; then
+ saved_ldflags=$LDFLAGS
+ saved_cppflags=$CPPFLAGS
+
+ BORINGOCSP_LIBS=-lboringocsp
+ if test "$boringocsp_base_dir" != "/usr"; then
+ BORINGOCSP_INCLUDES=-I${boringocsp_include}
+ BORINGOCSP_LDFLAGS=-L${boringocsp_ldflags}
+
+ TS_ADDTO_RPATH(${boringocsp_ldflags})
+ fi
+
+ if test "$boringocsp_include" != "0"; then
+ BORINGOCSP_INCLUDES=-I${boringocsp_include}
+ else
+ has_boringocsp=0
+ use_tls_ocsp=0
+ CPPFLAGS=$saved_cppflags
+ LDFLAGS=$saved_ldflags
+ fi
+fi
+],
+[
+ has_boringocsp=0
+ # we might be non-boringssl, don't disable if test has previously passed
+ if test "$use_tls_ocsp" != "1"; then
+ use_tls_ocsp=0
+ fi
+])
+
+AC_SUBST(has_boringocsp)
+AC_SUBST(use_tls_ocsp)
+AC_SUBST([BORINGOCSP_INCLUDES])
+AC_SUBST([BORINGOCSP_LIBS])
+AC_SUBST([BORINGOCSP_LDFLAGS])
+
+])
diff --git a/configure.ac b/configure.ac
index c01847f..86caa66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1454,6 +1454,9 @@ AM_CONDITIONAL([BUILD_YAML_CPP], [test x"$has_yaml_cpp" = x"no"])
TS_CHECK_YAML_HEADERS_EXPORT
AM_CONDITIONAL([EXPORT_YAML_HEADERS], [test x"$enable_yaml_headers" = x"yes"])
+# Check for optional boringocsp library
+TS_CHECK_BORINGOCSP
+
# Check for optional hiredis library
TS_CHECK_HIREDIS
diff --git a/include/tscore/ink_config.h.in b/include/tscore/ink_config.h.in
index 8d0740c..1832418 100644
--- a/include/tscore/ink_config.h.in
+++ b/include/tscore/ink_config.h.in
@@ -84,6 +84,8 @@
#define TS_USE_HRW_GEOIP @use_hrw_geoip@
#define TS_USE_HRW_MAXMINDDB @use_hrw_maxminddb@
+#define TS_HAS_BORINGOCSP @has_boringocsp@
+
#define TS_HAS_SO_PEERCRED @has_so_peercred@
/* OS API definitions */
diff --git a/iocore/net/Makefile.am b/iocore/net/Makefile.am
index 34d9fff..ad55406 100644
--- a/iocore/net/Makefile.am
+++ b/iocore/net/Makefile.am
@@ -33,6 +33,7 @@ AM_CPPFLAGS += \
-I$(abs_top_srcdir)/proxy/http \
$(TS_INCLUDES) \
@OPENSSL_INCLUDES@ \
+ @BORINGOCSP_INCLUDES@ \
@YAMLCPP_INCLUDES@
TESTS = $(check_PROGRAMS)
diff --git a/iocore/net/OCSPStapling.cc b/iocore/net/OCSPStapling.cc
index 7c39d2b..252fda1 100644
--- a/iocore/net/OCSPStapling.cc
+++ b/iocore/net/OCSPStapling.cc
@@ -20,11 +20,18 @@
*/
#include "P_OCSPStapling.h"
+
#if TS_USE_TLS_OCSP
#include <openssl/bio.h>
#include <openssl/ssl.h>
+
+#if TS_HAS_BORINGOCSP
+#include <boringocsp/ocsp.h>
+#else
#include <openssl/ocsp.h>
+#endif
+
#include "P_Net.h"
#include "P_SSLConfig.h"
#include "P_SSLUtils.h"
@@ -214,6 +221,7 @@ ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname, const cha
cinf->expire_time = 0;
if (cinf->is_prefetched) {
+#ifndef OPENSSL_IS_BORINGSSL
Debug("ssl_ocsp", "using OCSP prefetched response file %s", rsp_file);
rsp_bio = BIO_new_file(rsp_file, "r");
if (rsp_bio) {
@@ -235,6 +243,9 @@ ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname, const cha
BIO_free(rsp_bio);
rsp_bio = nullptr;
}
+#else
+ Warning("failed to set prefetched OCSP response; this functionality not supported by BoringSSL");
+#endif
}
issuer = stapling_get_issuer(ctx, cert);
@@ -261,10 +272,14 @@ ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname, const cha
goto err;
}
+#ifdef OPENSSL_IS_BORINGSSL
+ X509_up_ref(cert);
+#endif
+
map->insert(std::make_pair(cert, cinf));
SSL_CTX_set_ex_data(ctx, ssl_stapling_index, map);
- Note("successfully initialized stapling for %s into SSL_CTX: %p", certname, ctx);
+ Note("successfully initialized stapling for %s into SSL_CTX: %p uri=%s", certname, ctx, cinf->uri);
return true;
err:
@@ -458,7 +473,7 @@ stapling_refresh_response(certinfo *cinf, OCSP_RESPONSE **prsp)
if (!stapling_cache_response(*prsp, cinf)) {
Error("stapling_refresh_response: can not cache response");
} else {
- Debug("ssl_ocsp", "stapling_refresh_response: successful refresh OCSP response");
+ Debug("ssl_ocsp", "stapling_refresh_response: successfully refreshed OCSP response");
}
goto done;
@@ -489,6 +504,7 @@ ocsp_update()
SSLCertificateConfig::scoped_config certLookup;
const unsigned ctxCount = certLookup->count();
+ Debug("ssl_ocsp", "updating OCSP data");
for (unsigned i = 0; i < ctxCount; i++) {
SSLCertContext *cc = certLookup->get(i);
if (cc) {
@@ -505,7 +521,7 @@ ocsp_update()
if (cinf->resp_derlen == 0 || cinf->is_expire || cinf->expire_time < current_time) {
ink_mutex_release(&cinf->stapling_mutex);
if (stapling_refresh_response(cinf, &resp)) {
- Debug("Successfully refreshed OCSP for %s certificate. url=%s", cinf->certname, cinf->uri);
+ Debug("ssl_ocsp", "Successfully refreshed OCSP for %s certificate. url=%s", cinf->certname, cinf->uri);
SSL_INCREMENT_DYN_STAT(ssl_ocsp_refreshed_cert_stat);
} else {
Error("Failed to refresh OCSP for %s certificate. url=%s", cinf->certname, cinf->uri);
@@ -523,7 +539,11 @@ ocsp_update()
// RFC 6066 Section-8: Certificate Status Request
int
+#ifndef OPENSSL_IS_BORINGSSL
ssl_callback_ocsp_stapling(SSL *ssl)
+#else
+ssl_callback_ocsp_stapling(SSL *ssl, void *)
+#endif
{
// Assume SSL_get_SSL_CTX() is the same as reaching into the ssl structure
// Using the official call, to avoid leaking internal openssl knowledge
@@ -533,18 +553,43 @@ ssl_callback_ocsp_stapling(SSL *ssl)
Debug("ssl_ocsp", "ssl_callback_ocsp_stapling: failed to get certificate map");
return SSL_TLSEXT_ERR_NOACK;
}
+
+ if (map->empty()) {
+ Debug("ssl_ocsp", "ssl_callback_ocsp_stapling: certificate map empty");
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+
// Fetch the specific certificate used in this negotiation
X509 *cert = SSL_get_certificate(ssl);
if (!cert) {
Error("ssl_callback_ocsp_stapling: failed to get certificate");
return SSL_TLSEXT_ERR_NOACK;
}
+
+ certinfo *cinf = nullptr;
+#ifndef OPENSSL_IS_BORINGSSL
certinfo_map::iterator iter = map->find(cert);
- if (iter == map->end()) {
- Error("ssl_callback_ocsp_stapling: failed to get certificate information");
+ if (iter != map->end()) {
+ cinf = iter->second;
+ }
+#else
+ for (certinfo_map::iterator iter = map->begin(); iter != map->end(); ++iter) {
+ X509 *key = iter->first;
+ if (key == nullptr) {
+ continue;
+ }
+
+ if (X509_cmp(key, cert) == 0) {
+ cinf = iter->second;
+ break;
+ }
+ }
+#endif
+
+ if (cinf == nullptr) {
+ Error("ssl_callback_ocsp_stapling: failed to get certificate information for ssl=%p", ssl);
return SSL_TLSEXT_ERR_NOACK;
}
- certinfo *cinf = iter->second;
ink_mutex_acquire(&cinf->stapling_mutex);
time_t current_time = time(nullptr);
@@ -554,10 +599,9 @@ ssl_callback_ocsp_stapling(SSL *ssl)
return SSL_TLSEXT_ERR_NOACK;
} else {
unsigned char *p = static_cast<unsigned char *>(OPENSSL_malloc(cinf->resp_derlen));
- unsigned int len = cinf->resp_derlen;
memcpy(p, cinf->resp_der, cinf->resp_derlen);
ink_mutex_release(&cinf->stapling_mutex);
- SSL_set_tlsext_status_ocsp_resp(ssl, p, len);
+ SSL_set_tlsext_status_ocsp_resp(ssl, p, cinf->resp_derlen);
Debug("ssl_ocsp", "ssl_callback_ocsp_stapling: successfully got certificate status for %s", cinf->certname);
return SSL_TLSEXT_ERR_OK;
}
diff --git a/iocore/net/P_OCSPStapling.h b/iocore/net/P_OCSPStapling.h
index fbee110..94d0faf 100644
--- a/iocore/net/P_OCSPStapling.h
+++ b/iocore/net/P_OCSPStapling.h
@@ -25,10 +25,21 @@
#if TS_USE_TLS_OCSP
#include <openssl/ssl.h>
+
+#if TS_HAS_BORINGOCSP
+#include <boringocsp/ocsp.h>
+#else
#include <openssl/ocsp.h>
+#endif
void ssl_stapling_ex_init();
bool ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname, const char *rsp_file);
void ocsp_update();
+
+#ifndef OPENSSL_IS_BORINGSSL
int ssl_callback_ocsp_stapling(SSL *);
+#else
+int ssl_callback_ocsp_stapling(SSL *, void *);
+#endif
+
#endif
diff --git a/src/traffic_quic/Makefile.inc b/src/traffic_quic/Makefile.inc
index c00faf0..4471569 100644
--- a/src/traffic_quic/Makefile.inc
+++ b/src/traffic_quic/Makefile.inc
@@ -37,7 +37,8 @@ traffic_quic_traffic_quic_CPPFLAGS = \
traffic_quic_traffic_quic_LDFLAGS = \
$(AM_LDFLAGS) \
- @OPENSSL_LDFLAGS@
+ @OPENSSL_LDFLAGS@ \
+ @BORINGOCSP_LDFLAGS@
traffic_quic_traffic_quic_SOURCES = \
traffic_quic/quic_client.cc \
@@ -60,5 +61,6 @@ traffic_quic_traffic_quic_LDADD = \
@HWLOC_LIBS@ \
@YAMLCPP_LIBS@ \
@OPENSSL_LIBS@ \
+ @BORINGOCSP_LIBS@ \
@LIBPCRE@
diff --git a/src/traffic_server/Makefile.inc b/src/traffic_server/Makefile.inc
index d189bd7..0e5f43c 100644
--- a/src/traffic_server/Makefile.inc
+++ b/src/traffic_server/Makefile.inc
@@ -35,11 +35,13 @@ traffic_server_traffic_server_CPPFLAGS = \
-I$(abs_top_srcdir)/mgmt \
-I$(abs_top_srcdir)/mgmt/utils \
$(TS_INCLUDES) \
- @OPENSSL_INCLUDES@
+ @OPENSSL_INCLUDES@ \
+ @BORINGOCSP_INCLUDES@
traffic_server_traffic_server_LDFLAGS = \
$(AM_LDFLAGS) \
- @YAMLCPP_LDFLAGS@
+ @YAMLCPP_LDFLAGS@ \
+ @BORINGOCSP_LDFLAGS@
traffic_server_traffic_server_SOURCES = \
traffic_server/Crash.cc \
@@ -87,6 +89,7 @@ traffic_server_traffic_server_LDADD = \
@LIBPROFILER@ \
@OPENSSL_LIBS@ \
@YAMLCPP_LIBS@ \
+ @BORINGOCSP_LIBS@ \
-lm
if IS_DARWIN