summaryrefslogtreecommitdiff
path: root/src/lib/pgp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pgp')
-rw-r--r--src/lib/pgp/summary.ts216
-rw-r--r--src/lib/pgp/verify.ts38
2 files changed, 134 insertions, 120 deletions
diff --git a/src/lib/pgp/summary.ts b/src/lib/pgp/summary.ts
index 5c8a81c..bcd9bc8 100644
--- a/src/lib/pgp/summary.ts
+++ b/src/lib/pgp/summary.ts
@@ -57,7 +57,7 @@ export type Summary = {
result: VerificationResult.MISSING_KEY;
reason: Error;
keyID: string;
- created: Date;
+ created: Date | null;
} | {
result:
| VerificationResult.SIGNATURE_CORRUPTED
@@ -67,11 +67,11 @@ export type Summary = {
} | {
result: VerificationResult.TRUSTED_KEY;
key: PublicKey | Subkey;
- created: Date;
+ created: Date | null;
} | {
result: VerificationResult.UNTRUSTED_KEY;
key: PublicKey | Subkey;
- created: Date;
+ created: Date | null;
} | {
result: VerificationResult.EXPIRATION_AFTER_SIGNATURE;
key: PublicKey | Subkey;
@@ -99,7 +99,7 @@ export type Summary = {
key: PublicKey | Subkey;
};
-export async function createVerificationSummary(
+export async function createVerificationsSummary(
{ dataCorrupted, verifications, signature }: Verification,
): Promise<[NonEmptyArray<Summary>, Map<string, NonEmptyArray<Summary>>]> {
if (signature === undefined) {
@@ -116,107 +116,7 @@ export async function createVerificationSummary(
const summaries = await Promise.all<
Promise<[Summary[], Map<string, Summary[]>]>[]
- >(
- (verifications ?? []).map(
- async ({ signatureCorrupted, verified, packet, key }) => {
- const errors: Summary[] = [];
- const keys: Map<string, Summary[]> = new Map();
-
- try {
- await verified;
- } catch (e) {
- if (e instanceof Error) {
- if (
- e.message.startsWith("Could not find signing key with key ID")
- ) {
- const keyID = e.message.slice(e.message.lastIndexOf(" "));
- const key = keys.get(keyID) ?? [];
- key.push({
- result: VerificationResult.MISSING_KEY,
- keyID,
- reason: e,
- });
- keys.set(keyID, key);
- } else {
- errors.push({
- result: VerificationResult.SIGNATURE_COULD_NOT_BE_CHECKED,
- reason: e,
- });
- }
- } else {
- throw e;
- }
- }
-
- const corrupted = await signatureCorrupted;
- if (corrupted[0]) {
- errors.push({
- result: VerificationResult.SIGNATURE_CORRUPTED,
- reason: corrupted[1],
- });
- }
-
- const sig = await packet;
- const keyID = sig.issuerKeyID;
-
- sig.created;
-
- const keyAwaited = await key;
-
- if (keyAwaited === undefined) {
- const key = keys.get(keyID.toHex()) ?? [];
- key.push({
- result: VerificationResult.MISSING_KEY,
- keyID: keyID.toHex(),
- reason: new Error(
- `Could not find signing key with key ID ${keyID.toHex()}`,
- ),
- });
- keys.set(keyID.toHex(), key);
-
- return [errors, keys] as [Summary[], Map<string, Summary[]>];
- }
-
- const keySummaries = keys.get(keyAwaited.getKeyID().toHex()) ?? [];
- const expired = await isKeyExpired(keyAwaited);
-
- if (expired !== null && sig.created !== null) {
- keySummaries.push({
- result: expired <= sig.created
- ? VerificationResult.EXPIRATION_BEFORE_SIGNATURE
- : VerificationResult.EXPIRATION_AFTER_SIGNATURE,
- key: keyAwaited,
- date: expired,
- });
- }
-
- const revoked = isKeyRevoked(keyAwaited);
- if (revoked?.date !== undefined && sig.created !== null) {
- keySummaries.push({
- result: revoked?.date <= sig.created
- ? VerificationResult.REVOCATION_BEFORE_SIGNATURE
- : VerificationResult.REVOCATION_AFTER_SIGNATURE,
- key: keyAwaited,
- date: revoked.date,
- revocationReason: revoked.reason,
- });
- }
-
- const trust = sig.trustAmount ?? await keyTrust(keyAwaited as Key);
-
- keySummaries.push({
- result: trust > 0
- ? VerificationResult.TRUSTED_KEY
- : VerificationResult.UNTRUSTED_KEY,
- key: keyAwaited,
- });
-
- keys.set(keyAwaited.getKeyID().toHex(), keySummaries);
-
- return [errors, keys] as [Summary[], Map<string, Summary[]>];
- },
- ),
- );
+ >((verifications ?? []).map(createVerificationSummary));
const errors = summaries.flatMap(([x]) => x);
const keys = new Map(summaries.flatMap(([, x]) => x.entries().toArray()));
@@ -230,3 +130,109 @@ export async function createVerificationSummary(
throw new Error("unreachable");
}
+
+export const createVerificationSummary = async (
+ { signatureCorrupted, verified, packet, key }: NonNullable<
+ Verification["verifications"]
+ >[number],
+): Promise<[Summary[], Map<string, Summary[]>]> => {
+ const errors: Summary[] = [];
+ const keys: Map<string, Summary[]> = new Map();
+
+ const sig = await packet;
+
+ try {
+ await verified;
+ } catch (e) {
+ if (e instanceof Error) {
+ if (
+ e.message.startsWith("Could not find signing key with key ID")
+ ) {
+ const keyID = e.message.slice(e.message.lastIndexOf(" "));
+ const key = keys.get(keyID) ?? [];
+ key.push({
+ result: VerificationResult.MISSING_KEY,
+ keyID,
+ reason: e,
+ created: sig.created,
+ });
+ keys.set(keyID, key);
+ } else {
+ errors.push({
+ result: VerificationResult.SIGNATURE_COULD_NOT_BE_CHECKED,
+ reason: e,
+ });
+ }
+ } else {
+ throw e;
+ }
+ }
+
+ const corrupted = await signatureCorrupted;
+ if (corrupted[0]) {
+ errors.push({
+ result: VerificationResult.SIGNATURE_CORRUPTED,
+ reason: corrupted[1],
+ });
+ }
+
+ const keyID = sig.issuerKeyID;
+
+ const keyAwaited = await key;
+
+ if (keyAwaited === undefined) {
+ const key = keys.get(keyID.toHex()) ?? [];
+ key.push({
+ result: VerificationResult.MISSING_KEY,
+ keyID: keyID.toHex(),
+ reason: new Error(
+ `Could not find signing key with key ID ${keyID.toHex()}`,
+ ),
+ created: sig.created,
+ });
+ keys.set(keyID.toHex(), key);
+
+ return [errors, keys] as [Summary[], Map<string, Summary[]>];
+ }
+
+ const keySummaries = keys.get(keyAwaited.getKeyID().toHex()) ?? [];
+ const expired = await isKeyExpired(keyAwaited);
+
+ if (expired !== null && sig.created !== null) {
+ keySummaries.push({
+ result: expired <= sig.created
+ ? VerificationResult.EXPIRATION_BEFORE_SIGNATURE
+ : VerificationResult.EXPIRATION_AFTER_SIGNATURE,
+ key: keyAwaited,
+ created: sig.created,
+ expired,
+ });
+ }
+
+ const revoked = isKeyRevoked(keyAwaited);
+ if (revoked?.date !== undefined && sig.created !== null) {
+ keySummaries.push({
+ result: revoked?.date <= sig.created
+ ? VerificationResult.REVOCATION_BEFORE_SIGNATURE
+ : VerificationResult.REVOCATION_AFTER_SIGNATURE,
+ key: keyAwaited,
+ created: sig.created,
+ revoked: revoked.date,
+ revocationReason: revoked.reason,
+ });
+ }
+
+ const trust = sig.trustAmount ?? await keyTrust(keyAwaited as Key);
+
+ keySummaries.push({
+ result: trust > 0
+ ? VerificationResult.TRUSTED_KEY
+ : VerificationResult.UNTRUSTED_KEY,
+ key: keyAwaited,
+ created: sig.created,
+ });
+
+ keys.set(keyAwaited.getKeyID().toHex(), keySummaries);
+
+ return [errors, keys] as [Summary[], Map<string, Summary[]>];
+};
diff --git a/src/lib/pgp/verify.ts b/src/lib/pgp/verify.ts
index 026b6df..1003147 100644
--- a/src/lib/pgp/verify.ts
+++ b/src/lib/pgp/verify.ts
@@ -24,6 +24,7 @@ import type { Commit } from "../git/types.ts";
import { findMapAsync, type MaybeIterable } from "../../utils/iterator.ts";
import { getUserIDsFromKey } from "./user.ts";
import { env } from "../environment.ts";
+import { toPK } from "./index.ts";
type DataURL = [URL, URL?];
type Corrupted = [false] | [true, Error];
@@ -195,18 +196,21 @@ export class SignatureVerifier {
}
}
- addKey(key: MaybeIterable<PublicKey>): void {
+ addKey(key: MaybeIterable<PublicKey>): Iterable<PublicKey> {
if (key instanceof PublicKey) {
this.keys.push(key);
+ return [key];
} else {
this.keys.push(...key);
+ return key;
}
}
async addKeysFromDir(
key: string | URL,
rules: KeyDiscoveryRules = DEFAULT_KEY_DISCOVERY_RULES,
- ): Promise<void> {
+ ): Promise<Iterable<PublicKey>> {
+ const keys: PublicKey[] = [];
for await (
const i of createKeysFromDir(key, rules, {
encoder: this.#encoder,
@@ -214,39 +218,43 @@ export class SignatureVerifier {
})
) {
this.keys.push(i);
+ keys.push(i);
}
+ return keys;
}
async addKeyFromFile(
key: string | URL,
type: KeyFileFormat,
- ): Promise<void> {
+ ): Promise<PublicKey> {
switch (type) {
case armored: {
- this.keys.push(await createKeyFromFile(key, type, this.#decoder));
- break;
+ const k = await createKeyFromFile(key, type, this.#decoder);
+ this.keys.push(k);
+ return k;
}
case binary: {
- this.keys.push(await createKeyFromFile(key, type, this.#encoder));
- break;
+ const k = await createKeyFromFile(key, type, this.#encoder);
+ this.keys.push(k);
+ return k;
}
}
}
async addKeyFromArmor(
key: string | Uint8Array,
- ): Promise<void> {
- this.keys.push(
- await createKeyFromArmor(key, this.#decoder).then((x) => x.toPublic()),
- );
+ ): Promise<PublicKey> {
+ const k = await createKeyFromArmor(key, this.#decoder).then(toPK);
+ this.keys.push(k);
+ return k;
}
async addKeyFromBinary(
key: string | Uint8Array,
- ): Promise<void> {
- this.keys.push(
- await createKeyFromBinary(key, this.#encoder).then((x) => x.toPublic()),
- );
+ ): Promise<PublicKey> {
+ const k = await createKeyFromBinary(key, this.#encoder).then(toPK);
+ this.keys.push(k);
+ return k;
}
public static async instance(): Promise<SignatureVerifier> {