Skip to content

Commit

Permalink
Muxer selection in security handshake (#446)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
5 people committed Dec 12, 2022
1 parent 9a646c0 commit 41d5104
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 2 deletions.
8 changes: 7 additions & 1 deletion connections/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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 changes: 128 additions & 0 deletions connections/inlined-muxer-negotiation.md
Original file line number Diff line number Diff line change
@@ -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

3 changes: 2 additions & 1 deletion noise/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down Expand Up @@ -220,6 +220,7 @@ syntax = "proto2";
message NoiseExtensions {
repeated bytes webtransport_certhashes = 1;
repeated string stream_muxers = 2;
}
message NoiseHandshakePayload {
Expand Down

0 comments on commit 41d5104

Please sign in to comment.