fix: prevent inbound QUIC connections without peer certifate verification#1346
Open
sumanjeet0012 wants to merge 1 commit into
Open
fix: prevent inbound QUIC connections without peer certifate verification#1346sumanjeet0012 wants to merge 1 commit into
sumanjeet0012 wants to merge 1 commit into
Conversation
…rtificate verification
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong?
Fixes #1345
Inbound QUIC connections were being accepted and promoted to the application callback even when the remote client sent no peer certificate. This was an authentication bypass on the official QUIC listener path, allowing unauthenticated connections to appear legitimate.
The root cause involved a combination of
aioquicdefault behavior and libp2p security requirements:py-libp2p,verify_modeis intentionally set tossl.CERT_NONEso thataioquicdoes not validate self-signed libp2p certificates against the system CA store. We perform manual libp2p peer identity verification insideconnection.pyinstead.verify_modeisCERT_NONE,aioquic's TLS context (quic_conn.tls) defaults to_request_client_certificate = False.quic_conn.tls._request_client_certificate = Trueafter callingreceive_datagramon the initial packet.receive_datagramparses the initial datagram and synchronously processes the TLSClientHello, generating and sending theServerHello. Since our flag was not set yet, theServerHelloomitted theCertificateRequestblock.connection.pysilently returnedNonewhen_peer_certificatewas missing, failing open and invoking the user handler with an unauthenticated connection.What changed?
libp2p/transport/quic/connection.py_verify_peer_identity_with_securitynow explicitly raisesQUICPeerVerificationErrorwhen no peer certificate is present on an inbound (server-side) connection.None) since the client may not always have the remote cert immediately.get_peer_certificateto extract the certificate directly from the TLS context for early access before background tasks have flagged_handshake_completed.libp2p/transport/quic/listener.pyServerQuicConnectionsubclass ofaioquic'sQuicConnectionto cleanly hook into TLS initialization.aioquicinstantiates the TLS context internally inside a private_initialize()method on the very first datagram, right before it generates theServerHello. We override_initializeto immediately flipself.tls._request_client_certificate = Trueas soon as the context is created. This ensures theServerHelloaccurately includes theCertificateRequestblock._initializefrom the outside breaksaioquic's internal "first packet" state machine handling for internal variables like_versionand_network_paths._promote_pending_connection: inbound connections with no peer certificate are explicitly rejected and closed without invoking the user handler.connections_rejectedis correctly incremented.To-Do