asn1-ts
Version:
ASN.1 encoding and decoding, including BER, CER, and DER.
46 lines (45 loc) • 2.02 kB
JavaScript
import convertBytesToText from "../../../utils/convertBytesToText.mjs";
import * as errors from "../../../errors.mjs";
import validateDateTime from "../../../validators/validateDateTime.mjs";
export default function decodeUTCTime(value) {
const dateString = convertBytesToText(value);
let year = Number(dateString.slice(0, 2));
year = (year <= 49)
? (2000 + year)
: (1900 + year);
const month = (Number(dateString.slice(2, 4)) - 1);
const date = Number(dateString.slice(4, 6));
const hours = Number(dateString.slice(6, 8));
const minutes = Number(dateString.slice(8, 10));
const char10 = dateString.charCodeAt(10);
const secondsFieldPresent = (char10 >= 0x30 && char10 <= 0x39);
const seconds = secondsFieldPresent
? Number(dateString.slice(10, 12))
: 0;
let i = secondsFieldPresent ? 12 : 10;
if (dateString[i] === 'Z') {
validateDateTime("UTCTime", year, month, date, hours, minutes, seconds);
return new Date(Date.UTC(year, month, date, hours, minutes, seconds));
}
if ((dateString[i] !== '+') && (dateString[i] !== '-')) {
throw new errors.ASN1Error(`Malformed BER UTCTime: non +/- offset: ${dateString[i]}`);
}
const isPositive = dateString[i] === '+';
i++;
let j = 0;
while (value[i + j] && value[i + j] >= 0x30 && value[i + j] <= 0x39)
j++;
if (j !== 4) {
throw new errors.ASN1Error("Malformed BER UTCTime: non four-digit offset");
}
i += j;
if (dateString[i] !== undefined) {
throw new errors.ASN1Error("Malformed BER UTCTime: trailing data");
}
const offsetHour = Number.parseInt(dateString.slice(i - 4, i - 2), 10);
const offsetMinute = Number.parseInt(dateString.slice(i - 2, i), 10);
let epochTimeInMS = Date.UTC(year, month, date, hours, minutes, seconds);
const sign = isPositive ? -1 : 1;
epochTimeInMS += sign * ((offsetHour * 60 * 60 * 1000) + (offsetMinute * 60 * 1000));
return new Date(epochTimeInMS);
}