asn1-ts 8.0.3 → 8.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node/codecs/ber/decoders/decodeGeneralizedTime.js +107 -10
- package/dist/node/codecs/ber/decoders/decodeUTCTime.js +36 -13
- package/dist/node/codecs/ber.js +0 -6
- package/dist/node/codecs/der/decoders/decodeGeneralizedTime.js +33 -10
- package/dist/node/codecs/der/decoders/decodeUTCTime.js +12 -10
- package/dist/node/validators/validateDate.js +10 -1
- package/dist/node/validators/validateTime.js +9 -0
- package/package.json +1 -1
|
@@ -39,20 +39,117 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.default = decodeGeneralizedTime;
|
|
40
40
|
const errors = __importStar(require("../../../errors"));
|
|
41
41
|
const convertBytesToText_1 = __importDefault(require("../../../utils/convertBytesToText"));
|
|
42
|
-
const values_1 = require("../../../values");
|
|
43
42
|
const validateDateTime_1 = __importDefault(require("../../../validators/validateDateTime"));
|
|
43
|
+
const SMALLEST_CORRECT_GENERALIZED_TIME = "2000120123".length;
|
|
44
|
+
const PERIOD = ".".charCodeAt(0);
|
|
45
|
+
const COMMA = ",".charCodeAt(0);
|
|
46
|
+
const Z = "Z".charCodeAt(0);
|
|
47
|
+
const PLUS = "+".charCodeAt(0);
|
|
48
|
+
const MINUS = "-".charCodeAt(0);
|
|
49
|
+
;
|
|
50
|
+
function isStop(s, i) {
|
|
51
|
+
const char = s.charCodeAt(i);
|
|
52
|
+
return (char === PERIOD) || (char === COMMA);
|
|
53
|
+
}
|
|
44
54
|
function decodeGeneralizedTime(value) {
|
|
55
|
+
if (value.length < SMALLEST_CORRECT_GENERALIZED_TIME) {
|
|
56
|
+
throw new errors.ASN1Error("Malformed GeneralizedTime string.");
|
|
57
|
+
}
|
|
58
|
+
if (value.length > 32) {
|
|
59
|
+
throw new errors.ASN1Error("Outrageously large GeneralizedTime string.");
|
|
60
|
+
}
|
|
45
61
|
const dateString = (0, convertBytesToText_1.default)(value);
|
|
46
|
-
const
|
|
47
|
-
|
|
62
|
+
const year = Number(dateString.slice(0, 4));
|
|
63
|
+
const month = (Number(dateString.slice(4, 6)) - 1);
|
|
64
|
+
const date = Number(dateString.slice(6, 8));
|
|
65
|
+
const hours = Number(dateString.slice(8, 10));
|
|
66
|
+
if (value.length === 10) {
|
|
67
|
+
(0, validateDateTime_1.default)("GeneralizedTime", year, month, date, hours, 0, 0);
|
|
68
|
+
return new Date(year, month, date, hours, 0, 0);
|
|
69
|
+
}
|
|
70
|
+
let i = 10;
|
|
71
|
+
while (value[i] && value[i] >= 0x30 && value[i] <= 0x39)
|
|
72
|
+
i++;
|
|
73
|
+
let minutes = 0;
|
|
74
|
+
let seconds = 0;
|
|
75
|
+
let milliseconds = 0;
|
|
76
|
+
let fractionUnits = 0;
|
|
77
|
+
if (i == 14) {
|
|
78
|
+
minutes = Number.parseInt(dateString.slice(10, 12), 10);
|
|
79
|
+
seconds = Number.parseInt(dateString.slice(12, 14), 10);
|
|
80
|
+
fractionUnits = 2;
|
|
81
|
+
}
|
|
82
|
+
else if (i == 12) {
|
|
83
|
+
minutes = Number.parseInt(dateString.slice(10, 12), 10);
|
|
84
|
+
fractionUnits = 1;
|
|
85
|
+
}
|
|
86
|
+
else if (i != 10) {
|
|
87
|
+
throw new errors.ASN1Error("Malformed GeneralizedTime string.");
|
|
88
|
+
}
|
|
89
|
+
if (value[i] === undefined) {
|
|
90
|
+
(0, validateDateTime_1.default)("GeneralizedTime", year, month, date, hours, minutes, seconds);
|
|
91
|
+
return new Date(year, month, date, hours, minutes, seconds);
|
|
92
|
+
}
|
|
93
|
+
if (isStop(dateString, i)) {
|
|
94
|
+
i++;
|
|
95
|
+
let j = i;
|
|
96
|
+
while (value[j] && value[j] >= 0x30 && value[j] <= 0x39)
|
|
97
|
+
j++;
|
|
98
|
+
const fractionString = `0.${dateString.slice(i, j)}`;
|
|
99
|
+
i = j;
|
|
100
|
+
const fraction = Number.parseFloat(fractionString);
|
|
101
|
+
if (fractionUnits === 0) {
|
|
102
|
+
minutes = Math.floor(60 * fraction);
|
|
103
|
+
seconds = Math.floor((60 * 60 * fraction) % 60);
|
|
104
|
+
}
|
|
105
|
+
else if (fractionUnits === 1) {
|
|
106
|
+
seconds = Math.floor(60 * fraction);
|
|
107
|
+
}
|
|
108
|
+
else if (fractionUnits === 2) {
|
|
109
|
+
milliseconds = Math.floor(1000 * fraction);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
throw new Error("internal asn1-ts error: invalid FractionalUnits");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (value[i] === undefined) {
|
|
116
|
+
(0, validateDateTime_1.default)("GeneralizedTime", year, month, date, hours, minutes, seconds);
|
|
117
|
+
return new Date(year, month, date, hours, minutes, seconds, milliseconds);
|
|
118
|
+
}
|
|
119
|
+
if (value[i] === Z) {
|
|
120
|
+
(0, validateDateTime_1.default)("GeneralizedTime", year, month, date, hours, minutes, seconds);
|
|
121
|
+
return new Date(Date.UTC(year, month, date, hours, minutes, seconds, milliseconds));
|
|
122
|
+
}
|
|
123
|
+
if (value[i] === PLUS || value[i] === MINUS) {
|
|
124
|
+
const isPositive = value[i] === PLUS;
|
|
125
|
+
i++;
|
|
126
|
+
let j = i;
|
|
127
|
+
while (value[j] && value[j] >= 0x30 && value[j] <= 0x39)
|
|
128
|
+
j++;
|
|
129
|
+
const offsetSize = j - i;
|
|
130
|
+
if (value[j] !== undefined) {
|
|
131
|
+
throw new errors.ASN1Error("Malformed GeneralizedTime string.");
|
|
132
|
+
}
|
|
133
|
+
let offsetHour = 0;
|
|
134
|
+
let offsetMinute = 0;
|
|
135
|
+
if (offsetSize === 4) {
|
|
136
|
+
offsetHour = Number.parseInt(dateString.slice(j - 4, j - 2), 10);
|
|
137
|
+
offsetMinute = Number.parseInt(dateString.slice(j - 2, j), 10);
|
|
138
|
+
}
|
|
139
|
+
else if (offsetSize === 2) {
|
|
140
|
+
offsetHour = Number.parseInt(dateString.slice(j - 2, j));
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
throw new errors.ASN1Error("Malformed GeneralizedTime string.");
|
|
144
|
+
}
|
|
145
|
+
let epochTimeInMS = Date.UTC(year, month, date, hours, minutes, seconds, milliseconds);
|
|
146
|
+
const sign = isPositive ? -1 : 1;
|
|
147
|
+
epochTimeInMS += sign * ((offsetHour * 60 * 60 * 1000) + (offsetMinute * 60 * 1000));
|
|
148
|
+
return new Date(epochTimeInMS);
|
|
149
|
+
}
|
|
150
|
+
if (value[i] !== undefined) {
|
|
48
151
|
throw new errors.ASN1Error("Malformed GeneralizedTime string.");
|
|
49
152
|
}
|
|
50
|
-
const year = Number(match[1]);
|
|
51
|
-
const month = (Number(match[2]) - 1);
|
|
52
|
-
const date = Number(match[3]);
|
|
53
|
-
const hours = Number(match[4]);
|
|
54
|
-
const minutes = Number(match[5]);
|
|
55
|
-
const seconds = Number(match[6]);
|
|
56
153
|
(0, validateDateTime_1.default)("GeneralizedTime", year, month, date, hours, minutes, seconds);
|
|
57
|
-
return new Date(Date.UTC(year, month, date, hours, minutes, seconds));
|
|
154
|
+
return new Date(Date.UTC(year, month, date, hours, minutes, seconds, milliseconds));
|
|
58
155
|
}
|
|
@@ -39,23 +39,46 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.default = decodeUTCTime;
|
|
40
40
|
const convertBytesToText_1 = __importDefault(require("../../../utils/convertBytesToText"));
|
|
41
41
|
const errors = __importStar(require("../../../errors"));
|
|
42
|
-
const values_1 = require("../../../values");
|
|
43
42
|
const validateDateTime_1 = __importDefault(require("../../../validators/validateDateTime"));
|
|
44
43
|
function decodeUTCTime(value) {
|
|
45
44
|
const dateString = (0, convertBytesToText_1.default)(value);
|
|
46
|
-
|
|
47
|
-
if (match === null) {
|
|
48
|
-
throw new errors.ASN1Error("Malformed UTCTime string.");
|
|
49
|
-
}
|
|
50
|
-
let year = Number(match[1]);
|
|
45
|
+
let year = Number(dateString.slice(0, 2));
|
|
51
46
|
year = (year <= 49)
|
|
52
47
|
? (2000 + year)
|
|
53
48
|
: (1900 + year);
|
|
54
|
-
const month = (Number(
|
|
55
|
-
const date = Number(
|
|
56
|
-
const hours = Number(
|
|
57
|
-
const minutes = Number(
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
49
|
+
const month = (Number(dateString.slice(2, 4)) - 1);
|
|
50
|
+
const date = Number(dateString.slice(4, 6));
|
|
51
|
+
const hours = Number(dateString.slice(6, 8));
|
|
52
|
+
const minutes = Number(dateString.slice(8, 10));
|
|
53
|
+
const char10 = dateString.charCodeAt(10);
|
|
54
|
+
const secondsFieldPresent = (char10 >= 0x30 && char10 <= 0x39);
|
|
55
|
+
const seconds = secondsFieldPresent
|
|
56
|
+
? Number(dateString.slice(10, 12))
|
|
57
|
+
: 0;
|
|
58
|
+
let i = secondsFieldPresent ? 12 : 10;
|
|
59
|
+
if (dateString[i] === 'Z') {
|
|
60
|
+
(0, validateDateTime_1.default)("UTCTime", year, month, date, hours, minutes, seconds);
|
|
61
|
+
return new Date(Date.UTC(year, month, date, hours, minutes, seconds));
|
|
62
|
+
}
|
|
63
|
+
if ((dateString[i] !== '+') && (dateString[i] !== '-')) {
|
|
64
|
+
throw new errors.ASN1Error(`Malformed BER UTCTime: non +/- offset: ${dateString[i]}`);
|
|
65
|
+
}
|
|
66
|
+
const isPositive = dateString[i] === '+';
|
|
67
|
+
i++;
|
|
68
|
+
let j = 0;
|
|
69
|
+
while (value[i + j] && value[i + j] >= 0x30 && value[i + j] <= 0x39)
|
|
70
|
+
j++;
|
|
71
|
+
if (j !== 4) {
|
|
72
|
+
throw new errors.ASN1Error("Malformed BER UTCTime: non four-digit offset");
|
|
73
|
+
}
|
|
74
|
+
i += j;
|
|
75
|
+
if (dateString[i] !== undefined) {
|
|
76
|
+
throw new errors.ASN1Error("Malformed BER UTCTime: trailing data");
|
|
77
|
+
}
|
|
78
|
+
const offsetHour = Number.parseInt(dateString.slice(i - 4, i - 2), 10);
|
|
79
|
+
const offsetMinute = Number.parseInt(dateString.slice(i - 2, i), 10);
|
|
80
|
+
let epochTimeInMS = Date.UTC(year, month, date, hours, minutes, seconds);
|
|
81
|
+
const sign = isPositive ? -1 : 1;
|
|
82
|
+
epochTimeInMS += sign * ((offsetHour * 60 * 60 * 1000) + (offsetMinute * 60 * 1000));
|
|
83
|
+
return new Date(epochTimeInMS);
|
|
61
84
|
}
|
package/dist/node/codecs/ber.js
CHANGED
|
@@ -539,12 +539,6 @@ class BERElement extends x690_1.default {
|
|
|
539
539
|
throw new errors.ASN1UndefinedError("Length byte with undefined meaning encountered.", this);
|
|
540
540
|
}
|
|
541
541
|
if (numberOfLengthOctets > 4) {
|
|
542
|
-
if (bytes instanceof Buffer) {
|
|
543
|
-
console.log(bytes.toString("hex"));
|
|
544
|
-
}
|
|
545
|
-
else {
|
|
546
|
-
console.log(Buffer.from(bytes).toString("hex"));
|
|
547
|
-
}
|
|
548
542
|
throw new errors.ASN1OverflowError(`Element length too long to decode to an integer. Content octets occupied ${numberOfLengthOctets} bytes.`, this);
|
|
549
543
|
}
|
|
550
544
|
if (cursor + numberOfLengthOctets >= bytes.length) {
|
|
@@ -38,21 +38,44 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.default = decodeGeneralizedTime;
|
|
40
40
|
const convertBytesToText_1 = __importDefault(require("../../../utils/convertBytesToText"));
|
|
41
|
-
const values_1 = require("../../../values");
|
|
42
41
|
const errors = __importStar(require("../../../errors"));
|
|
43
42
|
const validateDateTime_1 = __importDefault(require("../../../validators/validateDateTime"));
|
|
44
43
|
function decodeGeneralizedTime(value) {
|
|
45
44
|
const dateString = (0, convertBytesToText_1.default)(value);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
if (!dateString.endsWith("Z")) {
|
|
46
|
+
throw new errors.ASN1Error("Malformed DER GeneralizedTime string: must use UTC timezone");
|
|
47
|
+
}
|
|
48
|
+
const year = Number(dateString.slice(0, 4));
|
|
49
|
+
const month = (Number(dateString.slice(4, 6)) - 1);
|
|
50
|
+
const date = Number(dateString.slice(6, 8));
|
|
51
|
+
const hours = Number(dateString.slice(8, 10));
|
|
52
|
+
const minutes = Number(dateString.slice(10, 12));
|
|
53
|
+
const seconds = Number(dateString.slice(12, 14));
|
|
54
|
+
if (dateString[14] === '.') {
|
|
55
|
+
let i = 15;
|
|
56
|
+
while (value[i] && value[i] >= 0x30 && value[i] <= 0x39)
|
|
57
|
+
i++;
|
|
58
|
+
if (i === 15) {
|
|
59
|
+
throw new errors.ASN1Error("Malformed DER GeneralizedTime string: trailing stop character");
|
|
60
|
+
}
|
|
61
|
+
if (dateString[i] === 'Z') {
|
|
62
|
+
i++;
|
|
63
|
+
}
|
|
64
|
+
if (dateString[i] !== undefined) {
|
|
65
|
+
throw new errors.ASN1Error("Malformed DER GeneralizedTime string: trailing data");
|
|
66
|
+
}
|
|
67
|
+
const fractionString = `0.${dateString.slice(15, i)}`;
|
|
68
|
+
if (fractionString.endsWith("0")) {
|
|
69
|
+
throw new errors.ASN1Error("Malformed DER GeneralizedTime string: trailing 0 in milliseconds");
|
|
70
|
+
}
|
|
71
|
+
const fraction = Number.parseFloat(fractionString);
|
|
72
|
+
const milliseconds = Math.floor(1000 * fraction);
|
|
73
|
+
(0, validateDateTime_1.default)("GeneralizedTime", year, month, date, hours, minutes, seconds);
|
|
74
|
+
return new Date(Date.UTC(year, month, date, hours, minutes, seconds, milliseconds));
|
|
75
|
+
}
|
|
76
|
+
else if (dateString[14] !== 'Z') {
|
|
77
|
+
throw new errors.ASN1Error("Malformed DER GeneralizedTime string: trailing data");
|
|
49
78
|
}
|
|
50
|
-
const year = Number(match[1]);
|
|
51
|
-
const month = (Number(match[2]) - 1);
|
|
52
|
-
const date = Number(match[3]);
|
|
53
|
-
const hours = Number(match[4]);
|
|
54
|
-
const minutes = Number(match[5]);
|
|
55
|
-
const seconds = Number(match[6]);
|
|
56
79
|
(0, validateDateTime_1.default)("GeneralizedTime", year, month, date, hours, minutes, seconds);
|
|
57
80
|
return new Date(Date.UTC(year, month, date, hours, minutes, seconds));
|
|
58
81
|
}
|
|
@@ -38,24 +38,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.default = decodeUTCTime;
|
|
40
40
|
const convertBytesToText_1 = __importDefault(require("../../../utils/convertBytesToText"));
|
|
41
|
-
const values_1 = require("../../../values");
|
|
42
41
|
const errors = __importStar(require("../../../errors"));
|
|
43
42
|
const validateDateTime_1 = __importDefault(require("../../../validators/validateDateTime"));
|
|
43
|
+
const DER_UTC_TIME_LENGTH = "920521000000Z".length;
|
|
44
44
|
function decodeUTCTime(value) {
|
|
45
|
+
if (value.length !== DER_UTC_TIME_LENGTH) {
|
|
46
|
+
throw new errors.ASN1Error("Malformed DER UTCTime string: not a valid length");
|
|
47
|
+
}
|
|
45
48
|
const dateString = (0, convertBytesToText_1.default)(value);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
throw new errors.ASN1Error("Malformed UTCTime string.");
|
|
49
|
+
if (!dateString.endsWith("Z")) {
|
|
50
|
+
throw new errors.ASN1Error("Malformed DER UTCTime string: not UTC timezone");
|
|
49
51
|
}
|
|
50
|
-
let year = Number(
|
|
52
|
+
let year = Number(dateString.slice(0, 2));
|
|
53
|
+
const month = (Number(dateString.slice(2, 4)) - 1);
|
|
54
|
+
const date = Number(dateString.slice(4, 6));
|
|
55
|
+
const hours = Number(dateString.slice(6, 8));
|
|
56
|
+
const minutes = Number(dateString.slice(8, 10));
|
|
57
|
+
const seconds = Number(dateString.slice(10, 12));
|
|
51
58
|
year = (year <= 49)
|
|
52
59
|
? (2000 + year)
|
|
53
60
|
: (1900 + year);
|
|
54
|
-
const month = (Number(match[2]) - 1);
|
|
55
|
-
const date = Number(match[3]);
|
|
56
|
-
const hours = Number(match[4]);
|
|
57
|
-
const minutes = Number(match[5]);
|
|
58
|
-
const seconds = Number(match[6]);
|
|
59
61
|
(0, validateDateTime_1.default)("UTCTime", year, month, date, hours, minutes, seconds);
|
|
60
62
|
return new Date(Date.UTC(year, month, date, hours, minutes, seconds));
|
|
61
63
|
}
|
|
@@ -36,6 +36,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.default = validateDate;
|
|
37
37
|
const errors = __importStar(require("../errors"));
|
|
38
38
|
function validateDate(dataType, year, month, date) {
|
|
39
|
+
if (!Number.isSafeInteger(year)) {
|
|
40
|
+
throw new errors.ASN1Error(`Invalid year in ${dataType}`);
|
|
41
|
+
}
|
|
42
|
+
if (!Number.isSafeInteger(month)) {
|
|
43
|
+
throw new errors.ASN1Error(`Invalid month in ${dataType}`);
|
|
44
|
+
}
|
|
45
|
+
if (!Number.isSafeInteger(date) || (date < 1)) {
|
|
46
|
+
throw new errors.ASN1Error(`Invalid day in ${dataType}`);
|
|
47
|
+
}
|
|
39
48
|
switch (month) {
|
|
40
49
|
case 0:
|
|
41
50
|
case 2:
|
|
@@ -71,6 +80,6 @@ function validateDate(dataType, year, month, date) {
|
|
|
71
80
|
break;
|
|
72
81
|
}
|
|
73
82
|
default:
|
|
74
|
-
throw new errors.ASN1Error(`
|
|
83
|
+
throw new errors.ASN1Error(`Invalid month in ${dataType}`);
|
|
75
84
|
}
|
|
76
85
|
}
|
|
@@ -36,6 +36,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.default = validateTime;
|
|
37
37
|
const errors = __importStar(require("../errors"));
|
|
38
38
|
function validateTime(dataType, hours, minutes, seconds) {
|
|
39
|
+
if (!Number.isSafeInteger(hours)) {
|
|
40
|
+
throw new errors.ASN1Error(`Invalid hours in ${dataType}`);
|
|
41
|
+
}
|
|
42
|
+
if (!Number.isSafeInteger(minutes)) {
|
|
43
|
+
throw new errors.ASN1Error(`Invalid minutes in ${dataType}`);
|
|
44
|
+
}
|
|
45
|
+
if (!Number.isSafeInteger(seconds) || (seconds < 0)) {
|
|
46
|
+
throw new errors.ASN1Error(`Invalid seconds in ${dataType}`);
|
|
47
|
+
}
|
|
39
48
|
if (hours > 23) {
|
|
40
49
|
throw new errors.ASN1Error(`Hours > 23 encountered in ${dataType}.`);
|
|
41
50
|
}
|
package/package.json
CHANGED