UNPKG

asn1-ts

Version:

ASN.1 encoding and decoding, including BER, CER, and DER.

43 lines (42 loc) 2.07 kB
import convertBytesToText from "../../../utils/convertBytesToText.mjs"; import * as errors from "../../../errors.mjs"; import validateDateTime from "../../../validators/validateDateTime.mjs"; export default function decodeGeneralizedTime(value) { const dateString = convertBytesToText(value); if (!dateString.endsWith("Z")) { throw new errors.ASN1Error("Malformed DER GeneralizedTime string: must use UTC timezone"); } const year = Number(dateString.slice(0, 4)); const month = (Number(dateString.slice(4, 6)) - 1); const date = Number(dateString.slice(6, 8)); const hours = Number(dateString.slice(8, 10)); const minutes = Number(dateString.slice(10, 12)); const seconds = Number(dateString.slice(12, 14)); if (dateString[14] === '.') { let i = 15; while (value[i] && value[i] >= 0x30 && value[i] <= 0x39) i++; if (i === 15) { throw new errors.ASN1Error("Malformed DER GeneralizedTime string: trailing stop character"); } if (dateString[i] === 'Z') { i++; } if (dateString[i] !== undefined) { throw new errors.ASN1Error("Malformed DER GeneralizedTime string: trailing data"); } const fractionString = `0.${dateString.slice(15, i)}`; if (fractionString.endsWith("0")) { throw new errors.ASN1Error("Malformed DER GeneralizedTime string: trailing 0 in milliseconds"); } const fraction = Number.parseFloat(fractionString); const milliseconds = Math.floor(1000 * fraction); validateDateTime("GeneralizedTime", year, month, date, hours, minutes, seconds); return new Date(Date.UTC(year, month, date, hours, minutes, seconds, milliseconds)); } else if (dateString[14] !== 'Z') { throw new errors.ASN1Error("Malformed DER GeneralizedTime string: trailing data"); } validateDateTime("GeneralizedTime", year, month, date, hours, minutes, seconds); return new Date(Date.UTC(year, month, date, hours, minutes, seconds)); }