-
Notifications
You must be signed in to change notification settings - Fork 311
Muxer selection in security handshake #446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 51 commits
dbde5fd
a8804dd
ad1bae7
0d35e15
ec2e959
0042384
dcac239
245361c
a5b3ef0
349ac76
d6eb581
07f5d70
808a6f6
c7a1db0
811fc05
239dfca
f0fe69a
1c716e2
24d021d
5c28fc1
3e3394a
c6b8ed2
54379a9
06896c3
cc2bbcb
f81c6f4
0b73a38
aecfbb8
5192ad1
4ff74a7
f69b691
8e51f46
eb4e697
ef8657d
8296442
0fc4452
a11ff1d
b4ce114
9b11a68
002e37f
e3fcb38
4a167d1
3e9586b
f682f6b
c07fb79
1e7a3c0
eafbffc
1e52c1e
fe88ccf
da63658
1306199
bb070b2
d90a15e
447be1f
c23af93
6fe4166
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| # Stream multiplexer negotiation in security handshake | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
|
|
||
|
|
||
| | Lifecycle Stage | Maturity | Status | Latest Revision | | ||
| |-----------------|---------------|--------|-----------------| | ||
| | 1A | Working Draft | Active | r1, 2022-12-07 | | ||
|
|
||
| Authors: [@julian88110], [@marten-seemann] | ||
|
|
||
| Interest Group: [@marcopolo], [@mxinden] | ||
|
|
||
| [@marten-seemann]: https://github.com/marten-seemann | ||
| [@marcopolo]: https://github.com/marcopolo | ||
| [@mxinden]: https://github.com/mxinden | ||
| [@julian88110]: https://github.com/julian88110 | ||
|
|
||
| See the [lifecycle document][lifecycle-spec] for context about maturity level | ||
| and spec status. | ||
|
|
||
| [lifecycle-spec]: https://github.com/libp2p/specs/blob/master/00-framework-01-spec-lifecycle.md | ||
|
|
||
| ## Table of Contents | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
|
|
||
| - [multiplexer negotiation in security handshake](#multiplexer-negotiation-in-security-handshake) | ||
| - [Table of Contents](#table-of-contents) | ||
| - [Overview](#overview) | ||
| - [Design](#design) | ||
| - [Current connection upgrade process](#current-connection-upgrade-process) | ||
| - [Improved multiplexer negotiation](#improved-multiplexer-negotiation) | ||
| - [Multiplexer negotiation over TLS](#multiplexer-negotiation-over-tls) | ||
| - [Multiplexer negotiation over Noise](#multiplexer-negotiation-over-noise) | ||
| - [Security](#security) | ||
| - [Alternative options considered](#alternative-options-considered) | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Overview | ||
|
|
||
| Transports that don't support native stream multiplexing (e.g. TCP, WebSocket) negotiate | ||
| a stream multiplexer after completion of the cryptographic handshake, as described in [connections]. | ||
| Negotiating the stream multiplexer takes one network roundtrip. | ||
| This document defines a backwards-compatible optimization, which allows running the | ||
| multiplexer negotiation during the cryptographic handshake, thereby reducing the latency of | ||
| connection establishment by one roundtrip. | ||
|
|
||
|
|
||
| ## Design | ||
|
|
||
| ### Multiplexer Negotiation over TLS | ||
|
|
||
| When using TLS, the [ALPN] extension is used to negotiate the multiplexer. | ||
|
|
||
| The ALPN TLS extension allows the client to send a list of supported application | ||
| protocols as part of the TLS ClientHello message. The server chooses | ||
| a protocol and sends the selected protocol as part of the TLS | ||
| ServerHello message. | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
|
|
||
| For the purpose of multiplexer negotiation, the protocol IDs of the stream | ||
| multiplexers are sent, followed by "libp2p". The multiplexer list is ordered by | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| the client's preference, with the most preferred multiplexer at the beginning. | ||
| The server SHOULD respect the client's preference and pick the first protocol | ||
| from the list that it supports. | ||
|
|
||
| Example for a node supporting both yamux and mplex, with a preference for yamux: | ||
| ```json | ||
| [ "/yamux/1.0.0", "/mplex/6.7.0", "libp2p" ] | ||
| ``` | ||
|
|
||
| The "libp2p" protocol code MUST always be the last item in the multiplexer list. | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| According to [tls], nodes that don't implement the optimization described in | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| this document use "libp2p" for their ALPN. If "libp2p" is the result of the | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| ALPN process, nodes MUST use multistream negotiation of the stream multiplexer | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| as described in [connections]. | ||
|
Comment on lines
+65
to
+67
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per connection spec, both sides can initiate the protocol negotiation. The client can't differentiate between whether the server doesn't support early muxer negotiation, or whether it doesn't support any of the its muxers.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, in case of noise we fail if no common muxer is supported. Sorry if this is a stupid question, but why don't we also fail the TLS handshake in that case?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is to enable backwards-compatibility with legacy implementations. With these nodes, the result of the negotiation process will be "libp2p", so we need to do multistream. |
||
|
|
||
| ### Multiplexer Negotiation over Noise | ||
|
|
||
| The libp2p Noise Specification allows Noise handshake messages to carry | ||
| early data. [Noise-Early-Data] is carried in the second and third message of | ||
| the XX handshake pattern as illustrated in the following message sequence chart. | ||
| The second message carries early data in the form of a list of multiplexers | ||
| supported by the responder.The initiator sends its supported multiplexer list | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| in the third message of the handshake process, ordered by its preference. It | ||
| MAY choose a single multiplexer from the responder's list and only send that | ||
| value. | ||
|
|
||
| The multiplexer to use is determined by picking the first item from the | ||
| initiator's list that both parties support. | ||
|
|
||
| Example: Noise handshake two clients that both support mplex and yamux. The | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| client prefers yamux, whereas the server prefers mplex. | ||
|
|
||
| ``` | ||
| XX: | ||
| -> e | ||
| <- e, ee, s, es, [ "/mplex/6.7.0", "/yamux/1.0.0" ] | ||
| -> s, se, [ "/yamux/1.0.0", "/mplex/6.7.0" ] | ||
| ``` | ||
|
|
||
| The result of this negotiation is "/mplex/6.7.0". | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
|
|
||
| If there is no overlap between the multiplexers support by client and server, | ||
| the handshake MUST fail. | ||
|
|
||
| The format of the early data is specified in [Noise-handshake-payload]. | ||
|
|
||
|
|
||
| ## Privacy | ||
|
|
||
| The list of multiplexers carried in the TLS ALPN extension field is part of the | ||
| ClientHello message which is not encrypted. Using this optimiziation therefore | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| exposes the list of supported multiplexers to an on-path observer. This leak can | ||
| be considered insignificant, since a libp2p node reveals its list of supported | ||
| multiplexers to any node that connects to it. | ||
|
|
||
| The NoiseExtensions sent in the Noise handshake is sent after the peers have | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| established a shared key, so an on-path observer won't be able to obtain the | ||
| list of multiplexers. | ||
|
|
||
|
|
||
| ## Alternative options considered | ||
|
|
||
| Instead of ALPN for multiplexer selection to reduce RTT, other options such as | ||
| TLS extension and X.509 extension were considered. The pros and cons are explored | ||
| and the discussion details can be found at [#454]. | ||
|
|
||
|
|
||
|
|
||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| [#426]: https://github.com/libp2p/specs/issues/426 | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| [connections]: https://github.com/libp2p/specs/tree/master/connections | ||
| [sequence-chart]: https://github.com/libp2p/specs/tree/master/connections#upgrading-connections | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| [ALPN]: https://datatracker.ietf.org/doc/html/rfc7301 | ||
| [Noise-Early-Data]: https://github.com/libp2p/specs/tree/master/noise#the-libp2p-handshake-payload | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| [ECH]: https://datatracker.ietf.org/doc/draft-ietf-tls-esni/ | ||
| [handshake-payload]: https://github.com/libp2p/specs/tree/master/noise#the-libp2p-handshake-payload | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
| [#454]: https://github.com/libp2p/specs/issues/454 | ||
| [Noise-handshake-payload]: https://github.com/libp2p/specs/blob/b0818fa956f9940a7cdee18198e0daf1645d8276/noise/README.md#libp2p-data-in-handshake-messages | ||
|
marten-seemann marked this conversation as resolved.
Outdated
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.