From 8f5136c8c84698e0b75235f41cc9754f670d78d2 Mon Sep 17 00:00:00 2001 From: Gaspard Wierzbinski Date: Sun, 26 Nov 2023 18:04:07 -1000 Subject: [PATCH 1/3] Update signing.md --- docs/cryptography/signing.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/docs/cryptography/signing.md b/docs/cryptography/signing.md index adf9215..f0d3aa6 100644 --- a/docs/cryptography/signing.md +++ b/docs/cryptography/signing.md @@ -56,7 +56,7 @@ Here is an example of signing a request using TypeScript and the WebCrypto API: ```typescript const privateKey = await crypto.subtle.importKey( "pkcs8", - atob("base64_private_key"), + str2ab(atob("base64_private_key")), "Ed25519", false, ["sign"] @@ -67,18 +67,26 @@ const digest = await crypto.subtle.digest( new TextEncoder().encode("request_body") ); +const userInbox = new URL("..."); + +const date = new Date(); + const signature = await crypto.subtle.sign( "Ed25519", privateKey, new TextEncoder().encode( - "(request-target): post /users/uuid/inbox\n" + - "host: example.com\n" + - "date: Fri, 01 Jan 2021 00:00:00 GMT\n" + - "digest: SHA-256=" + btoa(digest) + `(request-target): post ${userInbox.pathname}\n` + + `host: ${userInbox.host}\n` + + `date: ${date.toUTCString()}\n` + + `digest: SHA-256=${btoa( + String.fromCharCode(...new Uint8Array(digest)) + )}\n` ) ); -const signatureBase64 = base64Encode(signature); +const signatureBase64 = btoa( + String.fromCharCode(...new Uint8Array(signature)) +); ``` > **Note**: Support for Ed25519 in the WebCrypto API is recent and may not be available in some older runtimes, such as Node.js or older browsers. @@ -89,9 +97,9 @@ await fetch("https://example.com/users/uuid/inbox", { method: "POST", headers: { "Content-Type": "application/json", - "Date": "Fri, 01 Jan 2021 00:00:00 GMT", - "Origin": "https://example.com", - "Signature": `keyId="https://example.com/users/uuid",algorithm="ed25519",headers="(request-target) host date digest",signature="${signatureBase64}"` + Date: date.toUTCString(), + Origin: "https://example.com", + Signature: `keyId="${...}",algorithm="ed25519",headers="(request-target) host date digest",signature="${signatureBase64}"`, }, body: JSON.stringify({ // ... From 7c0e3755a03ab272965e9f8ea5f9ec36ba3b517a Mon Sep 17 00:00:00 2001 From: Gaspard Wierzbinski Date: Sun, 26 Nov 2023 18:07:35 -1000 Subject: [PATCH 2/3] Update signing.md --- docs/cryptography/signing.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/cryptography/signing.md b/docs/cryptography/signing.md index f0d3aa6..b6534d8 100644 --- a/docs/cryptography/signing.md +++ b/docs/cryptography/signing.md @@ -54,6 +54,19 @@ Where `/users/uuid/inbox` is the path of the request. Here is an example of signing a request using TypeScript and the WebCrypto API: ```typescript +/** + * Convert a string into an ArrayBuffer + * from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String + */ +const str2ab = (str: string) => { + const buf = new ArrayBuffer(str.length); + const bufView = new Uint8Array(buf); + for (let i = 0, strLen = str.length; i < strLen; i++) { + bufView[i] = str.charCodeAt(i); + } + return buf; +}; + const privateKey = await crypto.subtle.importKey( "pkcs8", str2ab(atob("base64_private_key")), From 158ec6ead4216cf6d9caecabff7edcfd605303d5 Mon Sep 17 00:00:00 2001 From: Gaspard Wierzbinski Date: Sun, 17 Dec 2023 00:05:14 -1000 Subject: [PATCH 3/3] Update spec.md --- docs/spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/spec.md b/docs/spec.md index b046b40..c3c8429 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -16,7 +16,7 @@ Lysand-compatible servers may implement other protocols as well, such as Activit # Required Across Implementations -All HTTP request bodies and response bodies **MUST** be encoded as UTF-8 JSON, with the `Content-Type` header set to `application/json; charset=utf-8`. If cryptography is supported by the server, there **MUST** also be a `Signature` header as defined in [/signatures](the signatures spec). +All HTTP request bodies and response bodies **MUST** be encoded as UTF-8 JSON, with the `Content-Type` header set to `application/json; charset=utf-8`. If cryptography is supported by the server, there **MUST** also be a `Signature` header as defined in [the signatures spec](/cryptography/signing). Servers **MUST** use UUIDs or a UUID-compatible system for the `id` field. Any kind of UUID is allowed, as long as it is a valid UUID. It **should** be unique across the entire known network if possible, but this is not needed as long as the server can guarantee that the `id` is unique across the server. @@ -24,4 +24,4 @@ Servers **MUST** use UUIDs or a UUID-compatible system for the `id` field. Any k All URIs **MUST** be absolute URIs, and **MUST** be HTTPS URIs, except for development purposes. They **MUST** be unique across the entire network, and **MUST** contain the `id` of the object in the URI. They **should not** contain data that can be changed, such as the actor's `username`. -All URIs **MUST** be normalized, and **MUST NOT** contain any query parameters \ No newline at end of file +All URIs **MUST** be normalized, and **MUST NOT** contain any query parameters