import { fromBase64, toBase64 } from "../crypto";
const encoder = new TextEncoder();
const MAGIC = "SSHSIG";
const GIT_NAMESPACE = "git";
const ARMOR = /-----BEGIN SSH SIGNATURE-----([\s\S]*?)-----END SSH SIGNATURE-----/;
const ED25519_KEY_BYTES = 32;
const UNCOMPRESSED_POINT = 4;
class SshReader {
private position = 0;
constructor(private readonly bytes: Uint8Array) {}
raw(length: number): Uint8Array {
if (this.position + length > this.bytes.byteLength) throw new Error("Truncated SSH data");
const out = this.bytes.subarray(this.position, this.position + length);
this.position += length;
return out;
}
uint32(): number {
const view = new DataView(this.bytes.buffer, this.bytes.byteOffset + this.position, 4);
this.raw(4);
return view.getUint32(0);
}
string(): Uint8Array {
return this.raw(this.uint32());
}
text(): string {
return new TextDecoder().decode(this.string());
}
}
function sshString(value: Uint8Array | string): Uint8Array {
const bytes = typeof value === "string" ? encoder.encode(value) : value;
const out = new Uint8Array(4 + bytes.byteLength);
new DataView(out.buffer).setUint32(0, bytes.byteLength);
out.set(bytes, 4);
return out;
}
function concat(parts: Uint8Array[]): Uint8Array<ArrayBuffer> {