Skip to content
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

Muxer selection in security handshake #446

Merged
merged 56 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
dbde5fd
Muxer selection in security handshake spec
julian88110 Sep 8, 2022
a8804dd
Add cross version and security sections
julian88110 Sep 9, 2022
ad1bae7
Add security and more sections
julian88110 Sep 9, 2022
0d35e15
Address review feedback points, add protobuf.
julian88110 Sep 12, 2022
ec2e959
Address some more review points.
julian88110 Sep 13, 2022
0042384
Correct some typos
julian88110 Sep 13, 2022
dcac239
Address feedback points and update noise section
julian88110 Sep 15, 2022
245361c
update Noise extention protobuf
julian88110 Sep 15, 2022
a5b3ef0
Remove TBD item
julian88110 Sep 15, 2022
349ac76
Remove some redandant info
julian88110 Sep 15, 2022
d6eb581
add alternative options considered
julian88110 Sep 20, 2022
07f5d70
rebase from master
julian88110 Sep 23, 2022
808a6f6
Merge remote-tracking branch 'origin/master' into MuxerSel-inSecHands…
julian88110 Sep 23, 2022
c7a1db0
Update noise registration with NoiseExtensions field for muxers.
julian88110 Sep 23, 2022
811fc05
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Sep 27, 2022
239dfca
Revise noise handshake section to reflect early data carrier msg change.
julian88110 Sep 27, 2022
f0fe69a
Merge branch 'MuxerSel-inSecHandshake' of https://github.com/libp2p/s…
julian88110 Sep 27, 2022
1c716e2
Correct sequence example in noise handshake
julian88110 Sep 27, 2022
24d021d
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Sep 27, 2022
5c28fc1
replace nextproto with ALPN extension
julian88110 Sep 27, 2022
3e3394a
Merge branch muxerSel-inSecHandshake' of https://github.com/libp2p/sp…
julian88110 Sep 27, 2022
c6b8ed2
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Oct 16, 2022
54379a9
Update title
julian88110 Oct 16, 2022
06896c3
Merge branch 'MuxerSel-inSecHandshake' of https://github.com/libp2p/s…
julian88110 Oct 16, 2022
cc2bbcb
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Oct 16, 2022
f81c6f4
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Oct 16, 2022
0b73a38
address some review points
julian88110 Oct 16, 2022
aecfbb8
Address some review points
julian88110 Oct 16, 2022
5192ad1
Revise some typos
julian88110 Oct 16, 2022
4ff74a7
Revise the Noise selection process so that the selection of muxer is …
julian88110 Oct 17, 2022
f69b691
Editorial
julian88110 Oct 17, 2022
8e51f46
formatting
julian88110 Oct 17, 2022
eb4e697
Update muxer-sel-in-sec-handshake.md
julian88110 Oct 18, 2022
ef8657d
Update muxer-sel-in-sec-handshake.md
julian88110 Oct 18, 2022
8296442
Update muxer-sel-in-sec-handshake.md
julian88110 Oct 19, 2022
0fc4452
Consolidate some sections again and simplify some descriptiosn.
julian88110 Oct 19, 2022
a11ff1d
remove accidentally checked file
julian88110 Oct 19, 2022
b4ce114
Editorial changes
julian88110 Oct 19, 2022
9b11a68
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Nov 9, 2022
002e37f
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Nov 14, 2022
e3fcb38
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Nov 14, 2022
4a167d1
Update connections/muxer-sel-in-sec-handshake.md
julian88110 Nov 14, 2022
3e9586b
Apply some suggestions from code review
marten-seemann Nov 16, 2022
f682f6b
add myself to list of authors
marten-seemann Nov 16, 2022
c07fb79
rewrite the Security section
marten-seemann Nov 16, 2022
1e7a3c0
use the client's preference in Noise
marten-seemann Nov 16, 2022
eafbffc
rename document, link to it from connections README
marten-seemann Dec 6, 2022
1e52c1e
remove section describing current muxer selection
marten-seemann Dec 6, 2022
fe88ccf
remove repetitive section introducing muxer selection
marten-seemann Dec 6, 2022
da63658
improve TLS section
marten-seemann Dec 6, 2022
1306199
condense Noise section
marten-seemann Dec 6, 2022
bb070b2
Apply suggestions from code review
marten-seemann Dec 6, 2022
d90a15e
Apply suggestions from code review
marten-seemann Dec 6, 2022
447be1f
Apply suggestions from code review
marten-seemann Dec 6, 2022
c23af93
bump revisions
marten-seemann Dec 6, 2022
6fe4166
Apply suggestions from code review
marten-seemann Dec 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
marten-seemann marked this conversation as resolved.
Show resolved Hide resolved

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
Comment on lines +64 to +65
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I am missing something this is not true: the TLS spec does not specify what ALPN to use.
Also: if we add libp2p over http as drafted in #477 we could also have the "h2" APLN here, no?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you could accept HTTP and libp2p at the same time. That's WebTransport does, by the way.
Negotiating HTTP though means that after completing the handshake, you're in HTTP land, not in libp2p land any more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I am missing something this is not true: the TLS spec does not specify what ALPN to use.

Good catch. Both Go and Rust do this. @marten-seemann can you add it to the TLS spec? Either in this pull request or a separate one?

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;
marten-seemann marked this conversation as resolved.
Show resolved Hide resolved
}

message NoiseHandshakePayload {
Expand Down