maskit commented on code in PR #13072:
URL: https://github.com/apache/trafficserver/pull/13072#discussion_r3054654273
##########
plugins/experimental/jax_fingerprint/ja4/tls_client_hello_summary.cc:
##########
@@ -22,91 +22,178 @@
*/
+#include "ts/ts.h"
+#include <plugin.h>
#include "ja4.h"
-#include <algorithm>
-#include <array>
+#include "tls_client_hello_summary.h"
+
+#include <openssl/sha.h>
#include <cstdint>
-#include <functional>
-#include <vector>
-namespace
+TLSClientHelloSummary::TLSClientHelloSummary(ja4::Datasource::Protocol
protocol, TSClientHello ch) : _ch(ch)
{
+ const uint8_t *buf;
+ size_t buflen;
+
+ // Protocol
+ this->_protocol = protocol;
+
+ // Version
+ if (TS_SUCCESS == TSClientHelloExtensionGet(this->_ch,
EXT_SUPPORTED_VERSIONS, &buf, &buflen)) {
+ uint16_t max_version{0};
+ size_t versions_len = buf[0];
+
+ if (buflen < versions_len + 1) {
+ Dbg(dbg_ctl, "Malformed supported_versions extension (truncated
vector)... using legacy version.");
+ this->_version = this->_ch.get_version();
+ } else {
+ for (size_t i = 1; (i + 1) < (versions_len + 1); i += 2) {
+ uint16_t version = (buf[i] << 8) | buf[i + 1];
+ if (!this->_is_GREASE(version) && version > max_version) {
+ max_version = version;
+ }
+ }
+ this->_version = max_version;
+ }
+ } else {
+ Dbg(dbg_ctl, "No supported_versions extension... using legacy version.");
+ this->_version = this->_ch.get_version();
+ }
-constexpr std::array<std::uint16_t, 16> GREASE_values{0x0a0a, 0x1a1a, 0x2a2a,
0x3a3a, 0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a,
- 0x8a8a, 0x9a9a, 0xaaaa,
0xbaba, 0xcaca, 0xdada, 0xeaea, 0xfafa};
-constexpr std::uint16_t extension_SNI{0x0};
-constexpr std::uint16_t extension_ALPN{0x10};
-
-} // end anonymous namespace
+ // Ciphers
+ buf = this->_ch.get_cipher_suites();
+ buflen = this->_ch.get_cipher_suites_len();
+
+ if (buflen / 2 <= MAX_CIPHERS_FOR_FAST_PATH) {
+ // Fast path
+ this->_ciphers = this->_fast_cipher_storage.data();
+ } else {
+ // Slow path
+ this->_slow_cipher_storage = std::make_unique<uint16_t[]>(buflen / 2);
+ this->_ciphers = this->_slow_cipher_storage.get();
+ }
+ for (size_t i = 0; i + 1 < buflen; i += 2) {
+ uint16_t cipher = (static_cast<uint16_t>(buf[i]) << 8) + buf[i + 1];
+ if (this->_is_GREASE(cipher)) {
+ continue;
+ }
+ this->_ciphers[++this->_n_ciphers] = cipher;
+ }
+ std::sort(this->_ciphers, this->_ciphers + this->_n_ciphers);
-static bool is_ignored_non_GREASE_extension(std::uint16_t extension);
+ // Extensions
+ auto count = 0;
+ for (auto &&type : this->_ch.get_extension_types()) {
+ (void)type;
+ ++count;
+ }
+ if (count <= MAX_EXTENSIONS_FOR_FAST_PATH) {
+ // Fast path
+ this->_extensions = this->_fast_extension_storage.data();
+ } else {
+ // Slow path
+ this->_slow_extension_storage = std::make_unique<uint16_t[]>(count);
+ this->_extensions = this->_slow_extension_storage.get();
+ }
+ for (auto &&type : this->_ch.get_extension_types()) {
+ if (type == EXT_SNI) {
+ this->_has_SNI = true;
+ continue;
+ }
+ if (type == EXT_ALPN) {
+ this->_has_ALPN = true;
+ continue;
+ }
+ if (this->_is_GREASE(type)) {
+ continue;
+ }
+ this->_extensions[++this->_n_extensions] = type;
+ }
+ std::sort(this->_extensions, this->_extensions + this->_n_extensions);
+}
-std::vector<std::uint16_t> const &
-JA4::TLSClientHelloSummary::get_ciphers() const
+std::string_view
+TLSClientHelloSummary::get_first_alpn()
{
- return this->_ciphers;
+ unsigned char const *buf{};
+ std::size_t buflen{};
+
+ if (TS_SUCCESS == TSClientHelloExtensionGet(this->_ch, EXT_ALPN, &buf,
&buflen)) {
+ // The first two bytes are a 16bit encoding of the total length.
+ unsigned char first_ALPN_length{buf[2]};
+ TSAssert(buflen > 4);
+ TSAssert(0 != first_ALPN_length);
+ return {reinterpret_cast<const char *>(&(buf[3])), first_ALPN_length};
Review Comment:
fixed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]