feat(tls): add key_exchange field to expose negotiated key exchange group#946
feat(tls): add key_exchange field to expose negotiated key exchange group#946usernametooshort wants to merge 1 commit intoprojectdiscovery:mainfrom
Conversation
…roup
In TLS 1.3 the cipher suite name (e.g. TLS_AES_128_GCM_SHA256) no
longer encodes the key agreement mechanism — it is negotiated via the
supported_groups extension and reported in ConnectionState.CurveID
(populated from Go 1.24+).
Without this field, tlsx cannot distinguish:
- X25519 (classical key exchange)
- X25519MLKEM768 (post-quantum, already default in Chrome + Cloudflare)
- CurveP256 / CurveP384 / CurveP521
This matters for auditing post-quantum readiness (FIPS 203 / ML-KEM) and
for detecting servers that only support older EC curves.
Changes:
- clients.go: add KeyExchange string field with json tag key_exchange
- tls/tls.go (ctls): read connectionState.CurveID after the handshake
and call .String() to get the human-readable group name
ztls (zcrypto) does not expose the selected key exchange group in its
ServerHello log structure and is TLS 1.2-only, so it is unchanged.
Closes projectdiscovery#935
Neo - PR Security ReviewNo security issues found Highlights
Comment |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughA new Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #935
What
Adds a new
key_exchangefield to the JSON output that reports the negotiated key exchange group after the TLS handshake (e.g.X25519,X25519MLKEM768,CurveP256).Why
In TLS 1.3 the cipher suite name no longer encodes the key agreement mechanism — both X25519 (classical) and X25519MLKEM768 (post-quantum) report the same
TLS_AES_128_GCM_SHA256. TheCurveIDfield in Go’sConnectionState(populated from Go 1.24+) is the only way to tell them apart.This matters for:
X25519MLKEM768, CurveID 4588)CurveP256only)Example output
{ "host": "cloudflare.com", "tls_version": "tls13", "cipher": "TLS_AES_128_GCM_SHA256", "key_exchange": "X25519MLKEM768" }Implementation
clients/clients.go: addsKeyExchange string \json:"key_exchange,omitempty"`toResponse`pkg/tlsx/tls/tls.go(ctls): readsconnectionState.CurveIDand calls.String()after the handshakeztls (zcrypto) does not expose the selected key exchange group in its
ServerHellolog structure and is TLS 1.2-only — left unchanged.Summary by CodeRabbit
Release Notes