You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: COLDWIRE_PROTOCOL.md
+68-4Lines changed: 68 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -67,6 +67,8 @@ If you rotate header sets between different requests, that creates a unique fing
67
67
#### 2.2. Federated servers headers
68
68
`Coldwire` server implementations *must* adhere to the following requirements for `HTTP` requests:
69
69
- You **must not** include any headers that may indicate to a server you're intending to receive compressed (gzip, etc) response!
70
+
71
+
- Your `Coldwire` server implementation **must not** return any compressed responses. Return responses as raw uncompressed bytes.
70
72
71
73
-*All*`HTTP` field headers name **must** be lower-case, for compatiability with `HTTP/2` servers.
72
74
The HTTP specification requires it, needed incase a Coldwire server implementation is behind another server.
@@ -231,12 +233,11 @@ The `Strandlock protocol` can be quite heavy (some ciphertext reaching MBs in si
231
233
### 5. Federation
232
234
Federation protocol between different `Coldwire` servers.
233
235
234
-
All `Coldwire` servers must have a long-term `ML-DSA-87` keypair.
235
-
236
-
All requests payloads and responses are returned in `JSON` format.
237
-
236
+
All `Coldwire` servers must have a long-term `ML-DSA-87` keypair saved securely, locally.
238
237
239
238
#### 5.1. Federation Info
239
+
All requests payloads and responses are sent and returned in `JSON` format.
240
+
240
241
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:
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.
264
265
265
266
267
+
#### 5.2. Federation send
268
+
When `Alice` who is using a Coldwire server (`server A`) sends `Bob` a request who is using another Coldwire server (`server B`), `server A` constructs a `Form` payload with field `metadata` and a `File Upload` with file name of `blob`.
269
+
270
+
The `metadata` field payload data:
271
+
```
272
+
{
273
+
"recipient": "recipient 16-digits User-ID, no URL",
274
+
"sender": "sender 16-digits User-ID, no URL",
275
+
"url": "server_A URL with no HTTP/S prefixes."
276
+
}
277
+
```
278
+
279
+
`server A` also creates a `ML-DSA-87- signature with following data:
`blob` being the ciphertext `Alice` is sending to `Bob.
289
+
290
+
291
+
`server B` receives the request, processes it by doing sanity checks against the provided User-IDs (i.e., are they correct format, etc), and sanity checks against provided `url` (is it valid domain and or IP, etc), and it checks if `recipient` exists in the database. If any of checks failed, `server B` must return a 40x error code to `server A`.
292
+
293
+
294
+
`server B` then checks if they have `server A` public-key saved, if not, they fetch and save it (see `5.1. Federation Info`).
295
+
`server B` then checks the saved `server A's` refetch_date, if the date is due (=< today), `server B` refetches `server A` public-key.
296
+
297
+
298
+
If all the previous checks and operations succeed, `server B` separates the `signature` from the `blob`:
299
+
```
300
+
signature = blob[:ML_DSA_87_SIGN_LEN]
301
+
```
302
+
And sets blob:
303
+
```
304
+
blob = blob[ML_DSA_87_SIGN_LEN:]
305
+
```
306
+
`ML_DSA_87_SIGN_LEN` being the signature length that `ML-DSA-87` produces (`4627 bytes`)
307
+
308
+
Then, `server B` checks signature using `server A's` public-key.
309
+
If not valid, `server B` returns a 40x error code.
310
+
311
+
If valid:
312
+
`server B` adds `url` to `sender`, separated by "`@`", then UTF-8 encoding it:
0 commit comments