mirror of
https://github.com/vacp2p/specs.git
synced 2026-01-09 15:28:03 -05:00
Nits and wordsmithing
This commit is contained in:
@@ -21,6 +21,7 @@ authenticate themselves to each other. The protocol works whether the Client
|
|||||||
provides the first challenge, or the Server provides the first challenge.
|
provides the first challenge, or the Server provides the first challenge.
|
||||||
|
|
||||||
Example Diagram of Server initiated handshake
|
Example Diagram of Server initiated handshake
|
||||||
|
|
||||||
```
|
```
|
||||||
┌─────────┐ ┌────────┐
|
┌─────────┐ ┌────────┐
|
||||||
│ Client │ │ Server │
|
│ Client │ │ Server │
|
||||||
@@ -48,6 +49,7 @@ Example Diagram of Server initiated handshake
|
|||||||
```
|
```
|
||||||
|
|
||||||
Example Diagram of Client initiated handshake
|
Example Diagram of Client initiated handshake
|
||||||
|
|
||||||
```
|
```
|
||||||
┌────────┐ ┌────────┐
|
┌────────┐ ┌────────┐
|
||||||
│ Client │ │ Server │
|
│ Client │ │ Server │
|
||||||
@@ -71,29 +73,29 @@ Example Diagram of Client initiated handshake
|
|||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
| Param Name | Description |
|
| Param Name | Description |
|
||||||
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| hostname | The server name used in the TLS connection (SNI). |
|
| hostname | The server name used in the TLS connection (SNI). |
|
||||||
| challenge-server | The random quoted string value the client generates to challenge the server to prove its identity |
|
| challenge-server | The random quoted string value the client generates to challenge the server to prove its identity |
|
||||||
| challenge-client | The random quoted string value the server generates to challenge the client to prove its identity |
|
| challenge-client | The random quoted string value the server generates to challenge the client to prove its identity |
|
||||||
| sig | A base64 encoded signature. |
|
| sig | A base64 encoded signature. |
|
||||||
| public-key | A base64 encoded value of peer's public key. This MUST be the key used for the Peer's Peer ID. The key itself is encoded per the [Peer ID spec]. |
|
| public-key | A base64 encoded value of peer's public key. This MUST be the key used for the Peer's Peer ID. The key itself is encoded per the [Peer ID spec]. |
|
||||||
| opaque | A value 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. |
|
| opaque | A value 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. |
|
||||||
|
|
||||||
Params are encoded per [RFC 9110 auth-param's ABNF](https://datatracker.ietf.org/doc/html/rfc9110#name-cmaollected-abnf). Generally it'll be something like: `hostname="example.com", challenge-server="challenge-string"`
|
Params are encoded per [RFC 9110 auth-param's ABNF](https://datatracker.ietf.org/doc/html/rfc9110#name-cmaollected-abnf). Generally it'll be something like: `hostname="example.com", challenge-server="challenge-string"`
|
||||||
|
|
||||||
## Signing
|
## Signing
|
||||||
|
|
||||||
Signatures sign some set of parameters prefixed by the string `libp2p-PeerID`. The parameters are sorted
|
Signatures sign some set of parameters prefixed by the string `libp2p-PeerID`.
|
||||||
alphabetically, prepended with a varint length prefix, and concatenated together
|
The parameters are sorted alphabetically, prepended with a varint length
|
||||||
to form the data to be signed. The parameter name and value is split with a `=`.
|
prefix, and concatenated together to form the data to be signed. The parameter
|
||||||
If the parameter value is appended directly after the `=`. Strings MUST be UTF-8
|
name and value is split with a `=`. The parameter value is appended directly
|
||||||
encoded. Byte Arrays MUST be appended as-is. The signing algorithm is defined by
|
after the `=`. Strings MUST be UTF-8 encoded. Byte Arrays MUST be appended
|
||||||
the key type used. Refer to the [Peer ID spec] for specifics on the signing
|
as-is. The signing algorithm is defined by the key type used. Refer to the
|
||||||
algorithm. The set of parameters is prefixed with the auth scheme
|
[Peer ID spec] for specifics on the signing algorithm.
|
||||||
"libp2p-PeerID"
|
|
||||||
|
|
||||||
### Signing Example
|
### Signing Example
|
||||||
|
|
||||||
| Parameter | Value |
|
| Parameter | Value |
|
||||||
| ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| hostname | example.com |
|
| hostname | example.com |
|
||||||
@@ -104,7 +106,7 @@ algorithm. The set of parameters is prefixed with the auth scheme
|
|||||||
| data to sign (hex encoded) | 6c69627032702d5065657249443d6368616c6c656e67652d7365727665723d455245524552455245524552455245524552455245524552455245524552455245524552455245524552453d36636c69656e742d7075626c69632d6b65793d080112208139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b39414686f73746e616d653d6578616d706c652e636f6d |
|
| data to sign (hex encoded) | 6c69627032702d5065657249443d6368616c6c656e67652d7365727665723d455245524552455245524552455245524552455245524552455245524552455245524552455245524552453d36636c69656e742d7075626c69632d6b65793d080112208139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b39414686f73746e616d653d6578616d706c652e636f6d |
|
||||||
| signature (base64 encoded) | UA88qZbLUzmAxrD9KECbDCgSKAUBAvBHrOCF2X0uPLR1uUCF7qGfLPc7dw3Olo-LaFCDpk5sXN7TkLWPVvuXAA== |
|
| signature (base64 encoded) | UA88qZbLUzmAxrD9KECbDCgSKAUBAvBHrOCF2X0uPLR1uUCF7qGfLPc7dw3Olo-LaFCDpk5sXN7TkLWPVvuXAA== |
|
||||||
|
|
||||||
Note that the `=` after the libp2p-PeerID scheme is actually the varint length of the challenge-server parameter.
|
Note that the `=` after the libp2p-PeerID scheme is the varint length of the challenge-server parameter.
|
||||||
|
|
||||||
## Base64 Encoding
|
## Base64 Encoding
|
||||||
|
|
||||||
@@ -130,7 +132,8 @@ protocol operates as follows:
|
|||||||
|
|
||||||
1. The client makes an HTTP request to an authenticated resource.
|
1. The client makes an HTTP request to an authenticated resource.
|
||||||
|
|
||||||
2. The server responds with status code 401 (Unauthorized) and set the header:
|
2. The server responds with status code 401 (Unauthorized) and sets the header:
|
||||||
|
|
||||||
```
|
```
|
||||||
WWW-Authenticate: libp2p-PeerID challenge-client="<challenge-string>", public-key="<base64-encoded-public-key-bytes>", opaque="<opaque-value>"
|
WWW-Authenticate: libp2p-PeerID challenge-client="<challenge-string>", public-key="<base64-encoded-public-key-bytes>", opaque="<opaque-value>"
|
||||||
```
|
```
|
||||||
@@ -153,9 +156,10 @@ protocol operates as follows:
|
|||||||
key used to derive the client's peer id.
|
key used to derive the client's peer id.
|
||||||
|
|
||||||
The `sig` param represents a signature over the parameters:
|
The `sig` param represents a signature over the parameters:
|
||||||
- `challenge-client`
|
|
||||||
- `server-public-key` the bytes of the server's public-key encoded per the [Peer ID spec].
|
- `challenge-client`
|
||||||
- `hostname`
|
- `server-public-key` the bytes of the server's public-key encoded per the [Peer ID spec].
|
||||||
|
- `hostname`
|
||||||
|
|
||||||
4. The server SHOULD verify the signature using the server name used in the TLS
|
4. The server SHOULD verify the signature using the server name used in the TLS
|
||||||
session. The server MUST return 401 Unauthorized if the server fails to
|
session. The server MUST return 401 Unauthorized if the server fails to
|
||||||
@@ -163,21 +167,24 @@ protocol operates as follows:
|
|||||||
authenticated the client's public key, and thus its PeerID. The server SHOULD
|
authenticated the client's public key, and thus its PeerID. The server SHOULD
|
||||||
proceed to serve the HTTP request. The server MUST set the following response
|
proceed to serve the HTTP request. The server MUST set the following response
|
||||||
headers:
|
headers:
|
||||||
|
|
||||||
```
|
```
|
||||||
Authentication-Info: libp2p-PeerID, sig="<base64-signature-bytes>" bearer="<base64-encoded-opaque-blob>"
|
Authentication-Info: libp2p-PeerID, sig="<base64-signature-bytes>" bearer="<base64-encoded-opaque-blob>"
|
||||||
```
|
```
|
||||||
|
|
||||||
The `sig` param represents a signature over the parameters:
|
The `sig` param represents a signature over the parameters:
|
||||||
- `challenge-server`
|
|
||||||
- `client-public-key` the bytes of the client's public-key encoded per the [Peer ID spec].
|
- `challenge-server`
|
||||||
- `hostname`
|
- `client-public-key` the bytes of the client's public-key encoded per the [Peer ID spec].
|
||||||
|
- `hostname`
|
||||||
|
|
||||||
The `bearer` token allows the client to make future Peer ID authenticated
|
The `bearer` token allows the client to make future Peer ID authenticated
|
||||||
requests. The value is opaque to the client, and the server may use it to
|
requests. The value is opaque to the client, and the server may use it to
|
||||||
store authentication state such as:
|
store authentication state such as:
|
||||||
- The client's Peer ID.
|
|
||||||
- The `hostname` parameter.
|
- The client's Peer ID.
|
||||||
- The token creation date (to allow tokens to expire).
|
- The `hostname` parameter.
|
||||||
|
- The token creation date (to allow tokens to expire).
|
||||||
|
|
||||||
5. The client MUST verify the signature. After verification the client has
|
5. The client MUST verify the signature. After verification the client has
|
||||||
authenticated the server's Peer ID. The client SHOULD send the `bearer`
|
authenticated the server's Peer ID. The client SHOULD send the `bearer`
|
||||||
@@ -200,14 +207,16 @@ The client initiated handshake is as follows
|
|||||||
```
|
```
|
||||||
|
|
||||||
2. The server responds with status code 401 (Unauthorized) and set the header:
|
2. The server responds with status code 401 (Unauthorized) and set the header:
|
||||||
|
|
||||||
```
|
```
|
||||||
WWW-Authenticate: libp2p-PeerID challenge-client="<challenge-string>", public-key="<base64-encoded-public-key-bytes>", sig="<base64-signature-bytes>", opaque="<opaque-value>"
|
WWW-Authenticate: libp2p-PeerID challenge-client="<challenge-string>", public-key="<base64-encoded-public-key-bytes>", sig="<base64-signature-bytes>", opaque="<opaque-value>"
|
||||||
```
|
```
|
||||||
|
|
||||||
The `sig` param represents a signature over the parameters:
|
The `sig` param represents a signature over the parameters:
|
||||||
- `challenge-server`
|
|
||||||
- `client-public-key` the bytes of the client's public-key encoded per the [Peer ID spec].
|
- `challenge-server`
|
||||||
- `hostname`
|
- `client-public-key` the bytes of the client's public-key encoded per the [Peer ID spec].
|
||||||
|
- `hostname`
|
||||||
|
|
||||||
3. The client MUST verify the signature. After verification the client has
|
3. The client MUST verify the signature. After verification the client has
|
||||||
authenticated the server's Peer ID.
|
authenticated the server's Peer ID.
|
||||||
@@ -222,9 +231,10 @@ The client initiated handshake is as follows
|
|||||||
The client MAY send application data in this request.
|
The client MAY send application data in this request.
|
||||||
|
|
||||||
The `sig` param represents a signature over the parameters:
|
The `sig` param represents a signature over the parameters:
|
||||||
- `challenge-client`
|
|
||||||
- `server-public-key` the bytes of the server's public-key encoded per the [Peer ID spec].
|
- `challenge-client`
|
||||||
- `hostname`
|
- `server-public-key` the bytes of the server's public-key encoded per the [Peer ID spec].
|
||||||
|
- `hostname`
|
||||||
|
|
||||||
4. The server MUST verify the signature. The server SHOULD verify the signature
|
4. The server MUST verify the signature. The server SHOULD verify the signature
|
||||||
using the server name used in the TLS session. The server MUST return 401
|
using the server name used in the TLS session. The server MUST return 401
|
||||||
@@ -232,6 +242,7 @@ The client initiated handshake is as follows
|
|||||||
is valid, the server has authenticated the client's public key, and thus its
|
is valid, the server has authenticated the client's public key, and thus its
|
||||||
PeerID. The server SHOULD proceed to serve the HTTP request. The server MUST
|
PeerID. The server SHOULD proceed to serve the HTTP request. The server MUST
|
||||||
set the following response headers:
|
set the following response headers:
|
||||||
|
|
||||||
```
|
```
|
||||||
Authentication-Info: libp2p-PeerID bearer="<base64-encoded-opaque-blob>"
|
Authentication-Info: libp2p-PeerID bearer="<base64-encoded-opaque-blob>"
|
||||||
```
|
```
|
||||||
@@ -239,14 +250,14 @@ The client initiated handshake is as follows
|
|||||||
The `bearer` token allows the client to make future Peer ID authenticated
|
The `bearer` token allows the client to make future Peer ID authenticated
|
||||||
requests. The value is opaque to the client, and the server MAY use it to
|
requests. The value is opaque to the client, and the server MAY use it to
|
||||||
store authentication state such as:
|
store authentication state such as:
|
||||||
- The client's Peer ID.
|
|
||||||
- The `hostname` parameter.
|
- The client's Peer ID.
|
||||||
- The token creation date (to allow tokens to expire).
|
- The `hostname` parameter.
|
||||||
|
- The token creation date (to allow tokens to expire).
|
||||||
|
|
||||||
5. The client SHOULD send the `bearer` token for future Peer ID authenticated
|
5. The client SHOULD send the `bearer` token for future Peer ID authenticated
|
||||||
requests.
|
requests.
|
||||||
|
|
||||||
|
|
||||||
## libp2p bearer token
|
## libp2p bearer token
|
||||||
|
|
||||||
The libp2p bearer token is a token given to the client from the server that
|
The libp2p bearer token is a token given to the client from the server that
|
||||||
@@ -259,6 +270,7 @@ authentication protocol when it wants the client to request a new libp2p
|
|||||||
bearer token.
|
bearer token.
|
||||||
|
|
||||||
To use the bearer token, the client MUST set the Authorization header as follows:
|
To use the bearer token, the client MUST set the Authorization header as follows:
|
||||||
|
|
||||||
```
|
```
|
||||||
Authorization: libp2p-PeerID bearer="<base64-encoded-opaque-blob>"
|
Authorization: libp2p-PeerID bearer="<base64-encoded-opaque-blob>"
|
||||||
```
|
```
|
||||||
@@ -273,36 +285,36 @@ but it only does the authentication flow. The client and server SHOULD NOT send
|
|||||||
any data besides what is defined in the above authentication flow. The protocol
|
any data besides what is defined in the above authentication flow. The protocol
|
||||||
id for the authentication endpoint is `/http-peer-id-auth/1.0.0`.
|
id for the authentication endpoint is `/http-peer-id-auth/1.0.0`.
|
||||||
|
|
||||||
|
|
||||||
## Considerations for Implementations
|
## Considerations for Implementations
|
||||||
|
|
||||||
* Implementations MUST only authenticate over a secured connection (i.e. TLS).
|
- Implementations SHOULD only authenticate over a secured connection (i.e. TLS).
|
||||||
* Implementations SHOULD limit the maximum length of any variable length field.
|
- Implementations SHOULD limit the maximum length of any variable length field.
|
||||||
* The suggested Maximum length of the Authentication related header should is
|
- The suggested Maximum length of the Authentication related header should is
|
||||||
2048 bytes.
|
2048 bytes.
|
||||||
|
|
||||||
## Security Considerations
|
## Security Considerations
|
||||||
|
|
||||||
Protection against man-in-the-middle (mitm) type attacks is through Web PKI. If
|
Protection against man-in-the-middle (MITM) type attacks is through Web PKI. If
|
||||||
the client is in an environment where Web PKI can not be fully trusted (e.g. an
|
the client is in an environment where Web PKI can not be fully trusted (e.g. an
|
||||||
enterprise network with a custom enterprise root CA installed on the client),
|
enterprise network with a custom enterprise root CA installed on the client),
|
||||||
then this authentication scheme can not protect the client from a mitm attack.
|
then this authentication scheme can not protect the client from a MITM attack.
|
||||||
|
|
||||||
This authentication scheme is also not secure in cases where you do not own your
|
This authentication scheme is also not secure in cases where you do not own
|
||||||
domain name or the certificate. If someone else can get a valid certificate for
|
your domain name or the TLS certificate. If someone else can get a valid
|
||||||
your domain, you may be vulnerable to a mitm attack.
|
certificate for your domain, you may be vulnerable to a MITM attack.
|
||||||
|
|
||||||
## Complete Server Initiated Handshake Example
|
## Complete Server Initiated Handshake Example
|
||||||
|
|
||||||
The following is a complete and reproducible handshake. Generated by the current
|
The following is a complete and reproducible handshake. Generated by the current
|
||||||
implementation of this spec in go-libp2p. This is a server-initiated handshake.
|
implementation of this spec in go-libp2p. This is a server-initiated handshake.
|
||||||
|
|
||||||
Understanding the opaque value is not necessary in order to understand this
|
Understanding the opaque value is not necessary in order to understand the
|
||||||
spec. Servers are free to do whatever they want with the opaque field. The
|
spec. Servers are free to do whatever they want with the opaque field. The
|
||||||
opaque value represents encoded server state authenticated with an HMAC. The
|
opaque value represents encoded server state authenticated with an HMAC. The
|
||||||
details can be found in the go-libp2p source.
|
details can be found in the go-libp2p source.
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
| Parameter | Value |
|
| Parameter | Value |
|
||||||
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| hostname | example.com |
|
| hostname | example.com |
|
||||||
@@ -314,6 +326,7 @@ details can be found in the go-libp2p source.
|
|||||||
| "Now" time | 1970-01-01 00:00:00 +0000 UTC |
|
| "Now" time | 1970-01-01 00:00:00 +0000 UTC |
|
||||||
|
|
||||||
### Handshake Diagram
|
### Handshake Diagram
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Client->>Server: Initial request
|
Client->>Server: Initial request
|
||||||
@@ -329,9 +342,10 @@ Client->>Server: Authorization=libp2p-PeerID bearer="YhlYjHWTMOkTleROtjMiChL7Mx1
|
|||||||
|
|
||||||
## Complete Client Initiated Handshake Example
|
## Complete Client Initiated Handshake Example
|
||||||
|
|
||||||
Below is the same as above, but using the client initated handshake.
|
Below is the same as above, but using the client initiated handshake.
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
| Parameter | Value |
|
| Parameter | Value |
|
||||||
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| hostname | example.com |
|
| hostname | example.com |
|
||||||
@@ -343,6 +357,7 @@ Below is the same as above, but using the client initated handshake.
|
|||||||
| "Now" time | 1970-01-01 00:00:00 +0000 UTC |
|
| "Now" time | 1970-01-01 00:00:00 +0000 UTC |
|
||||||
|
|
||||||
### Handshake Diagram
|
### Handshake Diagram
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Client->>Server: Authorization=libp2p-PeerID challenge-server="MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz", public-key="CAESIIE5dw6ofRdfVqNUZsNMfszLjYqRtO43ol32D1uPybOU"
|
Client->>Server: Authorization=libp2p-PeerID challenge-server="MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz", public-key="CAESIIE5dw6ofRdfVqNUZsNMfszLjYqRtO43ol32D1uPybOU"
|
||||||
@@ -356,7 +371,6 @@ Note over Client: Future requests use the bearer token
|
|||||||
```
|
```
|
||||||
|
|
||||||
[Peer ID spec]: https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md
|
[Peer ID spec]: https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md
|
||||||
|
|
||||||
[@MarcoPolo]: https://github.com/MarcoPolo
|
[@MarcoPolo]: https://github.com/MarcoPolo
|
||||||
[@sukunrt]: https://github.com/sukunrt
|
[@sukunrt]: https://github.com/sukunrt
|
||||||
[@achingbrain]: https://github.com/achingbrain
|
[@achingbrain]: https://github.com/achingbrain
|
||||||
|
|||||||
Reference in New Issue
Block a user