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