import { generateKeyPairSync } from "node:crypto"; /** Kleine Wire-Format-Helfer, um gezielt kaputte oder seltene Blobs zu bauen (#006). */ export function sshString(inhalt: Buffer | string): Buffer { const daten = typeof inhalt === "string" ? Buffer.from(inhalt) : inhalt; const laenge = Buffer.alloc(4); laenge.writeUInt32BE(daten.length); return Buffer.concat([laenge, daten]); } export function mpint(betrag: Buffer): Buffer { return sshString((betrag[0]! & 0x80) !== 0 ? Buffer.concat([Buffer.from([0]), betrag]) : betrag); } export function zeile(typ: string, blob: Buffer, kommentar = "test"): string { return `${typ} ${blob.toString("base64")} ${kommentar}`; } export function rsaBlob(bits: number): Buffer { const { publicKey } = generateKeyPairSync("rsa", { modulusLength: bits }); const jwk = publicKey.export({ format: "jwk" }); return Buffer.concat([ sshString("ssh-rsa"), mpint(Buffer.from(jwk.e!, "base64url")), mpint(Buffer.from(jwk.n!, "base64url")), ]); } const KURVEN = { nistp256: "P-256", nistp384: "P-384", nistp521: "P-521" } as const; export function ecdsaPunkt(kurve: keyof typeof KURVEN): Buffer { const { publicKey } = generateKeyPairSync("ec", { namedCurve: KURVEN[kurve] }); const jwk = publicKey.export({ format: "jwk" }); return Buffer.concat([ Buffer.from([4]), Buffer.from(jwk.x!, "base64url"), Buffer.from(jwk.y!, "base64url"), ]); } export function ecdsaBlob(kurve: keyof typeof KURVEN): Buffer { return Buffer.concat([sshString(`ecdsa-sha2-${kurve}`), sshString(kurve), sshString(ecdsaPunkt(kurve))]); } export function ed25519Roh(): Buffer { const { publicKey } = generateKeyPairSync("ed25519"); return Buffer.from(publicKey.export({ format: "jwk" }).x!, "base64url"); } export function ed25519Blob(): Buffer { return Buffer.concat([sshString("ssh-ed25519"), sshString(ed25519Roh())]); } export function skEd25519Blob(): Buffer { return Buffer.concat([sshString("sk-ssh-ed25519@openssh.com"), sshString(ed25519Roh()), sshString("ssh:")]); } export function skEcdsaBlob(): Buffer { return Buffer.concat([ sshString("sk-ecdsa-sha2-nistp256@openssh.com"), sshString("nistp256"), sshString(ecdsaPunkt("nistp256")), sshString("ssh:"), ]); } /** Base64-Rumpf eines PEM-Textes, um Fehlermeldungen auf Schluesselmaterial zu pruefen. */ export function pemRumpf(pem: string): string { return pem .split("\n") .filter((z) => z && !z.startsWith("-----")) .join(""); } /** Ob `text` irgendein 16-Zeichen-Stueck aus `material` enthaelt. */ export function enthaeltMaterial(text: string, material: string): boolean { for (let i = 0; i + 16 <= material.length; i += 4) { if (text.includes(material.slice(i, i + 16))) return true; } return false; }