import { parseSshSignature, sshFingerprint } from "./sshsig";
import { parsePgpSignature } from "./openpgp";
import type { PgpKey } from "./openpgp";
const decoder = new TextDecoder();
const encoder = new TextEncoder();
const SIGNATURE_HEADERS = new Set(["gpgsig", "gpgsig-sha256"]);
const EMAIL = /<([^>]*)>/;
export type SignedCommit = { payload: Uint8Array; signature: string | null; committerEmail: string | null };
/** Splits a raw commit into the signed payload (commit minus its gpgsig header) and the signature text. */
export function splitSignedCommit(raw: Uint8Array): SignedCommit {
const text = decoder.decode(raw);
const headerEnd = text.indexOf("\n\n");
const headers = headerEnd === -1 ? text : text.slice(0, headerEnd);
const rest = headerEnd === -1 ? "" : text.slice(headerEnd);
const kept: string[] = [];
const signature: string[] = [];
let inSignature = false;
let committerEmail: string | null = null;
for (const line of headers.split("\n")) {
if (line.startsWith(" ") && inSignature) {
signature.push(line.slice(1));
continue;
}
const name = line.slice(0, line.indexOf(" "));
inSignature = SIGNATURE_HEADERS.has(name) && signature.length === 0;
if (inSignature) {
signature.push(line.slice(name.length + 1));
continue;
}
if (name === "committer") committerEmail = EMAIL.exec(line)?.[1] ?? null;
kept.push(line);
}
return {
payload: encoder.encode(`${kept.join("\n")}${rest}`),
signature: signature.length > 0 ? `${signature.join("\n")}\n` : null,
committerEmail,
};