Skip to content

Commit

Permalink
Changes the spec to ensure public keys are user data.
Browse files Browse the repository at this point in the history
  • Loading branch information
Wes Biggs committed Apr 11, 2024
1 parent e1447f1 commit 5aab13a
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 12 deletions.
6 changes: 4 additions & 2 deletions pages/DSNP/Announcements.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ Each Announcement has an enumerated type for use when separating out a stream of
| 4 | [Reaction](Types/Reaction.md) | a public visual reply to a Broadcast | no | no |
| 5 | [Profile](Types/Profile.md) | a profile | YES | no |
| 6 | [Update](Types/Update.md) | an update to content| YES | no |
| 7 | [Public Key](Types/PublicKey.md) | a public key for secure communication | no | no |
| 7 | ~~[Public Key](Types/PublicKey.md)~~<sup>b</sup> | ~~a public key for secure communication~~ | ~~no~~ | ~~no~~ |

<sup>a</sup> Since DSNP version 1.2, social graph changes use [User Data](UserData.md) operations as described in the [Graph](Graph.md) section.
<sup>a</sup> Since DSNP version 1.2, social graph changes use [User Data](UserData.md) operations as described in the [Graph](Graph.md) section.

<sup>b</sup> Since DSNP version 1.3, public keys use [User Data](UserData.md) operations.

## Announcement Validation

Expand Down
2 changes: 2 additions & 0 deletions pages/DSNP/Types/PublicKey.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Public Key Announcement

<mark>_Since DSNP version 1.3, public keys use [User Data](../UserData.md) operations._</mark>

A Public Key Announcement is a way to note a new cryptographic key that can be used in DSNP to secure and verify the authenticity of communications.

The most recently published key (if one exists) for a given key type should be treated as the active key of that key type.
Expand Down
37 changes: 37 additions & 0 deletions pages/DSNP/Types/PublicKeyUserData.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Public Key

Represents an encoding of a public key, one half of a cryptographic key pair.

## Serialization

PublicKey object serialization MUST conform to the following [Avro](https://avro.apache.org) schema:

```
{
"namespace": "org.dsnp",
"name": "PublicKey",
"type": "record",
"fields": [
{
"name": "publicKey",
"type": "bytes",
"doc": "Multicodec public key"
}
]
}
```

## Generation

### publicKey

- MUST be a public key of an allowed key type for the associated User Data type, encoded in `multicodec` format

The byte encoding consists of a [multicodec](https://github.com/multiformats/multicodec/blob/master/table.csv) key identifier (as a varint) followed by the public key's binary data in the codec's described format.

#### Allowed Key Types

| User Data Type | Allowed Algorithms ([multicodec](https://github.com/multiformats/multicodec/blob/master/table.csv)) | Purpose |
| --- | --- | --- |
| `publicKey_keyAgreement` | `x25519-pub` | A Curve25519 public key that can be used in key exchange protocols to generate a shared secret |
| `publicKey_assertionMethod` | `ed25519-pub` | A public key for the EdDSA signature scheme using SHA-512 and Curve25519 that can be used to verify cryptographic signatures |
19 changes: 10 additions & 9 deletions pages/DSNP/UserData.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ DSNP implementations MUST support the following User Data Types:
| <a name="private-follows">`privateFollows`</a> | 1.2 | `curve25519xsalsa20poly1305` | [`DEFLATE`](https://en.wikipedia.org/wiki/Deflate) | [GraphEdge](Types/GraphEdge.md) |
| <a name="private-connections">`privateConnections`</a> | 1.2 | `curve25519xsalsa20poly1305` | [`DEFLATE`](https://en.wikipedia.org/wiki/Deflate) | [GraphEdge](Types/GraphEdge.md) |
| <a name="private-connection-prids">`privateConnectionPRIds`</a> | 1.2 | NONE | NONE | [PRId](Types/PRId.md) |
| <a name="public-key-key-agreement">`publicKey_keyAgreement`</a> | 1.3 | NONE | NONE | [PublicKey](Types/PublicKeyUserData.md) |
| <a name="public-key-assertion-method">`publicKey_assertionMethod`</a> | 1.3 | NONE | NONE | [PublicKey](Types/PublicKeyUserData.md) |

Data for each data type is initially formatted as a stream of Avro objects that should conform to the schema specified.
Avro file- and block-level information (including in-stream schema) is omitted.
Expand Down Expand Up @@ -46,8 +48,8 @@ The Replace User Data Operation takes the following parameters:

* A DSNP User Id
* Implementations MUST ensure that the principal invoking this Operation is this user, or a transparent chain of delegation from the user to the principal exists.
* A [Key Identifier](Types/PublicKey.md#keyid) for the `keyAgreement` key pair used to encrypt any private data in the operation.
(If only unencrypted user data types are included, the key identifier is optional.)
* The index of the `publicKey_keyAgreement` key pair used to encrypt any private data in the operation.
(If only unencrypted user data types are included, the key index may be omitted.)
* A map containing the set of data types to update as the keys, and tuples consisting of (1) the schema version used to encode the data type, and (2) a list where each element includes a data chunk and its associated entity tag, as the values.

If the Operation is successful, any previous data associated with the user for each data type included in the input MUST be removed and replaced by the new data.
Expand All @@ -61,9 +63,8 @@ Data chunks should be generated for each included data type using the following
3. For each chunk generated, the application should then:
1. If the data type requires compression, apply the compression codec noted.
1. If the data type requires encryption,
1. Retrieve the user's active (most recently announced) `keyAgreement` public key, U<sub>public</sub>.
The `keyId` in the announcement should match the key identifier provided for this Operation.
If no key exists, one should be created and published as an Announcement before invoking the Operation.
1. Retrieve the user's active (last in the list) `publicKey_keyAgreement` key, U<sub>public</sub>.
If no key exists, one should be created and published as User Data before invoking the Operation.
1. Create a sealed box (a payload encrypted with a symmetric key derived from an ephemeral key pair, and accompanied by the ephemeral public key), as in the [libsodium](https://doc.libsodium.org/public-key_cryptography/sealed_boxes) function `crypto_box_seal`, using U<sub>public</sub>.
1. Include the previous `etag` value for the chunk. If the chunk is new, `etag` should be set to `null`.
If any chunks are to be deleted, they should be included in the input identified with the existing `etag` and a `null` value for the data.
Expand Down Expand Up @@ -151,13 +152,13 @@ The Get User Data Operation takes the following parameters:
* Note: While _writing_ user data is reserved for the user and any delegates, anyone on the network can read any user's data (though it may be encrypted).
* The User Data Types (by system name) that should be retrieved.

The operation returns a mapping of User Data Type to data chunks, with each data chunk annotated with an entity tag and (optionally) a key identifier. (Note that this is the same general structure as the input data for [Replace User Data](#replace-user-data-operation), for each requested data type.
The operation returns a mapping of User Data Type to data chunks, with each data chunk annotated with an entity tag and (optionally) a key index. (Note that this is the same general structure as the input data for [Replace User Data](#replace-user-data-operation), for each requested data type.
If no chunks for a requested data type exist, an implementation MAY omit that data type from the response.

To transform the data from the output to Avro binary records, a consumer should apply the following algorithm to each data type included:
1. Determine the relevant encryption algorithm, compression codec, and object schema from the User Data Type and version noted.
1. For each chunk,
1. If encryption is indicated, decrypt the chunk data using the user's secret key (identified using the key identifier) as in the [libsodium](https://doc.libsodium.org/public-key_cryptography/sealed_boxes) function `crypto_box_seal_open`.
1. If encryption is indicated, decrypt the chunk data using the user's secret key (identified using the key index) as in the [libsodium](https://doc.libsodium.org/public-key_cryptography/sealed_boxes) function `crypto_box_seal_open`.
1. If compression is required, uncompress the chunk data using the specified codec.
1. Deserialize the uncompressed data to logical records according to the Avro object schema.
1. Retain the chunk's `etag` value if needed for any updates.
Expand Down Expand Up @@ -190,12 +191,12 @@ The following example illustrates the output of a Get User Data Operation invoca
{
"data": base64_string,
"etag": string,
"keyId": integer
"keyIndex": integer
},
{
"data": base64_string,
"etag": string,
"keyId": integer
"keyIndex": integer
}
]
},
Expand Down
3 changes: 2 additions & 1 deletion pages/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [User Data](DSNP/UserData.md)
- [Graph Edge](DSNP/Types/GraphEdge.md)
- [PRId](DSNP/Types/PRId.md)
- [Public Key](DSNP/Types/PublicKeyUserData.md)
- [Batch Publications](DSNP/BatchPublications.md)
- [Announcements](DSNP/Announcements.md)
- [Tombstone](DSNP/Types/Tombstone.md)
Expand All @@ -16,9 +17,9 @@
- [Reaction](DSNP/Types/Reaction.md)
- [Profile](DSNP/Types/Profile.md)
- [Update](DSNP/Types/Update.md)
- [Public Key](DSNP/Types/PublicKey.md)
- [Migrated Announcements](DSNP/Migrated.md)
- [Graph Change](DSNP/Types/GraphChange.md)
- [Public Key](DSNP/Types/PublicKey.md)
- [Operations](DSNP/Operations.md)
- [State Change Records](DSNP/Records.md)
- [Serializations](DSNP/Serializations.md)
Expand Down

0 comments on commit 5aab13a

Please sign in to comment.