From 41d5104513340e758639d06d785d413de1a6722e Mon Sep 17 00:00:00 2001 From: julian88110 <111450570+julian88110@users.noreply.github.com> Date: Mon, 12 Dec 2022 13:18:38 -0800 Subject: [PATCH] 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 * 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 * replace nextproto with ALPN extension * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann * Update title * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann * 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 * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann * Update connections/muxer-sel-in-sec-handshake.md Co-authored-by: Marten Seemann * 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 Co-authored-by: Max Inden Co-authored-by: Marten Seemann Co-authored-by: Prithvi Shahi <50885601+p-shahi@users.noreply.github.com> Co-authored-by: Elena Frank --- connections/README.md | 8 +- connections/inlined-muxer-negotiation.md | 128 +++++++++++++++++++++++ noise/README.md | 3 +- 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 connections/inlined-muxer-negotiation.md diff --git a/connections/README.md b/connections/README.md index 1d51b498f..22338f622 100644 --- a/connections/README.md +++ b/connections/README.md @@ -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 diff --git a/connections/inlined-muxer-negotiation.md b/connections/inlined-muxer-negotiation.md new file mode 100644 index 000000000..a437dfce9 --- /dev/null +++ b/connections/inlined-muxer-negotiation.md @@ -0,0 +1,128 @@ +# Stream multiplexer negotiation in security handshake + + +| 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 + +- [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 + diff --git a/noise/README.md b/noise/README.md index 7648b06d1..714c80a34 100644 --- a/noise/README.md +++ b/noise/README.md @@ -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 {