import { describe, expect, it } from "@suaveplan/testing/runner"; import { buildEcdsaP256Chain, buildEd25519Chain, buildOverLongSerialDer, buildUnsupportedVersionDer, } from "../__fixtures__/build-certs.js"; import { X509Error } from "../errors/error-codes.js"; import { parseCertificate } from "./parse.js"; describe("parseCertificate", () => { it("parses a v3 leaf certificate to typed fields", { timeout: 5000, }, () => { const { leafDer } = buildEd25519Chain(); const cert = parseCertificate(leafDer); expect(cert.tbs.version).toBe("v3"); expect(cert.tbs.serialNumber.length).toBeGreaterThan(0); expect(cert.tbs.extensions.length).toBeGreaterThan(0); expect(cert.tbsCertificateBytes.length).toBeGreaterThan(0); expect(cert.signatureValue.length).toBeGreaterThan(0); }); it("parses an ECDSA P-256 leaf certificate", { timeout: 5000 }, () => { const { leafDer } = buildEcdsaP256Chain(); const cert = parseCertificate(leafDer); expect(cert.tbs.version).toBe("v3"); expect(cert.signatureAlgorithm.oid).toBe("1.2.840.10045.4.3.2"); }); it("rejects a serial number longer than 20 bytes", { timeout: 5000, }, () => { try { parseCertificate(buildOverLongSerialDer()); throw new Error("expected throw"); } catch (e) { expect(e).toBeInstanceOf(X509Error); expect((e as X509Error).code).toBe("X509.CERTIFICATE_MALFORMED"); } }); it("rejects v4 or higher with UNSUPPORTED_VERSION", { timeout: 5000, }, () => { try { parseCertificate(buildUnsupportedVersionDer()); throw new Error("expected throw"); } catch (e) { expect(e).toBeInstanceOf(X509Error); expect((e as X509Error).code).toBe("X509.UNSUPPORTED_VERSION"); } }); it("accepts the PEM-wrapped form of a DER cert", { timeout: 5000 }, () => { const { leafPem } = buildEd25519Chain(); const cert = parseCertificate(new TextEncoder().encode(leafPem)); expect(cert.tbs.version).toBe("v3"); }); it("rejects garbage bytes", { timeout: 5000 }, () => { expect(() => parseCertificate(new Uint8Array([0x30, 0x05, 0x02, 0x01, 0x01])) ).toThrow(); }); });