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 48af5b64bc Update cert compression reporting (#13197)
48af5b64bc is described below

commit 48af5b64bcdd8fce22d30923cdeb81979ab0c6a5
Author: Brian Neradt <[email protected]>
AuthorDate: Mon Jun 1 14:52:51 2026 -0500

    Update cert compression reporting (#13197)
    
    Some OpenSSL builds expose certificate-compression preference APIs while
    disabling the built-in compression algorithms. In that shape, ATS reported
    cert compression support based on API availability even though configured
    algorithms could not actually run.
    
    This reports certificate-compression support from the algorithms ATS can use
    in the selected OpenSSL API path, and skips the callback-only AuTest unless
    callbacks are available. This also makes the supported algorithm table
    contain only usable entries, so configuration fails cleanly when an
    unavailable algorithm is requested.
---
 src/iocore/net/TLSCertCompression.cc       | 91 ++++++++++++++++++------------
 src/traffic_layout/info.cc                 | 44 +++++++++++++--
 tests/gold_tests/tls/tls_cert_comp.test.py |  2 +-
 3 files changed, 96 insertions(+), 41 deletions(-)

diff --git a/src/iocore/net/TLSCertCompression.cc 
b/src/iocore/net/TLSCertCompression.cc
index 3b31d3e1be..90192990f3 100644
--- a/src/iocore/net/TLSCertCompression.cc
+++ b/src/iocore/net/TLSCertCompression.cc
@@ -31,7 +31,9 @@ namespace
 DbgCtl dbg_ctl_ssl_cert_compress{"ssl_cert_compress"};
 }
 
+#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG || 
HAVE_SSL_CTX_SET1_CERT_COMP_PREFERENCE
 constexpr unsigned int N_ALGORITHMS = 3;
+#endif
 
 #if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG
 #include "TLSCertCompression_zlib.h"
@@ -45,6 +47,9 @@ constexpr unsigned int N_ALGORITHMS = 3;
 #endif
 #endif
 
+#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG || 
HAVE_SSL_CTX_SET1_CERT_COMP_PREFERENCE
+namespace
+{
 struct alg_info {
   const char *name;
   int32_t     number;
@@ -53,70 +58,86 @@ struct alg_info {
   ssl_cert_decompression_func_t decompress_func;
 #endif
 } supported_algs[] = {
-  {"zlib",   1,
 #if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG
-   compression_func_zlib,   decompression_func_zlib
-#endif
-  },
+  {"zlib",   1, compression_func_zlib,   decompression_func_zlib  },
 #if HAVE_BROTLI_ENCODE_H
-  {"brotli", 2,
-#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG
-   compression_func_brotli, decompression_func_brotli
-#endif
-  },
+  {"brotli", 2, compression_func_brotli, decompression_func_brotli},
 #endif
 #if HAVE_ZSTD_H
-  {"zstd",   3,
-#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG
-   compression_func_zstd,   decompression_func_zstd
+  {"zstd",   3, compression_func_zstd,   decompression_func_zstd  },
+#endif
+  {nullptr,  0, nullptr,                 nullptr                  },
+#elif HAVE_SSL_CTX_SET1_CERT_COMP_PREFERENCE
+#if !defined(OPENSSL_NO_ZLIB)
+  {"zlib", 1},
 #endif
-  },
+#if !defined(OPENSSL_NO_BROTLI)
+  {"brotli", 2},
+#endif
+#if !defined(OPENSSL_NO_ZSTD)
+  {"zstd", 3},
+#endif
+  {nullptr, 0},
+#else
+  {nullptr, 0},
 #endif
 };
 
+alg_info const *
+find_algorithm(std::string const &name)
+{
+  for (auto const &alg : supported_algs) {
+    if (alg.name != nullptr && name == alg.name) {
+      return &alg;
+    }
+  }
+  return nullptr;
+}
+
+} // end anonymous namespace
+#endif
+
 int
 register_certificate_compression_preference(SSL_CTX *ctx, const 
std::vector<std::string> &specified_algs)
 {
   ink_assert(ctx != nullptr);
-  if (specified_algs.size() > N_ALGORITHMS) {
-    return 0;
-  }
-
   if (specified_algs.empty()) {
     return 1;
   }
 
 #if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG
-  for (auto &&alg : specified_algs) {
-    struct alg_info *info = nullptr;
+  if (specified_algs.size() > N_ALGORITHMS) {
+    return 0;
+  }
 
-    for (unsigned int i = 0; i < countof(supported_algs); ++i) {
-      if (strcmp(alg.c_str(), supported_algs[i].name) == 0) {
-        info = &supported_algs[i];
-      }
+  for (auto &&alg : specified_algs) {
+    auto const *info = find_algorithm(alg);
+    if (info == nullptr) {
+      Dbg(dbg_ctl_ssl_cert_compress, "Unsupported algorithm: %s", alg.c_str());
+      return 0;
     }
-    if (info != nullptr) {
-      if (SSL_CTX_add_cert_compression_alg(ctx, info->number, 
info->compress_func, info->decompress_func) == 0) {
-        return 0;
-      }
-      Dbg(dbg_ctl_ssl_cert_compress, "Enabled %s", info->name);
-    } else {
-      Dbg(dbg_ctl_ssl_cert_compress, "Unrecognized algorithm: %s", 
alg.c_str());
+    if (SSL_CTX_add_cert_compression_alg(ctx, info->number, 
info->compress_func, info->decompress_func) == 0) {
       return 0;
     }
+    Dbg(dbg_ctl_ssl_cert_compress, "Enabled %s", info->name);
   }
   return 1;
 #elif HAVE_SSL_CTX_SET1_CERT_COMP_PREFERENCE
+  if (specified_algs.size() > N_ALGORITHMS) {
+    return 0;
+  }
+
   int algs[N_ALGORITHMS];
   int n = 0;
 
   for (unsigned int i = 0; i < specified_algs.size(); ++i) {
-    for (unsigned int j = 0; j < countof(supported_algs); ++j) {
-      if (strcmp(specified_algs[i].c_str(), supported_algs[j].name) == 0) {
-        algs[n++] = supported_algs[j].number;
-        Dbg(dbg_ctl_ssl_cert_compress, "Enabled %s", supported_algs[j].name);
-      }
+    auto const *info = find_algorithm(specified_algs[i]);
+    if (info == nullptr) {
+      Dbg(dbg_ctl_ssl_cert_compress, "Unsupported algorithm: %s", 
specified_algs[i].c_str());
+      return 0;
     }
+    algs[n++] = info->number;
+    Dbg(dbg_ctl_ssl_cert_compress, "Enabled %s", info->name);
   }
   return SSL_CTX_set1_cert_comp_preference(ctx, algs, n);
 #else
diff --git a/src/traffic_layout/info.cc b/src/traffic_layout/info.cc
index d75393dd8c..e77c2926d3 100644
--- a/src/traffic_layout/info.cc
+++ b/src/traffic_layout/info.cc
@@ -23,6 +23,7 @@
 
 #include <fcntl.h>
 #include <openssl/crypto.h>
+#include <openssl/ssl.h>
 #include <swoc/BufferWriter.h>
 #include <swoc/bwf_base.h>
 #include "tscore/Layout.h"
@@ -53,6 +54,39 @@
 #include <zstd.h>
 #endif
 
+#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG
+static constexpr int ts_has_cert_compression_callbacks = 1;
+#else
+static constexpr int ts_has_cert_compression_callbacks = 0;
+#endif
+
+#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG
+static constexpr int ts_has_cert_compression_zlib = 1;
+#elif HAVE_SSL_CTX_SET1_CERT_COMP_PREFERENCE && !defined(OPENSSL_NO_ZLIB)
+static constexpr int ts_has_cert_compression_zlib = 1;
+#else
+static constexpr int ts_has_cert_compression_zlib = 0;
+#endif
+
+#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG && HAVE_BROTLI_ENCODE_H
+static constexpr int ts_has_cert_compression_brotli = 1;
+#elif !HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG && 
HAVE_SSL_CTX_SET1_CERT_COMP_PREFERENCE && !defined(OPENSSL_NO_BROTLI)
+static constexpr int ts_has_cert_compression_brotli = 1;
+#else
+static constexpr int ts_has_cert_compression_brotli = 0;
+#endif
+
+#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG && HAVE_ZSTD_H
+static constexpr int ts_has_cert_compression_zstd = 1;
+#elif !HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG && 
HAVE_SSL_CTX_SET1_CERT_COMP_PREFERENCE && !defined(OPENSSL_NO_ZSTD)
+static constexpr int ts_has_cert_compression_zstd = 1;
+#else
+static constexpr int ts_has_cert_compression_zstd = 0;
+#endif
+
+static constexpr int ts_has_cert_compression =
+  ts_has_cert_compression_zlib | ts_has_cert_compression_brotli | 
ts_has_cert_compression_zstd;
+
 // Produce output about compile time features, useful for checking how things 
were built
 static void
 print_feature(std::string_view name, int value, bool json, bool last = false)
@@ -100,11 +134,11 @@ produce_features(bool json)
 #else
   print_feature("TS_HAS_ZSTD", 0, json);
 #endif
-#if HAVE_SSL_CTX_ADD_CERT_COMPRESSION_ALG || 
HAVE_SSL_CTX_SET1_CERT_COMP_PREFERENCE
-  print_feature("TS_HAS_CERT_COMPRESSION", 1, json);
-#else
-  print_feature("TS_HAS_CERT_COMPRESSION", 0, json);
-#endif
+  print_feature("TS_HAS_CERT_COMPRESSION", ts_has_cert_compression, json);
+  print_feature("TS_HAS_CERT_COMPRESSION_CALLBACKS", 
ts_has_cert_compression_callbacks, json);
+  print_feature("TS_HAS_CERT_COMPRESSION_ZLIB", ts_has_cert_compression_zlib, 
json);
+  print_feature("TS_HAS_CERT_COMPRESSION_BROTLI", 
ts_has_cert_compression_brotli, json);
+  print_feature("TS_HAS_CERT_COMPRESSION_ZSTD", ts_has_cert_compression_zstd, 
json);
   print_feature("TS_HAS_CRIPTS", TS_HAS_CRIPTS, json);
 #ifdef F_GETPIPE_SZ
   print_feature("TS_HAS_PIPE_BUFFER_SIZE_CONFIG", 1, json);
diff --git a/tests/gold_tests/tls/tls_cert_comp.test.py 
b/tests/gold_tests/tls/tls_cert_comp.test.py
index 53d87c670b..0bb17e9095 100644
--- a/tests/gold_tests/tls/tls_cert_comp.test.py
+++ b/tests/gold_tests/tls/tls_cert_comp.test.py
@@ -24,7 +24,7 @@ with cert compression enabled. The test verifies compression 
and
 decompression succeed by checking the ssl cert compression metrics.
 '''
 
-Test.SkipUnless(Condition.HasATSFeature('TS_HAS_CERT_COMPRESSION'))
+Test.SkipUnless(Condition.HasATSFeature('TS_HAS_CERT_COMPRESSION_CALLBACKS'))
 
 REPLAY_FILE = 'replay/tls_cert_compression.replay.yaml'
 

Reply via email to