Skip to content

Commit 5e06e34

Browse files
authored
Update COLDWIRE_PROTOCOL.md
1 parent 401468b commit 5e06e34

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

COLDWIRE_PROTOCOL.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Author(s): **`ChadSec1`** (**`Freedom Club Sec`**)
77

88
Contact: github.com/Freedom-Club-Sec
99

10-
Status: **`Draft`**
10+
Status: **`Work-in-progress`**
1111

1212
Intended Audience: Security engineers, cryptographers, protocol implementers
1313

@@ -170,13 +170,16 @@ metadata: {
170170
"recipient": "Bobs User_ID"
171171
}
172172
```
173+
173174
and bundled within the same request, is a `File Upload` with name `blob`, containing raw bytes (ciphertext, etc)
174175

175176
#### 4.2. Data processor (`Server`)
176177
`Coldwire` server receives data request, verifies the `Alice's` `JWT token`, and checks if the `recipient` is all digits:
178+
177179
if not, checks if `recipient` format is correct (i.e. "[email protected]") and sends a request to the target `Coldwire` server.
178180

179181
If `recipient` is all digits, the server checks if they exist in the local database, if not, they return a 400 error.
182+
180183
If they exist, the `Coldwire` server then processes the `blob`, rejecting it if it's empty.
181184

182185
If the sender or `recipient` contain a "@", request is rejected.
@@ -185,11 +188,13 @@ The `Coldwire` server then process the request by constructing a payload which c
185188
```
186189
payload = user_id_utf_8 + \x0 + blob
187190
```
191+
188192
Then the length of the `payload` is calculated, and a `length` prefix of size `3 bytes` in `big-endian` format is inserted at the start of the payload:
189193
```
190194
payload = length_prefix + payload
191195
```
192196

197+
193198
And the data is saved to the `recipient` inbox (any saving medium, can be Redis, SQL database, etc).
194199

195200
#### 4.3. Receiving Data (`Bob` <- `Server`)
@@ -199,20 +204,58 @@ URL: example.com/data/longpoll
199204
```
200205

201206
The `Coldewire` server sends a response of either empty bytes, or many `message_payloads` continunesly concatenated together.
207+
202208
After `Coldwire` server sends a response to `Bob`, it deletes all the previously saved data payloads queue.
203209

204210
`Bob` client parses the response, by using the `length_prefix` at start of each message, `Bob` can separate each message.
211+
205212
`Bob` then further parses it, by separating a message sender, from the blob, by splitting on the first NULL byte (`\0`)
213+
206214
`Bob` client verifies the format of the `sender` identifier is correct, simply dismissing message if not.
215+
207216
`Bob` then processes the `blob` using the `Strandlock protocol`
208217

209218

210219
#### 4.4. Notes
211220
Replay protection, tampering protection, authentication, MiTM protection, etc, are all handled by the `Strandlock protocol`.
212221

213-
The reason we send request in `Form` and `File Uploads`, and receive back response as `raw bytes`, is to save bandwidth. The `Strandlock protocol` can be quite heavy (some ciphertext reaching MBs in size).
222+
The reason we send request in `Form` and `File Uploads`, and receive back response as `raw bytes`, is to save bandwidth.
223+
The `Strandlock protocol` can be quite heavy (some ciphertext reaching MBs in size).
224+
225+
226+
227+
### 5. Federation
228+
Federation protocol between different `Coldwire` servers.
229+
230+
All `Coldwire` servers must have a long-term `ML-DSA-87` keypair.
214231

232+
All requests payloads and responses are returned in `JSON` format.
215233

216234

235+
#### 5.1. Federation Info
236+
When a `Coldwire` server (`server A`) process a request from another `Coldwire` server (`server B`), `server A` checks if they have `server B` public-key saved, if not, they fetch it by sending a `GET` request to the following endpoint:
237+
```
238+
URL: example.com/federation/info
239+
```
240+
241+
The `server_B` constructs a response to be signed:
242+
```
243+
response = server_url_utf_8 + refetch_date_utf_8
244+
```
245+
`server_B_url_utf_8` being the server's own URL, and `refetch_date_utf_8` being the timestamp in UTC for when the requester should refetch the key again, in format:
246+
```
247+
%Y-%m-%d
248+
```
249+
250+
`server B` signs the response with it's private signing key, and returns a `JSON` response of:
251+
```json
252+
{
253+
"public_key": "base64_encoded_server_public_key"
254+
"refetch_date": "UTC timestamp of when to refetch key"
255+
"signature": "base64_encoded_response_signature"
256+
}
257+
```
258+
259+
After `server A` receives the response from `server B`, they verify the signature. If valid, they save the `public_key` and `refetch_date` alongside `server B`'s` URL.
217260

218261

0 commit comments

Comments
 (0)