X.509

X.509 certificate handling per RFC 5280. The seed surface is parse -- turn a DER or PEM certificate into a structured, fully-decoded object: version, serial, signature algorithm, issuer and subject distinguished names, validity window (as real Dates), subject public-key info, and the extension list. The parser composes the strict DER codec and the OID registry, so every field is validated on the way in and every algorithm / attribute / extension is named where the registry knows it.

The raw tbsCertificate bytes are returned alongside the parsed fields. A signature-verification layer hashes exactly the bytes that were signed, with no re-encoding step whose round-trip fidelity it would have to trust.

pki.schema.x509.pemDecode

since 0.1.7 stable
pki.schema.x509.pemDecode(text, label?) -> Buffer

Extract the DER bytes from a PEM block (default label CERTIFICATE, the RFC 7468 sec. 5 armor -- the canonical-label default every sibling format applies). Pass a label to enforce a different block type, or an explicit null to take the first block of any type. Throws PemError on a missing / mismatched envelope or a non-base64 body.

Example

async function example() {
  var pair = await pki.key.generate("Ed25519");
  var pemText = await pki.x509.sign({ subject: "example.com", subjectPublicKey: await pki.key.export(pair.publicKey),
    notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
    { key: await pki.key.export(pair.privateKey) }, { pem: true });
  var der = pki.schema.x509.pemDecode(pemText);
}
example();

References

pki.schema.x509.pemEncode

since 0.1.7 stable
pki.schema.x509.pemEncode(der, label) -> string

Wrap DER bytes in a PEM envelope with 64-column base64 lines.

Example

async function example() {
  var pair = await pki.key.generate("Ed25519");
  var der = await pki.x509.sign({ subject: "example.com", subjectPublicKey: await pki.key.export(pair.publicKey),
    notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
    { key: await pki.key.export(pair.privateKey) });
  var pem = pki.schema.x509.pemEncode(der, "CERTIFICATE");
}
example();

References

pki.schema.x509.parse

since 0.1.7 stable
pki.schema.x509.parse(input) -> certificate

Parse a DER Buffer or a PEM string/Buffer into a structured certificate: { version, serialNumber, serialNumberHex, signatureAlgorithm, issuer, subject, validity, subjectPublicKeyInfo, extensions, tbsBytes, signatureValue }. Distinguished names come back both as a rendered dn string and as structured rdns; the validity window is real Dates; tbsBytes is the exact signed byte range for a downstream verifier.

Throws CertificateError when the bytes are not a well-formed certificate and Asn1Error when the underlying DER is malformed.

Example

async function example() {
  var pair = await pki.key.generate("Ed25519");
  var pemString = await pki.x509.sign({ subject: [{ commonName: "example.com" }, { organizationName: "Example" }],
    subjectPublicKey: await pki.key.export(pair.publicKey),
    notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
    { key: await pki.key.export(pair.privateKey) }, { pem: true });
  var cert = pki.schema.x509.parse(pemString);
  cert.subject.dn;                 // "CN=example.com, O=Example"
  cert.validity.notAfter;          // Date
  cert.signatureAlgorithm.name;    // "Ed25519" (the algorithm the issuer signed with)
}
example();

References

  • spec RFC 5280
  • spec X.509
  • defends malformed-certificate-parse (CWE-20)