No prompt for client certificate when network.http.http3.enable=true
Categories
(Core :: Networking, defect, P2)
Tracking
()
People
(Reporter: peterpaul2k12, Unassigned)
References
(Blocks 1 open bug)
Details
(Whiteboard: [necko-triaged][necko-priority-next])
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:148.0) Gecko/20100101 Firefox/148.0
Steps to reproduce:
-
Open the browser and ensure network.http.http3.enable is set to true in about:config.
-
Access a web server that requires Client Certificate Authentication (mTLS) and supports HTTP/3
-
Attempt to load the page via HTTPS.
Actual results:
The UI does not trigger the certificate selection prompt, preventing the user from choosing a valid identity for the handshake. Disabling HTTP/3 (network.http.http3.enable = false) immediately restores the expected behavior and the prompt appears.
Expected results:
Even with HTTP/3 enabled, the browser should detect the server's request for a client certificate during the handshake. It should display the standard certificate picker dialog, allowing the user to select the appropriate certificate to complete the authentication, just as it does over HTTP/1.1 or HTTP/2.
Comment 1•3 months ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::Networking' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Comment 2•3 months ago
|
||
Bug Analysis: Bug 2027559 - No client certificate prompt with HTTP/3
Root Cause
The HTTP/3 (QUIC) path in Firefox never registers an SSL_GetClientAuthDataHook with NSS. This hook is what NSS calls when the server sends a TLS CertificateRequest message,
which is how servers request client certificates during mTLS.
In the HTTP/1.1 and HTTP/2 path (nsNSSIOLayer.cpp:1297), the hook is properly set up:
SSL_GetClientAuthDataHook(sslSock, clientAuthDataHook, infoObject);
This hook calls SSLGetClientAuthDataHook() in TLSClientAuthCertSelection.cpp:768, which triggers the whole client certificate selection UI flow.
In the HTTP/3 path, the TLS handshake is handled by neqo (the Rust QUIC library) via neqo-crypto. In neqo-crypto/src/agent.rs, only SSL_AuthCertificateHook is set up (for server
cert verification), but SSL_GetClientAuthDataHook is never called. Without this hook, when the server requests a client certificate, NSS has no way to select one and likely
sends an empty certificate message.
The Event Flow Gap
Looking at the event pipeline:
- neqo-transport ConnectionEvent has no client-cert-request event
- neqo-http3 Http3ClientEvent has no client-cert-request event
- neqo_glue (lib.rs) event mapping has no handling for client cert requests
- Http3Session::ProcessEvents has no case for client certificate requests
The only auth-related event is AuthenticationNeeded, which is for server certificate verification (the client verifying the server's cert), not for client certificate selection.
What Needs to Happen
This is a multi-layer fix:
- neqo-crypto (agent.rs): Register SSL_GetClientAuthDataHook with NSS, and add a mechanism to surface "client certificate needed" to the caller (similar to
auth_required/authentication_needed) - neqo-transport (events.rs): Add a new ClientCertificateNeeded event to ConnectionEvent
- neqo-http3 (client_events.rs): Add a new ClientCertificateNeeded event to Http3ClientEvent
- neqo_glue (lib.rs): Map the new event from Http3ClientEvent to Http3Event
- Http3Session (Http3Session.cpp): Handle the new event by triggering client cert selection via QuicSocketControl/NSSSocketControl, similar to how SSLGetClientAuthDataHook
works for HTTP/2 - Wire up the callback so that once the user selects a cert, it gets provided back to neqo/NSS
Description
•