gchq/CyberChef · error · OperationError

CRL entry extension object missing 'extname' key: ${ext}

Error message

CRL entry extension object missing 'extname' key: ${ext}

What it means

While rendering CRL-level extensions, formatCRLExtensions iterates crl.getParam().ext and requires each extension object to carry an 'extname' key to switch on. If jsrsasign returns an extension object without 'extname', the op throws. This is an internal contract assertion about jsrsasign's parsed structure, triggered by unusual or unsupported CRL extensions.

Source

Thrown at src/core/operations/ParseX509CRL.mjs:163

    let out = ``;

    extensions.sort((a, b) => {
        if (!Object.hasOwn(a, "extname") || !Object.hasOwn(b, "extname")) {
            return 0;
        }
        if (a.extname < b.extname) {
            return -1;
        } else if (a.extname === b.extname) {
            return 0;
        } else {
            return 1;
        }
    });

    extensions.forEach((ext) => {
        if (!Object.hasOwn(ext, "extname")) {
            throw new OperationError(`CRL entry extension object missing 'extname' key: ${ext}`);
        }
        switch (ext.extname) {
            case "authorityKeyIdentifier":
                out += `X509v3 Authority Key Identifier:\n`;
                if (Object.hasOwn(ext, "kid")) {
                    out += `\tkeyid:${colonDelimitedHexFormatString(ext.kid.hex.toUpperCase())}\n`;
                }
                if (Object.hasOwn(ext, "issuer")) {
                    out += `\tDirName:${ext.issuer.str}\n`;
                }
                if (Object.hasOwn(ext, "sn")) {
                    out += `\tserial:${colonDelimitedHexFormatString(ext.sn.hex.toUpperCase())}\n`;
                }
                break;
            case "cRLDistributionPoints":
                out += `X509v3 CRL Distribution Points:\n`;
                ext.array.forEach((distPoint) => {
                    const fullName = `Full Name:\n${formatGeneralNames(distPoint.dpname.full, 4)}`;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Validate the CRL with 'openssl crl -in crl.pem -noout -text' to see which extension is unusual.
  2. Re-obtain the CRL from the issuer; a corrupt download can produce malformed extension objects.
  3. Check the bundled jsrsasign version against the one this op expects; upgrade/downgrade if the structure changed.
  4. If the CRL is legitimately using an unsupported extension, file an issue so the op tolerates the shape.
Defensive patterns

Strategy: try-catch

Validate before calling

const crl = new r.X509CRL(input);
const exts = crl.getParam().ext || [];
if (exts.some(e => !Object.hasOwn(e, "extname"))) {
  throw new Error("CRL contains an extension without 'extname'; parsing will fail");
}

Type guard

function extensionsHaveExtname(exts) {
  return Array.isArray(exts) && exts.every(e => Object.hasOwn(e, "extname"));
}

Try / catch

try {
  return parseX509CRL.run(crlInput, [inputFormat]);
} catch (e) {
  if (e.message.includes("missing 'extname' key")) {
    // an extension shape jsrsasign produced is unexpected; inspect with openssl
  }
  throw e;
}

Prevention

When it happens

Trigger: A CRL containing an extension that jsrsasign parses into an object lacking 'extname'; a malformed extensions sequence; a jsrsasign version that emits a different key for some extensions.

Common situations: Encountering a non-standard or proprietary CRL extension; parsing CRLs from older/newer CAs; version skew between CyberChef's expectations and the bundled jsrsasign.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/5d01a02c9ff0307a. Report an issue: GitHub.