utls: [BUG] (Fake|Utls)PreSharedKeyExtension
I noticed while trying to implement / understand implementing a PSK for UtlsPreSharedKeyExtension on ClientHelloSpec i ran into a weird problem… so i started looking at full raw bytes from wireshark for a full client hello replication , the PSK is not actually populated and errors out , im not sure if this due to the recent change with fakePSK to UtlsPreSharedKeyExtension
empty psk detected; remove the psk extension for this connection or set OmitEmptyPsk to true to conceal it in utls
1603010200010001fc0303cee3cca75d5c385f42d7389f48cf75535b403d58159fecdfdf8ef276bf97deba20a581ab3a59648aead9f3a8715e523c82bee686636cf76c50226295badba9e2ee0020aaaa130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f003501000193aaaa0000000500050100000000ff0100010000230000000b00020100000d0012001004030804040105030805050108060601001200000010000e000c02683208687474702f312e310033002b00299a9a000100001d00203fcef7f05620d78f9aee265cee94d71e0ced2e692532c18f7cdb6add0055a22d446900050003026832001b000302000200170000000a000a00089a9a001d00170018002d0002010100000010000e00000b746c732e706565742e7773002b000706fafa03040303caca0001000015002c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029009c00770071854aabbb2c615e18010431cde6cd36b8e5184aab74d3f8e663befea450d68633ad4fbdf8d14a1e2790e04a3434806eea98e7a33fe5c2c5e74c44dba77c7b1da3e475b9fd6345eb5ad557002f95f36f771a40736de379b4cfe741d351d4121963f35abbd4b4c1a2c1c25e234ab30cb2b786857cf5e6002120ff98ad8e80d2b6d6d2f3e3ab73a5447afe9b79cb9e143aaac613b671b1910d58
This occurs if RealPSKResumption is true or false
About this issue
- Original URL
- State: closed
- Created 9 months ago
- Comments: 30 (30 by maintainers)
Commits related to this issue
- fix: Reuse existing PreSharedKeyExtension bug (#248) — committed to VeNoMouS/utls by VeNoMouS 9 months ago
- fix: default PreSharedKeyExtension bug (#248) (#251) — committed to refraction-networking/utls by VeNoMouS 9 months ago
There appears to be a bug/typo, which I’ll clarify. In short, the bug is in newSessionController, where we should set these to nil: https://github.com/refraction-networking/utls/blob/df6e4c827aa5895583d53e9ccc5139077af27786/u_session_controller.go#L57-L58
The
SessionControllerwas designed to manage all session-related operations. Initially, it had ownership over extensions.But this posed a challenge. The ClientHelloSpec might have a different set of PSK/Session extensions. For clarity, the original design had the
SessionControllertake charge of the extensions, overwriting those from the spec. This leads to the design thatnewSessionControllerproduces a non-nil session and a psk extension. A downside of this approach was that it altered the signature of a public method, and we didn’t have a clear vision for v2.0 yet.To circumvent this, I pivoted to a strategy where the Spec owns the extensions, ensuring the method signature remains unchanged. However, users should be able to override psk/session extensions before invoking
ApplyPreset. These overriding extensions should exclusively reside in theSessionController. In such cases, theSessionControllerhave ownership over the extensions.This necessitated the creation of the
syncSessionExtsmethod to discern which extension takes precedence. The guiding principle is straightforward:Yet, during this overhaul, I overlooked the
newSessionControllermethod. As illustrated in the comments, deep in my mind I believe that the extension would default to nil unless overridden by the user: https://github.com/refraction-networking/utls/blob/df6e4c827aa5895583d53e9ccc5139077af27786/u_session_controller.go#L271-L273Sorry about the delay in getting a PR sorted… life and all that 😄
@VeNoMouS No problem! Thanks for your efforts!
Ok, i’ll dive deeper into
FakePreSharedKeyExtensionand see if i can fix what ever is broken with it (if a PSK is present) … 🤞To clarify on the intended behaviors:
RealPSKResumptionis set to true: parsing from raw bytes will discard the ticket and binders from the raw bytes, but use the available ones fromClientSessionCacheinstead.RealPSKResumptionis false: parsing from raw bytes with legitimate PSK tickets and binders IS GUARANTEED TO FAIL, given that:Interesting observation. I don’t believe we are ready to parse raw byte ClientHello into PSK yet. On the other hand it is theoretically not possible to resume the connection with just the PSK ticket and binder from raw bytes.
That said, it might worth debugging and fixing to make at least FakePreSharedKeyExtension work with raw bytes. But note that in the end, unexpected things would happen, such as server rejecting you for submitting a valid ticket with an incorrect binder, etc.
Tagging @3andne for visibility.