mirror of
https://github.com/vacp2p/specs.git
synced 2026-01-07 22:44:07 -05:00
Muxer selection in security handshake (#446)
* Muxer selection in security handshake spec * Add cross version and security sections * Add security and more sections * Address review feedback points, add protobuf. * Address some more review points. Update Noise handshake section, Revise muxer string in examples. * Correct some typos * Address feedback points and update noise section * update Noise extention protobuf * Remove TBD item * Remove some redandant info * add alternative options considered * Update noise registration with NoiseExtensions field for muxers. * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Max Inden <mail@max-inden.de> * Revise noise handshake section to reflect early data carrier msg change. * Correct sequence example in noise handshake * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann <martenseemann@gmail.com> * replace nextproto with ALPN extension * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann <martenseemann@gmail.com> * Update title * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann <martenseemann@gmail.com> * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann <martenseemann@gmail.com> * address some review points * Revise some typos * Revise the Noise selection process so that the selection of muxer is based on the responder's priority and fix some typos * Editorial * formatting * Update muxer-sel-in-sec-handshake.md * Update muxer-sel-in-sec-handshake.md * Update muxer-sel-in-sec-handshake.md Consolidate some sections and clarify backward compatibility section. * Consolidate some sections again and simplify some descriptiosn. * remove accidentally checked file * Editorial changes * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann <martenseemann@gmail.com> * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann <martenseemann@gmail.com> * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann <martenseemann@gmail.com> * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann <martenseemann@gmail.com> * Apply some suggestions from code review * add myself to list of authors * rewrite the Security section * use the client's preference in Noise * rename document, link to it from connections README * remove section describing current muxer selection * remove repetitive section introducing muxer selection * improve TLS section * condense Noise section * Apply suggestions from code review Co-authored-by: Prithvi Shahi <50885601+p-shahi@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Prithvi Shahi <50885601+p-shahi@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Prithvi Shahi <50885601+p-shahi@users.noreply.github.com> * bump revisions * Apply suggestions from code review Co-authored-by: Elena Frank <elena.frank@protonmail.com> Co-authored-by: Max Inden <mail@max-inden.de> Co-authored-by: Marten Seemann <martenseemann@gmail.com> Co-authored-by: Prithvi Shahi <50885601+p-shahi@users.noreply.github.com> Co-authored-by: Elena Frank <elena.frank@protonmail.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
| Lifecycle Stage | Maturity | Status | Latest Revision |
|
||||
|-----------------|---------------|--------|-----------------|
|
||||
| 1A | Working Draft | Active | r0, 2019-06-20 |
|
||||
| 1A | Working Draft | Active | r1, 2022-12-07 |
|
||||
|
||||
Authors: [@yusefnapora]
|
||||
|
||||
@@ -234,6 +234,11 @@ Note: In the case where both peers initially act as initiators, e.g. during NAT
|
||||
hole punching, tie-breaking is done via the [multistream-select simultaneous
|
||||
open protocol extension][simopen].
|
||||
|
||||
### Inlining Muxer Negotiation
|
||||
|
||||
If both peers support it, it's possible to shortcut the muxer selection by moving
|
||||
it into the security handshake. Details are specified in [inlined-muxer-negotiation].
|
||||
|
||||
|
||||
## Opening New Streams Over a Connection
|
||||
|
||||
@@ -409,3 +414,4 @@ updated to incorporate the changes.
|
||||
[simopen]: ./simopen.md
|
||||
[resource-manager-issue]: https://github.com/libp2p/go-libp2p/issues/635
|
||||
[hole-punching]: ./hole-punching.md
|
||||
[inlined-muxer-selection]: ./inlined-muxer-negotiation.md
|
||||
|
||||
128
connections/inlined-muxer-negotiation.md
Normal file
128
connections/inlined-muxer-negotiation.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Stream multiplexer negotiation in security handshake <!-- omit in toc -->
|
||||
|
||||
|
||||
| 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 <!-- omit in toc -->
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Design](#design)
|
||||
- [Multiplexer Negotiation over TLS](#multiplexer-negotiation-over-tls)
|
||||
- [Multiplexer Negotiation over Noise](#multiplexer-negotiation-over-noise)
|
||||
- [Privacy](#privacy)
|
||||
- [Alternative options considered](#alternative-options-considered)
|
||||
|
||||
## 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.
|
||||
|
||||
For the purpose of multiplexer negotiation, the protocol IDs of the stream
|
||||
multiplexers are sent, followed by the `"libp2p"` protocol code. The multiplexer list is ordered by
|
||||
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.
|
||||
According to [TLS], nodes that don't implement the optimization described in
|
||||
this document use `"libp2p"` for their ALPN. If `"libp2p"` is the result of the
|
||||
ALPN process, nodes MUST use protocol negotiation of the stream multiplexer
|
||||
as described in [connections].
|
||||
|
||||
### 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
|
||||
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 between two clients that both support mplex and yamux. The
|
||||
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"`.
|
||||
|
||||
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
|
||||
unencrypted ClientHello message. Therefore, using this optimization
|
||||
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.
|
||||
|
||||
However, the NoiseExtensions in the Noise handshake are sent after the peers have
|
||||
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].
|
||||
|
||||
|
||||
[TLS]: https://github.com/libp2p/specs/blob/master/tls/tls.md
|
||||
[connections]: https://github.com/libp2p/specs/tree/master/connections
|
||||
[ALPN]: https://datatracker.ietf.org/doc/html/rfc7301
|
||||
[Noise-Early-Data]: https://github.com/libp2p/specs/tree/master/noise#libp2p-data-in-handshake-messages
|
||||
[ECH]: https://datatracker.ietf.org/doc/draft-ietf-tls-esni/
|
||||
[#454]: https://github.com/libp2p/specs/issues/454
|
||||
[Noise-handshake-payload]: https://github.com/libp2p/specs/tree/master/noise#the-libp2p-handshake-payload
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
| Lifecycle Stage | Maturity | Status | Latest Revision |
|
||||
|-----------------|----------------|--------|-----------------|
|
||||
| 3A | Recommendation | Active | r4, 2022-09-22 |
|
||||
| 3A | Recommendation | Active | r5, 2022-12-07 |
|
||||
|
||||
Authors: [@yusefnapora]
|
||||
|
||||
@@ -220,6 +220,7 @@ syntax = "proto2";
|
||||
|
||||
message NoiseExtensions {
|
||||
repeated bytes webtransport_certhashes = 1;
|
||||
repeated string stream_muxers = 2;
|
||||
}
|
||||
|
||||
message NoiseHandshakePayload {
|
||||
|
||||
Reference in New Issue
Block a user