Before the PXY-7002 fix, tungsten read the client's TLS ClientHello into a 4096-byte buffer.
A CONNECT tunnel whose ClientHello record was larger got a 200 and then a closed socket.
In production the large hellos come from resumed mutual-TLS sessions: the server puts the
client certificate in the session ticket, and the browser sends the ticket back in every later ClientHello.
The first visit works (a full handshake has a small hello); every resumed connection fails.
This page reproduces that. The caesium [mtls] listener asks for a client certificate and
resumes sessions with tickets that carry the certificate. Install one of the test certificates below; its
size sets the size of the resumed ClientHello. Then run the probes: each one is a new connection
(Connection: close), so after the first one the browser resumes with the large ticket.
https://sso.caesium.menlotest.com:8448, uses sso.caesium.menlotest.com, which is already
in tungsten's passthrough_domains: no tungsten setup is needed.PKCS#12 password: caesium. The .pem files hold the certificate and the
key for curl or openssl. These are throw-away test identities; the listener accepts any client certificate.
| Profile | Certificate size | Download | Expected result through tungsten |
|---|---|---|---|
| small | 454 bytes | small.p12 · small.pem | Control. The resumed hello stays under 4096 bytes, so every tungsten version passes it. |
| medium | 6002 bytes | medium.p12 · medium.pem | The PXY-7002 case (about 8 KB). Tungsten without the fix drops the resumed connections; tungsten with the fix passes them. |
| large | 13003 bytes | large.p12 · large.pem | Near the 16,384-byte single-record limit. Tungsten with the fix passes it. |
| split | 18003 bytes | split.p12 · split.pem | Above 16,384 bytes: the browser splits the hello across TLS records. Tungsten does not support that and closes the connection, even with the PXY-7002 fix. |
The resumed ClientHello is about the certificate size plus 2 KB (the browser's normal hello and the ticket overhead). The probe table shows the exact size.
.p12 file. The Certificate Import Wizard starts.caesium. Next..p12 file. Keychain Access opens.caesium.chrome://certificate-manager, go to your client certificates, and choose
Import. Select the .p12 file and enter the password caesium.pk12util -d sql:$HOME/.pki/nssdb -i caesium-pxy7002-medium.p12 -W caesium.p12 file → password
caesium.On the first probe the browser asks which certificate to send. Choose caesium PXY-7002 test client (…) (in Firefox, also tick Remember this decision).
Switching profiles: the browser keeps the chosen certificate and the session
ticket for the host until it restarts. Restart the browser (in Chrome: chrome://restart) before you
try another profile. Removing: delete the caesium PXY-7002 test client entries in the
same certificate manager (macOS: search for caesium in Keychain Access).
| # | Result | Handshake | TLS | Client certificate | First record | ClientHello | Spans records |
|---|
Directly to caesium (no proxy) every probe passes; use that as the baseline. Through tungsten, the first probe is normally a full handshake and the rest resume. A browser that still holds a ticket from an earlier run resumes on the first probe too.
As caesium saw the connection that loaded this page. Only the [mtls] listener
requests certificates and resumes sessions.
{
"mtls_listener": false,
"tls_version": "TLS 1.3",
"resumed": false,
"client_cert": null,
"client_hello": {
"record_len": 261,
"message_len": 261,
"spans_records": false
}
}