#define SSL_EV_CONN_SWITCHCTX_CB (1ULL << 12)
#define SSL_EV_CONN_CHOOSE_SNI_CTX (1ULL << 13)
#define SSL_EV_CONN_SIGALG_EXT (1ULL << 14)
+#define SSL_EV_CONN_CIPHERS_EXT (1ULL << 15)
+
+
+#define SSL_VERB_CLEAN 1
+#define SSL_VERB_MINIMAL 2
+#define SSL_VERB_SIMPLE 3
+#define SSL_VERB_ADVANCED 4
+#define SSL_VERB_COMPLETE 5
#define TRACE_SOURCE &trace_ssl
TRACE_DEVEL("Sigalg parsing: has_rsa_sig (default)", SSL_EV_CONN_SWITCHCTX_CB, conn);
has_rsa_sig = 1;
}
+
+ if ((TRACE_SOURCE)->verbosity > SSL_VERB_ADVANCED &&
+ TRACE_ENABLED(TRACE_LEVEL_DATA, SSL_EV_CONN_CIPHERS_EXT, conn, 0, 0, 0)) {
+ const uint8_t *cipher_suites;
+ size_t len;
+
+#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+ len = ctx->cipher_suites_len;
+ cipher_suites = ctx->cipher_suites;
+#else
+ len = SSL_client_hello_get0_ciphers(ssl, &cipher_suites);
+#endif
+ TRACE_DATA("Ciphers value", SSL_EV_CONN_CIPHERS_EXT, conn, ssl, cipher_suites, &len);
+ }
+
if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
const SSL_CIPHER *cipher;
STACK_OF(SSL_CIPHER) *ha_ciphers; /* haproxy side ciphers */
{ .mask = SSL_EV_CONN_SWITCHCTX_CB, .name = "sslc_switchctx_cb", .desc = "SSL switchctx callback"},
{ .mask = SSL_EV_CONN_CHOOSE_SNI_CTX, .name = "sslc_choose_sni_ctx", .desc = "SSL choose sni context"},
{ .mask = SSL_EV_CONN_SIGALG_EXT, .name = "sslc_sigalg_ext", .desc = "SSL sigalg extension parsing"},
+ { .mask = SSL_EV_CONN_CIPHERS_EXT, .name = "sslc_ciphers_ext", .desc = "SSL ciphers extension parsing"},
{ }
};
};
static const struct name_desc ssl_trace_decoding[] = {
-#define SSL_VERB_CLEAN 1
{ .name="clean", .desc="only user-friendly stuff, generally suitable for level \"user\"" },
-#define SSL_VERB_MINIMAL 2
{ .name="minimal", .desc="report only conn, no real decoding" },
-#define SSL_VERB_SIMPLE 3
{ .name="simple", .desc="add error messages" },
-#define SSL_VERB_ADVANCED 4
{ .name="advanced", .desc="add handshake-related details" },
-#define SSL_VERB_COMPLETE 5
{ .name="complete", .desc="add full data dump when available" },
{ /* end */ }
};
}
}
}
+
+ if (mask & SSL_EV_CONN_CIPHERS_EXT && src->verbosity > SSL_VERB_ADVANCED) {
+ if (a2 && a3 && a4) {
+ SSL *ssl = (SSL*)a2;
+ const uint16_t *extension_data = a3;
+ size_t extension_len = *((size_t*)a4);
+ int first = 1;
+
+ chunk_appendf(&trace_buf, " value=");
+
+ while (extension_len > 1) {
+ const char *str;
+ const SSL_CIPHER *cipher;
+ uint16_t id = ntohs(*extension_data);
+#if defined(OPENSSL_IS_BORINGSSL)
+ cipher = SSL_get_cipher_by_value(id);
+#else
+ cipher = SSL_CIPHER_find(ssl, (unsigned char*)extension_data);
+#endif
+ str = SSL_CIPHER_get_name(cipher);
+ if (!str || strcmp(str, "(NONE)") == 0)
+ chunk_appendf(&trace_buf, "%sUNKNOWN(%04x)", first ? "" : ",", id);
+ else
+ chunk_appendf(&trace_buf, "%s%s", first ? "" : ",", str);
+
+ first = 0;
+
+ extension_len-=sizeof(*extension_data);
+ ++extension_data;
+ }
+ }
+ }
}