import { enums, PublicKey, type Subkey } from "openpgp"; export async function isKeyExpired( key: PublicKey | Subkey, ): Promise { const keyExpiration = await key.getExpirationTime(); return typeof keyExpiration === "number" ? new Date(keyExpiration) : keyExpiration; } export type RevocationReason = { flag?: string; msg?: string }; export type Revocation = { date: Date; reason: RevocationReason }; export function isKeyRevoked( key: PublicKey | Subkey, ): Revocation | undefined { const revokes = key.revocationSignatures.map(( { created, reasonForRevocationFlag, reasonForRevocationString }, ) => ({ created, reasonForRevocationFlag, reasonForRevocationString })); let keyRevocation: Revocation | undefined = undefined; for (const i of revokes) { const unix = i.created?.getTime(); if (unix === undefined) { continue; } const date = new Date(unix); if (keyRevocation === undefined || unix < keyRevocation.date.getTime()) { let flag = undefined; switch (i.reasonForRevocationFlag) { case enums.reasonForRevocation.noReason: { flag = "No reason specified (key revocations or cert revocations)"; break; } case enums.reasonForRevocation.keySuperseded: { flag = "Key is superseded (key revocations)"; break; } case enums.reasonForRevocation.keyCompromised: { flag = "Key material has been compromised (key revocations)"; break; } case enums.reasonForRevocation.keyRetired: { flag = "Key is retired and no longer used (key revocations)"; break; } case enums.reasonForRevocation.userIDInvalid: { flag = "User ID information is no longer valid (cert revocations)"; break; } } keyRevocation = { date, reason: { msg: i.reasonForRevocationString ?? undefined, flag }, }; } } return keyRevocation; } export const toPK = (key: PublicKey | Subkey): PublicKey => key instanceof PublicKey ? key : key.mainKey;