gchq/CyberChef · error · OperationError

invalid revoked certificate object, missing either serial nu

Error message

invalid revoked certificate object, missing either serial number or date

What it means

formatRevokedCertificates iterates crl.getRevCertArray() and requires every revoked certificate entry to have both 'sn' (serial number) and 'date' (revocation date). If either is missing the entry cannot be rendered meaningfully, so the op throws. This guards the parser's expectation of jsrsasign's revoked-cert object shape.

Source

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

    return chop(hexString.replace(/(..)/g, "$&:"));
}

/**
 * Format revoked certificates array
 * @param {r.RevokedCertificate[] | null} revokedCertificates
 * @param {Number} indent
 * @returns Multi-line formatted string output of revoked certificates array
 */
function formatRevokedCertificates(revokedCertificates, indent) {
    if (Array.isArray(revokedCertificates) === false || revokedCertificates.length === 0) {
        return indentString("No Revoked Certificates.", indent);
    }

    let out=``;

    revokedCertificates.forEach((revCert) => {
        if (!Object.hasOwn(revCert, "sn") || !Object.hasOwn(revCert, "date")) {
            throw new OperationError("invalid revoked certificate object, missing either serial number or date");
        }

        out += `Serial Number: ${revCert.sn.hex.toUpperCase()}
    Revocation Date: ${generalizedDateTimeToUTC(revCert.date)}\n`;
        if (Object.hasOwn(revCert, "ext") && Array.isArray(revCert.ext) && revCert.ext.length !== 0) {
            out += `\tCRL entry extensions:\n${indentString(formatCRLEntryExtensions(revCert.ext), 2*indent)}\n`;
        }
    });

    return indentString(chop(out), indent);
}

/**
 * Format CRL entry extensions.
 * @param {Object[]} exts
 * @returns Formatted multi-line string describing CRL entry extensions.
 */
function formatCRLEntryExtensions(exts) {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Validate the CRL with openssl to confirm every revoked entry has a serial and date.
  2. Re-fetch the CRL from the CA's distribution point.
  3. Check the bundled jsrsasign version for revoked-cert object changes.
  4. If the CRL is valid, report the entry shape so the op can tolerate it.
Defensive patterns

Strategy: try-catch

Validate before calling

const crl = new r.X509CRL(input);
const revoked = crl.getRevCertArray() || [];
if (revoked.some(rc => !Object.hasOwn(rc, "sn") || !Object.hasOwn(rc, "date"))) {
  throw new Error("A revoked-cert entry is missing 'sn' or 'date'");
}

Type guard

function revokedCertsHaveSnAndDate(revoked) {
  return Array.isArray(revoked) && revoked.every(rc => Object.hasOwn(rc, "sn") && Object.hasOwn(rc, "date"));
}

Try / catch

try {
  return parseX509CRL.run(crlInput, [inputFormat]);
} catch (e) {
  if (e.message === "invalid revoked certificate object, missing either serial number or date") {
    // a revoked entry is malformed; validate the CRL with openssl
  }
  throw e;
}

Prevention

When it happens

Trigger: A CRL with a revoked-cert entry missing the serial number or revocation date; malformed revoked-cert sequence; jsrsasign returning a partial object for an unusual entry encoding.

Common situations: Parsing a corrupt or truncated CRL; CRLs from non-conformant CAs; version skew in jsrsasign's revoked-cert representation.

Understand the failure class

Related errors


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