From 1f1d05ccb97c56e20b3b976491172b101470aa6c Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Sat, 29 Jun 2024 12:19:19 -0700 Subject: [PATCH] Add overview, add parameter table --- http/peer-id-auth.md | 90 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 11 deletions(-) diff --git a/http/peer-id-auth.md b/http/peer-id-auth.md index 4e984f1..f68985f 100644 --- a/http/peer-id-auth.md +++ b/http/peer-id-auth.md @@ -14,23 +14,91 @@ Interest Group: Same as [HTTP](README.md) This spec defines an authentication scheme of libp2p Peer IDs in accordance with [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-PeerIDchallenge-server=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=, 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="", opaque=... challenge-server="", sig="" + ``` + 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="",sig="" + ``` + 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 - be authenticated with the response header `WWW-Authenticate: Libp2p-PeerID + be authenticated with the response header `WWW-Authenticate: libp2p-PeerID challenge-client="`. The challenge MUST be indistinguishable from random data. The Server MAY randomly generate this data, or MAY use an server-encrypted value. If using random data the server SHOULD store the challenge temporarily until the authentication is 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 to the following: ``` - Libp2p-PeerID peer-id="",[challenge-server="",]sig=""] + libp2p-PeerID peer-id="",[challenge-server="",]sig=""] ``` * 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 signature is over the concatenated result of: ``` - + "origin=" + server-name + + + "origin=" + server-name + [ + "challenge-server=" + base64-encoded-client-chosen-challenge-server + ] + "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 following: ``` - Libp2p-PeerID peer-id="",sig="" + libp2p-PeerID peer-id="",sig="" ``` * The signature is over the concatenated result of: ``` - + "origin=" + server-name + + + "origin=" + server-name + [ + "challenge-server=" + base64-encoded-client-chosen-challenge-server + ] + "client=" + ``` * Strings are UTF-8 encoded. - * Optionally, the server MAY include a [Bearer - token](https://datatracker.ietf.org/doc/html/rfc6750) in the + * Optionally, the server MAY include a libp2p-Bearer + token in the `Authentication-Info` response header. This allows clients to avoid a future iteration of this authentication protocol. If clients see a bearer token, they SHOULD store it for future use. For example, an `Authentication-Info` header with a bearer token would look like: ``` - Libp2p-PeerID peer-id="",sig="",bearer-token="". + libp2p-PeerID peer-id="",sig="",bearer-token="". ``` 4. The client can then authenticate the server with the the signature from `Authentication-info`.