Skip to content
Closed
Changes from all commits
Commits
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
86 changes: 59 additions & 27 deletions noise/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,54 +204,86 @@ the early data MUST be included as described below.

#### The libp2p Signed Handshake Payload

libp2p-specific data, including the signature used for static key
authentication, is transmitted in Noise handshake message payloads. When
decrypted, the message payload has the structure described in [Encrypted
libp2p-specific early data, plus a signature that links the static Noise key
of the session with the libp2p identity key (for authentication), is
transmitted in Noise handshake message payloads.

These payloads MUST appear in the first handshake message that guarantees
secrecy, sender authentication, and integrity:

* In XX-initiated handshakes, the initiator will send its payload in message 3
(closing message), whereas the responder will send it in message 2 (its only
message).
* In IK-initiated optimistic handshakes, the initiator will send its message
payload message 1, as it satisfies the guarantees.
* If the responder continues the IK handshake, it will send its message
payload in message 2.
* If the responder fall backs to XXfallback, it won't be able to decrypt
the initiator's message data from message 1. Therefore, the initiator
MUST rebuild the message payload with the new cryptographic material,
and resend it in the 3rd message.

To guard against replay attacks, these message payloads are signed with the
Copy link

@zmanian zmanian Aug 25, 2019

Choose a reason for hiding this comment

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

Shouldn't you be signing the HandshakeHash + the message payload to bind the signature to a specific channel.

Signing with an X25519 keys can get annoying. Signal protocol does it but X25519 to ed25519 is not provided by many implementations.

Copy link

Choose a reason for hiding this comment

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

Yeah easier to make the static keys Ed25519 if you want this.

ephemeral key of the session.

When decrypted, the signed payload has the structure described in [Encrypted
Payloads](#encrypted-payloads), consisting of a length-prefixed `body` field
followed by optional padding. The `body` of the payload contains a serialized
[protobuf][protobuf] message with the following schema:
followed by optional padding.

The `body` of the payload contains a serialized [protobuf][protobuf]
`NoiseSignedHandshakePayload` message with the following schema:

``` protobuf
message NoiseSignedHandshakePayload {
NoiseHandshakePayload payload = 1;
bytes payload_sig = 2;
}

message NoiseHandshakePayload {
bytes libp2p_key = 1;
bytes noise_static_key_signature = 2;
bytes libp2p_data = 3;
bytes libp2p_data_signature = 4;
bytes identity_key = 1;
bytes identity_sig = 2;
bytes data = 3;
bytes data_sig = 4;
}
```

The `libp2p_key` field contains a serialized `PublicKey` message as defined in
the [peer id spec][peer-id-spec].
The `payload` field contains a Protobuf-serialized `NoiseHandshakePayload`
struct.

The `payload_sig` field contains the signature of the `payload` against the
ephemeral key for the session.

The `identity_key` field contains a serialized `PublicKey` message as defined
in the [peer id spec][peer-id-spec].

The `noise_static_key_signature` field is produced using the libp2p identity
private key according to the [signing rules in the peer id
The `identity_sig` field is produced using the libp2p identity private key
according to the [signing rules in the peer id
spec][peer-id-spec-signing-rules]. The data to be signed is the UTF-8 string
`noise-libp2p-static-key:`, followed by the Noise static public key, encoded
according to the rules defined in [section 5 of RFC 7748][rfc-7748-sec-5].

The `libp2p_data` field contains the "early data" provided to the Noise module
when initiating the handshake, if any. The structure of this data is opaque to
The `data` field contains the "early data" provided to the Noise module when
initiating the handshake, if any. The structure of this data is opaque to
noise-libp2p and is expected to be defined in a future iteration of the
connection establishment spec.

If `libp2p_data` is non-empty, the `libp2p_data_signature` field MUST contain a
signature produced with the libp2p identity key. The data to be signed is the
UTF-8 string `noise-libp2p-early-data:` followed by the contents of the
`libp2p_data` field.
If `data` is non-empty, the `data_sig` field MUST contain a signature produced
with the libp2p identity key. The data to be signed is the UTF-8 string
`noise-libp2p-early-data:` followed by the contents of the `data` field.

Upon receiving the handshake payload, peers MUST decode the public key from the
`libp2p_key` field into a usable form. The key MUST be used to validate the
`noise_static_key_signature` field against the static Noise key received in the
Upon receiving the handshake payload, peers MUST decode the public key from
the `identity_key` field into a usable form. The key MUST be used to validate
the `identity_sig` field against the static Noise key received in the
handshake. If the signature is invalid, the connection MUST be terminated
immediately.

If the `libp2p_data` field is non-empty, the `libp2p_data_signature` MUST be
validated against the supplied `libp2p_data`. If the signature is invalid, the
connection MUST be terminated immediately.
If the `data` field is non-empty, the `data_sig` MUST be validated against the
supplied `data`. If the signature is invalid, the connection MUST be
terminated immediately.

If a noise-libp2p implementation does not expose an API for early data, they
MUST still validate the signature upon receiving a non-empty `libp2p_data`
field and abort the connection if it is invalid.
MUST still validate the signature upon receiving a non-empty `data` field and
abort the connection if it is invalid.

### Supported Handshake Patterns

Expand Down