Add overview, add parameter table

This commit is contained in:
Marco Munizaga
2024-06-29 12:19:19 -07:00
parent 6c733c4925
commit 1f1d05ccb9

View File

@@ -14,23 +14,91 @@ Interest Group: Same as [HTTP](README.md)
This spec defines an authentication scheme of libp2p Peer IDs in accordance with This spec defines an authentication scheme of libp2p Peer IDs in accordance with
[RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110). The authentication [RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110). The authentication
scheme is called `Libp2p-PeerID`. scheme is called `libp2p-PeerID`.
## Mutual Client and Server Peer ID Authentication ## Protocol Overview
## Parameters
| Param Name | Description |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| origin | The server name used in the TLS connection (SNI) |
| challenge-server | The random base64 encoded value the client generates to challenge the server to prove its identity |
| challenge-client | The random base64 encoded value the server generates to challenge the client to prove its identity |
| sig | the signature over some set of fields |
| client-peer-id | A client's peer id |
| server-peer-id | A server's peer id |
| public-key | A peer's public key |
| opaque | An base64 encoded opaque to the client blob generated by the server. If a client receives this it must return it. A server may use this to authenticate statelessly. For example, it could store the challenge-client and a expiry time. |
Params are encoded per [RFC 9110 auth-param's ABNF](https://datatracker.ietf.org/doc/html/rfc9110#name-collected-abnf). Generally it'll be something like: `origin=example.com, challenge-server=base64EncodedVal`
## Signing
Signatures sign some set of parameters. The parameters are sorted
alphabetically, prepended with a varint length prefix, and concatenated together
to form the data to be signed. The signing algorithm is defined by the key type
used. Refer to the [PeerID
spec](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md) for
specifics on the signing algorithm. The set of parameters is prefixed with the auth scheme "libp2p-PeerID"
As an example, if we wanted to sign the parameters `origin=example.com,
challenger-server=base64String` we would first structure the parameters as:
```
libp2p-PeerID<varintprefix>challenge-server=<base64String><varintprefix>origin=example.com
```
See the test vectors below for more examples. (todo)
## Base64 Encoding
The base64 encoding follows Base 64 Encoding with URL and Filename Safe Alphabet
from [RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648#section-5). The
reason this is not a multibase is to aid clients or servers who can not or
prefer not to import a multibase dependency.
## Mutual Client and Server Peer ID Authentication Overview
1. The client makes a request to the autentication URI.
2. The server responds with the header `WWW-Authenticate: libp2p-PeerID
challenge-client=<base64-encoded-challenge>, opaque=...`. The challenge MUST
be indistinguishable from random data.
3. The client sends a request to the same URI and sets the `Authorization`
[header](https://www.rfc-editor.org/rfc/rfc9110.html#section-11.6.2) header
to the following:
```
libp2p-PeerID peer-id="<encoded-peer-id-bytes>", opaque=... challenge-server="<base64-encoded-challenge-server>", sig="<base64-signature-bytes>"
```
The signature is the client signing the parameters `challenge-client` and `origin`.
4. The server authenticates the signature, and responds by setting the `Authentication-Info` response header to the
following:
```
libp2p-PeerID peer-id="<encoded-peer-id-bytes>",sig="<base64-signature-bytes>"
```
The signature is the server signing the parameters `challenge-server`,
`origin`, and `client` (`client` is the client's string encoded peer id)
5. The client authenticates the signature. At this point both the client and
server have authenticated each other.
## Mutual Client and Server Peer ID Authentication Detailed
(todo reword this)
1. The server initiates the authentication by responding to a request that must 1. The server initiates the authentication by responding to a request that must
be authenticated with the response header `WWW-Authenticate: Libp2p-PeerID be authenticated with the response header `WWW-Authenticate: libp2p-PeerID
challenge-client="<base64-encoded-challenge>`. The challenge MUST be challenge-client="<base64-encoded-challenge>`. The challenge MUST be
indistinguishable from random data. The Server MAY randomly generate this indistinguishable from random data. The Server MAY randomly generate this
data, or MAY use an server-encrypted value. If using random data the data, or MAY use an server-encrypted value. If using random data the
server SHOULD store the challenge temporarily until the authentication is server SHOULD store the challenge temporarily until the authentication is
done. The challenge SHOULD be at least 32 bytes. done. The challenge SHOULD be at least 32 bytes.
1. The client sends a request and sets the `Authorization` 2. The client sends a request and sets the `Authorization`
[header](https://www.rfc-editor.org/rfc/rfc9110.html#section-11.6.2) header [header](https://www.rfc-editor.org/rfc/rfc9110.html#section-11.6.2) header
to the following: to the following:
``` ```
Libp2p-PeerID peer-id="<encoded-peer-id-bytes>",[challenge-server="<base64-encoded-challenge-server>",]sig="<base64-signature-bytes>"] libp2p-PeerID peer-id="<encoded-peer-id-bytes>",[challenge-server="<base64-encoded-challenge-server>",]sig="<base64-signature-bytes>"]
``` ```
* The `challenge-server` parameter is optional. The client should set it if * The `challenge-server` parameter is optional. The client should set it if
@@ -38,7 +106,7 @@ scheme is called `Libp2p-PeerID`.
* The peer-id is encoded per the string encoding described in the [peer-ids spec](../peer-ids/peer-ids.md). * The peer-id is encoded per the string encoding described in the [peer-ids spec](../peer-ids/peer-ids.md).
* The signature is over the concatenated result of: * The signature is over the concatenated result of:
``` ```
<varint-length> + "origin=" + server-name + <varint-length> + "origin=" + server-name +
[<varint-length> + "challenge-server=" + base64-encoded-client-chosen-challenge-server + ] [<varint-length> + "challenge-server=" + base64-encoded-client-chosen-challenge-server + ]
<varint-length> + "challenge-client=" + base64-encoded-challenge <varint-length> + "challenge-client=" + base64-encoded-challenge
``` ```
@@ -87,23 +155,23 @@ scheme is called `Libp2p-PeerID`.
fulfilled, the server sets the `Authentication-Info` response header to the fulfilled, the server sets the `Authentication-Info` response header to the
following: following:
``` ```
Libp2p-PeerID peer-id="<encoded-peer-id-bytes>",sig="<base64-signature-bytes>" libp2p-PeerID peer-id="<encoded-peer-id-bytes>",sig="<base64-signature-bytes>"
``` ```
* The signature is over the concatenated result of: * The signature is over the concatenated result of:
``` ```
<varint-length> + "origin=" + server-name + <varint-length> + "origin=" + server-name +
[<varint-length> + "challenge-server=" + base64-encoded-client-chosen-challenge-server + ] [<varint-length> + "challenge-server=" + base64-encoded-client-chosen-challenge-server + ]
<varint-length> + "client=" + <encoded-client-peer-id-bytes> <varint-length> + "client=" + <encoded-client-peer-id-bytes>
``` ```
* Strings are UTF-8 encoded. * Strings are UTF-8 encoded.
* Optionally, the server MAY include a [Bearer * Optionally, the server MAY include a libp2p-Bearer
token](https://datatracker.ietf.org/doc/html/rfc6750) in the token in the
`Authentication-Info` response header. This allows clients to avoid a `Authentication-Info` response header. This allows clients to avoid a
future iteration of this authentication protocol. If clients see a bearer future iteration of this authentication protocol. If clients see a bearer
token, they SHOULD store it for future use. For example, an token, they SHOULD store it for future use. For example, an
`Authentication-Info` header with a bearer token would look like: `Authentication-Info` header with a bearer token would look like:
``` ```
Libp2p-PeerID peer-id="<encoded-peer-id-bytes>",sig="<base64-signature-bytes>",bearer-token="<token>". libp2p-PeerID peer-id="<encoded-peer-id-bytes>",sig="<base64-signature-bytes>",bearer-token="<token>".
``` ```
4. The client can then authenticate the server with the the signature from 4. The client can then authenticate the server with the the signature from
`Authentication-info`. `Authentication-info`.