aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/canaries/keystore.ts
diff options
context:
space:
mode:
authorLibravatarLarge Libravatar memdmp <memdmpestrogenzone>2025-01-22 21:19:22 +0100
committerLibravatarLarge Libravatar memdmp <memdmpestrogenzone>2025-01-22 21:19:22 +0100
commitc5a7e704d1c836119319ce3b308642f195b078d9 (patch)
tree616e94bc0e92e5df378208e8c4f81af3c2e71c7e /src/routes/canaries/keystore.ts
parent09e7d196b200ad7c61d223c70295644eafcae717 (diff)
downloadmem-estrogen-zone-c5a7e704d1c836119319ce3b308642f195b078d9.tar.gz
mem-estrogen-zone-c5a7e704d1c836119319ce3b308642f195b078d9.tar.bz2
mem-estrogen-zone-c5a7e704d1c836119319ce3b308642f195b078d9.tar.lz
mem-estrogen-zone-c5a7e704d1c836119319ce3b308642f195b078d9.zip

feat: canarytool :3

Diffstat (limited to 'src/routes/canaries/keystore.ts')
-rw-r--r--src/routes/canaries/keystore.ts71
1 files changed, 56 insertions, 15 deletions
diff --git a/src/routes/canaries/keystore.ts b/src/routes/canaries/keystore.ts
index af710ec..1d2aefb 100644
--- a/src/routes/canaries/keystore.ts
+++ b/src/routes/canaries/keystore.ts
@@ -1,7 +1,10 @@
+import { dev } from "$app/environment";
import { PublicKey, readCleartextMessage, readKey, verify } from "openpgp";
+import { fallbackKeys } from "./fallback-keys";
export const keyStore = new Map<string, PublicKey>();
-export const validateSignature = async (message: string, id: string) => {
- await initKeystore;
+const will_debug = false;
+const debug = dev && will_debug ? console.debug : () => void 0;
+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");
@@ -14,36 +17,64 @@ export const validateSignature = async (message: string, id: string) => {
expectSigned: true,
});
return verificationResult.data;
+}
+export const validateSignature: typeof _validateSignature = async (message, id) => {
+ await initKeystore;
+ return _validateSignature(message, id)
};
const pushKey = async ({
ids,
key,
is_url,
- expectUserIds,
+ expect_user_ids,
+ expect_fingerprint,
signed_by,
}: {
ids?: string[];
- expectUserIds?: string[];
+ expect_user_ids?: string[];
+ expect_fingerprint?: string;
key: string;
is_url?: boolean;
signed_by?: string;
}) => {
ids = ids ?? [];
if (is_url) {
+ const url = new URL(key, "https://keys.openpgp.org/vks/v1/by-fingerprint/");
+ debug('getting key with url', url)
key = await fetch(
- new URL(key, "https://keys.openpgp.org/vks/v1/by-fingerprint/"),
- {},
- ).then((v) => v.text());
+ url,
+ ).then((v) => v.text()).catch(e => {
+ if (fallbackKeys.has(key)) {
+ debug('failed with error', e, 'but found fallback key')
+ return fallbackKeys.get(key)!
+ }
+ else {
+ debug('failed to fetch key, cannot find fallback')
+ throw e
+ }
+ });
+ debug('fetched key', key)
+ } else {
+ debug('found key', key)
}
+ if (key === null)
+ throw new Error('Key is null.')
+ if (key === '')
+ throw new Error('Key is empty string.')
+ if (typeof key !== 'string')
+ throw new Error(`Expected key with type string, got key of type ${key}`)
if (signed_by) {
- key = await validateSignature(key, signed_by);
+ debug('key must be signed by', signed_by)
+ key = await _validateSignature(key, signed_by);
+ debug('validated signature')
}
const parsedKey = await readKey({
armoredKey: key,
}).then((v) => v.toPublic());
{
+ const ids = parsedKey.getUserIDs();
const missingUserIds =
- expectUserIds?.filter((v) => !expectUserIds.includes(v)) ?? [];
+ expect_user_ids?.filter((v) => !ids.includes(v)) ?? [];
if (missingUserIds.length) {
throw new Error(
`Key ${parsedKey.getFingerprint()} is missing User IDs: ${missingUserIds.join(
@@ -52,24 +83,34 @@ const pushKey = async ({
);
}
}
+ if (expect_fingerprint && parsedKey.getFingerprint().toUpperCase() !== expect_fingerprint.toUpperCase())
+ throw new Error(
+ `Key ${parsedKey.getFingerprint()} is not ${expect_fingerprint}`,
+ );
+ else if (expect_fingerprint)
+ debug('fingerprint matches expected fingerprint')
+ else
+ debug('no expected fingerprint passed')
ids.push(
parsedKey.getKeyID().toHex().replace(/ /g, ""),
parsedKey.getFingerprint().replace(/ /g, ""),
- ...(expectUserIds ?? []),
+ ...(expect_user_ids ?? []),
);
ids = ids.filter((v, i, a) => a.indexOf(v) === i).map((v) => v.toUpperCase());
for (const id of ids) {
keyStore.set(id, parsedKey);
}
+ debug('added key', parsedKey, 'with ids', ids, 'to keystore')
};
export const initKeystore = (async () => {
await pushKey({
- key: "B546778F06BBCC8EC167DB3CD919706487B8B6DE",
+ key: 'B546778F06BBCC8EC167DB3CD919706487B8B6DE',
ids: ["memdmp"],
- expectUserIds: [
+ expect_user_ids: [
"memdmp <memdmp@estrogen.zone>",
"memdmp <memdmp@memeware.net>",
],
+ expect_fingerprint: 'B546778F06BBCC8EC167DB3CD919706487B8B6DE',
is_url: true,
});
await pushKey({
@@ -108,12 +149,12 @@ ZQ4KTbprMz8J4AD/bG33f9Kqg3AqehEyU2TldJs9U9Oni5AXGSGfKLJhmQc=
`,
signed_by: "memdmp <memdmp@memeware.net>",
ids: ["canary-sigkey-signing"],
+ expect_fingerprint: '55D3582CAE78601990A8CA1DBFD0F9E61CB7D84E'
});
await pushKey({
- // TODO: adapt to the relevant url on current domain when up
- key: "https://files.catbox.moe/yf4x40.sig",
+ key: "https://git.estrogen.zone/mem-estrogen-zone.git/plain/static/keys/external/napatha.pgp.sig",
ids: ["napatha"],
- expectUserIds: ["chef naphtha <naphtha@kyun.host>"],
+ expect_user_ids: ["chef naphtha <naphtha@kyun.host>"],
is_url: true,
signed_by: "canary-sigkey-signing",
});