{"record":{"id":"9bba20712d1f113e","repo":"gchq/CyberChef","slug":"failed-to-format-datetime-string-datetime","errorCode":null,"errorMessage":"failed to format datetime string ${datetime}","messagePattern":"failed to format datetime string (.+?)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/ParseX509CRL.mjs","lineNumber":110,"sourceCode":"            out += `\\tCRL extensions:\\n${formatCRLExtensions(crl.getParam().ext, 8)}\\n`;\n        }\n\n        out += `Revoked Certificates:\\n${formatRevokedCertificates(crl.getRevCertArray(), 4)}\nSignature Value:\\n${formatCRLSignature(crl.getSignatureValueHex(), 8)}`;\n\n        return out;\n    }\n}\n\n/**\n * Generalized date time string to UTC.\n * @param {string} datetime\n * @returns UTC datetime string.\n */\nfunction generalizedDateTimeToUTC(datetime) {\n    // Ensure the string is in the correct format\n    if (!/^\\d{12,14}Z$/.test(datetime)) {\n        throw new OperationError(`failed to format datetime string ${datetime}`);\n    }\n\n    // Extract components\n    let centuary = \"20\";\n    if (datetime.length === 15) {\n        centuary = datetime.substring(0, 2);\n        datetime = datetime.slice(2);\n    }\n    const year = centuary + datetime.substring(0, 2);\n    const month = datetime.substring(2, 4);\n    const day = datetime.substring(4, 6);\n    const hour = datetime.substring(6, 8);\n    const minute = datetime.substring(8, 10);\n    const second = datetime.substring(10, 12);\n\n    // Construct ISO 8601 format string\n    const isoString = `${year}-${month}-${day}T${hour}:${minute}:${second}Z`;\n","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ParseX509CRL.mjs#L92-L128","documentation":"ParseX509CRL formats date fields (thisUpdate, nextUpdate, revocation dates, invalidity dates) via generalizedDateTimeToUTC, which expects a UTCTime/GeneralizedTime string matching ^\\d{12,14}Z$. If jsrsasign hands back a date string not matching that shape, formatting aborts. The input comes from the parsed CRL, so this reflects a malformed or unexpected CRL/date encoding rather than user-typed text.","triggerScenarios":"A CRL whose thisUpdate/nextUpdate fields are not standard UTCTime (YYMMDDHHMMSSZ) or GeneralizedTime; a jsrsasign version that returns dates in a different format; a corrupt or hand-edited CRL; a revocation entry whose date field is malformed.","commonSituations":"Parsing a CRL produced by a non-RFC-conformant CA; jsrsasign upgrade changing date output; DER that was incorrectly re-encoded; partial/truncated CRL bytes fed in.","solutions":["Re-export the CRL in canonical PEM/DER from a trusted source (e.g. openssl crl).","Verify the CRL with openssl first: 'openssl crl -in crl.pem -noout -text'.","Check that the jsrsasign version bundled with your CyberChef build matches the one this op was written against.","If the CRL is valid but the date shape differs, report it — the regex may need widening for that GeneralizedTime variant."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function isValidGeneralizedTime(s) {\n  return /^\\d{12,14}Z$/.test(s);\n}\n// Validate each date field before formatting if you control the CRL parsing pipeline.","typeGuard":"function isGeneralizedTimeString(s) {\n  return typeof s === \"string\" && /^\\d{12,14}Z$/.test(s);\n}","tryCatchPattern":"try {\n  return parseX509CRL.run(crlInput, [inputFormat]);\n} catch (e) {\n  if (e.message.startsWith(\"failed to format datetime string\")) {\n    // CRL date encoding is non-standard; validate with openssl externally\n  }\n  throw e;\n}","preventionTips":["Validate CRLs with openssl crl before parsing.","Keep the bundled jsrsasign version aligned with this op's expectations.","Re-fetch CRLs from the CA distribution point rather than re-using stale copies."],"tags":["crypto","x509","crl","parsing","datetime"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}