aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/canaries/keystore.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes/canaries/keystore.ts')
-rw-r--r--src/routes/canaries/keystore.ts120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/routes/canaries/keystore.ts b/src/routes/canaries/keystore.ts
new file mode 100644
index 0000000..788428d
--- /dev/null
+++ b/src/routes/canaries/keystore.ts
@@ -0,0 +1,120 @@
+import { PublicKey, readCleartextMessage, readKey, verify } from 'openpgp';
+export const keyStore = new Map<string, PublicKey>();
+export const validateSignature = async (
+ message: string,
+ id: string,
+) => {
+ id = id.toUpperCase();
+ const key = keyStore.get(id) ?? keyStore.get(id.replace(/ /g, ''));
+ if (!key) throw new Error('Could not find key from keystore');
+ const signedMessage = await readCleartextMessage({
+ cleartextMessage: message,
+ });
+ const verificationResult = await verify({
+ message: signedMessage,
+ verificationKeys: key,
+ expectSigned: true,
+ });
+ return verificationResult.data;
+};
+const pushKey = async (
+ { ids, key, is_url, expectUserIds, signed_by }: {
+ ids?: string[];
+ expectUserIds?: string[];
+ key: string;
+ is_url?: boolean;
+ signed_by?: string;
+ },
+) => {
+ ids = ids ?? [];
+ if (is_url) {
+ key = await fetch(
+ new URL(key, 'https://keys.openpgp.org/vks/v1/by-fingerprint/'),
+ {},
+ ).then((v) => v.text());
+ }
+ if (signed_by) {
+ key = await validateSignature(key, signed_by);
+ }
+ const parsedKey = await readKey({
+ armoredKey: key,
+ }).then((v) => v.toPublic());
+ {
+ const missingUserIds =
+ expectUserIds?.filter((v) => !expectUserIds.includes(v)) ?? [];
+ if (missingUserIds.length) {
+ throw new Error(
+ `Key ${parsedKey.getFingerprint()} is missing User IDs: ${
+ missingUserIds.join(', ')
+ }`,
+ );
+ }
+ }
+ ids.push(
+ parsedKey.getKeyID().toHex().replace(/ /g, ''),
+ parsedKey.getFingerprint().replace(/ /g, ''),
+ ...(expectUserIds ?? []),
+ );
+ ids = ids.filter((v, i, a) => a.indexOf(v) === i).map((v) => v.toUpperCase());
+ for (const id of ids) {
+ keyStore.set(id, parsedKey);
+ }
+};
+await pushKey({
+ key: 'B546778F06BBCC8EC167DB3CD919706487B8B6DE',
+ ids: ['memdmp'],
+ expectUserIds: [
+ 'memdmp <memdmp@estrogen.zone>',
+ 'memdmp <memdmp@memeware.net>',
+ ],
+ is_url: true,
+});
+await pushKey({
+ // TODO: when primary memdmp key rotates, or when this key expires, replace this inline string with a new one
+ key: `-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+- -----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: User ID: memdmp canary keysig <memdmp-key-for-signing-canary-related-keys-for-external-services@fakemail.uwu>
+Comment: Valid from: 22 Nov 2024 18:31:11
+Comment: Valid until: 22 Nov 2027 12:00:00
+Comment: Type: 255-bit EdDSA (secret key available)
+Comment: Usage: Signing, Encryption, Certifying User IDs
+Comment: Fingerprint: 55D3582CAE78601990A8CA1DBFD0F9E61CB7D84E
+
+mDMEZ0C/3xYJKwYBBAHaRw8BAQdA5w4ET7V3FmasUc3h9sb0O0/y38LXp+IUV8Wf
+La95jm20ZG1lbWRtcCBjYW5hcnkga2V5c2lnIDxtZW1kbXAta2V5LWZvci1zaWdu
+aW5nLWNhbmFyeS1yZWxhdGVkLWtleXMtZm9yLWV4dGVybmFsLXNlcnZpY2VzQGZh
+a2VtYWlsLnV3dT6ImQQTFgoAQRYhBFXTWCyueGAZkKjKHb/Q+eYct9hOBQJnQL/f
+AhsDBQkFoz7RBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEL/Q+eYct9hO
+X68BAPPBy76J7EWb25+fj/QUD0rYyi/E2kLfGbW+PLhrB/AdAQDl5icCilAI/2xv
+X4jpGCH9KdJoClIV4g2AyKoEITKBDbg4BGdAv98SCisGAQQBl1UBBQEBB0CcYmml
+AWFCXVjIerJJrs/GA65EZDwoZowiVVTS99FvaQMBCAeIfgQYFgoAJhYhBFXTWCyu
+eGAZkKjKHb/Q+eYct9hOBQJnQL/fAhsMBQkFoz7RAAoJEL/Q+eYct9hOr2IA/22U
+2rOPevvUoiObv/DeeQlP2mvaQcOCFHp1HVF+4oHrAQDWZiihBvdIESbqm5MH0zLe
+EkEE03+lW4Zbe25P6MHsBg==
+=5NPo
+- -----END PGP PUBLIC KEY BLOCK-----
+-----BEGIN PGP SIGNATURE-----
+
+iIoEARYKADIWIQS1RnePBrvMjsFn2zzZGXBkh7i23gUCZ0DABRQcbWVtZG1wQG1l
+bWV3YXJlLm5ldAAKCRDZGXBkh7i23vV5AP9K2Q6j6cOGovTVqsWlThK7qxA2Faz+
+ZQ4KTbprMz8J4AD/bG33f9Kqg3AqehEyU2TldJs9U9Oni5AXGSGfKLJhmQc=
+=945T
+-----END PGP SIGNATURE-----
+`,
+ signed_by: 'memdmp <memdmp@memeware.net>',
+ ids: ['canary-sigkey-signing'],
+});
+await pushKey({
+ // TODO: adapt to the relevant url on current domain when up
+ key: 'https://files.catbox.moe/yf4x40.sig',
+ ids: ['napatha'],
+ expectUserIds: [
+ 'chef naphtha <naphtha@kyun.host>',
+ ],
+ is_url: true,
+ signed_by: 'canary-sigkey-signing',
+});
+
+export default keyStore;