Socket
Socket
Sign inDemoInstall

@lapo/asn1js

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lapo/asn1js - npm Package Compare versions

Comparing version 1.2.4 to 1.3.0

1057

asn1.js
// ASN.1 JavaScript decoder
// Copyright (c) 2008-2022 Lapo Luchini <lapo@lapo.it>
// Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>

@@ -16,13 +16,29 @@ // Permission to use, copy, modify, and/or distribute this software for any

(typeof define != 'undefined' ? define : function (factory) { 'use strict';
if (typeof module == 'object') module.exports = factory(function (name) { return require(name); });
else window.asn1 = factory(function (name) { return window[name.substring(2)]; });
})(function (require) {
"use strict";
import { Int10 } from './int10.js';
import { oids } from './oids.js';
var Int10 = require('./int10'),
oids = require('./oids'),
ellipsis = "\u2026",
const
ellipsis = '\u2026',
reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|(-(?:0\d|1[0-2])|[+](?:0\d|1[0-4]))([0-5]\d)?)?$/,
reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|(-(?:0\d|1[0-2])|[+](?:0\d|1[0-4]))([0-5]\d)?)?$/;
reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|(-(?:0\d|1[0-2])|[+](?:0\d|1[0-4]))([0-5]\d)?)?$/,
hexDigits = '0123456789ABCDEF',
b64Safe = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
tableT61 = [
['', ''],
['AEIOUaeiou', 'ÀÈÌÒÙàèìòù'], // Grave
['ACEILNORSUYZacegilnorsuyz', 'ÁĆÉÍĹŃÓŔŚÚÝŹáćéģíĺńóŕśúýź'], // Acute
['ACEGHIJOSUWYaceghijosuwy', 'ÂĈÊĜĤÎĴÔŜÛŴŶâĉêĝĥîĵôŝûŵŷ'], // Circumflex
['AINOUainou', 'ÃĨÑÕŨãĩñõũ'], // Tilde
['AEIOUaeiou', 'ĀĒĪŌŪāēīōū'], // Macron
['AGUagu', 'ĂĞŬăğŭ'], // Breve
['CEGIZcegz', 'ĊĖĠİŻċėġż'], // Dot
['AEIOUYaeiouy', 'ÄËÏÖÜŸäëïöüÿ'], // Umlaut or diæresis
['', ''],
['AUau', 'ÅŮåů'], // Ring
['CGKLNRSTcklnrst', 'ÇĢĶĻŅŖŞŢçķļņŗşţ'], // Cedilla
['', ''],
['OUou', 'ŐŰőű'], // Double Acute
['AEIUaeiu', 'ĄĘĮŲąęįų'], // Ogonek
['CDELNRSTZcdelnrstz', 'ČĎĚĽŇŘŠŤŽčďěľňřšťž'] // Caron
];

@@ -35,344 +51,280 @@ function stringCut(str, len) {

function Stream(enc, pos) {
if (enc instanceof Stream) {
this.enc = enc.enc;
this.pos = enc.pos;
} else {
// enc should be an array or a binary string
this.enc = enc;
this.pos = pos;
function checkPrintable(s) {
let i, v;
for (i = 0; i < s.length; ++i) {
v = s.charCodeAt(i);
if (v < 32 && v != 9 && v != 10 && v != 13) // [\t\r\n] are (kinda) printable
throw new Error('Unprintable character at index ' + i + ' (code ' + s.str.charCodeAt(i) + ')');
}
}
Stream.prototype.get = function (pos) {
if (pos === undefined)
pos = this.pos++;
if (pos >= this.enc.length)
throw 'Requesting byte offset ' + pos + ' on a stream of length ' + this.enc.length;
return (typeof this.enc == "string") ? this.enc.charCodeAt(pos) : this.enc[pos];
};
Stream.prototype.hexDigits = "0123456789ABCDEF";
Stream.prototype.hexByte = function (b) {
return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);
};
Stream.prototype.hexDump = function (start, end, raw) {
var s = "";
for (var i = start; i < end; ++i) {
s += this.hexByte(this.get(i));
if (raw !== true)
switch (i & 0xF) {
case 0x7: s += " "; break;
case 0xF: s += "\n"; break;
default: s += " ";
}
class Stream {
constructor(enc, pos) {
if (enc instanceof Stream) {
this.enc = enc.enc;
this.pos = enc.pos;
} else {
// enc should be an array or a binary string
this.enc = enc;
this.pos = pos;
}
}
return s;
};
var b64Safe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
Stream.prototype.b64Dump = function (start, end) {
var extra = (end - start) % 3,
s = '',
i, c;
for (i = start; i + 2 < end; i += 3) {
c = this.get(i) << 16 | this.get(i + 1) << 8 | this.get(i + 2);
s += b64Safe.charAt(c >> 18 & 0x3F);
s += b64Safe.charAt(c >> 12 & 0x3F);
s += b64Safe.charAt(c >> 6 & 0x3F);
s += b64Safe.charAt(c & 0x3F);
get(pos) {
if (pos === undefined)
pos = this.pos++;
if (pos >= this.enc.length)
throw 'Requesting byte offset ' + pos + ' on a stream of length ' + this.enc.length;
return (typeof this.enc == 'string') ? this.enc.charCodeAt(pos) : this.enc[pos];
}
if (extra > 0) {
c = this.get(i) << 16;
if (extra > 1) c |= this.get(i + 1) << 8;
s += b64Safe.charAt(c >> 18 & 0x3F);
s += b64Safe.charAt(c >> 12 & 0x3F);
if (extra == 2) s += b64Safe.charAt(c >> 6 & 0x3F);
hexByte(b) {
return hexDigits.charAt((b >> 4) & 0xF) + hexDigits.charAt(b & 0xF);
}
return s;
};
Stream.prototype.isASCII = function (start, end) {
for (var i = start; i < end; ++i) {
var c = this.get(i);
if (c < 32 || c > 176)
return false;
hexDump(start, end, raw) {
let s = '';
for (let i = start; i < end; ++i) {
s += this.hexByte(this.get(i));
if (raw !== true)
switch (i & 0xF) {
case 0x7: s += ' '; break;
case 0xF: s += '\n'; break;
default: s += ' ';
}
}
return s;
}
return true;
};
Stream.prototype.parseStringISO = function (start, end, maxLength) {
var s = "";
for (var i = start; i < end; ++i)
s += String.fromCharCode(this.get(i));
return { size: s.length, str: stringCut(s, maxLength) };
};
var tableT61 = [
['', ''],
['AEIOUaeiou', 'ÀÈÌÒÙàèìòù'], // Grave
['ACEILNORSUYZacegilnorsuyz', 'ÁĆÉÍĹŃÓŔŚÚÝŹáćéģíĺńóŕśúýź'], // Acute
['ACEGHIJOSUWYaceghijosuwy', 'ÂĈÊĜĤÎĴÔŜÛŴŶâĉêĝĥîĵôŝûŵŷ'], // Circumflex
['AINOUainou', 'ÃĨÑÕŨãĩñõũ'], // Tilde
['AEIOUaeiou', 'ĀĒĪŌŪāēīōū'], // Macron
['AGUagu', 'ĂĞŬăğŭ'], // Breve
['CEGIZcegz', 'ĊĖĠİŻċėġż'], // Dot
['AEIOUYaeiouy', 'ÄËÏÖÜŸäëïöüÿ'], // Umlaut or diæresis
['', ''],
['AUau', 'ÅŮåů'], // Ring
['CGKLNRSTcklnrst', 'ÇĢĶĻŅŖŞŢçķļņŗşţ'], // Cedilla
['', ''],
['OUou', 'ŐŰőű'], // Double Acute
['AEIUaeiu', 'ĄĘĮŲąęįų'], // Ogonek
['CDELNRSTZcdelnrstz', 'ČĎĚĽŇŘŠŤŽčďěľňřšťž'] // Caron
];
Stream.prototype.parseStringT61 = function (start, end, maxLength) {
// warning: this code is not very well tested so far
function merge(c, d) {
var t = tableT61[c - 0xC0];
var i = t[0].indexOf(String.fromCharCode(d));
return (i < 0) ? '\0' : t[1].charAt(i);
b64Dump(start, end) {
let extra = (end - start) % 3,
s = '',
i, c;
for (i = start; i + 2 < end; i += 3) {
c = this.get(i) << 16 | this.get(i + 1) << 8 | this.get(i + 2);
s += b64Safe.charAt(c >> 18 & 0x3F);
s += b64Safe.charAt(c >> 12 & 0x3F);
s += b64Safe.charAt(c >> 6 & 0x3F);
s += b64Safe.charAt(c & 0x3F);
}
if (extra > 0) {
c = this.get(i) << 16;
if (extra > 1) c |= this.get(i + 1) << 8;
s += b64Safe.charAt(c >> 18 & 0x3F);
s += b64Safe.charAt(c >> 12 & 0x3F);
if (extra == 2) s += b64Safe.charAt(c >> 6 & 0x3F);
}
return s;
}
var s = "", c;
for (var i = start; i < end; ++i) {
c = this.get(i);
if (c >= 0xA4 && c <= 0xBF)
s += '$¥#§¤\0\0«\0\0\0\0°±²³×µ¶·÷\0\0»¼½¾¿'.charAt(c - 0xA4);
else if (c >= 0xE0 && c <= 0xFF)
s += 'ΩÆЪĦ\0IJĿŁØŒºÞŦŊʼnĸæđðħıijŀłøœßþŧŋ\0'.charAt(c - 0xE0);
else if (c >= 0xC0 && c <= 0xCF)
s += merge(c, this.get(++i));
else // using ISO 8859-1 for characters undefined (or equal) in T.61
s += String.fromCharCode(c);
isASCII(start, end) {
for (let i = start; i < end; ++i) {
let c = this.get(i);
if (c < 32 || c > 176)
return false;
}
return true;
}
return { size: s.length, str: stringCut(s, maxLength) };
};
Stream.prototype.parseStringUTF = function (start, end, maxLength) {
function ex(c) { // must be 10xxxxxx
if ((c < 0x80) || (c >= 0xC0))
throw new Error('Invalid UTF-8 continuation byte: ' + c);
return (c & 0x3F);
parseStringISO(start, end, maxLength) {
let s = '';
for (let i = start; i < end; ++i)
s += String.fromCharCode(this.get(i));
return { size: s.length, str: stringCut(s, maxLength) };
}
function surrogate(cp) {
if (cp < 0x10000)
throw new Error('UTF-8 overlong encoding, codepoint encoded in 4 bytes: ' + cp);
// we could use String.fromCodePoint(cp) but let's be nice to older browsers and use surrogate pairs
cp -= 0x10000;
return String.fromCharCode((cp >> 10) + 0xD800, (cp & 0x3FF) + 0xDC00);
parseStringT61(start, end, maxLength) {
// warning: this code is not very well tested so far
function merge(c, d) {
let t = tableT61[c - 0xC0];
let i = t[0].indexOf(String.fromCharCode(d));
return (i < 0) ? '\0' : t[1].charAt(i);
}
let s = '', c;
for (let i = start; i < end; ++i) {
c = this.get(i);
if (c >= 0xA4 && c <= 0xBF)
s += '$¥#§¤\0\0«\0\0\0\0°±²³×µ¶·÷\0\0»¼½¾¿'.charAt(c - 0xA4);
else if (c >= 0xE0 && c <= 0xFF)
s += 'ΩÆЪĦ\0IJĿŁØŒºÞŦŊʼnĸæđðħıijŀłøœßþŧŋ\0'.charAt(c - 0xE0);
else if (c >= 0xC0 && c <= 0xCF)
s += merge(c, this.get(++i));
else // using ISO 8859-1 for characters undefined (or equal) in T.61
s += String.fromCharCode(c);
}
return { size: s.length, str: stringCut(s, maxLength) };
}
var s = "";
for (var i = start; i < end; ) {
var c = this.get(i++);
if (c < 0x80) // 0xxxxxxx (7 bit)
s += String.fromCharCode(c);
else if (c < 0xC0)
throw new Error('Invalid UTF-8 starting byte: ' + c);
else if (c < 0xE0) // 110xxxxx 10xxxxxx (11 bit)
s += String.fromCharCode(((c & 0x1F) << 6) | ex(this.get(i++)));
else if (c < 0xF0) // 1110xxxx 10xxxxxx 10xxxxxx (16 bit)
s += String.fromCharCode(((c & 0x0F) << 12) | (ex(this.get(i++)) << 6) | ex(this.get(i++)));
else if (c < 0xF8) // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (21 bit)
s += surrogate(((c & 0x07) << 18) | (ex(this.get(i++)) << 12) | (ex(this.get(i++)) << 6) | ex(this.get(i++)));
else
throw new Error('Invalid UTF-8 starting byte (since 2003 it is restricted to 4 bytes): ' + c);
parseStringUTF(start, end, maxLength) {
function ex(c) { // must be 10xxxxxx
if ((c < 0x80) || (c >= 0xC0))
throw new Error('Invalid UTF-8 continuation byte: ' + c);
return (c & 0x3F);
}
function surrogate(cp) {
if (cp < 0x10000)
throw new Error('UTF-8 overlong encoding, codepoint encoded in 4 bytes: ' + cp);
// we could use String.fromCodePoint(cp) but let's be nice to older browsers and use surrogate pairs
cp -= 0x10000;
return String.fromCharCode((cp >> 10) + 0xD800, (cp & 0x3FF) + 0xDC00);
}
let s = '';
for (let i = start; i < end; ) {
let c = this.get(i++);
if (c < 0x80) // 0xxxxxxx (7 bit)
s += String.fromCharCode(c);
else if (c < 0xC0)
throw new Error('Invalid UTF-8 starting byte: ' + c);
else if (c < 0xE0) // 110xxxxx 10xxxxxx (11 bit)
s += String.fromCharCode(((c & 0x1F) << 6) | ex(this.get(i++)));
else if (c < 0xF0) // 1110xxxx 10xxxxxx 10xxxxxx (16 bit)
s += String.fromCharCode(((c & 0x0F) << 12) | (ex(this.get(i++)) << 6) | ex(this.get(i++)));
else if (c < 0xF8) // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (21 bit)
s += surrogate(((c & 0x07) << 18) | (ex(this.get(i++)) << 12) | (ex(this.get(i++)) << 6) | ex(this.get(i++)));
else
throw new Error('Invalid UTF-8 starting byte (since 2003 it is restricted to 4 bytes): ' + c);
}
return { size: s.length, str: stringCut(s, maxLength) };
}
return { size: s.length, str: stringCut(s, maxLength) };
};
Stream.prototype.parseStringBMP = function (start, end, maxLength) {
var s = "", hi, lo;
for (var i = start; i < end; ) {
hi = this.get(i++);
lo = this.get(i++);
s += String.fromCharCode((hi << 8) | lo);
parseStringBMP(start, end, maxLength) {
let s = '', hi, lo;
for (let i = start; i < end; ) {
hi = this.get(i++);
lo = this.get(i++);
s += String.fromCharCode((hi << 8) | lo);
}
return { size: s.length, str: stringCut(s, maxLength) };
}
return { size: s.length, str: stringCut(s, maxLength) };
};
Stream.prototype.parseTime = function (start, end, shortYear) {
var s = this.parseStringISO(start, end).str,
m = (shortYear ? reTimeS : reTimeL).exec(s);
if (!m)
return "Unrecognized time: " + s;
if (shortYear) {
// to avoid querying the timer, use the fixed range [1970, 2069]
// it will conform with ITU X.400 [-10, +40] sliding window until 2030
m[1] = +m[1];
m[1] += (m[1] < 70) ? 2000 : 1900;
parseTime(start, end, shortYear) {
let s = this.parseStringISO(start, end).str,
m = (shortYear ? reTimeS : reTimeL).exec(s);
if (!m)
return 'Unrecognized time: ' + s;
if (shortYear) {
// to avoid querying the timer, use the fixed range [1970, 2069]
// it will conform with ITU X.400 [-10, +40] sliding window until 2030
m[1] = +m[1];
m[1] += (m[1] < 70) ? 2000 : 1900;
}
s = m[1] + '-' + m[2] + '-' + m[3] + ' ' + m[4];
if (m[5]) {
s += ':' + m[5];
if (m[6]) {
s += ':' + m[6];
if (m[7])
s += '.' + m[7];
}
}
if (m[8]) {
s += ' UTC';
if (m[9])
s += m[9] + ':' + (m[10] || '00');
}
return s;
}
s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4];
if (m[5]) {
s += ":" + m[5];
if (m[6]) {
s += ":" + m[6];
if (m[7])
s += "." + m[7];
parseInteger(start, end) {
let v = this.get(start),
neg = (v > 127),
pad = neg ? 255 : 0,
len,
s = '';
// skip unuseful bits (not allowed in DER)
while (v == pad && ++start < end)
v = this.get(start);
len = end - start;
if (len === 0)
return neg ? '-1' : '0';
// show bit length of huge integers
if (len > 4) {
s = v;
len <<= 3;
while (((s ^ pad) & 0x80) == 0) {
s <<= 1;
--len;
}
s = '(' + len + ' bit)\n';
}
// decode the integer
if (neg) v = v - 256;
let n = new Int10(v);
for (let i = start + 1; i < end; ++i)
n.mulAdd(256, this.get(i));
return s + n.toString();
}
if (m[8]) {
s += " UTC";
if (m[9])
s += m[9] + ":" + (m[10] || "00");
parseBitString(start, end, maxLength) {
let unusedBits = this.get(start);
if (unusedBits > 7)
throw 'Invalid BitString with unusedBits=' + unusedBits;
let lenBit = ((end - start - 1) << 3) - unusedBits,
s = '';
for (let i = start + 1; i < end; ++i) {
let b = this.get(i),
skip = (i == end - 1) ? unusedBits : 0;
for (let j = 7; j >= skip; --j)
s += (b >> j) & 1 ? '1' : '0';
if (s.length > maxLength)
s = stringCut(s, maxLength);
}
return { size: lenBit, str: s };
}
return s;
};
Stream.prototype.parseInteger = function (start, end) {
var v = this.get(start),
neg = (v > 127),
pad = neg ? 255 : 0,
len,
parseOctetString(start, end, maxLength) {
let len = end - start,
s;
try {
s = this.parseStringUTF(start, end, maxLength);
checkPrintable(s.str);
return { size: end - start, str: s.str };
} catch (e) {
// ignore
}
maxLength /= 2; // we work in bytes
if (len > maxLength)
end = start + maxLength;
s = '';
// skip unuseful bits (not allowed in DER)
while (v == pad && ++start < end)
v = this.get(start);
len = end - start;
if (len === 0)
return neg ? '-1' : '0';
// show bit length of huge integers
if (len > 4) {
s = v;
len <<= 3;
while (((s ^ pad) & 0x80) == 0) {
s <<= 1;
--len;
}
s = "(" + len + " bit)\n";
for (let i = start; i < end; ++i)
s += this.hexByte(this.get(i));
if (len > maxLength)
s += ellipsis;
return { size: len, str: s };
}
// decode the integer
if (neg) v = v - 256;
var n = new Int10(v);
for (var i = start + 1; i < end; ++i)
n.mulAdd(256, this.get(i));
return s + n.toString();
};
Stream.prototype.parseBitString = function (start, end, maxLength) {
var unusedBits = this.get(start);
if (unusedBits > 7)
throw 'Invalid BitString with unusedBits=' + unusedBits;
var lenBit = ((end - start - 1) << 3) - unusedBits,
s = "";
for (var i = start + 1; i < end; ++i) {
var b = this.get(i),
skip = (i == end - 1) ? unusedBits : 0;
for (var j = 7; j >= skip; --j)
s += (b >> j) & 1 ? "1" : "0";
if (s.length > maxLength)
s = stringCut(s, maxLength);
}
return { size: lenBit, str: s };
};
function checkPrintable(s) {
var i, v;
for (i = 0; i < s.length; ++i) {
v = s.charCodeAt(i);
if (v < 32 && v != 9 && v != 10 && v != 13) // [\t\r\n] are (kinda) printable
throw new Error('Unprintable character at index ' + i + ' (code ' + s.str.charCodeAt(i) + ")");
}
}
Stream.prototype.parseOctetString = function (start, end, maxLength) {
var len = end - start,
s;
try {
s = this.parseStringUTF(start, end, maxLength);
checkPrintable(s.str);
return { size: end - start, str: s.str };
} catch (e) {
// ignore
}
maxLength /= 2; // we work in bytes
if (len > maxLength)
end = start + maxLength;
s = '';
for (var i = start; i < end; ++i)
s += this.hexByte(this.get(i));
if (len > maxLength)
s += ellipsis;
return { size: len, str: s };
};
Stream.prototype.parseOID = function (start, end, maxLength, isRelative) {
var s = '',
n = new Int10(),
bits = 0;
for (var i = start; i < end; ++i) {
var v = this.get(i);
n.mulAdd(128, v & 0x7F);
bits += 7;
if (!(v & 0x80)) { // finished
if (s === '') {
n = n.simplify();
if (isRelative) {
s = (n instanceof Int10) ? n.toString() : "" + n;
} else if (n instanceof Int10) {
n.sub(80);
s = "2." + n.toString();
} else {
var m = n < 80 ? n < 40 ? 0 : 1 : 2;
s = m + "." + (n - m * 40);
}
} else
s += "." + n.toString();
if (s.length > maxLength)
return stringCut(s, maxLength);
n = new Int10();
parseOID(start, end, maxLength, isRelative) {
let s = '',
n = new Int10(),
bits = 0;
for (let i = start; i < end; ++i) {
let v = this.get(i);
n.mulAdd(128, v & 0x7F);
bits += 7;
if (!(v & 0x80)) { // finished
if (s === '') {
n = n.simplify();
if (isRelative) {
s = (n instanceof Int10) ? n.toString() : '' + n;
} else if (n instanceof Int10) {
n.sub(80);
s = '2.' + n.toString();
} else {
let m = n < 80 ? n < 40 ? 0 : 1 : 2;
s = m + '.' + (n - m * 40);
}
} else
s += '.' + n.toString();
if (s.length > maxLength)
return stringCut(s, maxLength);
n = new Int10();
bits = 0;
}
}
}
if (bits > 0)
s += ".incomplete";
if (typeof oids === 'object' && !isRelative) {
var oid = oids[s];
if (oid) {
if (oid.d) s += "\n" + oid.d;
if (oid.c) s += "\n" + oid.c;
if (oid.w) s += "\n(warning!)";
if (bits > 0)
s += '.incomplete';
if (typeof oids === 'object' && !isRelative) {
let oid = oids[s];
if (oid) {
if (oid.d) s += '\n' + oid.d;
if (oid.c) s += '\n' + oid.c;
if (oid.w) s += '\n(warning!)';
}
}
return s;
}
return s;
};
Stream.prototype.parseRelativeOID = function (start, end, maxLength) {
return this.parseOID(start, end, maxLength, true);
};
parseRelativeOID(start, end, maxLength) {
return this.parseOID(start, end, maxLength, true);
}
}
function ASN1(stream, header, length, tag, tagLen, sub) {
if (!(tag instanceof ASN1Tag)) throw 'Invalid tag value.';
this.stream = stream;
this.header = header;
this.length = length;
this.tag = tag;
this.tagLen = tagLen;
this.sub = sub;
}
ASN1.prototype.typeName = function () {
switch (this.tag.tagClass) {
case 0: // universal
switch (this.tag.tagNumber) {
case 0x00: return "EOC";
case 0x01: return "BOOLEAN";
case 0x02: return "INTEGER";
case 0x03: return "BIT_STRING";
case 0x04: return "OCTET_STRING";
case 0x05: return "NULL";
case 0x06: return "OBJECT_IDENTIFIER";
case 0x07: return "ObjectDescriptor";
case 0x08: return "EXTERNAL";
case 0x09: return "REAL";
case 0x0A: return "ENUMERATED";
case 0x0B: return "EMBEDDED_PDV";
case 0x0C: return "UTF8String";
case 0x0D: return "RELATIVE_OID";
case 0x10: return "SEQUENCE";
case 0x11: return "SET";
case 0x12: return "NumericString";
case 0x13: return "PrintableString"; // ASCII subset
case 0x14: return "TeletexString"; // aka T61String
case 0x15: return "VideotexString";
case 0x16: return "IA5String"; // ASCII
case 0x17: return "UTCTime";
case 0x18: return "GeneralizedTime";
case 0x19: return "GraphicString";
case 0x1A: return "VisibleString"; // ASCII subset
case 0x1B: return "GeneralString";
case 0x1C: return "UniversalString";
case 0x1E: return "BMPString";
}
return "Universal_" + this.tag.tagNumber.toString();
case 1: return "Application_" + this.tag.tagNumber.toString();
case 2: return "[" + this.tag.tagNumber.toString() + "]"; // Context
case 3: return "Private_" + this.tag.tagNumber.toString();
}
};
function recurse(el, parser, maxLength) {
var avoidRecurse = true;
let avoidRecurse = true;
if (el.tag.tagConstructed && el.sub) {

@@ -387,5 +339,5 @@ avoidRecurse = false;

return el.stream[parser](el.posContent(), el.posContent() + Math.abs(el.length), maxLength);
var d = { size: 0, str: '' };
let d = { size: 0, str: '' };
el.sub.forEach(function (el) {
var d1 = recurse(el, parser, maxLength - d.str.length);
let d1 = recurse(el, parser, maxLength - d.str.length);
d.size += d1.size;

@@ -396,207 +348,262 @@ d.str += d1.str;

}
/** A string preview of the content (intended for humans). */
ASN1.prototype.content = function (maxLength) {
if (this.tag === undefined)
class ASN1Tag {
constructor(stream) {
let buf = stream.get();
this.tagClass = buf >> 6;
this.tagConstructed = ((buf & 0x20) !== 0);
this.tagNumber = buf & 0x1F;
if (this.tagNumber == 0x1F) { // long tag
let n = new Int10();
do {
buf = stream.get();
n.mulAdd(128, buf & 0x7F);
} while (buf & 0x80);
this.tagNumber = n.simplify();
}
}
isUniversal() {
return this.tagClass === 0x00;
}
isEOC() {
return this.tagClass === 0x00 && this.tagNumber === 0x00;
}
}
export class ASN1 {
constructor(stream, header, length, tag, tagLen, sub) {
if (!(tag instanceof ASN1Tag)) throw 'Invalid tag value.';
this.stream = stream;
this.header = header;
this.length = length;
this.tag = tag;
this.tagLen = tagLen;
this.sub = sub;
}
typeName() {
switch (this.tag.tagClass) {
case 0: // universal
switch (this.tag.tagNumber) {
case 0x00: return 'EOC';
case 0x01: return 'BOOLEAN';
case 0x02: return 'INTEGER';
case 0x03: return 'BIT_STRING';
case 0x04: return 'OCTET_STRING';
case 0x05: return 'NULL';
case 0x06: return 'OBJECT_IDENTIFIER';
case 0x07: return 'ObjectDescriptor';
case 0x08: return 'EXTERNAL';
case 0x09: return 'REAL';
case 0x0A: return 'ENUMERATED';
case 0x0B: return 'EMBEDDED_PDV';
case 0x0C: return 'UTF8String';
case 0x0D: return 'RELATIVE_OID';
case 0x10: return 'SEQUENCE';
case 0x11: return 'SET';
case 0x12: return 'NumericString';
case 0x13: return 'PrintableString'; // ASCII subset
case 0x14: return 'TeletexString'; // aka T61String
case 0x15: return 'VideotexString';
case 0x16: return 'IA5String'; // ASCII
case 0x17: return 'UTCTime';
case 0x18: return 'GeneralizedTime';
case 0x19: return 'GraphicString';
case 0x1A: return 'VisibleString'; // ASCII subset
case 0x1B: return 'GeneralString';
case 0x1C: return 'UniversalString';
case 0x1E: return 'BMPString';
}
return 'Universal_' + this.tag.tagNumber.toString();
case 1: return 'Application_' + this.tag.tagNumber.toString();
case 2: return '[' + this.tag.tagNumber.toString() + ']'; // Context
case 3: return 'Private_' + this.tag.tagNumber.toString();
}
}
/** A string preview of the content (intended for humans). */
content(maxLength) {
if (this.tag === undefined)
return null;
if (maxLength === undefined)
maxLength = Infinity;
let content = this.posContent(),
len = Math.abs(this.length);
if (!this.tag.isUniversal()) {
if (this.sub !== null)
return '(' + this.sub.length + ' elem)';
let d1 = this.stream.parseOctetString(content, content + len, maxLength);
return '(' + d1.size + ' byte)\n' + d1.str;
}
switch (this.tag.tagNumber) {
case 0x01: // BOOLEAN
return (this.stream.get(content) === 0) ? 'false' : 'true';
case 0x02: // INTEGER
return this.stream.parseInteger(content, content + len);
case 0x03: { // BIT_STRING
let d = recurse(this, 'parseBitString', maxLength);
return '(' + d.size + ' bit)\n' + d.str;
}
case 0x04: { // OCTET_STRING
let d = recurse(this, 'parseOctetString', maxLength);
return '(' + d.size + ' byte)\n' + d.str;
}
//case 0x05: // NULL
case 0x06: // OBJECT_IDENTIFIER
return this.stream.parseOID(content, content + len, maxLength);
//case 0x07: // ObjectDescriptor
//case 0x08: // EXTERNAL
//case 0x09: // REAL
case 0x0A: // ENUMERATED
return this.stream.parseInteger(content, content + len);
//case 0x0B: // EMBEDDED_PDV
case 0x0D: // RELATIVE-OID
return this.stream.parseRelativeOID(content, content + len, maxLength);
case 0x10: // SEQUENCE
case 0x11: // SET
if (this.sub !== null)
return '(' + this.sub.length + ' elem)';
else
return '(no elem)';
case 0x0C: // UTF8String
return recurse(this, 'parseStringUTF', maxLength).str;
case 0x14: // TeletexString
return recurse(this, 'parseStringT61', maxLength).str;
case 0x12: // NumericString
case 0x13: // PrintableString
case 0x15: // VideotexString
case 0x16: // IA5String
case 0x1A: // VisibleString
case 0x1B: // GeneralString
//case 0x19: // GraphicString
//case 0x1C: // UniversalString
return recurse(this, 'parseStringISO', maxLength).str;
case 0x1E: // BMPString
return recurse(this, 'parseStringBMP', maxLength).str;
case 0x17: // UTCTime
case 0x18: // GeneralizedTime
return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17));
}
return null;
if (maxLength === undefined)
maxLength = Infinity;
var content = this.posContent(),
len = Math.abs(this.length);
if (!this.tag.isUniversal()) {
if (this.sub !== null)
return "(" + this.sub.length + " elem)";
var d1 = this.stream.parseOctetString(content, content + len, maxLength);
return "(" + d1.size + " byte)\n" + d1.str;
}
switch (this.tag.tagNumber) {
case 0x01: // BOOLEAN
return (this.stream.get(content) === 0) ? "false" : "true";
case 0x02: // INTEGER
return this.stream.parseInteger(content, content + len);
case 0x03: // BIT_STRING
var d = recurse(this, 'parseBitString', maxLength);
return "(" + d.size + " bit)\n" + d.str;
case 0x04: // OCTET_STRING
d = recurse(this, 'parseOctetString', maxLength);
return "(" + d.size + " byte)\n" + d.str;
//case 0x05: // NULL
case 0x06: // OBJECT_IDENTIFIER
return this.stream.parseOID(content, content + len, maxLength);
//case 0x07: // ObjectDescriptor
//case 0x08: // EXTERNAL
//case 0x09: // REAL
case 0x0A: // ENUMERATED
return this.stream.parseInteger(content, content + len);
//case 0x0B: // EMBEDDED_PDV
case 0x0D: // RELATIVE-OID
return this.stream.parseRelativeOID(content, content + len, maxLength);
case 0x10: // SEQUENCE
case 0x11: // SET
if (this.sub !== null)
return "(" + this.sub.length + " elem)";
else
return "(no elem)";
case 0x0C: // UTF8String
return recurse(this, 'parseStringUTF', maxLength).str;
case 0x14: // TeletexString
return recurse(this, 'parseStringT61', maxLength).str;
case 0x12: // NumericString
case 0x13: // PrintableString
case 0x15: // VideotexString
case 0x16: // IA5String
case 0x1A: // VisibleString
case 0x1B: // GeneralString
//case 0x19: // GraphicString
//case 0x1C: // UniversalString
return recurse(this, 'parseStringISO', maxLength).str;
case 0x1E: // BMPString
return recurse(this, 'parseStringBMP', maxLength).str;
case 0x17: // UTCTime
case 0x18: // GeneralizedTime
return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17));
toString() {
return this.typeName() + '@' + this.stream.pos + '[header:' + this.header + ',length:' + this.length + ',sub:' + ((this.sub === null) ? 'null' : this.sub.length) + ']';
}
return null;
};
ASN1.prototype.toString = function () {
return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? 'null' : this.sub.length) + "]";
};
ASN1.prototype.toPrettyString = function (indent) {
if (indent === undefined) indent = '';
var s = indent + this.typeName() + " @" + this.stream.pos;
if (this.length >= 0)
s += "+";
s += this.length;
if (this.tag.tagConstructed)
s += " (constructed)";
else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null))
s += " (encapsulates)";
var content = this.content();
if (content)
s += ": " + content.replace(/\n/g, '|');
s += "\n";
if (this.sub !== null) {
indent += ' ';
for (var i = 0, max = this.sub.length; i < max; ++i)
s += this.sub[i].toPrettyString(indent);
toPrettyString(indent) {
if (indent === undefined) indent = '';
let s = indent + this.typeName() + ' @' + this.stream.pos;
if (this.length >= 0)
s += '+';
s += this.length;
if (this.tag.tagConstructed)
s += ' (constructed)';
else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null))
s += ' (encapsulates)';
let content = this.content();
if (content)
s += ': ' + content.replace(/\n/g, '|');
s += '\n';
if (this.sub !== null) {
indent += ' ';
for (let i = 0, max = this.sub.length; i < max; ++i)
s += this.sub[i].toPrettyString(indent);
}
return s;
}
return s;
};
ASN1.prototype.posStart = function () {
return this.stream.pos;
};
ASN1.prototype.posContent = function () {
return this.stream.pos + this.header;
};
ASN1.prototype.posEnd = function () {
return this.stream.pos + this.header + Math.abs(this.length);
};
/** Position of the length. */
ASN1.prototype.posLen = function() {
return this.stream.pos + this.tagLen;
};
ASN1.prototype.toHexString = function () {
return this.stream.hexDump(this.posStart(), this.posEnd(), true);
};
ASN1.prototype.toB64String = function () {
return this.stream.b64Dump(this.posStart(), this.posEnd());
};
ASN1.decodeLength = function (stream) {
var buf = stream.get(),
len = buf & 0x7F;
if (len == buf) // first bit was 0, short form
return len;
if (len === 0) // long form with length 0 is a special case
return null; // undefined length
if (len > 6) // no reason to use Int10, as it would be a huge buffer anyways
throw "Length over 48 bits not supported at position " + (stream.pos - 1);
buf = 0;
for (var i = 0; i < len; ++i)
buf = (buf * 256) + stream.get();
return buf;
};
function ASN1Tag(stream) {
var buf = stream.get();
this.tagClass = buf >> 6;
this.tagConstructed = ((buf & 0x20) !== 0);
this.tagNumber = buf & 0x1F;
if (this.tagNumber == 0x1F) { // long tag
var n = new Int10();
do {
buf = stream.get();
n.mulAdd(128, buf & 0x7F);
} while (buf & 0x80);
this.tagNumber = n.simplify();
posStart() {
return this.stream.pos;
}
}
ASN1Tag.prototype.isUniversal = function () {
return this.tagClass === 0x00;
};
ASN1Tag.prototype.isEOC = function () {
return this.tagClass === 0x00 && this.tagNumber === 0x00;
};
ASN1.decode = function (stream, offset) {
if (!(stream instanceof Stream))
stream = new Stream(stream, offset || 0);
var streamStart = new Stream(stream),
tag = new ASN1Tag(stream),
tagLen = stream.pos - streamStart.pos,
len = ASN1.decodeLength(stream),
start = stream.pos,
header = start - streamStart.pos,
sub = null,
getSub = function () {
sub = [];
if (len !== null) {
// definite length
var end = start + len;
if (end > stream.enc.length)
throw 'Container at offset ' + start + ' has a length of ' + len + ', which is past the end of the stream';
while (stream.pos < end)
sub[sub.length] = ASN1.decode(stream);
if (stream.pos != end)
throw 'Content size is not correct for container at offset ' + start;
} else {
// undefined length
try {
for (;;) {
var s = ASN1.decode(stream);
if (s.tag.isEOC())
break;
sub[sub.length] = s;
posContent() {
return this.stream.pos + this.header;
}
posEnd() {
return this.stream.pos + this.header + Math.abs(this.length);
}
/** Position of the length. */
posLen() {
return this.stream.pos + this.tagLen;
}
toHexString() {
return this.stream.hexDump(this.posStart(), this.posEnd(), true);
}
toB64String() {
return this.stream.b64Dump(this.posStart(), this.posEnd());
}
static decodeLength(stream) {
let buf = stream.get(),
len = buf & 0x7F;
if (len == buf) // first bit was 0, short form
return len;
if (len === 0) // long form with length 0 is a special case
return null; // undefined length
if (len > 6) // no reason to use Int10, as it would be a huge buffer anyways
throw 'Length over 48 bits not supported at position ' + (stream.pos - 1);
buf = 0;
for (let i = 0; i < len; ++i)
buf = (buf * 256) + stream.get();
return buf;
}
static decode(stream, offset, type = ASN1) {
if (!(type == ASN1 || type.prototype instanceof ASN1))
throw 'Must pass a class that extends ASN1';
if (!(stream instanceof Stream))
stream = new Stream(stream, offset || 0);
let streamStart = new Stream(stream),
tag = new ASN1Tag(stream),
tagLen = stream.pos - streamStart.pos,
len = ASN1.decodeLength(stream),
start = stream.pos,
header = start - streamStart.pos,
sub = null,
getSub = function () {
sub = [];
if (len !== null) {
// definite length
let end = start + len;
if (end > stream.enc.length)
throw 'Container at offset ' + start + ' has a length of ' + len + ', which is past the end of the stream';
while (stream.pos < end)
sub[sub.length] = type.decode(stream);
if (stream.pos != end)
throw 'Content size is not correct for container at offset ' + start;
} else {
// undefined length
try {
for (;;) {
let s = type.decode(stream);
if (s.tag.isEOC())
break;
sub[sub.length] = s;
}
len = start - stream.pos; // undefined lengths are represented as negative values
} catch (e) {
throw 'Exception while decoding undefined length content at offset ' + start + ': ' + e;
}
len = start - stream.pos; // undefined lengths are represented as negative values
} catch (e) {
throw 'Exception while decoding undefined length content at offset ' + start + ': ' + e;
}
};
if (tag.tagConstructed) {
// must have valid content
getSub();
} else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) {
// sometimes BitString and OctetString are used to encapsulate ASN.1
try {
if (tag.tagNumber == 0x03)
if (stream.get() != 0)
throw 'BIT STRINGs with unused bits cannot encapsulate.';
getSub();
for (let i = 0; i < sub.length; ++i)
if (sub[i].tag.isEOC())
throw 'EOC is not supposed to be actual content.';
} catch (e) {
// but silently ignore when they don't
sub = null;
//DEBUG console.log('Could not decode structure at ' + start + ':', e);
}
};
if (tag.tagConstructed) {
// must have valid content
getSub();
} else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) {
// sometimes BitString and OctetString are used to encapsulate ASN.1
try {
if (tag.tagNumber == 0x03)
if (stream.get() != 0)
throw "BIT STRINGs with unused bits cannot encapsulate.";
getSub();
for (var i = 0; i < sub.length; ++i)
if (sub[i].tag.isEOC())
throw 'EOC is not supposed to be actual content.';
} catch (e) {
// but silently ignore when they don't
sub = null;
//DEBUG console.log('Could not decode structure at ' + start + ':', e);
}
if (sub === null) {
if (len === null)
throw "We can't skip over an invalid tag with undefined length at offset " + start;
stream.pos = start + Math.abs(len);
}
return new type(streamStart, header, len, tag, tagLen, sub);
}
if (sub === null) {
if (len === null)
throw "We can't skip over an invalid tag with undefined length at offset " + start;
stream.pos = start + Math.abs(len);
}
return new ASN1(streamStart, header, len, tag, tagLen, sub);
};
return ASN1;
});
}
// Base64 JavaScript decoder
// Copyright (c) 2008-2022 Lapo Luchini <lapo@lapo.it>
// Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>

@@ -16,93 +16,89 @@ // Permission to use, copy, modify, and/or distribute this software for any

(typeof define != 'undefined' ? define : function (factory) { 'use strict';
if (typeof module == 'object') module.exports = factory();
else window.base64 = factory();
})(function () {
"use strict";
var Base64 = {},
decoder, // populated on first usage
const
haveU8 = (typeof Uint8Array == 'function');
Base64.decode = function (a) {
var isString = (typeof a == 'string');
var i;
if (decoder === undefined) {
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
ignore = "= \f\n\r\t\u00A0\u2028\u2029";
decoder = [];
for (i = 0; i < 64; ++i)
decoder[b64.charCodeAt(i)] = i;
for (i = 0; i < ignore.length; ++i)
decoder[ignore.charCodeAt(i)] = -1;
// RFC 3548 URL & file safe encoding
decoder['-'.charCodeAt(0)] = decoder['+'.charCodeAt(0)];
decoder['_'.charCodeAt(0)] = decoder['/'.charCodeAt(0)];
}
var out = haveU8 ? new Uint8Array(a.length * 3 >> 2) : [];
var bits = 0, char_count = 0, len = 0;
for (i = 0; i < a.length; ++i) {
var c = isString ? a.charCodeAt(i) : a[i];
if (c == 61) // '='.charCodeAt(0)
let decoder; // populated on first usage
export class Base64 {
static decode(a) {
let isString = (typeof a == 'string');
let i;
if (decoder === undefined) {
let b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
ignore = '= \f\n\r\t\u00A0\u2028\u2029';
decoder = [];
for (i = 0; i < 64; ++i)
decoder[b64.charCodeAt(i)] = i;
for (i = 0; i < ignore.length; ++i)
decoder[ignore.charCodeAt(i)] = -1;
// RFC 3548 URL & file safe encoding
decoder['-'.charCodeAt(0)] = decoder['+'.charCodeAt(0)];
decoder['_'.charCodeAt(0)] = decoder['/'.charCodeAt(0)];
}
let out = haveU8 ? new Uint8Array(a.length * 3 >> 2) : [];
let bits = 0, char_count = 0, len = 0;
for (i = 0; i < a.length; ++i) {
let c = isString ? a.charCodeAt(i) : a[i];
if (c == 61) // '='.charCodeAt(0)
break;
c = decoder[c];
if (c == -1)
continue;
if (c === undefined)
throw 'Illegal character at offset ' + i;
bits |= c;
if (++char_count >= 4) {
out[len++] = (bits >> 16);
out[len++] = (bits >> 8) & 0xFF;
out[len++] = bits & 0xFF;
bits = 0;
char_count = 0;
} else {
bits <<= 6;
}
}
switch (char_count) {
case 1:
throw 'Base64 encoding incomplete: at least 2 bits missing';
case 2:
out[len++] = (bits >> 10);
break;
c = decoder[c];
if (c == -1)
continue;
if (c === undefined)
throw 'Illegal character at offset ' + i;
bits |= c;
if (++char_count >= 4) {
case 3:
out[len++] = (bits >> 16);
out[len++] = (bits >> 8) & 0xFF;
out[len++] = bits & 0xFF;
bits = 0;
char_count = 0;
} else {
bits <<= 6;
break;
}
if (haveU8 && out.length > len) // in case it was originally longer because of ignored characters
out = out.subarray(0, len);
return out;
}
switch (char_count) {
case 1:
throw "Base64 encoding incomplete: at least 2 bits missing";
case 2:
out[len++] = (bits >> 10);
break;
case 3:
out[len++] = (bits >> 16);
out[len++] = (bits >> 8) & 0xFF;
break;
static pretty(str) {
// fix padding
if (str.length % 4 > 0)
str = (str + '===').slice(0, str.length + str.length % 4);
// convert RFC 3548 to standard Base64
str = str.replace(/-/g, '+').replace(/_/g, '/');
// 80 column width
return str.replace(/(.{80})/g, '$1\n');
}
if (haveU8 && out.length > len) // in case it was originally longer because of ignored characters
out = out.subarray(0, len);
return out;
};
Base64.pretty = function (str) {
// fix padding
if (str.length % 4 > 0)
str = (str + '===').slice(0, str.length + str.length % 4);
// convert RFC 3548 to standard Base64
str = str.replace(/-/g, '+').replace(/_/g, '/');
// 80 column width
return str.replace(/(.{80})/g, '$1\n');
};
Base64.re = /-----BEGIN [^-]+-----([A-Za-z0-9+/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+/=\s]+)====|^([A-Za-z0-9+/=\s]+)$/;
Base64.unarmor = function (a) {
var m = Base64.re.exec(a);
if (m) {
if (m[1])
a = m[1];
else if (m[2])
a = m[2];
else if (m[3])
a = m[3];
else
throw "RegExp out of sync";
static unarmor(a) {
let m = Base64.re.exec(a);
if (m) {
if (m[1])
a = m[1];
else if (m[2])
a = m[2];
else if (m[3])
a = m[3];
else
throw 'RegExp out of sync';
}
return Base64.decode(a);
}
return Base64.decode(a);
};
return Base64;
}
});
Base64.re = /-----BEGIN [^-]+-----([A-Za-z0-9+/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+/=\s]+)====|^([A-Za-z0-9+/=\s]+)$/;
// Hex JavaScript decoder
// Copyright (c) 2008-2022 Lapo Luchini <lapo@lapo.it>
// Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>

@@ -16,60 +16,55 @@ // Permission to use, copy, modify, and/or distribute this software for any

(typeof define != 'undefined' ? define : function (factory) { 'use strict';
if (typeof module == 'object') module.exports = factory();
else window.hex = factory();
})(function () {
"use strict";
var Hex = {},
decoder, // populated on first usage
const
haveU8 = (typeof Uint8Array == 'function');
/**
* Decodes an hexadecimal value.
* @param {string|Array|Uint8Array} a - a string representing hexadecimal data, or an array representation of its charcodes
*/
Hex.decode = function(a) {
var isString = (typeof a == 'string');
var i;
if (decoder === undefined) {
var hex = "0123456789ABCDEF",
ignore = " \f\n\r\t\u00A0\u2028\u2029";
decoder = [];
for (i = 0; i < 16; ++i)
decoder[hex.charCodeAt(i)] = i;
hex = hex.toLowerCase();
for (i = 10; i < 16; ++i)
decoder[hex.charCodeAt(i)] = i;
for (i = 0; i < ignore.length; ++i)
decoder[ignore.charCodeAt(i)] = -1;
}
var out = haveU8 ? new Uint8Array(a.length >> 1) : [],
bits = 0,
char_count = 0,
len = 0;
for (i = 0; i < a.length; ++i) {
var c = isString ? a.charCodeAt(i) : a[i];
c = decoder[c];
if (c == -1)
continue;
if (c === undefined)
throw 'Illegal character at offset ' + i;
bits |= c;
if (++char_count >= 2) {
out[len++] = bits;
bits = 0;
char_count = 0;
} else {
bits <<= 4;
let decoder; // populated on first usage
export class Hex {
/**
* Decodes an hexadecimal value.
* @param {string|Array|Uint8Array} a - a string representing hexadecimal data, or an array representation of its charcodes
*/
static decode(a) {
let isString = (typeof a == 'string');
let i;
if (decoder === undefined) {
let hex = '0123456789ABCDEF',
ignore = ' \f\n\r\t\u00A0\u2028\u2029';
decoder = [];
for (i = 0; i < 16; ++i)
decoder[hex.charCodeAt(i)] = i;
hex = hex.toLowerCase();
for (i = 10; i < 16; ++i)
decoder[hex.charCodeAt(i)] = i;
for (i = 0; i < ignore.length; ++i)
decoder[ignore.charCodeAt(i)] = -1;
}
let out = haveU8 ? new Uint8Array(a.length >> 1) : [],
bits = 0,
char_count = 0,
len = 0;
for (i = 0; i < a.length; ++i) {
let c = isString ? a.charCodeAt(i) : a[i];
c = decoder[c];
if (c == -1)
continue;
if (c === undefined)
throw 'Illegal character at offset ' + i;
bits |= c;
if (++char_count >= 2) {
out[len++] = bits;
bits = 0;
char_count = 0;
} else {
bits <<= 4;
}
}
if (char_count)
throw 'Hex encoding incomplete: 4 bits missing';
if (haveU8 && out.length > len) // in case it was originally longer because of ignored characters
out = out.subarray(0, len);
return out;
}
if (char_count)
throw "Hex encoding incomplete: 4 bits missing";
if (haveU8 && out.length > len) // in case it was originally longer because of ignored characters
out = out.subarray(0, len);
return out;
};
return Hex;
});
}
// Big integer base-10 printing library
// Copyright (c) 2008-2022 Lapo Luchini <lapo@lapo.it>
// Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>

@@ -16,99 +16,92 @@ // Permission to use, copy, modify, and/or distribute this software for any

(typeof define != 'undefined' ? define : function (factory) { 'use strict';
if (typeof module == 'object') module.exports = factory();
else window.int10 = factory();
})(function () {
"use strict";
let max = 10000000000000; // biggest 10^n integer that can still fit 2^53 when multiplied by 256
var max = 10000000000000; // biggest 10^n integer that can still fit 2^53 when multiplied by 256
export class Int10 {
/**
* Arbitrary length base-10 value.
* @param {number} value - Optional initial value (will be 0 otherwise).
*/
constructor(value) {
this.buf = [+value || 0];
}
/**
* Arbitrary length base-10 value.
* @param {number} value - Optional initial value (will be 0 otherwise).
*/
function Int10(value) {
this.buf = [+value || 0];
}
/**
* Multiply value by m and add c.
* @param {number} m - multiplier, must be < =256
* @param {number} c - value to add
*/
mulAdd(m, c) {
// assert(m <= 256)
let b = this.buf,
l = b.length,
i, t;
for (i = 0; i < l; ++i) {
t = b[i] * m + c;
if (t < max)
c = 0;
else {
c = 0|(t / max);
t -= c * max;
}
b[i] = t;
}
if (c > 0)
b[i] = c;
}
/**
* Multiply value by m and add c.
* @param {number} m - multiplier, must be < =256
* @param {number} c - value to add
*/
Int10.prototype.mulAdd = function (m, c) {
// assert(m <= 256)
var b = this.buf,
l = b.length,
i, t;
for (i = 0; i < l; ++i) {
t = b[i] * m + c;
if (t < max)
c = 0;
else {
c = 0|(t / max);
t -= c * max;
/**
* Subtract value.
* @param {number} c - value to subtract
*/
sub(c) {
let b = this.buf,
l = b.length,
i, t;
for (i = 0; i < l; ++i) {
t = b[i] - c;
if (t < 0) {
t += max;
c = 1;
} else
c = 0;
b[i] = t;
}
b[i] = t;
while (b[b.length - 1] === 0)
b.pop();
}
if (c > 0)
b[i] = c;
};
/**
* Subtract value.
* @param {number} c - value to subtract
*/
Int10.prototype.sub = function (c) {
var b = this.buf,
l = b.length,
i, t;
for (i = 0; i < l; ++i) {
t = b[i] - c;
if (t < 0) {
t += max;
c = 1;
} else
c = 0;
b[i] = t;
/**
* Convert to decimal string representation.
* @param {*} base - optional value, only value accepted is 10
*/
toString(base) {
if ((base || 10) != 10)
throw 'only base 10 is supported';
let b = this.buf,
s = b[b.length - 1].toString();
for (let i = b.length - 2; i >= 0; --i)
s += (max + b[i]).toString().substring(1);
return s;
}
while (b[b.length - 1] === 0)
b.pop();
};
/**
* Convert to decimal string representation.
* @param {*} base - optional value, only value accepted is 10
*/
Int10.prototype.toString = function (base) {
if ((base || 10) != 10)
throw 'only base 10 is supported';
var b = this.buf,
s = b[b.length - 1].toString();
for (var i = b.length - 2; i >= 0; --i)
s += (max + b[i]).toString().substring(1);
return s;
};
/**
* Convert to Number value representation.
* Will probably overflow 2^53 and thus become approximate.
*/
valueOf() {
let b = this.buf,
v = 0;
for (let i = b.length - 1; i >= 0; --i)
v = v * max + b[i];
return v;
}
/**
* Convert to Number value representation.
* Will probably overflow 2^53 and thus become approximate.
*/
Int10.prototype.valueOf = function () {
var b = this.buf,
v = 0;
for (var i = b.length - 1; i >= 0; --i)
v = v * max + b[i];
return v;
};
/**
* Return value as a simple Number (if it is <= 10000000000000), or return this.
*/
simplify() {
let b = this.buf;
return (b.length == 1) ? b[0] : this;
}
/**
* Return value as a simple Number (if it is <= 10000000000000), or return this.
*/
Int10.prototype.simplify = function () {
var b = this.buf;
return (b.length == 1) ? b[0] : this;
};
return Int10;
});
}
{
"name": "@lapo/asn1js",
"version": "1.2.4",
"version": "1.3.0",
"description": "Generic ASN.1 parser/decoder that can decode any valid ASN.1 DER or BER structures.",
"type": "module",
"main": "asn1.js",

@@ -16,12 +17,24 @@ "repository": {

"files": [ "asn1.js", "base64.js", "hex.js", "int10.js", "oids.js" ],
"scripts" : {
"lint" : "npx eslint asn1.js base64.js hex.js int10.js oids.js parseRFC.js dumpASN1.js",
"test" : "node test"
"scripts": {
"lint": "npx eslint asn1.js base64.js hex.js int10.js oids.js tags.js index.js parseRFC.js dumpASN1.js",
"lint-action": "npx @action-validator/cli .github/workflows/node.js.yml",
"serve": "echo 'Connect to http://localhost:3000/' ; npx statik --port 3000 .",
"test": "node test"
},
"engines": {
"node": ">=12.20.0"
},
"devDependencies": {
"eslint": "^8.34.0"
},
"eslintConfig": {
"env": {
"amd": true,
"es6": true,
"browser": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 2015,
"sourceType": "module"
},
"extends": [ "eslint:recommended" ],

@@ -33,5 +46,7 @@ "globals": {

"strict": [ "error", "function" ],
"indent": [ "error", 4, { "ignoredNodes": [ "Program > ExpressionStatement > CallExpression > FunctionExpression > BlockStatement > ExpressionStatement[directive='use strict']:first-child" ] } ],
"indent": [ "error", 4 ],
"linebreak-style": [ "error", "unix" ],
"semi": [ "warn", "always" ],
"quotes": [ "error", "single", { "avoidEscape": true } ],
"no-var": [ "warn" ],
"comma-dangle": [ "error", "never" ]

@@ -43,3 +58,3 @@ },

"parserOptions": {
"ecmaVersion": 2020
"ecmaVersion": 2021
},

@@ -53,4 +68,16 @@ "rules": {

"rules": {
"indent": "off"
"indent": "off",
"quotes": [ "warn", "double" ]
}
}, {
"files": [ "tags.js" ],
"rules": {
"comma-dangle": [ "error", "always-multiline" ],
"quotes": [ "warn", "double" ]
}
}, {
"files": [ "defs.js" ],
"parserOptions": {
"ecmaVersion": 2021
}
}

@@ -57,0 +84,0 @@ ]

@@ -55,3 +55,3 @@ asn1js

ASN.1 JavaScript decoder Copyright (c) 2008-2022 Lapo Luchini <lapo@lapo.it>
ASN.1 JavaScript decoder Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>

@@ -70,2 +70,4 @@ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

- Relative OID support added by [Mistial Developer](https://github.com/mistial-dev)
- dark mode support added by [Oliver Burgmaier](https://github.com/olibu/)
- patches by [Nicolai Søborg](https://github.com/NicolaiSoeborg)

@@ -76,4 +78,5 @@ links

- [official website](https://lapo.it/asn1js/)
- [dedicated domain](https://asn1js.eu/)
- [InDefero tracker](http://idf.lapo.it/p/asn1js/)
- [GitHub mirror](https://github.com/lapo-luchini/asn1js)
- [Ohloh code stats](https://www.openhub.net/p/asn1js)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc