{"record":{"id":"42981104d7a6e973","repo":"gchq/CyberChef","slug":"crlreason-crl-entry-extension-missing-code-key","errorCode":null,"errorMessage":"'cRLReason' CRL entry extension missing 'code' key: ${ext}","messagePattern":"'cRLReason' CRL entry extension missing 'code' key: (.+?)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/ParseX509CRL.mjs","lineNumber":318,"sourceCode":"        8: \"Remove From CRL\",\n        9: \"Privilege Withdrawn\",\n        10: \"AA Compromise\",\n    };\n\n    const holdInstructionOIDToName = {\n        \"1.2.840.10040.2.1\": \"Hold Instruction None\",\n        \"1.2.840.10040.2.2\": \"Hold Instruction Call Issuer\",\n        \"1.2.840.10040.2.3\": \"Hold Instruction Reject\",\n    };\n\n    exts.forEach((ext) => {\n        if (!Object.hasOwn(ext, \"extname\")) {\n            throw new OperationError(`CRL entry extension object missing 'extname' key: ${ext}`);\n        }\n        switch (ext.extname) {\n            case \"cRLReason\":\n                if (!Object.hasOwn(ext, \"code\")) {\n                    throw new OperationError(`'cRLReason' CRL entry extension missing 'code' key: ${ext}`);\n                }\n                out += `X509v3 CRL Reason Code:\n    ${Object.hasOwn(crlReasonCodeToReasonMessage, ext.code) ? crlReasonCodeToReasonMessage[ext.code] : `invalid reason code: ${ext.code}`}\\n`;\n                break;\n            case \"2.5.29.23\": // Hold instruction\n                out += `Hold Instruction Code:\\n\\t${Object.hasOwn(holdInstructionOIDToName, ext.extn.oid) ? holdInstructionOIDToName[ext.extn.oid] : `${ext.extn.oid}: unknown hold instruction OID`}\\n`;\n                break;\n            case \"2.5.29.24\": // Invalidity Date\n                out += `Invalidity Date:\\n\\t${generalizedDateTimeToUTC(ext.extn.gentime.str)}\\n`;\n                break;\n            default:\n                out += `${ext.extname}:\\n`;\n                out += `\\tUnsupported CRL entry extension. Try openssl CLI.\\n`;\n                break;\n        }\n    });\n\n    return chop(out);","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ParseX509CRL.mjs#L300-L336","documentation":"For a CRL entry extension with extname 'cRLReason', formatCRLEntryExtensions requires a 'code' key (the numeric reason code). If absent the op cannot render the revocation reason and throws. This is an assertion about jsrsasign's parsed cRLReason structure inside a revoked-cert entry.","triggerScenarios":"A revoked-cert entry with a cRLReason extension (OID 2.5.29.21) whose parsed object lacks 'code'; malformed reason-code value; jsrsasign returning a different key name.","commonSituations":"Non-standard reason-code encoding; corrupt CRL; jsrsasign version skew.","solutions":["Inspect the entry's reason code with openssl.","Re-fetch the CRL from the CA distribution point.","Verify the bundled jsrsasign version.","Report a conformant CRL that the op rejects so the key check can be relaxed."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const crl = new r.X509CRL(input);\nconst reasonExts = (crl.getRevCertArray() || []).flatMap(rc => (rc.ext || []).filter(e => e.extname === \"cRLReason\"));\nif (reasonExts.some(e => !Object.hasOwn(e, \"code\"))) {\n  throw new Error(\"A cRLReason entry extension is missing 'code'\");\n}","typeGuard":"function isValidCrlReasonExtension(ext) {\n  return ext.extname !== \"cRLReason\" || Object.hasOwn(ext, \"code\");\n}","tryCatchPattern":"try {\n  return parseX509CRL.run(crlInput, [inputFormat]);\n} catch (e) {\n  if (e.message.includes(\"'cRLReason' CRL entry extension missing 'code'\")) {\n    // non-standard reason-code encoding; validate with openssl\n  }\n  throw e;\n}","preventionTips":["Validate CRLs with openssl crl -text.","Keep jsrsasign version aligned.","Re-fetch CRLs from a trusted source."],"tags":["crypto","x509","crl","parsing","extensions"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}