+10
.editorconfig
+10
.editorconfig
+9
-5
.github/workflows/node.js.yml
+9
-5
.github/workflows/node.js.yml
···
12
13
strategy:
14
matrix:
15
-
node-version: [ 12.20.0, latest ]
16
17
steps:
18
- uses: actions/checkout@v4
19
- name: Use Node.js ${{ matrix.node-version }}
20
uses: actions/setup-node@v4
21
with:
22
node-version: ${{ matrix.node-version }}
23
-
- run: npm test all
24
-
- run: npm install
25
-
if: matrix.node-version == 'latest'
26
-
- run: npm run lint
27
if: matrix.node-version == 'latest'
···
12
13
strategy:
14
matrix:
15
+
node-version: [ 14.6.0, latest ]
16
17
steps:
18
- uses: actions/checkout@v4
19
+
- name: Use pnpm
20
+
uses: pnpm/action-setup@v4
21
+
with:
22
+
run_install: false
23
- name: Use Node.js ${{ matrix.node-version }}
24
uses: actions/setup-node@v4
25
with:
26
node-version: ${{ matrix.node-version }}
27
+
cache: pnpm
28
+
- run: pnpm install
29
+
- run: node test all
30
+
- run: pnpm run lint
31
if: matrix.node-version == 'latest'
-1
.gitignore
-1
.gitignore
+1
-2
.mtn-ignore
+1
-2
.mtn-ignore
+99
.vscode/launch.json
+99
.vscode/launch.json
···
···
1
+
{
2
+
// Use IntelliSense to learn about possible attributes.
3
+
// Hover to view descriptions of existing attributes.
4
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+
"version": "0.2.0",
6
+
"configurations": [
7
+
{
8
+
"type": "node",
9
+
"request": "launch",
10
+
"name": "test",
11
+
"skipFiles": [
12
+
"<node_internals>/**"
13
+
],
14
+
"program": "${workspaceFolder}/test.js",
15
+
"args": []
16
+
},
17
+
{
18
+
"type": "node",
19
+
"request": "launch",
20
+
"name": "dumpASN1",
21
+
"skipFiles": [
22
+
"<node_internals>/**"
23
+
],
24
+
"program": "${workspaceFolder}/dumpASN1.js",
25
+
"args": [
26
+
"examples/ed25519.cer"
27
+
]
28
+
},
29
+
{
30
+
"type": "node",
31
+
"request": "launch",
32
+
"name": "parseRFC",
33
+
"skipFiles": [
34
+
"<node_internals>/**"
35
+
],
36
+
"program": "${workspaceFolder}/parseRFC.js",
37
+
"args": [
38
+
"rfc/rfc4511.txt",
39
+
"rfcdef.json"
40
+
]
41
+
},
42
+
{
43
+
"type": "node",
44
+
"request": "launch",
45
+
"name": "dumpASN1 X.509",
46
+
"skipFiles": [
47
+
"<node_internals>/**"
48
+
],
49
+
"program": "${workspaceFolder}/dumpASN1.js",
50
+
"args": [
51
+
"examples/ed25519.cer",
52
+
"1.3.6.1.5.5.7.0.18",
53
+
"Certificate"
54
+
]
55
+
},
56
+
{
57
+
"type": "node",
58
+
"request": "launch",
59
+
"name": "dumpASN1 CRL",
60
+
"skipFiles": [
61
+
"<node_internals>/**"
62
+
],
63
+
"program": "${workspaceFolder}/dumpASN1.js",
64
+
"args": [
65
+
"data:base64,MIG9AgEBMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxUUjM0IFNhbXBsZXMxGzAZBgNVBAMTElRSMzQgU2FtcGxlIENBIEtESBcNMTAxMTAyMTczMzMwWhcNMTAxMjAyMTczMzMwWjBIMBYCBTQAAAAIFw0xMDExMDIxNzI4MTNaMBYCBTQAAAAKFw0xMDExMDIxNzMxNDZaMBYCBTQAAAALFw0xMDExMDIxNzMzMjVa",
66
+
"1.3.6.1.5.5.7.0.18",
67
+
"TBSCertList"
68
+
]
69
+
},
70
+
{
71
+
"type": "node",
72
+
"request": "launch",
73
+
"name": "dumpASN1 CMS",
74
+
"skipFiles": [
75
+
"<node_internals>/**"
76
+
],
77
+
"program": "${workspaceFolder}/dumpASN1.js",
78
+
"args": [
79
+
"examples/cms-password.p7m",
80
+
"1.2.840.113549.1.9.16.0.14",
81
+
"ContentInfo"
82
+
]
83
+
},
84
+
{
85
+
"type": "node",
86
+
"request": "launch",
87
+
"name": "dumpASN1 LDAP",
88
+
"skipFiles": [
89
+
"<node_internals>/**"
90
+
],
91
+
"program": "${workspaceFolder}/dumpASN1.js",
92
+
"args": [
93
+
"data:base64,MDMCAQFjLgQACgEACgEAAgEAAgEAAQEAoA+jDQQFTnRWZXIEBAEAAAAwCgQITmV0bG9nb24===",
94
+
"1.3.6.1.1.18",
95
+
"LDAPMessage"
96
+
]
97
+
}
98
+
]
99
+
}
+9
.vscode/settings.json
+9
.vscode/settings.json
+38
CHANGELOG.md
+38
CHANGELOG.md
···
···
1
+
# ChangeLog
2
+
3
+
## 2.1.1 - 2025-10-24
4
+
5
+
### Changed
6
+
7
+
- update dev dependencies
8
+
- fix test suite that was reporting no error with empty responses
9
+
10
+
### Added
11
+
12
+
- add content length check for BOOLEAN, INTEGER, OID ([GitHub #104](https://github.com/lapo-luchini/asn1js/pull/104))
13
+
14
+
## 2.1.0 - 2025-08-03
15
+
16
+
### Changed
17
+
18
+
- when fields are CHOICEs now both the field name and the choice name are shown (fixes [GitHub #102](https://github.com/lapo-luchini/asn1js/issues/102))
19
+
- upgrade minimum NodeJS version supported from 12.20.0 to 14.6.0 due to usage of ?. and ?? operators in defs.js (ECMAScript 2020); older code is still linted against ECMAScript 2015 for now
20
+
21
+
### Added
22
+
23
+
- add tests to check expected decoding
24
+
25
+
## 2.0.6 - 2025-07-29
26
+
27
+
### Added
28
+
29
+
- add proper support for standard Base64 (we previously only supported Base64url) (fixes [GitHub #99](https://github.com/lapo-luchini/asn1js/pull/99))
30
+
- improve test harness
31
+
32
+
## 2.0.5 - 2025-04-12
33
+
34
+
### Added
35
+
36
+
- add `index-local.html` for local `file://` usage without needing a web server
37
+
- add definitions support for `LDAPMessage`
38
+
- #TODO continue producing old ChangeLog entries
+1
-1
LICENSE
+1
-1
LICENSE
+8
-6
README.md
+8
-6
README.md
···
3
4
asn1js is a JavaScript generic ASN.1 parser/decoder that can decode any valid ASN.1 DER or BER structures.
5
6
-
An example page that can decode Base64-encoded (raw base64, PEM armoring and `begin-base64` are recognized) or Hex-encoded (or local files with some browsers) is included and can be used both [online on the official website](https://lapo.it/asn1js/) or [offline (ZIP file)](https://lapo.it/asn1js/asn1js.zip).
7
8
Usage with `nodejs`
9
-------------------
···
67
Local usage
68
--------------------
69
70
-
Since unfortunately ESM modules are not working on `file:` protocol due to [CORS issues](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#other_differences_between_modules_and_standard_scripts), there is a bundled [single-file version working locally](https://asn1js.eu/index-local.html). It doesn't work online (due to [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) restrictions about inline content) but can be saved locally and opened in a browser. ([known bug](https://github.com/lapo-luchini/asn1js/issues/89): dark mode is currently broken in this mode)
71
72
Usage from CLI
73
--------------------
···
81
ISC license
82
-----------
83
84
-
ASN.1 JavaScript decoder Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>
85
86
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.
87
···
101
links
102
-----
103
104
-
- [official website](https://lapo.it/asn1js/)
105
-
- [dedicated domain](https://asn1js.eu/)
106
-
- [InDefero tracker](http://idf.lapo.it/p/asn1js/)
107
- [GitHub mirror](https://github.com/lapo-luchini/asn1js)
108
- [Ohloh code stats](https://www.openhub.net/p/asn1js)
···
3
4
asn1js is a JavaScript generic ASN.1 parser/decoder that can decode any valid ASN.1 DER or BER structures.
5
6
+
An example page that can decode Base64-encoded (raw base64, PEM armoring and `begin-base64` are recognized) or Hex-encoded (or local files with some browsers) is included and can be used both [online on the official website](https://asn1js.eu/) or [offline (ZIP file)](https://lapo.it/asn1js/asn1js.zip) by opening `index-local.html`.
7
8
Usage with `nodejs`
9
-------------------
···
67
Local usage
68
--------------------
69
70
+
Since unfortunately ESM modules are not working on `file:` protocol due to [CORS issues](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#other_differences_between_modules_and_standard_scripts), there is a bundled [single-file version working locally](https://asn1js.eu/index-local.html). It doesn't work online (due to [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) restrictions about inline content) but can be saved locally and opened in a browser.
71
72
Usage from CLI
73
--------------------
···
81
ISC license
82
-----------
83
84
+
ASN.1 JavaScript decoder Copyright (c) 2008-2025 Lapo Luchini <lapo@lapo.it>
85
86
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.
87
···
101
links
102
-----
103
104
+
- [official website](https://asn1js.eu/)
105
+
- [alternate website](https://lapo.it/asn1js/)
106
+
- [single-file version working locally](https://asn1js.eu/index-local.html) (just save this link)
107
+
- [InDefero tracker](http://idf.lapo.it/p/asn1js/) (currently offline)
108
- [GitHub mirror](https://github.com/lapo-luchini/asn1js)
109
+
- [ChangeLog on GitHub](https://github.com/lapo-luchini/asn1js/blob/trunk/CHANGELOG.md)
110
- [Ohloh code stats](https://www.openhub.net/p/asn1js)
+306
-74
asn1.js
+306
-74
asn1.js
···
1
// ASN.1 JavaScript decoder
2
-
// Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>
3
4
// Permission to use, copy, modify, and/or distribute this software for any
5
// purpose with or without fee is hereby granted, provided that the above
···
13
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16
-
import { Int10 } from './int10.js';
17
import { oids } from './oids.js';
18
19
const
···
21
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)?)?$/,
22
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)?)?$/,
23
hexDigits = '0123456789ABCDEF',
24
-
b64Safe = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
25
tableT61 = [
26
['', ''],
27
['AEIOUaeiou', 'รรรรรร รจรฌรฒรน'], // Grave
···
41
['CDELNRSTZcdelnrstz', 'ฤฤฤฤฝลลล ลคลฝฤฤฤฤพลลลกลฅลพ'], // Caron
42
];
43
44
function stringCut(str, len) {
45
if (str.length > len)
46
str = str.substring(0, len) + ellipsis;
47
return str;
48
}
49
50
function checkPrintable(s) {
51
let i, v;
52
for (i = 0; i < s.length; ++i) {
···
56
}
57
}
58
59
-
class Stream {
60
61
constructor(enc, pos) {
62
if (enc instanceof Stream) {
63
this.enc = enc.enc;
64
this.pos = enc.pos;
65
} else {
66
-
// enc should be an array or a binary string
67
this.enc = enc;
68
this.pos = pos;
69
}
70
}
71
get(pos) {
72
if (pos === undefined)
73
pos = this.pos++;
74
if (pos >= this.enc.length)
75
throw new Error('Requesting byte offset ' + pos + ' on a stream of length ' + this.enc.length);
76
-
return (typeof this.enc == 'string') ? this.enc.charCodeAt(pos) : this.enc[pos];
77
}
78
-
hexByte(b) {
79
return hexDigits.charAt((b >> 4) & 0xF) + hexDigits.charAt(b & 0xF);
80
}
81
-
/** Hexadecimal dump.
82
-
* @param type 'raw', 'byte' or 'dump' */
83
hexDump(start, end, type = 'dump') {
84
let s = '';
85
for (let i = start; i < end; ++i) {
86
if (type == 'byte' && i > start)
87
s += ' ';
88
-
s += this.hexByte(this.get(i));
89
if (type == 'dump')
90
switch (i & 0xF) {
91
case 0x7: s += ' '; break;
···
95
}
96
return s;
97
}
98
-
b64Dump(start, end) {
99
-
let extra = (end - start) % 3,
100
-
s = '',
101
i, c;
102
for (i = start; i + 2 < end; i += 3) {
103
c = this.get(i) << 16 | this.get(i + 1) << 8 | this.get(i + 2);
104
-
s += b64Safe.charAt(c >> 18 & 0x3F);
105
-
s += b64Safe.charAt(c >> 12 & 0x3F);
106
-
s += b64Safe.charAt(c >> 6 & 0x3F);
107
-
s += b64Safe.charAt(c & 0x3F);
108
}
109
if (extra > 0) {
110
c = this.get(i) << 16;
111
if (extra > 1) c |= this.get(i + 1) << 8;
112
-
s += b64Safe.charAt(c >> 18 & 0x3F);
113
-
s += b64Safe.charAt(c >> 12 & 0x3F);
114
-
if (extra == 2) s += b64Safe.charAt(c >> 6 & 0x3F);
115
}
116
return s;
117
}
118
isASCII(start, end) {
119
for (let i = start; i < end; ++i) {
120
let c = this.get(i);
···
123
}
124
return true;
125
}
126
parseStringISO(start, end, maxLength) {
127
let s = '';
128
for (let i = start; i < end; ++i)
129
s += String.fromCharCode(this.get(i));
130
return { size: s.length, str: stringCut(s, maxLength) };
131
}
132
parseStringT61(start, end, maxLength) {
133
// warning: this code is not very well tested so far
134
function merge(c, d) {
135
-
let t = tableT61[c - 0xC0];
136
-
let i = t[0].indexOf(String.fromCharCode(d));
137
return (i < 0) ? '\0' : t[1].charAt(i);
138
}
139
let s = '', c;
···
150
}
151
return { size: s.length, str: stringCut(s, maxLength) };
152
}
153
parseStringUTF(start, end, maxLength) {
154
function ex(c) { // must be 10xxxxxx
155
if ((c < 0x80) || (c >= 0xC0))
156
throw new Error('Invalid UTF-8 continuation byte: ' + c);
157
return (c & 0x3F);
158
}
159
function surrogate(cp) {
160
if (cp < 0x10000)
161
throw new Error('UTF-8 overlong encoding, codepoint encoded in 4 bytes: ' + cp);
···
165
}
166
let s = '';
167
for (let i = start; i < end; ) {
168
-
let c = this.get(i++);
169
if (c < 0x80) // 0xxxxxxx (7 bit)
170
s += String.fromCharCode(c);
171
else if (c < 0xC0)
···
181
}
182
return { size: s.length, str: stringCut(s, maxLength) };
183
}
184
parseStringBMP(start, end, maxLength) {
185
let s = '', hi, lo;
186
for (let i = start; i < end; ) {
···
190
}
191
return { size: s.length, str: stringCut(s, maxLength) };
192
}
193
parseTime(start, end, shortYear) {
194
let s = this.parseStringISO(start, end).str,
195
m = (shortYear ? reTimeS : reTimeL).exec(s);
···
217
}
218
return s;
219
}
220
parseInteger(start, end) {
221
let v = this.get(start),
222
-
neg = (v > 127),
223
-
pad = neg ? 255 : 0,
224
-
len,
225
s = '';
226
// skip unuseful bits (not allowed in DER)
227
while (v == pad && ++start < end)
228
v = this.get(start);
229
-
len = end - start;
230
if (len === 0)
231
return neg ? '-1' : '0';
232
// show bit length of huge integers
233
if (len > 4) {
234
-
s = v;
235
-
len <<= 3;
236
-
while (((s ^ pad) & 0x80) == 0) {
237
-
s <<= 1;
238
-
--len;
239
}
240
-
s = '(' + len + ' bit)\n';
241
}
242
// decode the integer
243
if (neg) v = v - 256;
244
-
let n = new Int10(v);
245
for (let i = start + 1; i < end; ++i)
246
-
n.mulAdd(256, this.get(i));
247
-
return s + n.toString();
248
}
249
parseBitString(start, end, maxLength) {
250
-
let unusedBits = this.get(start);
251
if (unusedBits > 7)
252
throw new Error('Invalid BitString with unusedBits=' + unusedBits);
253
-
let lenBit = ((end - start - 1) << 3) - unusedBits,
254
-
s = '';
255
for (let i = start + 1; i < end; ++i) {
256
let b = this.get(i),
257
skip = (i == end - 1) ? unusedBits : 0;
···
262
}
263
return { size: lenBit, str: s };
264
}
265
parseOctetString(start, end, maxLength) {
266
-
let len = end - start,
267
-
s;
268
try {
269
-
s = this.parseStringUTF(start, end, maxLength);
270
checkPrintable(s.str);
271
return { size: end - start, str: s.str };
272
-
} catch (e) {
273
-
// ignore
274
}
275
maxLength /= 2; // we work in bytes
276
if (len > maxLength)
277
end = start + maxLength;
278
-
s = '';
279
for (let i = start; i < end; ++i)
280
-
s += this.hexByte(this.get(i));
281
if (len > maxLength)
282
s += ellipsis;
283
return { size: len, str: s };
284
}
285
parseOID(start, end, maxLength, isRelative) {
286
let s = '',
287
-
n = new Int10(),
288
bits = 0;
289
for (let i = start; i < end; ++i) {
290
let v = this.get(i);
291
-
n.mulAdd(128, v & 0x7F);
292
bits += 7;
293
if (!(v & 0x80)) { // finished
294
if (s === '') {
295
-
n = n.simplify();
296
if (isRelative) {
297
-
s = (n instanceof Int10) ? n.toString() : '' + n;
298
-
} else if (n instanceof Int10) {
299
-
n.sub(80);
300
-
s = '2.' + n.toString();
301
} else {
302
-
let m = n < 80 ? n < 40 ? 0 : 1 : 2;
303
-
s = m + '.' + (n - m * 40);
304
}
305
} else
306
-
s += '.' + n.toString();
307
if (s.length > maxLength)
308
return stringCut(s, maxLength);
309
-
n = new Int10();
310
bits = 0;
311
}
312
}
313
if (bits > 0)
314
s += '.incomplete';
315
if (typeof oids === 'object' && !isRelative) {
316
let oid = oids[s];
317
if (oid) {
···
322
}
323
return s;
324
}
325
parseRelativeOID(start, end, maxLength) {
326
return this.parseOID(start, end, maxLength, true);
327
}
···
354
this.tagConstructed = ((buf & 0x20) !== 0);
355
this.tagNumber = buf & 0x1F;
356
if (this.tagNumber == 0x1F) { // long tag
357
-
let n = new Int10();
358
do {
359
buf = stream.get();
360
-
n.mulAdd(128, buf & 0x7F);
361
} while (buf & 0x80);
362
-
this.tagNumber = n.simplify();
363
}
364
}
365
isUniversal() {
···
370
}
371
}
372
373
export class ASN1 {
374
constructor(stream, header, length, tag, tagLen, sub) {
375
if (!(tag instanceof ASN1Tag)) throw new Error('Invalid tag value.');
376
this.stream = stream;
···
380
this.tagLen = tagLen;
381
this.sub = sub;
382
}
383
typeName() {
384
switch (this.tag.tagClass) {
385
case 0: // universal
···
419
case 3: return 'Private_' + this.tag.tagNumber.toString();
420
}
421
}
422
-
/** A string preview of the content (intended for humans). */
423
content(maxLength) {
424
if (this.tag === undefined)
425
return null;
426
if (maxLength === undefined)
427
maxLength = Infinity;
428
-
let content = this.posContent(),
429
len = Math.abs(this.length);
430
if (!this.tag.isUniversal()) {
431
if (this.sub !== null)
···
435
}
436
switch (this.tag.tagNumber) {
437
case 0x01: // BOOLEAN
438
return (this.stream.get(content) === 0) ? 'false' : 'true';
439
case 0x02: // INTEGER
440
return this.stream.parseInteger(content, content + len);
441
case 0x03: { // BIT_STRING
442
let d = recurse(this, 'parseBitString', maxLength);
···
448
}
449
//case 0x05: // NULL
450
case 0x06: // OBJECT_IDENTIFIER
451
return this.stream.parseOID(content, content + len, maxLength);
452
//case 0x07: // ObjectDescriptor
453
//case 0x08: // EXTERNAL
···
484
}
485
return null;
486
}
487
toString() {
488
return this.typeName() + '@' + this.stream.pos + '[header:' + this.header + ',length:' + this.length + ',sub:' + ((this.sub === null) ? 'null' : this.sub.length) + ']';
489
}
490
toPrettyString(indent) {
491
if (indent === undefined) indent = '';
492
let s = indent;
···
517
}
518
return s;
519
}
520
posStart() {
521
return this.stream.pos;
522
}
523
posContent() {
524
return this.stream.pos + this.header;
525
}
526
posEnd() {
527
return this.stream.pos + this.header + Math.abs(this.length);
528
}
529
-
/** Position of the length. */
530
posLen() {
531
return this.stream.pos + this.tagLen;
532
}
533
-
/** Hexadecimal dump of the node.
534
-
* @param type 'raw', 'byte' or 'dump' */
535
toHexString(type = 'raw') {
536
return this.stream.hexDump(this.posStart(), this.posEnd(), type);
537
}
538
-
/** Base64 dump of the node. */
539
-
toB64String() {
540
-
return this.stream.b64Dump(this.posStart(), this.posEnd());
541
}
542
static decodeLength(stream) {
543
-
let buf = stream.get(),
544
len = buf & 0x7F;
545
if (len == buf) // first bit was 0, short form
546
return len;
547
if (len === 0) // long form with length 0 is a special case
548
return null; // undefined length
549
-
if (len > 6) // no reason to use Int10, as it would be a huge buffer anyways
550
throw new Error('Length over 48 bits not supported at position ' + (stream.pos - 1));
551
-
buf = 0;
552
for (let i = 0; i < len; ++i)
553
-
buf = (buf * 256) + stream.get();
554
-
return buf;
555
}
556
static decode(stream, offset, type = ASN1) {
557
if (!(type == ASN1 || type.prototype instanceof ASN1))
558
throw new Error('Must pass a class that extends ASN1');
···
610
throw new Error('Unable to parse content: ' + e);
611
}
612
}
613
-
} catch (e) {
614
// but silently ignore when they don't
615
sub = null;
616
//DEBUG console.log('Could not decode structure at ' + start + ':', e);
···
1
// ASN.1 JavaScript decoder
2
+
// Copyright (c) 2008 Lapo Luchini <lapo@lapo.it>
3
4
// Permission to use, copy, modify, and/or distribute this software for any
5
// purpose with or without fee is hereby granted, provided that the above
···
13
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16
import { oids } from './oids.js';
17
18
const
···
20
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)?)?$/,
21
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)?)?$/,
22
hexDigits = '0123456789ABCDEF',
23
+
b64Std = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
24
+
b64URL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
25
tableT61 = [
26
['', ''],
27
['AEIOUaeiou', 'รรรรรร รจรฌรฒรน'], // Grave
···
41
['CDELNRSTZcdelnrstz', 'ฤฤฤฤฝลลล ลคลฝฤฤฤฤพลลลกลฅลพ'], // Caron
42
];
43
44
+
/**
45
+
* Truncates a string to a specified length and adds an ellipsis if needed.
46
+
* @param {string} str - The input string to truncate
47
+
* @param {number} len - The maximum length of the string
48
+
* @returns {string} The truncated string
49
+
*/
50
function stringCut(str, len) {
51
if (str.length > len)
52
str = str.substring(0, len) + ellipsis;
53
return str;
54
}
55
56
+
/**
57
+
* Checks if a string contains only printable characters (ASCII 32-126, plus tab, newline, carriage return)
58
+
* @param {string} s - The string to check
59
+
* @throws {Error} If an unprintable character is found
60
+
*/
61
function checkPrintable(s) {
62
let i, v;
63
for (i = 0; i < s.length; ++i) {
···
67
}
68
}
69
70
+
/**
71
+
* Class to manage a stream of bytes, with a zero-copy approach.
72
+
* It uses an existing array or binary string and advances a position index.
73
+
*/
74
+
export class Stream {
75
76
+
/**
77
+
* Creates a new Stream object.
78
+
* @param {Stream|array|string} enc data (will not be copied)
79
+
* @param {?number} pos starting position (mandatory when `end` is not a Stream)
80
+
*/
81
constructor(enc, pos) {
82
if (enc instanceof Stream) {
83
this.enc = enc.enc;
84
this.pos = enc.pos;
85
} else {
86
this.enc = enc;
87
this.pos = pos;
88
}
89
+
if (typeof this.pos != 'number')
90
+
throw new Error('"pos" must be a numeric value');
91
+
// Set up the raw byte access function based on the type of data
92
+
if (typeof this.enc == 'string')
93
+
this.getRaw = pos => this.enc.charCodeAt(pos);
94
+
else if (typeof this.enc[0] == 'number')
95
+
this.getRaw = pos => this.enc[pos];
96
+
else
97
+
throw new Error('"enc" must be a numeric array or a string');
98
}
99
+
100
+
/**
101
+
* Get the byte at current position (and increment it) or at a specified position (and avoid moving current position).
102
+
* @param {?number} pos read position if specified, else current position (and increment it)
103
+
* @returns {number} The byte value at the specified position
104
+
*/
105
get(pos) {
106
if (pos === undefined)
107
pos = this.pos++;
108
if (pos >= this.enc.length)
109
throw new Error('Requesting byte offset ' + pos + ' on a stream of length ' + this.enc.length);
110
+
return this.getRaw(pos);
111
}
112
+
113
+
/**
114
+
* Convert a single byte to a hexadecimal string (of length 2).
115
+
* @param {number} b - The byte to convert
116
+
* @returns {string} Hexadecimal representation of the byte
117
+
*/
118
+
static hexByte(b) {
119
return hexDigits.charAt((b >> 4) & 0xF) + hexDigits.charAt(b & 0xF);
120
}
121
+
122
+
/**
123
+
* Hexadecimal dump of a specified region of the stream.
124
+
* @param {number} start - starting position (included)
125
+
* @param {number} end - ending position (excluded)
126
+
* @param {string} type - 'raw', 'byte' or 'dump' (default)
127
+
* @returns {string} Hexadecimal representation of the data
128
+
*/
129
hexDump(start, end, type = 'dump') {
130
let s = '';
131
for (let i = start; i < end; ++i) {
132
if (type == 'byte' && i > start)
133
s += ' ';
134
+
s += Stream.hexByte(this.get(i));
135
if (type == 'dump')
136
switch (i & 0xF) {
137
case 0x7: s += ' '; break;
···
141
}
142
return s;
143
}
144
+
145
+
/**
146
+
* Base64url dump of a specified region of the stream (according to RFC 4648 section 5).
147
+
* @param {number} start - starting position (included)
148
+
* @param {number} end - ending position (excluded)
149
+
* @param {string} type - 'url' (default, section 5 without padding) or 'std' (section 4 with padding)
150
+
* @returns {string} Base64 encoded representation of the data
151
+
*/
152
+
b64Dump(start, end, type = 'url') {
153
+
const b64 = type === 'url' ? b64URL : b64Std,
154
+
extra = (end - start) % 3;
155
+
let s = '',
156
i, c;
157
for (i = start; i + 2 < end; i += 3) {
158
c = this.get(i) << 16 | this.get(i + 1) << 8 | this.get(i + 2);
159
+
s += b64.charAt(c >> 18 & 0x3F);
160
+
s += b64.charAt(c >> 12 & 0x3F);
161
+
s += b64.charAt(c >> 6 & 0x3F);
162
+
s += b64.charAt(c & 0x3F);
163
}
164
if (extra > 0) {
165
c = this.get(i) << 16;
166
if (extra > 1) c |= this.get(i + 1) << 8;
167
+
s += b64.charAt(c >> 18 & 0x3F);
168
+
s += b64.charAt(c >> 12 & 0x3F);
169
+
if (extra == 2) s += b64.charAt(c >> 6 & 0x3F);
170
+
if (b64 === b64Std) s += '==='.slice(0, 3 - extra);
171
}
172
return s;
173
}
174
+
175
+
/**
176
+
* Check if a region of the stream contains only ASCII characters (32-176)
177
+
* @param {number} start - starting position (included)
178
+
* @param {number} end - ending position (excluded)
179
+
* @returns {boolean} True if all characters are ASCII, false otherwise
180
+
*/
181
isASCII(start, end) {
182
for (let i = start; i < end; ++i) {
183
let c = this.get(i);
···
186
}
187
return true;
188
}
189
+
190
+
/**
191
+
* Parse a region of the stream as an ISO string
192
+
* @param {number} start - starting position (included)
193
+
* @param {number} end - ending position (excluded)
194
+
* @param {number} maxLength - maximum length of the output string
195
+
* @returns {Object} Object with size and str properties
196
+
*/
197
parseStringISO(start, end, maxLength) {
198
let s = '';
199
for (let i = start; i < end; ++i)
200
s += String.fromCharCode(this.get(i));
201
return { size: s.length, str: stringCut(s, maxLength) };
202
}
203
+
204
+
/**
205
+
* Parse a region of the stream as a T.61 string
206
+
* @param {number} start - starting position (included)
207
+
* @param {number} end - ending position (excluded)
208
+
* @param {number} maxLength - maximum length of the output string
209
+
* @returns {Object} Object with size and str properties
210
+
*/
211
parseStringT61(start, end, maxLength) {
212
// warning: this code is not very well tested so far
213
function merge(c, d) {
214
+
const t = tableT61[c - 0xC0];
215
+
const i = t[0].indexOf(String.fromCharCode(d));
216
return (i < 0) ? '\0' : t[1].charAt(i);
217
}
218
let s = '', c;
···
229
}
230
return { size: s.length, str: stringCut(s, maxLength) };
231
}
232
+
233
+
/**
234
+
* Parse a region of the stream as a UTF-8 string
235
+
* @param {number} start - starting position (included)
236
+
* @param {number} end - ending position (excluded)
237
+
* @param {number} maxLength - maximum length of the output string
238
+
* @returns {Object} Object with size and str properties
239
+
*/
240
parseStringUTF(start, end, maxLength) {
241
+
/**
242
+
* Helper function to process UTF-8 continuation bytes
243
+
* @param {number} c - The continuation byte
244
+
* @returns {number} The extracted data bits
245
+
*/
246
function ex(c) { // must be 10xxxxxx
247
if ((c < 0x80) || (c >= 0xC0))
248
throw new Error('Invalid UTF-8 continuation byte: ' + c);
249
return (c & 0x3F);
250
}
251
+
/**
252
+
* Helper function to convert a code point to a surrogate pair
253
+
* @param {number} cp - The code point to convert
254
+
* @returns {string} The surrogate pair as a string
255
+
*/
256
function surrogate(cp) {
257
if (cp < 0x10000)
258
throw new Error('UTF-8 overlong encoding, codepoint encoded in 4 bytes: ' + cp);
···
262
}
263
let s = '';
264
for (let i = start; i < end; ) {
265
+
const c = this.get(i++);
266
if (c < 0x80) // 0xxxxxxx (7 bit)
267
s += String.fromCharCode(c);
268
else if (c < 0xC0)
···
278
}
279
return { size: s.length, str: stringCut(s, maxLength) };
280
}
281
+
282
+
/**
283
+
* Parse a region of the stream as a BMP (Basic Multilingual Plane) string
284
+
* @param {number} start - starting position (included)
285
+
* @param {number} end - ending position (excluded)
286
+
* @param {number} maxLength - maximum length of the output string
287
+
* @returns {Object} Object with size and str properties
288
+
*/
289
parseStringBMP(start, end, maxLength) {
290
let s = '', hi, lo;
291
for (let i = start; i < end; ) {
···
295
}
296
return { size: s.length, str: stringCut(s, maxLength) };
297
}
298
+
299
+
/**
300
+
* Parse a region of the stream as a time string
301
+
* @param {number} start - starting position (included)
302
+
* @param {number} end - ending position (excluded)
303
+
* @param {boolean} shortYear - Whether to parse as short year (2-digit)
304
+
* @returns {string} Formatted time string
305
+
*/
306
parseTime(start, end, shortYear) {
307
let s = this.parseStringISO(start, end).str,
308
m = (shortYear ? reTimeS : reTimeL).exec(s);
···
330
}
331
return s;
332
}
333
+
334
+
/**
335
+
* Parse a region of the stream as an integer
336
+
* @param {number} start - starting position (included)
337
+
* @param {number} end - ending position (excluded)
338
+
* @returns {string} Formatted integer string
339
+
*/
340
parseInteger(start, end) {
341
let v = this.get(start),
342
s = '';
343
+
const neg = (v > 127),
344
+
pad = neg ? 255 : 0;
345
// skip unuseful bits (not allowed in DER)
346
while (v == pad && ++start < end)
347
v = this.get(start);
348
+
const len = end - start;
349
if (len === 0)
350
return neg ? '-1' : '0';
351
// show bit length of huge integers
352
if (len > 4) {
353
+
let v2 = v,
354
+
lenBit = len << 3;
355
+
while (((v2 ^ pad) & 0x80) == 0) {
356
+
v2 <<= 1;
357
+
--lenBit;
358
}
359
+
s = '(' + lenBit + ' bit)\n';
360
}
361
// decode the integer
362
if (neg) v = v - 256;
363
+
let n = BigInt(v);
364
for (let i = start + 1; i < end; ++i)
365
+
n = (n << 8n) | BigInt(this.get(i));
366
+
return s + n;
367
}
368
+
369
+
/**
370
+
* Parse a region of the stream as a bit string.
371
+
* @param {number} start - starting position (included)
372
+
* @param {number} end - ending position (excluded)
373
+
* @param {number} maxLength - maximum length of the output string
374
+
* @returns {Object} Object with size and str properties
375
+
*/
376
parseBitString(start, end, maxLength) {
377
+
const unusedBits = this.get(start);
378
if (unusedBits > 7)
379
throw new Error('Invalid BitString with unusedBits=' + unusedBits);
380
+
const lenBit = ((end - start - 1) << 3) - unusedBits;
381
+
let s = '';
382
for (let i = start + 1; i < end; ++i) {
383
let b = this.get(i),
384
skip = (i == end - 1) ? unusedBits : 0;
···
389
}
390
return { size: lenBit, str: s };
391
}
392
+
393
+
/**
394
+
* Parse a region of the stream as an octet string.
395
+
* @param {number} start - starting position (included)
396
+
* @param {number} end - ending position (excluded)
397
+
* @param {number} maxLength - maximum length of the output string
398
+
* @returns {Object} Object with size and str properties
399
+
*/
400
parseOctetString(start, end, maxLength) {
401
try {
402
+
let s = this.parseStringUTF(start, end, maxLength);
403
checkPrintable(s.str);
404
return { size: end - start, str: s.str };
405
+
} catch (ignore) {
406
+
// If UTF-8 parsing fails, fall back to hexadecimal dump
407
}
408
+
const len = end - start;
409
maxLength /= 2; // we work in bytes
410
if (len > maxLength)
411
end = start + maxLength;
412
+
let s = '';
413
for (let i = start; i < end; ++i)
414
+
s += Stream.hexByte(this.get(i));
415
if (len > maxLength)
416
s += ellipsis;
417
return { size: len, str: s };
418
}
419
+
420
+
/**
421
+
* Parse a region of the stream as an OID (Object Identifier).
422
+
* @param {number} start - starting position (included)
423
+
* @param {number} end - ending position (excluded)
424
+
* @param {number} maxLength - maximum length of the output string
425
+
* @param {boolean} isRelative - Whether the OID is relative
426
+
* @returns {string} Formatted OID string
427
+
*/
428
parseOID(start, end, maxLength, isRelative) {
429
let s = '',
430
+
n = 0n,
431
bits = 0;
432
for (let i = start; i < end; ++i) {
433
let v = this.get(i);
434
+
// Shift bits and add the lower 7 bits of the byte
435
+
n = (n << 7n) | BigInt(v & 0x7F);
436
bits += 7;
437
+
// If the most significant bit is 0, this is the last byte of the OID component
438
if (!(v & 0x80)) { // finished
439
+
// If this is the first component, handle it specially
440
if (s === '') {
441
if (isRelative) {
442
+
s = n.toString();
443
} else {
444
+
let m = n < 80 ? n < 40 ? 0n : 1n : 2n;
445
+
s = m + '.' + (n - m * 40n);
446
}
447
} else
448
+
s += '.' + n;
449
if (s.length > maxLength)
450
return stringCut(s, maxLength);
451
+
n = 0n;
452
bits = 0;
453
}
454
}
455
if (bits > 0)
456
s += '.incomplete';
457
+
// If OIDs mapping is available and the OID is absolute, try to resolve it
458
if (typeof oids === 'object' && !isRelative) {
459
let oid = oids[s];
460
if (oid) {
···
465
}
466
return s;
467
}
468
+
469
+
/**
470
+
* Parse a region of the stream as a relative OID (Object Identifier).
471
+
* @param {number} start - starting position (included)
472
+
* @param {number} end - ending position (excluded)
473
+
* @param {number} maxLength - maximum length of the output string
474
+
* @returns {string} Formatted relative OID string
475
+
*/
476
parseRelativeOID(start, end, maxLength) {
477
return this.parseOID(start, end, maxLength, true);
478
}
···
505
this.tagConstructed = ((buf & 0x20) !== 0);
506
this.tagNumber = buf & 0x1F;
507
if (this.tagNumber == 0x1F) { // long tag
508
+
let n = 0n;
509
do {
510
buf = stream.get();
511
+
n = (n << 7n) | BigInt(buf & 0x7F);
512
} while (buf & 0x80);
513
+
this.tagNumber = n <= Number.MAX_SAFE_INTEGER ? Number(n) : n;
514
}
515
}
516
isUniversal() {
···
521
}
522
}
523
524
+
/**
525
+
* ASN1 class for parsing ASN.1 encoded data.
526
+
* Instances of this class represent an ASN.1 element and provides methods to parse and display its content.
527
+
*/
528
export class ASN1 {
529
+
/**
530
+
* Creates an ASN1 parser object.
531
+
* @param {Stream} stream - The stream containing the ASN.1 data.
532
+
* @param {number} header - The header length.
533
+
* @param {number} length - The length of the data.
534
+
* @param {ASN1Tag} tag - The ASN.1 tag.
535
+
* @param {number} tagLen - The length of the tag.
536
+
* @param {Array} sub - The sub-elements.
537
+
*/
538
constructor(stream, header, length, tag, tagLen, sub) {
539
if (!(tag instanceof ASN1Tag)) throw new Error('Invalid tag value.');
540
this.stream = stream;
···
544
this.tagLen = tagLen;
545
this.sub = sub;
546
}
547
+
548
+
/**
549
+
* Get the type name of the ASN.1 element.
550
+
* @returns {string} The type name.
551
+
*/
552
typeName() {
553
switch (this.tag.tagClass) {
554
case 0: // universal
···
588
case 3: return 'Private_' + this.tag.tagNumber.toString();
589
}
590
}
591
+
592
+
/**
593
+
* Get a string preview of the content (intended for humans).
594
+
* @param {number} maxLength - The maximum length of the content.
595
+
* @returns {string|null} The content preview or null if not supported.
596
+
*/
597
content(maxLength) {
598
if (this.tag === undefined)
599
return null;
600
if (maxLength === undefined)
601
maxLength = Infinity;
602
+
const content = this.posContent(),
603
len = Math.abs(this.length);
604
if (!this.tag.isUniversal()) {
605
if (this.sub !== null)
···
609
}
610
switch (this.tag.tagNumber) {
611
case 0x01: // BOOLEAN
612
+
if (len != 1) return 'invalid length ' + len;
613
return (this.stream.get(content) === 0) ? 'false' : 'true';
614
case 0x02: // INTEGER
615
+
if (len < 1) return 'invalid length ' + len;
616
return this.stream.parseInteger(content, content + len);
617
case 0x03: { // BIT_STRING
618
let d = recurse(this, 'parseBitString', maxLength);
···
624
}
625
//case 0x05: // NULL
626
case 0x06: // OBJECT_IDENTIFIER
627
+
if (len < 1) return 'invalid length ' + len; // pgut001's dumpasn1.c enforces a minimum lenght of 3
628
return this.stream.parseOID(content, content + len, maxLength);
629
//case 0x07: // ObjectDescriptor
630
//case 0x08: // EXTERNAL
···
661
}
662
return null;
663
}
664
+
665
+
/**
666
+
* Get a string representation of the ASN.1 element.
667
+
* @returns {string} The string representation.
668
+
*/
669
toString() {
670
return this.typeName() + '@' + this.stream.pos + '[header:' + this.header + ',length:' + this.length + ',sub:' + ((this.sub === null) ? 'null' : this.sub.length) + ']';
671
}
672
+
673
+
/**
674
+
* Get a pretty string representation of the ASN.1 element.
675
+
* @param {string} indent - The indentation string.
676
+
* @returns {string} The pretty string representation.
677
+
*/
678
toPrettyString(indent) {
679
if (indent === undefined) indent = '';
680
let s = indent;
···
705
}
706
return s;
707
}
708
+
709
+
/**
710
+
* Get the starting position of the element in the stream.
711
+
* @returns {number} The starting position.
712
+
*/
713
posStart() {
714
return this.stream.pos;
715
}
716
+
717
+
/**
718
+
* Get the position of the content in the stream.
719
+
* @returns {number} The content position.
720
+
*/
721
posContent() {
722
return this.stream.pos + this.header;
723
}
724
+
725
+
/**
726
+
* Get the ending position of the element in the stream.
727
+
* @returns {number} The ending position.
728
+
*/
729
posEnd() {
730
return this.stream.pos + this.header + Math.abs(this.length);
731
}
732
+
733
+
/**
734
+
* Get the position of the length in the stream.
735
+
* @returns {number} The length position.
736
+
*/
737
posLen() {
738
return this.stream.pos + this.tagLen;
739
}
740
+
741
+
/**
742
+
* Get a hexadecimal dump of the node.
743
+
* @param {string} [type='raw'] - The dump type: 'raw', 'byte', or 'dump'.
744
+
* @returns {string} The hexadecimal dump.
745
+
*/
746
toHexString(type = 'raw') {
747
return this.stream.hexDump(this.posStart(), this.posEnd(), type);
748
}
749
+
750
+
/**
751
+
* Get a base64url dump of the node (according to RFC 4648 section 5).
752
+
* @param {string} [type='url'] - The dump type: 'url' (section 5 without padding) or 'std' (section 4 with padding).
753
+
* @returns {string} The base64 encoded representation.
754
+
*/
755
+
toB64String(type = 'url') {
756
+
return this.stream.b64Dump(this.posStart(), this.posEnd(), type);
757
}
758
+
759
+
/**
760
+
* Decode the length field of an ASN.1 element.
761
+
* @param {Stream} stream - The stream to read from.
762
+
* @returns {number|null} The decoded length, or null for indefinite length.
763
+
* @throws {Error} If the length is invalid or exceeds 48 bits.
764
+
*/
765
static decodeLength(stream) {
766
+
const buf = stream.get(),
767
len = buf & 0x7F;
768
if (len == buf) // first bit was 0, short form
769
return len;
770
if (len === 0) // long form with length 0 is a special case
771
return null; // undefined length
772
+
if (len > 6) // no reason to use BigInt, as it would be a huge buffer anyways
773
throw new Error('Length over 48 bits not supported at position ' + (stream.pos - 1));
774
+
let value = 0;
775
for (let i = 0; i < len; ++i)
776
+
value = (value << 8) | stream.get();
777
+
return value;
778
}
779
+
780
+
/**
781
+
* Decode an ASN.1 element from a stream.
782
+
* @param {Stream|array|string} stream - The input data.
783
+
* @param {number} [offset=0] - The offset to start decoding from.
784
+
* @param {Function} [type=ASN1] - The class to instantiate.
785
+
* @returns {ASN1} The decoded ASN.1 element.
786
+
* @throws {Error} If the decoding fails.
787
+
*/
788
static decode(stream, offset, type = ASN1) {
789
if (!(type == ASN1 || type.prototype instanceof ASN1))
790
throw new Error('Must pass a class that extends ASN1');
···
842
throw new Error('Unable to parse content: ' + e);
843
}
844
}
845
+
} catch (ignore) {
846
// but silently ignore when they don't
847
sub = null;
848
//DEBUG console.log('Could not decode structure at ' + start + ':', e);
+7
-6
base64.js
+7
-6
base64.js
···
1
// Base64 JavaScript decoder
2
-
// Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>
3
4
// Permission to use, copy, modify, and/or distribute this software for any
5
// purpose with or without fee is hereby granted, provided that the above
···
31
decoder[b64.charCodeAt(i)] = i;
32
for (i = 0; i < ignore.length; ++i)
33
decoder[ignore.charCodeAt(i)] = -1;
34
-
// RFC 3548 URL & file safe encoding
35
decoder['-'.charCodeAt(0)] = decoder['+'.charCodeAt(0)];
36
decoder['_'.charCodeAt(0)] = decoder['/'.charCodeAt(0)];
37
}
···
75
76
static pretty(str) {
77
// fix padding
78
-
if (str.length % 4 > 0)
79
-
str = (str + '===').slice(0, str.length + str.length % 4);
80
-
// convert RFC 3548 to standard Base64
81
str = str.replace(/-/g, '+').replace(/_/g, '/');
82
// 80 column width
83
-
return str.replace(/(.{80})/g, '$1\n');
84
}
85
86
static unarmor(a) {
···
1
// Base64 JavaScript decoder
2
+
// Copyright (c) 2008 Lapo Luchini <lapo@lapo.it>
3
4
// Permission to use, copy, modify, and/or distribute this software for any
5
// purpose with or without fee is hereby granted, provided that the above
···
31
decoder[b64.charCodeAt(i)] = i;
32
for (i = 0; i < ignore.length; ++i)
33
decoder[ignore.charCodeAt(i)] = -1;
34
+
// also support decoding Base64url (RFC 4648 section 5)
35
decoder['-'.charCodeAt(0)] = decoder['+'.charCodeAt(0)];
36
decoder['_'.charCodeAt(0)] = decoder['/'.charCodeAt(0)];
37
}
···
75
76
static pretty(str) {
77
// fix padding
78
+
let pad = 4 - str.length % 4;
79
+
if (pad < 4)
80
+
str += '==='.slice(0, pad);
81
+
// convert Base64url (RFC 4648 section 5) to standard Base64 (RFC 4648 section 4)
82
str = str.replace(/-/g, '+').replace(/_/g, '/');
83
// 80 column width
84
+
return str.replace(/.{80}/g, '$&\n');
85
}
86
87
static unarmor(a) {
+14
-8
defs.js
+14
-8
defs.js
···
1
// ASN.1 RFC definitions matcher
2
-
// Copyright (c) 2023-2024 Lapo Luchini <lapo@lapo.it>
3
4
// Permission to use, copy, modify, and/or distribute this software for any
5
// purpose with or without fee is hereby granted, provided that the above
···
23
try {
24
// hope current OIDs contain the type name (will need to parse from RFC itself)
25
def = Defs.searchType(firstUpper(stats.defs[def.definedBy][1]));
26
-
} catch (e) { /*ignore*/ }
27
while (def?.type == 'defined' || def?.type?.type == 'defined') {
28
const name = def?.type?.type ? def.type.name : def.name;
29
def = Object.assign({}, def);
30
def.type = Defs.searchType(name).type;
31
}
32
-
if (def?.type?.name == 'CHOICE') {
33
-
for (let c of def.type.content) {
34
if (tn != c.type.name && tn != c.name)
35
c = translate(c);
36
if (tn == c.type.name || tn == c.name) {
37
def = Object.assign({}, def);
38
def.type = c.type.name ? c.type : c;
39
break;
40
}
···
68
69
static match(value, def, stats = { total: 0, recognized: 0, defs: {} }) {
70
value.def = {};
71
-
let tn = value.typeName().replaceAll('_', ' ');
72
def = translate(def, tn, stats);
73
++stats.total;
74
if (def?.type) {
···
89
if (def.typeOf)
90
type = def.content[0];
91
else {
92
-
let tn = subval.typeName().replaceAll('_', ' ');
93
for (;;) {
94
type = def.content[j++];
95
if (!type || typeof type != 'object') break;
96
if (type?.type?.type)
97
-
type = type.type;
98
if (type.type == 'defined') {
99
let t2 = translate(type, tn);
100
if (t2.type.name == tn) break; // exact match
···
112
} else if (type?.definedBy && stats.defs?.[type.definedBy]?.[1]) { // hope current OIDs contain the type name (will need to parse from RFC itself)
113
try {
114
type = Defs.searchType(firstUpper(stats.defs[type.definedBy][1]));
115
-
} catch (e) { /*ignore*/ }
116
}
117
}
118
}
···
129
Defs.commonTypes = [
130
[ 'X.509 certificate', '1.3.6.1.5.5.7.0.18', 'Certificate' ],
131
[ 'X.509 public key info', '1.3.6.1.5.5.7.0.18', 'SubjectPublicKeyInfo' ],
132
[ 'CMS / PKCS#7 envelope', '1.2.840.113549.1.9.16.0.14', 'ContentInfo' ],
133
[ 'PKCS#1 RSA private key', '1.2.840.113549.1.1.0.1', 'RSAPrivateKey' ],
134
[ 'PKCS#8 encrypted private key', '1.2.840.113549.1.8.1.1', 'EncryptedPrivateKeyInfo' ],
135
[ 'PKCS#8 private key', '1.2.840.113549.1.8.1.1', 'PrivateKeyInfo' ],
136
[ 'PKCS#10 certification request', '1.2.840.113549.1.10.1.1', 'CertificationRequest' ],
137
[ 'CMP PKI Message', '1.3.6.1.5.5.7.0.16', 'PKIMessage' ],
138
].map(arr => ({ description: arr[0], ...Defs.moduleAndType(rfcdef[arr[1]], arr[2]) }));
···
1
// ASN.1 RFC definitions matcher
2
+
// Copyright (c) 2023 Lapo Luchini <lapo@lapo.it>
3
4
// Permission to use, copy, modify, and/or distribute this software for any
5
// purpose with or without fee is hereby granted, provided that the above
···
23
try {
24
// hope current OIDs contain the type name (will need to parse from RFC itself)
25
def = Defs.searchType(firstUpper(stats.defs[def.definedBy][1]));
26
+
} catch (ignore) { /*ignore*/ }
27
while (def?.type == 'defined' || def?.type?.type == 'defined') {
28
const name = def?.type?.type ? def.type.name : def.name;
29
def = Object.assign({}, def);
30
def.type = Defs.searchType(name).type;
31
}
32
+
if (def?.name == 'CHOICE' || def?.type?.name == 'CHOICE') {
33
+
for (let c of def.content ?? def.type.content) {
34
if (tn != c.type.name && tn != c.name)
35
c = translate(c);
36
if (tn == c.type.name || tn == c.name) {
37
def = Object.assign({}, def);
38
+
if (c.id) // show the CHOICE id, but add it to existing one if present
39
+
def.id = def.id ? def.id + ' ' + c.id : c.id;
40
def.type = c.type.name ? c.type : c;
41
break;
42
}
···
70
71
static match(value, def, stats = { total: 0, recognized: 0, defs: {} }) {
72
value.def = {};
73
+
let tn = value.typeName().replace(/_/g, ' ');
74
def = translate(def, tn, stats);
75
++stats.total;
76
if (def?.type) {
···
91
if (def.typeOf)
92
type = def.content[0];
93
else {
94
+
let tn = subval.typeName().replace(/_/g, ' ');
95
for (;;) {
96
type = def.content[j++];
97
if (!type || typeof type != 'object') break;
98
if (type?.type?.type)
99
+
// type = type.type;
100
+
type = Object.assign({}, type.type, {id: type.id});
101
if (type.type == 'defined') {
102
let t2 = translate(type, tn);
103
if (t2.type.name == tn) break; // exact match
···
115
} else if (type?.definedBy && stats.defs?.[type.definedBy]?.[1]) { // hope current OIDs contain the type name (will need to parse from RFC itself)
116
try {
117
type = Defs.searchType(firstUpper(stats.defs[type.definedBy][1]));
118
+
} catch (ignore) { /*ignore*/ }
119
}
120
}
121
}
···
132
Defs.commonTypes = [
133
[ 'X.509 certificate', '1.3.6.1.5.5.7.0.18', 'Certificate' ],
134
[ 'X.509 public key info', '1.3.6.1.5.5.7.0.18', 'SubjectPublicKeyInfo' ],
135
+
[ 'X.509 certificate revocation list', '1.3.6.1.5.5.7.0.18', 'CertificateList' ],
136
[ 'CMS / PKCS#7 envelope', '1.2.840.113549.1.9.16.0.14', 'ContentInfo' ],
137
[ 'PKCS#1 RSA private key', '1.2.840.113549.1.1.0.1', 'RSAPrivateKey' ],
138
[ 'PKCS#8 encrypted private key', '1.2.840.113549.1.8.1.1', 'EncryptedPrivateKeyInfo' ],
139
[ 'PKCS#8 private key', '1.2.840.113549.1.8.1.1', 'PrivateKeyInfo' ],
140
[ 'PKCS#10 certification request', '1.2.840.113549.1.10.1.1', 'CertificationRequest' ],
141
[ 'CMP PKI Message', '1.3.6.1.5.5.7.0.16', 'PKIMessage' ],
142
+
[ 'LDAP Message', '1.3.6.1.1.18', 'LDAPMessage' ],
143
+
[ 'Time Stamp Request', '1.3.6.1.5.5.7.0.13', 'TimeStampReq' ],
144
].map(arr => ({ description: arr[0], ...Defs.moduleAndType(rfcdef[arr[1]], arr[2]) }));
+1
-1
dom.js
+1
-1
dom.js
+5
-1
dumpASN1.js
+5
-1
dumpASN1.js
···
1
#!/usr/bin/env node
2
3
import * as fs from 'node:fs';
4
import { Base64 } from './base64.js';
5
import { ASN1 } from './asn1.js';
···
48
: fs.readFileSync(filename);
49
try { // try PEM first
50
content = Base64.unarmor(content);
51
-
} catch (e) { // try DER/BER then
52
}
53
let result = ASN1.decode(content);
54
content = null;
···
1
#!/usr/bin/env node
2
3
+
// usage:
4
+
// ./dumpASN1.js filename
5
+
// ./dumpASN1.js data:base64,MDMCAQFjLgQACgEACgEAAgEAAgEAAQEAoA+jDQQFTnRWZXIEBAEAAAAwCgQITmV0bG9nb24===
6
+
7
import * as fs from 'node:fs';
8
import { Base64 } from './base64.js';
9
import { ASN1 } from './asn1.js';
···
52
: fs.readFileSync(filename);
53
try { // try PEM first
54
content = Base64.unarmor(content);
55
+
} catch (ignore) { // try DER/BER then
56
}
57
let result = ASN1.decode(content);
58
content = null;
+63
eslint.config.js
+63
eslint.config.js
···
···
1
+
import globals from 'globals';
2
+
import js from '@eslint/js';
3
+
4
+
export default [
5
+
js.configs.recommended,
6
+
{
7
+
languageOptions: {
8
+
globals: {
9
+
...globals.browser,
10
+
...globals.node,
11
+
Uint8Array: 'readonly',
12
+
},
13
+
ecmaVersion: 2020,
14
+
},
15
+
rules: {
16
+
indent: ['error', 4],
17
+
'no-trailing-spaces': ['error'],
18
+
'linebreak-style': ['error', 'unix'],
19
+
'eol-last': ['error', 'always'],
20
+
semi: ['warn', 'always'],
21
+
quotes: [ 'error', 'single', {
22
+
avoidEscape: true,
23
+
}],
24
+
'no-var': ['warn'],
25
+
'comma-dangle': ['error', 'always-multiline'],
26
+
'no-unused-vars': ['error', {
27
+
caughtErrorsIgnorePattern: 'ignore',
28
+
}],
29
+
},
30
+
},
31
+
{
32
+
files: ['oids.js'],
33
+
rules: {
34
+
indent: 'off',
35
+
quotes: ['warn', 'double'],
36
+
},
37
+
},
38
+
{
39
+
files: ['tags.js', 'rfcdef.js'],
40
+
rules: {
41
+
indent: [
42
+
'error',
43
+
2,
44
+
{
45
+
ignoredNodes: [
46
+
"Program > ExpressionStatement > CallExpression > FunctionExpression > BlockStatement > ExpressionStatement[directive='use strict']:first-child",
47
+
],
48
+
},
49
+
],
50
+
'comma-dangle': 'off',
51
+
quotes: ['warn', 'double'],
52
+
},
53
+
},
54
+
{
55
+
files: ['test.js', 'parseRFC.js', 'dumpASN1.js', 'testDefs.js', 'eslint.config.js'],
56
+
languageOptions: {
57
+
ecmaVersion: 'latest',
58
+
},
59
+
rules: {
60
+
strict: ['error', 'global'],
61
+
},
62
+
},
63
+
];
+12
examples/crl-rfc5280.b64
+12
examples/crl-rfc5280.b64
···
···
1
+
CRL example from RFC5280 as found here:
2
+
https://csrc.nist.gov/projects/pki-testing/sample-certificates-and-crls
3
+
4
+
begin-base64 644 crl-rfc5280.der
5
+
MIIBYDCBygIBATANBgkqhkiG9w0BAQUFADBDMRMwEQYKCZImiZPyLGQBGRYDY29tMRcwFQYKCZIm
6
+
iZPyLGQBGRYHZXhhbXBsZTETMBEGA1UEAxMKRXhhbXBsZSBDQRcNMDUwMjA1MTIwMDAwWhcNMDUw
7
+
MjA2MTIwMDAwWjAiMCACARIXDTA0MTExOTE1NTcwM1owDDAKBgNVHRUEAwoBAaAvMC0wHwYDVR0j
8
+
BBgwFoAUCGivhTPIOUp6+IKTjnBqSiCELDIwCgYDVR0UBAMCAQwwDQYJKoZIhvcNAQEFBQADgYEA
9
+
ItwYffcIzsx10NBqm60Q9HYjtIFutW2+DvsVFGzIF20f7pAXom9g5L2qjFXejoRvkvifEBInr0rU
10
+
L4XiNkR9qqNMJTgV/wD9Pn7uPSYS69jnK2LiK8NGgO94gtEVxtCccmrLznrtZ5mLbnCBfUNCdMGm
11
+
r8FVF6IzTNYGmCuk/C4=
12
+
====
+45
examples/crl-rfc5280.b64.dump
+45
examples/crl-rfc5280.b64.dump
···
···
1
+
CertificateList SEQUENCE @0+352 (constructed): (3 elem)
2
+
tbsCertList TBSCertList SEQUENCE @4+202 (constructed): (7 elem)
3
+
version Version INTEGER @7+1: 1
4
+
signature AlgorithmIdentifier SEQUENCE @10+13 (constructed): (2 elem)
5
+
algorithm OBJECT_IDENTIFIER @12+9: 1.2.840.113549.1.1.5|sha1WithRSAEncryption|PKCS #1
6
+
parameters ANY NULL @23+0
7
+
issuer rdnSequence Name SEQUENCE @25+67 (constructed): (3 elem)
8
+
RelativeDistinguishedName SET @27+19 (constructed): (1 elem)
9
+
AttributeTypeAndValue SEQUENCE @29+17 (constructed): (2 elem)
10
+
type AttributeType OBJECT_IDENTIFIER @31+10: 0.9.2342.19200300.100.1.25|domainComponent|Men are from Mars, this OID is from Pluto
11
+
value AttributeValue [?] IA5String @43+3: com
12
+
RelativeDistinguishedName SET @48+23 (constructed): (1 elem)
13
+
AttributeTypeAndValue SEQUENCE @50+21 (constructed): (2 elem)
14
+
type AttributeType OBJECT_IDENTIFIER @52+10: 0.9.2342.19200300.100.1.25|domainComponent|Men are from Mars, this OID is from Pluto
15
+
value AttributeValue [?] IA5String @64+7: example
16
+
RelativeDistinguishedName SET @73+19 (constructed): (1 elem)
17
+
AttributeTypeAndValue SEQUENCE @75+17 (constructed): (2 elem)
18
+
type AttributeType OBJECT_IDENTIFIER @77+3: 2.5.4.3|commonName|X.520 DN component
19
+
value AttributeValue [?] PrintableString @82+10: Example CA
20
+
thisUpdate utcTime Time UTCTime @94+13: 2005-02-05 12:00:00 UTC
21
+
nextUpdate utcTime Time UTCTime @109+13: 2005-02-06 12:00:00 UTC
22
+
revokedCertificates SEQUENCE @124+34 (constructed): (1 elem)
23
+
SEQUENCE @126+32 (constructed): (3 elem)
24
+
userCertificate CertificateSerialNumber INTEGER @128+1: 18
25
+
revocationDate utcTime Time UTCTime @131+13: 2004-11-19 15:57:03 UTC
26
+
crlEntryExtensions Extensions SEQUENCE @146+12 (constructed): (1 elem)
27
+
Extension SEQUENCE @148+10 (constructed): (2 elem)
28
+
extnID OBJECT_IDENTIFIER @150+3: 2.5.29.21|cRLReason|X.509 extension
29
+
extnValue OCTET_STRING @155+3 (encapsulates): (3 byte)|0A0101
30
+
ENUMERATED @157+1: 1
31
+
crlExtensions [0] @160+47 (constructed): (1 elem)
32
+
Extensions SEQUENCE @162+45 (constructed): (2 elem)
33
+
Extension SEQUENCE @164+31 (constructed): (2 elem)
34
+
extnID OBJECT_IDENTIFIER @166+3: 2.5.29.35|authorityKeyIdentifier|X.509 extension
35
+
extnValue OCTET_STRING @171+24 (encapsulates): (24 byte)|301680140868AF8533C8394A7AF882938E706A4A20842C32
36
+
SEQUENCE @173+22 (constructed): (1 elem)
37
+
[0] @175+20: (20 byte)|0868AF8533C8394A7AF882938E706A4A20842C32
38
+
Extension SEQUENCE @197+10 (constructed): (2 elem)
39
+
extnID OBJECT_IDENTIFIER @199+3: 2.5.29.20|cRLNumber|X.509 extension
40
+
extnValue OCTET_STRING @204+3 (encapsulates): (3 byte)|02010C
41
+
INTEGER @206+1: 12
42
+
signatureAlgorithm AlgorithmIdentifier SEQUENCE @209+13 (constructed): (2 elem)
43
+
algorithm OBJECT_IDENTIFIER @211+9: 1.2.840.113549.1.1.5|sha1WithRSAEncryption|PKCS #1
44
+
parameters ANY NULL @222+0
45
+
signature BIT_STRING @224+129: (1024 bit)|0010001011011100000110000111110111110111000010001100111011001100011101011101000011010000011010101001101110101101000100001111010001110110001000111011010010000001011011101011010101101101101111100000111011111011000101010001010001101100110010000001011101101101000111111110111010010000000101111010001001101111011000001110010010111101101010101000110001010101110111101000111010000100011011111001001011111000100111110001000000010010001001111010111101001010110101000010111110000101111000100011011001000100011111011010101010100011010011000010010100111000000101011111111100000000111111010011111001111110111011100011110100100110000100101110101111011000111001110010101101100010111000100010101111000011010001101000000011101111011110001000001011010001000101011100011011010000100111000111001001101010110010111100111001111010111011010110011110011001100010110110111001110000100000010111110101000011010000100111010011000001101001101010111111000001010101010001011110100010001100110100110011010110000001101001100000101011101001001111110000101110
+60
examples/ed25519.cer.dump
+60
examples/ed25519.cer.dump
···
···
1
+
Certificate SEQUENCE @0+383 (constructed): (3 elem)
2
+
tbsCertificate TBSCertificate SEQUENCE @4+305 (constructed): (8 elem)
3
+
version [0] @8+3 (constructed): (1 elem)
4
+
Version INTEGER @10+1: 2
5
+
serialNumber CertificateSerialNumber INTEGER @13+20: (159 bit)|711090297755414526861352146244170174161660335942
6
+
signature AlgorithmIdentifier SEQUENCE @35+5 (constructed): (1 elem)
7
+
algorithm OBJECT_IDENTIFIER @37+3: 1.3.101.112|curveEd25519|EdDSA 25519 signature algorithm
8
+
issuer rdnSequence Name SEQUENCE @42+53 (constructed): (3 elem)
9
+
RelativeDistinguishedName SET @44+11 (constructed): (1 elem)
10
+
AttributeTypeAndValue SEQUENCE @46+9 (constructed): (2 elem)
11
+
type AttributeType OBJECT_IDENTIFIER @48+3: 2.5.4.6|countryName|X.520 DN component
12
+
value AttributeValue [?] PrintableString @53+2: IT
13
+
RelativeDistinguishedName SET @57+15 (constructed): (1 elem)
14
+
AttributeTypeAndValue SEQUENCE @59+13 (constructed): (2 elem)
15
+
type AttributeType OBJECT_IDENTIFIER @61+3: 2.5.4.7|localityName|X.520 DN component
16
+
value AttributeValue [?] UTF8String @66+6: Milano
17
+
RelativeDistinguishedName SET @74+21 (constructed): (1 elem)
18
+
AttributeTypeAndValue SEQUENCE @76+19 (constructed): (2 elem)
19
+
type AttributeType OBJECT_IDENTIFIER @78+3: 2.5.4.3|commonName|X.520 DN component
20
+
value AttributeValue [?] UTF8String @83+12: Test ed25519
21
+
validity Validity SEQUENCE @97+30 (constructed): (2 elem)
22
+
notBefore utcTime Time UTCTime @99+13: 2020-09-02 13:25:26 UTC
23
+
notAfter utcTime Time UTCTime @114+13: 2030-09-02 13:25:26 UTC
24
+
subject rdnSequence Name SEQUENCE @129+53 (constructed): (3 elem)
25
+
RelativeDistinguishedName SET @131+11 (constructed): (1 elem)
26
+
AttributeTypeAndValue SEQUENCE @133+9 (constructed): (2 elem)
27
+
type AttributeType OBJECT_IDENTIFIER @135+3: 2.5.4.6|countryName|X.520 DN component
28
+
value AttributeValue [?] PrintableString @140+2: IT
29
+
RelativeDistinguishedName SET @144+15 (constructed): (1 elem)
30
+
AttributeTypeAndValue SEQUENCE @146+13 (constructed): (2 elem)
31
+
type AttributeType OBJECT_IDENTIFIER @148+3: 2.5.4.7|localityName|X.520 DN component
32
+
value AttributeValue [?] UTF8String @153+6: Milano
33
+
RelativeDistinguishedName SET @161+21 (constructed): (1 elem)
34
+
AttributeTypeAndValue SEQUENCE @163+19 (constructed): (2 elem)
35
+
type AttributeType OBJECT_IDENTIFIER @165+3: 2.5.4.3|commonName|X.520 DN component
36
+
value AttributeValue [?] UTF8String @170+12: Test ed25519
37
+
subjectPublicKeyInfo SubjectPublicKeyInfo SEQUENCE @184+42 (constructed): (2 elem)
38
+
algorithm AlgorithmIdentifier SEQUENCE @186+5 (constructed): (1 elem)
39
+
algorithm OBJECT_IDENTIFIER @188+3: 1.3.101.112|curveEd25519|EdDSA 25519 signature algorithm
40
+
subjectPublicKey BIT_STRING @193+33: (256 bit)|0011101110101001001011111111110111001011000101110110011011011110010000001010001010010010111101111001001111011110001100001111100000001010001000111010100000110001001000010101110111010000000001111101100001100011001001000010111011111111011010000010000110000101
41
+
extensions [3] @228+83 (constructed): (1 elem)
42
+
Extensions SEQUENCE @230+81 (constructed): (3 elem)
43
+
Extension SEQUENCE @232+29 (constructed): (2 elem)
44
+
extnID OBJECT_IDENTIFIER @234+3: 2.5.29.14|subjectKeyIdentifier|X.509 extension
45
+
extnValue OCTET_STRING @239+22 (encapsulates): (22 byte)|04146BA5BDCF9DFA235978126417AE1E72D89A804AE8
46
+
OCTET_STRING @241+20: (20 byte)|6BA5BDCF9DFA235978126417AE1E72D89A804AE8
47
+
Extension SEQUENCE @263+31 (constructed): (2 elem)
48
+
extnID OBJECT_IDENTIFIER @265+3: 2.5.29.35|authorityKeyIdentifier|X.509 extension
49
+
extnValue OCTET_STRING @270+24 (encapsulates): (24 byte)|301680146BA5BDCF9DFA235978126417AE1E72D89A804AE8
50
+
SEQUENCE @272+22 (constructed): (1 elem)
51
+
[0] @274+20: (20 byte)|6BA5BDCF9DFA235978126417AE1E72D89A804AE8
52
+
Extension SEQUENCE @296+15 (constructed): (3 elem)
53
+
extnID OBJECT_IDENTIFIER @298+3: 2.5.29.19|basicConstraints|X.509 extension
54
+
critical BOOLEAN @303+1: true
55
+
extnValue OCTET_STRING @306+5 (encapsulates): (5 byte)|30030101FF
56
+
SEQUENCE @308+3 (constructed): (1 elem)
57
+
BOOLEAN @310+1: true
58
+
signatureAlgorithm AlgorithmIdentifier SEQUENCE @313+5 (constructed): (1 elem)
59
+
algorithm OBJECT_IDENTIFIER @315+3: 1.3.101.112|curveEd25519|EdDSA 25519 signature algorithm
60
+
signature BIT_STRING @320+65: (512 bit)|01101111011100110111011110111110001010001001011001011010001100110011011011010111111001010011010011111101100100001111001111111101010000000111111100011111000000101111100100000000010101111111001000010110000011110001011001101011000001001011111101100101100001001011011010011000110100101101000011010010101111110100110011010110011011110000111010110110111000101110100010011101000001001010001111100000100110010101000011111001110000100110110111011110011100111010110100011101001101010101011110000101011001011000011000000110
+8
examples/ldapmessage.b64
+8
examples/ldapmessage.b64
+7
examples/ldapmessage.b64.dump
+7
examples/ldapmessage.b64.dump
···
···
1
+
LDAPMessage SEQUENCE @0+53 (constructed): (3 elem)
2
+
messageID MessageID INTEGER @2+1: 5
3
+
protocolOp delRequest CHOICE Application_10 @5+17: (17 byte)|dc=example,dc=com
4
+
Controls [?] [0] @24+29 (constructed): (1 elem)
5
+
AttributeTypeAndValue SEQUENCE @26+27 (constructed): (2 elem)
6
+
type AttributeType [?] OCTET_STRING @28+22: (22 byte)|1.2.840.113556.1.4.805
7
+
value AttributeValue [?] BOOLEAN @52+1: true
+10
examples/pkcs1.pem.dump
+10
examples/pkcs1.pem.dump
···
···
1
+
RSAPrivateKey SEQUENCE @0+605 (constructed): (9 elem)
2
+
version Version INTEGER @4+1: 0
3
+
modulus INTEGER @7+129: (1024 bit)|117127183230921204401013393277767517103803021018182691416238029726599496957198017684901559383009459523071384847726671610377559004781710040051270748910270447756432733966622455162759462672603884318432883204215291756888413811504344870556870978773843838353155520698675084344179957236491745093327422201227604749459
4
+
publicExponent INTEGER @139+3: 65537
5
+
privateExponent INTEGER @144+129: (1024 bit)|92276282475226568589241550905865273709561889943250510752753436239739158443231274686159532997597455087892667385718350070754140814118578097684166368734227728473322161416664690885212698653195373932779792506838124961141214987311742627151011567342689730655630521241854903774681567286735997541758916977964830429313
6
+
prime1 INTEGER @276+65: (512 bit)|10896821561662485361386011233938116142526936125648167362054539174681694465821232677159478832161550957167298418313068706031799276527005193877616679381489381
7
+
prime2 INTEGER @343+65: (512 bit)|10748747473575365133625210720374663113238804836624829882840358384492696273600075746246298849279878235356215808273663889910189484797595139778277124898735639
8
+
exponent1 INTEGER @410+64: (511 bit)|6091625365131581796315047890165719534213640521161662994088715561328917102465668272778610952193459304175325574129665657306361751287362700277617869028176853
9
+
exponent2 INTEGER @476+65: (512 bit)|9619864112105977791898517014707043200694399482542575521432448550956476604540013165392532656448448632323473488540572223305800601817570919153380021725291669
10
+
coefficient INTEGER @543+64: (511 bit)|4162468593383244686217782691133418477400302049612992866028022118893358867845916127581019785866484075341057799618361552573853678007698434146811407259880551
+16
examples/pkcs8-rsa.pem.dump
+16
examples/pkcs8-rsa.pem.dump
···
···
1
+
PrivateKeyInfo SEQUENCE @0+631 (constructed): (3 elem)
2
+
version Version INTEGER @4+1: 0
3
+
privateKeyAlgorithm AlgorithmIdentifier SEQUENCE @7+13 (constructed): (2 elem)
4
+
algorithm OBJECT_IDENTIFIER @9+9: 1.2.840.113549.1.1.1|rsaEncryption|PKCS #1
5
+
parameters ANY NULL @20+0
6
+
privateKey PrivateKey OCTET_STRING @22+609 (encapsulates): (609 byte)|3082025D02010002818100A6CB6DE27CDF698B92CEE0C4772D4854D2FF8B666BFBF07FA377E47A90571665FD6A5B8C9F2930E4AF28E32E522162AC66CD70AA1B26888E3EEE268A2B59FECA7E4C693AE26B878B3027F5868429FD8BEBE85BFED3B0E5DF0E9D72AAB1216902B074FA2DD59001EFC4CDB1E7305FF48E0D310C0A4F798EFC758F9703C4F96C930203010001028181008367E1BA7E06C57060C8FBEBCCB8B033A3C8105B30D7DC31B2E7D1E97DAE1EC75B4F5FB0F9F3C9C160FE257D68D74495EEA80C0AF838F37C9DB7A24558C21E28C49D57470B002D90A383CAEBB5821A59583D15502F0012C9235F806C62C97F1E3CAFBC72118FCF60743168125801E06CC7293CDE64D241339AAD516E7BCC1081024100D00E8DE65F7C32094B732A5628CEFEDC35ED796B7CEA6297614545DF71D8DBC67EA14565534BFC9BC5F1A680239227189C2D493924A5BD64641169533201D6E5024100CD3AC881CC47AA776A9829C0E529E3D0DBB5A43C366842578341A051DAFAF4F6164F2DC0E72A3BD3B33F8B2F84A6CF35F0781E7C466E677FF8E553DE5C92C6170240744F3E9A83D4AD302F02B1AF3ADF04F0DC20E698E55B2E448C372AA9903E78164E221FE6561B8B9B159C52C51D9D8DC79F3F5DC8D928E268A5DC69F1FD69B3D5024100B7ACEA92B05F5B8370D52A5947400C727A90C0A25B174878C6324FE7B29273F662D50E5FDD04017360B3784058FA69ED1E8082D83AB8C8CCD1D77D0E3FCFE49502404F79B900CE9185833573BBA54E1B1D157EDFE8C37FC328D2520CCE7CC804A9A28B58D937626EBAD5FDE96534BBEE4E292EE8010CFFC8DB1E546C99FC517B4C67
7
+
SEQUENCE @26+605 (constructed): (9 elem)
8
+
INTEGER @30+1: 0
9
+
INTEGER @33+129: (1024 bit)|117127183230921204401013393277767517103803021018182691416238029726599496957198017684901559383009459523071384847726671610377559004781710040051270748910270447756432733966622455162759462672603884318432883204215291756888413811504344870556870978773843838353155520698675084344179957236491745093327422201227604749459
10
+
INTEGER @165+3: 65537
11
+
INTEGER @170+129: (1024 bit)|92276282475226568589241550905865273709561889943250510752753436239739158443231274686159532997597455087892667385718350070754140814118578097684166368734227728473322161416664690885212698653195373932779792506838124961141214987311742627151011567342689730655630521241854903774681567286735997541758916977964830429313
12
+
INTEGER @302+65: (512 bit)|10896821561662485361386011233938116142526936125648167362054539174681694465821232677159478832161550957167298418313068706031799276527005193877616679381489381
13
+
INTEGER @369+65: (512 bit)|10748747473575365133625210720374663113238804836624829882840358384492696273600075746246298849279878235356215808273663889910189484797595139778277124898735639
14
+
INTEGER @436+64: (511 bit)|6091625365131581796315047890165719534213640521161662994088715561328917102465668272778610952193459304175325574129665657306361751287362700277617869028176853
15
+
INTEGER @502+65: (512 bit)|9619864112105977791898517014707043200694399482542575521432448550956476604540013165392532656448448632323473488540572223305800601817570919153380021725291669
16
+
INTEGER @569+64: (511 bit)|4162468593383244686217782691133418477400302049612992866028022118893358867845916127581019785866484075341057799618361552573853678007698434146811407259880551
+118
examples/sig-p256-der.p7m.dump
+118
examples/sig-p256-der.p7m.dump
···
···
1
+
ContentInfo SEQUENCE @0+10868 (constructed): (2 elem)
2
+
contentType ContentType OBJECT_IDENTIFIER @4+9: 1.2.840.113549.1.7.2|signedData|PKCS #7
3
+
content [0] @15+10853 (constructed): (1 elem)
4
+
SignedData SEQUENCE @19+10849 (constructed): (5 elem)
5
+
version CMSVersion INTEGER @23+1: 1
6
+
digestAlgorithms DigestAlgorithmIdentifiers SET @26+15 (constructed): (1 elem)
7
+
DigestAlgorithmIdentifier SEQUENCE @28+13 (constructed): (2 elem)
8
+
algorithm OBJECT_IDENTIFIER @30+9: 2.16.840.1.101.3.4.2.1|sha-256|NIST Algorithm
9
+
parameters ANY NULL @41+0
10
+
encapContentInfo EncapsulatedContentInfo SEQUENCE @43+10053 (constructed): (2 elem)
11
+
eContentType ContentType OBJECT_IDENTIFIER @47+9: 1.2.840.113549.1.7.1|data|PKCS #7
12
+
eContent [0] @58+10038 (constructed): (1 elem)
13
+
OCTET_STRING @62+10034: (10034 byte)|Inizio contenuto.|AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|Fine contenuto.
14
+
CertificateSet [?] [0] @10100+370 (constructed): (1 elem)
15
+
certificate CertificateChoices SEQUENCE @10104+366 (constructed): (3 elem)
16
+
tbsCertificate TBSCertificate SEQUENCE @10108+276 (constructed): (8 elem)
17
+
version [0] @10112+3 (constructed): (1 elem)
18
+
Version INTEGER @10114+1: 2
19
+
serialNumber CertificateSerialNumber INTEGER @10117+16: (127 bit)|128087855099855233032551836648087377254
20
+
signature AlgorithmIdentifier SEQUENCE @10135+10 (constructed): (1 elem)
21
+
algorithm OBJECT_IDENTIFIER @10137+8: 1.2.840.10045.4.3.2|ecdsaWithSHA256|ANSI X9.62 ECDSA algorithm with SHA256
22
+
issuer rdnSequence Name SEQUENCE @10147+15 (constructed): (1 elem)
23
+
RelativeDistinguishedName SET @10149+13 (constructed): (1 elem)
24
+
AttributeTypeAndValue SEQUENCE @10151+11 (constructed): (2 elem)
25
+
type AttributeType OBJECT_IDENTIFIER @10153+3: 2.5.4.3|commonName|X.520 DN component
26
+
value AttributeValue [?] UTF8String @10158+4: Test
27
+
validity Validity SEQUENCE @10164+30 (constructed): (2 elem)
28
+
notBefore utcTime Time UTCTime @10166+13: 2018-07-16 14:56:35 UTC
29
+
notAfter utcTime Time UTCTime @10181+13: 2019-07-16 14:56:35 UTC
30
+
subject rdnSequence Name SEQUENCE @10196+15 (constructed): (1 elem)
31
+
RelativeDistinguishedName SET @10198+13 (constructed): (1 elem)
32
+
AttributeTypeAndValue SEQUENCE @10200+11 (constructed): (2 elem)
33
+
type AttributeType OBJECT_IDENTIFIER @10202+3: 2.5.4.3|commonName|X.520 DN component
34
+
value AttributeValue [?] UTF8String @10207+4: Test
35
+
subjectPublicKeyInfo SubjectPublicKeyInfo SEQUENCE @10213+89 (constructed): (2 elem)
36
+
algorithm AlgorithmIdentifier SEQUENCE @10215+19 (constructed): (2 elem)
37
+
algorithm OBJECT_IDENTIFIER @10217+7: 1.2.840.10045.2.1|ecPublicKey|ANSI X9.62 public key type
38
+
parameters ANY OBJECT_IDENTIFIER @10226+8: 1.2.840.10045.3.1.7|prime256v1|ANSI X9.62 named elliptic curve
39
+
subjectPublicKey BIT_STRING @10236+66: (520 bit)|0000010000100100010011001011011011001100000111000110100100100001111111110100100111011000101111100010011000111110000010110111110011010000010110100010100001100101010110101000010001101100100000100101111011001010111001101110110011100110100110100110101000100001110001001110010011110010001000000010010011000000111010011111010011100100011101001001110010011000101000011010110111110010010111111001000011011110011011101111100101001000001010110110011100011000100000111010011100001110101101001011011110101011100111110000011001000011
40
+
extensions [3] @10304+82 (constructed): (1 elem)
41
+
Extensions SEQUENCE @10306+80 (constructed): (3 elem)
42
+
Extension SEQUENCE @10308+14 (constructed): (3 elem)
43
+
extnID OBJECT_IDENTIFIER @10310+3: 2.5.29.15|keyUsage|X.509 extension
44
+
critical BOOLEAN @10315+1: true
45
+
extnValue OCTET_STRING @10318+4 (encapsulates): (4 byte)|030204F0
46
+
BIT_STRING @10320+2: (4 bit)|1111
47
+
Extension SEQUENCE @10324+29 (constructed): (2 elem)
48
+
extnID OBJECT_IDENTIFIER @10326+3: 2.5.29.14|subjectKeyIdentifier|X.509 extension
49
+
extnValue OCTET_STRING @10331+22 (encapsulates): (22 byte)|0414C3C084DF7B040DB038AF518CE397F6EC20D626E6
50
+
OCTET_STRING @10333+20: (20 byte)|C3C084DF7B040DB038AF518CE397F6EC20D626E6
51
+
Extension SEQUENCE @10355+31 (constructed): (2 elem)
52
+
extnID OBJECT_IDENTIFIER @10357+3: 2.5.29.35|authorityKeyIdentifier|X.509 extension
53
+
extnValue OCTET_STRING @10362+24 (encapsulates): (24 byte)|30168014C3C084DF7B040DB038AF518CE397F6EC20D626E6
54
+
SEQUENCE @10364+22 (constructed): (1 elem)
55
+
[0] @10366+20: (20 byte)|C3C084DF7B040DB038AF518CE397F6EC20D626E6
56
+
signatureAlgorithm AlgorithmIdentifier SEQUENCE @10388+10 (constructed): (1 elem)
57
+
algorithm OBJECT_IDENTIFIER @10390+8: 1.2.840.10045.4.3.2|ecdsaWithSHA256|ANSI X9.62 ECDSA algorithm with SHA256
58
+
signature BIT_STRING @10400+72 (encapsulates): (568 bit)|0011000001000101000000100010000100000000110111100110000000011110010101110011110110101111101101011001101111000101010100011101010110001110001111100111101110011110110110100000011000010010110111010000000100010010100000000101101000100010000101111011011100110100011101011001101110001000010001000001011100000010001000000110011111000011111111011110011000000111100000001101010000011100000111010111101000111011100100000010100100011111001111010011100111000100110111000010111100100000011011011100110010111010001011111001100000101100000001101011011001111100000010011011001000110010
59
+
SEQUENCE @10403+69 (constructed): (2 elem)
60
+
INTEGER @10405+33: (256 bit)|100583279108105959323277080420227859612360091217401498640290749528265835693079
61
+
INTEGER @10440+32: (255 bit)|46934510925111877438867701170553238261516280994969183555881415710868278719026
62
+
signerInfos SignerInfos SET @10474+394 (constructed): (1 elem)
63
+
SignerInfo SEQUENCE @10478+390 (constructed): (6 elem)
64
+
version CMSVersion INTEGER @10482+1: 1
65
+
sid issuerAndSerialNumber SignerIdentifier SEQUENCE @10485+35 (constructed): (2 elem)
66
+
issuer rdnSequence Name SEQUENCE @10487+15 (constructed): (1 elem)
67
+
RelativeDistinguishedName SET @10489+13 (constructed): (1 elem)
68
+
AttributeTypeAndValue SEQUENCE @10491+11 (constructed): (2 elem)
69
+
type AttributeType OBJECT_IDENTIFIER @10493+3: 2.5.4.3|commonName|X.520 DN component
70
+
value AttributeValue [?] UTF8String @10498+4: Test
71
+
serialNumber CertificateSerialNumber INTEGER @10504+16: (127 bit)|128087855099855233032551836648087377254
72
+
digestAlgorithm DigestAlgorithmIdentifier SEQUENCE @10522+13 (constructed): (2 elem)
73
+
algorithm OBJECT_IDENTIFIER @10524+9: 2.16.840.1.101.3.4.2.1|sha-256|NIST Algorithm
74
+
parameters ANY NULL @10535+0
75
+
SignedAttributes [?] [0] @10537+247 (constructed): (5 elem)
76
+
Attribute SEQUENCE @10540+24 (constructed): (2 elem)
77
+
type AttributeType OBJECT_IDENTIFIER @10542+9: 1.2.840.113549.1.9.3|contentType|PKCS #9
78
+
values SET @10553+11 (constructed): (1 elem)
79
+
AttributeValue [?] OBJECT_IDENTIFIER @10555+9: 1.2.840.113549.1.7.1|data|PKCS #7
80
+
Attribute SEQUENCE @10566+28 (constructed): (2 elem)
81
+
type AttributeType OBJECT_IDENTIFIER @10568+9: 1.2.840.113549.1.9.5|signingTime|PKCS #9
82
+
values SET @10579+15 (constructed): (1 elem)
83
+
AttributeValue [?] UTCTime @10581+13: 2018-07-16 14:56:35 UTC
84
+
Attribute SEQUENCE @10596+42 (constructed): (2 elem)
85
+
type AttributeType OBJECT_IDENTIFIER @10598+9: 1.2.840.113549.1.9.52|cmsAlgorithmProtection|RFC 6211
86
+
values SET @10609+29 (constructed): (1 elem)
87
+
AttributeValue [?] SEQUENCE @10611+27 (constructed): (2 elem)
88
+
SEQUENCE @10613+13 (constructed): (2 elem)
89
+
OBJECT_IDENTIFIER @10615+9: 2.16.840.1.101.3.4.2.1|sha-256|NIST Algorithm
90
+
NULL @10626+0
91
+
[1] @10628+10 (constructed): (1 elem)
92
+
OBJECT_IDENTIFIER @10630+8: 1.2.840.10045.4.3.2|ecdsaWithSHA256|ANSI X9.62 ECDSA algorithm with SHA256
93
+
Attribute SEQUENCE @10640+47 (constructed): (2 elem)
94
+
type AttributeType OBJECT_IDENTIFIER @10642+9: 1.2.840.113549.1.9.4|messageDigest|PKCS #9
95
+
values SET @10653+34 (constructed): (1 elem)
96
+
AttributeValue [?] OCTET_STRING @10655+32: (32 byte)|724C51BBE76DA05AFB20CBE8EB037CDAE1AFD713125D2DC13D552DA9F442D24D
97
+
Attribute SEQUENCE @10689+96 (constructed): (2 elem)
98
+
type AttributeType OBJECT_IDENTIFIER @10691+11: 1.2.840.113549.1.9.16.2.47|signingCertificateV2|S/MIME Authenticated Attributes
99
+
values SET @10704+81 (constructed): (1 elem)
100
+
AttributeValue [?] SEQUENCE @10706+79 (constructed): (1 elem)
101
+
SEQUENCE @10708+77 (constructed): (1 elem)
102
+
SEQUENCE @10710+75 (constructed): (2 elem)
103
+
OCTET_STRING @10712+32: (32 byte)|BABC08434C58267301E006861D27ECA125670E792797248E76A5717A5BF993C2
104
+
SEQUENCE @10746+39 (constructed): (2 elem)
105
+
SEQUENCE @10748+19 (constructed): (1 elem)
106
+
[4] @10750+17 (constructed): (1 elem)
107
+
SEQUENCE @10752+15 (constructed): (1 elem)
108
+
SET @10754+13 (constructed): (1 elem)
109
+
SEQUENCE @10756+11 (constructed): (2 elem)
110
+
OBJECT_IDENTIFIER @10758+3: 2.5.4.3|commonName|X.520 DN component
111
+
UTF8String @10763+4: Test
112
+
INTEGER @10769+16: (127 bit)|128087855099855233032551836648087377254
113
+
signatureAlgorithm SignatureAlgorithmIdentifier SEQUENCE @10787+10 (constructed): (1 elem)
114
+
algorithm OBJECT_IDENTIFIER @10789+8: 1.2.840.10045.4.3.2|ecdsaWithSHA256|ANSI X9.62 ECDSA algorithm with SHA256
115
+
signature SignatureValue OCTET_STRING @10799+71 (encapsulates): (71 byte)|3045022100F104302EABB428ECC8E71CE2E38F6CBED848A8E9A2B5D5DA19933E485C83CC7102200CBB40A0B7B9B2E048920622FB286FD14695F24CF650BDAA40B885F84C34BBB9
116
+
SEQUENCE @10801+69 (constructed): (2 elem)
117
+
INTEGER @10803+33: (256 bit)|109014796438891021115527318269695135443977065935278579101750090430030910049393
118
+
INTEGER @10838+32: (252 bit)|5758600628818957274240888478952309319266088628943097300803726649607194983353
+5
examples/timestamp-req.b64
+5
examples/timestamp-req.b64
+1
-1
hex.js
+1
-1
hex.js
+8
-4
index.html
+8
-4
index.html
···
37
<div id="tree"></div>
38
</div>
39
<form>
40
-
<textarea id="area" rows="8"></textarea>
41
<br>
42
<br>
43
<label title="can be slow with big files"><input type="checkbox" id="wantHex" checked="checked"> with hex dump</label>
···
58
<option value="pkcs1.pem">PKCS#1 RSA key (RFC 8017)</option>
59
<option value="pkcs8-rsa.pem">PKCS#8 RSA key (RFC 5208)</option>
60
<option value="pkcs10.pem">PKCS#10 certification request (RFC 2986)</option>
61
<option value="cmpv2.b64">CMP PKI message (RFC 4210)</option>
62
</select>
63
<input id="butExample" type="button" value="load"><br>
64
</td></tr>
···
70
<div id="help">
71
<h2>Instructions</h2>
72
<p>This page contains a JavaScript generic ASN.1 parser that can decode any valid ASN.1 DER or BER structure whether Base64-encoded (raw base64, PEM armoring and <span class="tt">begin-base64</span> are recognized) or Hex-encoded. </p>
73
-
<p>This tool can be used online at the address <a href="https://asn1js.eu/"><span class="tt">https://asn1js.eu/</span></a> or offline, unpacking <a href="https://asn1js.eu/asn1js.zip">the ZIP file</a> in a directory and opening <span class="tt">index.html</span> in a browser</p>
74
<p>On the left of the page will be printed a tree representing the hierarchical structure, on the right side an hex dump will be shown. <br>
75
Hovering on the tree highlights ancestry (the hovered node and all its ancestors get colored) and the position of the hovered node gets highlighted in the hex dump (with header and content in a different colors). <br>
76
Clicking a node in the tree will hide its sub-nodes (collapsed nodes can be noticed because they will become <i>italic</i>).</p>
···
80
<h3>Copyright</h3>
81
<div><p class="hidden">
82
ASN.1 JavaScript decoder<br>
83
-
Copyright © 2008-2024 Lapo Luchini <a href="mailto:lapo@lapo.it?subject=ASN1js"><lapo@lapo.it></a><br>
84
<br>
85
Permission to use, copy, modify, and/or distribute this software for any
86
purpose with or without fee is hereby granted, provided that the above
···
94
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
95
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
96
</p></div>
97
-
<p>ASN.1 JavaScript decoder Copyright © 2008-2024 <a href="https://lapo.it/">Lapo Luchini</a>; released as <a href="https://opensource.org/licenses/isc-license.txt">opensource</a> under the <a href="https://en.wikipedia.org/wiki/ISC_licence">ISC license</a>.</p>
98
</div>
99
<p><span class="tt">OBJECT IDENTIFIER</span> values are recognized using data taken from Peter Gutmann's <a href="https://www.cs.auckland.ac.nz/~pgut001/#standards">dumpasn1</a> program.</p>
100
<h3>Links</h3>
···
105
<li>previous versions on githack: <select id="tags"><option>[select tag]</option></select></li>
106
<li><a href="http://idf.lapo.it/p/asn1js/">InDefero tracker</a> (currently offline)</li>
107
<li><a href="https://github.com/lapo-luchini/asn1js">github mirror</a></li>
108
<li><a href="https://www.openhub.net/p/asn1js">OpenHub code stats</a></li>
109
</ul>
110
</div>
···
37
<div id="tree"></div>
38
</div>
39
<form>
40
+
<textarea id="area" rows="8" placeholder="Paste hex or base64 or PEM encoded ASN.1 BER or DER structures here, or load a file."></textarea>
41
<br>
42
<br>
43
<label title="can be slow with big files"><input type="checkbox" id="wantHex" checked="checked"> with hex dump</label>
···
58
<option value="pkcs1.pem">PKCS#1 RSA key (RFC 8017)</option>
59
<option value="pkcs8-rsa.pem">PKCS#8 RSA key (RFC 5208)</option>
60
<option value="pkcs10.pem">PKCS#10 certification request (RFC 2986)</option>
61
+
<option value="crl-rfc5280.b64">CRL example (RFC 5280)</option>
62
<option value="cmpv2.b64">CMP PKI message (RFC 4210)</option>
63
+
<option value="ldapmessage.b64">LDAP message (RFC 4511)</option>
64
+
<option value="timestamp-req.b64">TimeStamp request (RFC 3161)</option>
65
</select>
66
<input id="butExample" type="button" value="load"><br>
67
</td></tr>
···
73
<div id="help">
74
<h2>Instructions</h2>
75
<p>This page contains a JavaScript generic ASN.1 parser that can decode any valid ASN.1 DER or BER structure whether Base64-encoded (raw base64, PEM armoring and <span class="tt">begin-base64</span> are recognized) or Hex-encoded. </p>
76
+
<p>This tool can be used online at the address <a href="https://asn1js.eu/"><span class="tt">https://asn1js.eu/</span></a> or offline, unpacking <a href="https://asn1js.eu/asn1js.zip">the ZIP file</a> in a directory and opening <span class="tt">index-local.html</span> in a browser.</p>
77
<p>On the left of the page will be printed a tree representing the hierarchical structure, on the right side an hex dump will be shown. <br>
78
Hovering on the tree highlights ancestry (the hovered node and all its ancestors get colored) and the position of the hovered node gets highlighted in the hex dump (with header and content in a different colors). <br>
79
Clicking a node in the tree will hide its sub-nodes (collapsed nodes can be noticed because they will become <i>italic</i>).</p>
···
83
<h3>Copyright</h3>
84
<div><p class="hidden">
85
ASN.1 JavaScript decoder<br>
86
+
Copyright © 2008-2025 Lapo Luchini <a href="mailto:lapo@lapo.it?subject=ASN1js"><lapo@lapo.it></a><br>
87
<br>
88
Permission to use, copy, modify, and/or distribute this software for any
89
purpose with or without fee is hereby granted, provided that the above
···
97
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
98
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
99
</p></div>
100
+
<p>ASN.1 JavaScript decoder Copyright © 2008-2025 <a href="https://lapo.it/">Lapo Luchini</a>; released as <a href="https://opensource.org/licenses/isc-license.txt">opensource</a> under the <a href="https://en.wikipedia.org/wiki/ISC_licence">ISC license</a>.</p>
101
</div>
102
<p><span class="tt">OBJECT IDENTIFIER</span> values are recognized using data taken from Peter Gutmann's <a href="https://www.cs.auckland.ac.nz/~pgut001/#standards">dumpasn1</a> program.</p>
103
<h3>Links</h3>
···
108
<li>previous versions on githack: <select id="tags"><option>[select tag]</option></select></li>
109
<li><a href="http://idf.lapo.it/p/asn1js/">InDefero tracker</a> (currently offline)</li>
110
<li><a href="https://github.com/lapo-luchini/asn1js">github mirror</a></li>
111
+
<li><a href="https://github.com/lapo-luchini/asn1js/blob/trunk/CHANGELOG.md">ChangeLog on GitHub</a></li>
112
<li><a href="https://www.openhub.net/p/asn1js">OpenHub code stats</a></li>
113
</ul>
114
</div>
+2
-2
index.js
+2
-2
index.js
···
86
if (area.value === '') area.value = Base64.pretty(b64);
87
try {
88
window.location.hash = hash = '#' + b64;
89
-
} catch (e) {
90
// fails with "Access Denied" on IE with URLs longer than ~2048 chars
91
window.location.hash = hash = '#';
92
}
···
122
else if (Base64.re.test(str)) der = Base64.unarmor(str);
123
else der = str;
124
decode(der);
125
-
} catch (e) {
126
text(tree, 'Cannot decode file.');
127
dump.innerHTML = '';
128
}
···
86
if (area.value === '') area.value = Base64.pretty(b64);
87
try {
88
window.location.hash = hash = '#' + b64;
89
+
} catch (ignore) {
90
// fails with "Access Denied" on IE with URLs longer than ~2048 chars
91
window.location.hash = hash = '#';
92
}
···
122
else if (Base64.re.test(str)) der = Base64.unarmor(str);
123
else der = str;
124
decode(der);
125
+
} catch (ignore) {
126
text(tree, 'Cannot decode file.');
127
dump.innerHTML = '';
128
}
-106
int10.js
-106
int10.js
···
1
-
// Big integer base-10 printing library
2
-
// Copyright (c) 2008-2024 Lapo Luchini <lapo@lapo.it>
3
-
4
-
// Permission to use, copy, modify, and/or distribute this software for any
5
-
// purpose with or without fee is hereby granted, provided that the above
6
-
// copyright notice and this permission notice appear in all copies.
7
-
//
8
-
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
-
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
-
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
-
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
-
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
-
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
-
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
-
16
-
let max = 10000000000000; // biggest 10^n integer that can still fit 2^53 when multiplied by 256
17
-
18
-
export class Int10 {
19
-
/**
20
-
* Arbitrary length base-10 value.
21
-
* @param {number} value - Optional initial value (will be 0 otherwise).
22
-
*/
23
-
constructor(value) {
24
-
this.buf = [+value || 0];
25
-
}
26
-
27
-
/**
28
-
* Multiply value by m and add c.
29
-
* @param {number} m - multiplier, must be < =256
30
-
* @param {number} c - value to add
31
-
*/
32
-
mulAdd(m, c) {
33
-
// assert(m <= 256)
34
-
let b = this.buf,
35
-
l = b.length,
36
-
i, t;
37
-
for (i = 0; i < l; ++i) {
38
-
t = b[i] * m + c;
39
-
if (t < max)
40
-
c = 0;
41
-
else {
42
-
c = 0|(t / max);
43
-
t -= c * max;
44
-
}
45
-
b[i] = t;
46
-
}
47
-
if (c > 0)
48
-
b[i] = c;
49
-
}
50
-
51
-
/**
52
-
* Subtract value.
53
-
* @param {number} c - value to subtract
54
-
*/
55
-
sub(c) {
56
-
let b = this.buf,
57
-
l = b.length,
58
-
i, t;
59
-
for (i = 0; i < l; ++i) {
60
-
t = b[i] - c;
61
-
if (t < 0) {
62
-
t += max;
63
-
c = 1;
64
-
} else
65
-
c = 0;
66
-
b[i] = t;
67
-
}
68
-
while (b[b.length - 1] === 0)
69
-
b.pop();
70
-
}
71
-
72
-
/**
73
-
* Convert to decimal string representation.
74
-
* @param {*} base - optional value, only value accepted is 10
75
-
*/
76
-
toString(base) {
77
-
if ((base || 10) != 10)
78
-
throw 'only base 10 is supported';
79
-
let b = this.buf,
80
-
s = b[b.length - 1].toString();
81
-
for (let i = b.length - 2; i >= 0; --i)
82
-
s += (max + b[i]).toString().substring(1);
83
-
return s;
84
-
}
85
-
86
-
/**
87
-
* Convert to Number value representation.
88
-
* Will probably overflow 2^53 and thus become approximate.
89
-
*/
90
-
valueOf() {
91
-
let b = this.buf,
92
-
v = 0;
93
-
for (let i = b.length - 1; i >= 0; --i)
94
-
v = v * max + b[i];
95
-
return v;
96
-
}
97
-
98
-
/**
99
-
* Return value as a simple Number (if it is <= 10000000000000), or return this.
100
-
*/
101
-
simplify() {
102
-
let b = this.buf;
103
-
return (b.length == 1) ? b[0] : this;
104
-
}
105
-
106
-
}
···
+33
-78
package.json
+33
-78
package.json
···
1
{
2
"name": "@lapo/asn1js",
3
-
"version": "2.0.4",
4
"description": "Generic ASN.1 parser/decoder that can decode any valid ASN.1 DER or BER structures.",
5
"type": "module",
6
"main": "asn1.js",
···
8
"type": "git",
9
"url": "git+https://github.com/lapo-luchini/asn1js.git"
10
},
11
-
"keywords": [ "asn1", "ber", "der", "pem" ],
12
"author": "Lapo Luchini <lapo@lapo.it>",
13
"license": "ISC",
14
-
"bugs": { "url": "https://github.com/lapo-luchini/asn1js/issues" },
15
"homepage": "https://lapo.it/asn1js/",
16
-
"files": [ "asn1.js", "base64.js", "hex.js", "int10.js", "dom.js", "defs.js", "oids.js", "rfcdef.js", "dumpASN1.js" ],
17
"scripts": {
18
-
"lint": "npx eslint asn1.js base64.js hex.js int10.js dom.js defs.js oids.js rfcdef.js tags.js context.js index.js parseRFC.js dumpASN1.js test.js testDefs.js vite.config.js theme.js",
19
"lint-action": "npx @action-validator/cli .github/workflows/node.js.yml",
20
"build": "vite build",
21
-
"serve": "echo 'Connect to http://localhost:3000/' ; npx statik --port 3000 .",
22
"test": "node test",
23
"testdefs": "node testDefs"
24
},
···
26
"dumpASN1": "./dumpASN1.js"
27
},
28
"engines": {
29
-
"node": ">=12.20.0"
30
},
31
"devDependencies": {
32
-
"@rollup/wasm-node": "^4.17.2",
33
-
"eslint": "^8.34.0",
34
"htmlparser2": "^9.1.0",
35
-
"rollup": "^4.12.0",
36
-
"vite": "^5.2.10",
37
-
"vite-plugin-dom": "^1.0.3",
38
-
"vite-plugin-singlefile": "^2.0.1"
39
},
40
"overrides": {
41
"rollup": "npm:@rollup/wasm-node"
···
44
"overrides": {
45
"rollup": "npm:@rollup/wasm-node"
46
}
47
-
},
48
-
"eslintConfig": {
49
-
"env": {
50
-
"es6": true,
51
-
"browser": true,
52
-
"node": true
53
-
},
54
-
"parserOptions": {
55
-
"ecmaVersion": 2015,
56
-
"sourceType": "module"
57
-
},
58
-
"extends": [ "eslint:recommended" ],
59
-
"globals": {
60
-
"Uint8Array": "readonly"
61
-
},
62
-
"rules": {
63
-
"strict": [ "error", "function" ],
64
-
"indent": [ "error", 4 ],
65
-
"no-trailing-spaces": [ "error" ],
66
-
"linebreak-style": [ "error", "unix" ],
67
-
"eol-last": [ "error", "always" ],
68
-
"semi": [ "warn", "always" ],
69
-
"quotes": [ "error", "single", { "avoidEscape": true } ],
70
-
"no-var": [ "warn" ],
71
-
"comma-dangle": [ "error", "always-multiline" ]
72
-
},
73
-
"overrides": [
74
-
{
75
-
"files": [ "defs.js" ],
76
-
"parserOptions": {
77
-
"ecmaVersion": 2020
78
-
}
79
-
}, {
80
-
"files": [ "test.js", "parseRFC.js", "dumpASN1.js" ],
81
-
"parserOptions": {
82
-
"ecmaVersion": 2021
83
-
},
84
-
"rules": {
85
-
"strict": [ "error", "global" ]
86
-
}
87
-
}, {
88
-
"files": [ "oids.js" ],
89
-
"rules": {
90
-
"indent": "off",
91
-
"quotes": [ "warn", "double" ]
92
-
}
93
-
}, {
94
-
"files": [ "tags.js", "rfcdef.js" ],
95
-
"rules": {
96
-
"indent": [ "error", 2, { "ignoredNodes": [ "Program > ExpressionStatement > CallExpression > FunctionExpression > BlockStatement > ExpressionStatement[directive='use strict']:first-child" ] } ],
97
-
"comma-dangle": "off",
98
-
"quotes": [ "warn", "double" ]
99
-
}
100
-
}, {
101
-
"files": [ "defs.js" ],
102
-
"parserOptions": {
103
-
"ecmaVersion": 2021
104
-
}
105
-
}, {
106
-
"files": [ "testDefs.js" ],
107
-
"parserOptions": {
108
-
"ecmaVersion": 2022
109
-
}
110
-
}
111
-
]
112
}
113
}
···
1
{
2
"name": "@lapo/asn1js",
3
+
"version": "2.1.1",
4
"description": "Generic ASN.1 parser/decoder that can decode any valid ASN.1 DER or BER structures.",
5
"type": "module",
6
"main": "asn1.js",
···
8
"type": "git",
9
"url": "git+https://github.com/lapo-luchini/asn1js.git"
10
},
11
+
"keywords": [
12
+
"asn1",
13
+
"ber",
14
+
"der",
15
+
"pem"
16
+
],
17
"author": "Lapo Luchini <lapo@lapo.it>",
18
"license": "ISC",
19
+
"bugs": {
20
+
"url": "https://github.com/lapo-luchini/asn1js/issues"
21
+
},
22
"homepage": "https://lapo.it/asn1js/",
23
+
"files": [
24
+
"asn1.js",
25
+
"base64.js",
26
+
"hex.js",
27
+
"dom.js",
28
+
"defs.js",
29
+
"oids.js",
30
+
"rfcdef.js",
31
+
"dumpASN1.js"
32
+
],
33
"scripts": {
34
+
"lint": "npx eslint asn1.js base64.js hex.js dom.js defs.js oids.js rfcdef.js tags.js context.js index.js parseRFC.js dumpASN1.js test.js testDefs.js vite.config.js theme.js",
35
"lint-action": "npx @action-validator/cli .github/workflows/node.js.yml",
36
"build": "vite build",
37
+
"serve": "npx -p local-web-server ws",
38
"test": "node test",
39
"testdefs": "node testDefs"
40
},
···
42
"dumpASN1": "./dumpASN1.js"
43
},
44
"engines": {
45
+
"node": ">=14.6.0"
46
},
47
+
"packageManager": "pnpm@7.33.7",
48
"devDependencies": {
49
+
"@eslint/eslintrc": "^3.3.1",
50
+
"@eslint/js": "^9.38.0",
51
+
"@rollup/wasm-node": "^4.52.5",
52
+
"diff": "^8.0.2",
53
+
"eslint": "^9.38.0",
54
+
"globals": "^16.4.0",
55
"htmlparser2": "^9.1.0",
56
+
"vite": "^7.1.12",
57
+
"vite-plugin-dom": "^1.0.5",
58
+
"vite-plugin-singlefile": "^2.3.0"
59
},
60
"overrides": {
61
"rollup": "npm:@rollup/wasm-node"
···
64
"overrides": {
65
"rollup": "npm:@rollup/wasm-node"
66
}
67
}
68
}
+53
-5
parseRFC.js
+53
-5
parseRFC.js
···
1
#! /usr/bin/env node
2
3
import * as fs from 'node:fs';
4
5
const
···
56
[ /emptyString {4}EncodingParameters ::= ''H/g, '' ],
57
[ /[(]CONSTRAINED BY[^)]+[)]/g, '' ],
58
],
59
};
60
61
// const reWhitespace = /(?:\s|--(?:[}-]?[^\n}-])*(?:\n|--))*/y;
···
179
tryToken(expect) {
180
let p = this.pos;
181
let t;
182
-
try { t = this.parseToken(); } catch (e) { /*ignore*/ }
183
// console.log('[debug] tryToken(' + expect + ') = ' + t);
184
if (t == expect)
185
return true;
···
309
let plicit = this.getRegEx('explicit/implicit', reTagType);
310
if (plicit == '') plicit = currentMod.tagDefault;
311
let x = this.parseType();
312
return {
313
-
name: '[' + t + ']',
314
type: 'tag',
315
'class': tagClass,
316
explicit: (plicit == 'EXPLICIT'),
···
323
let p = this.pos;
324
try {
325
return this.parseBuiltinType();
326
-
} catch (e) {
327
// console.log('[debug] parseAssignment failed on parseType', e);
328
this.pos = p;
329
let x = {
···
394
case 'NULL':
395
return null;
396
}
397
-
} catch (e) {
398
this.pos = p;
399
}
400
p = this.pos;
401
try {
402
return this.parseIdentifier();
403
-
} catch (e) {
404
this.pos = p;
405
}
406
this.exception('Unknown value type.');
···
1
#! /usr/bin/env node
2
3
+
// RFC ASN.1 definition parser
4
+
// Copyright (c) 2021 Lapo Luchini <lapo@lapo.it>
5
+
6
+
// Permission to use, copy, modify, and/or distribute this software for any
7
+
// purpose with or without fee is hereby granted, provided that the above
8
+
// copyright notice and this permission notice appear in all copies.
9
+
//
10
+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+
18
import * as fs from 'node:fs';
19
20
const
···
71
[ /emptyString {4}EncodingParameters ::= ''H/g, '' ],
72
[ /[(]CONSTRAINED BY[^)]+[)]/g, '' ],
73
],
74
+
4511: [
75
+
[ /^\s+-- .*\r?\n/mg, '' ], // comments
76
+
[ 'EXTENSIBILITY IMPLIED', '' ],
77
+
[ /\.\.\.(,| {2})/g, '' ],
78
+
[ /value AttributeValue/g, 'AttributeValue' ],
79
+
[ /control Control/g, 'Control' ],
80
+
[ /Attribute ::= PartialAttribute\(WITH COMPONENTS \{[^}]+\}\)/g, 'PartialAttribute ::= SEQUENCE { type AttributeDescription, vals SET SIZE (1..MAX) OF AttributeValue }' ],
81
+
[ /,\s+\}/g, '}' ],
82
+
[ /SaslCredentials,/g, 'SaslCredentials' ],
83
+
[ /(BindResponse|ExtendedResponse) ::= \[APPLICATION [0-9]+\] SEQUENCE \{[^}]+\}/g, '$1 ::= ANY' ],
84
+
[ /selector LDAPString/g, 'LDAPString' ],
85
+
[ /filter Filter/g, 'Filter' ],
86
+
[ /MatchingRuleAssertion,/g, 'MatchingRuleAssertion' ],
87
+
[ /OF substring CHOICE/g, 'OF CHOICE' ],
88
+
[ /partialAttribute PartialAttribute/g, 'PartialAttribute' ],
89
+
[ /uri URI/g, 'URI' ],
90
+
[ /OF change SEQUENCE/g, 'OF SEQUENCE' ],
91
+
[ /attribute Attribute/g, 'Attribute' ],
92
+
],
93
};
94
95
// const reWhitespace = /(?:\s|--(?:[}-]?[^\n}-])*(?:\n|--))*/y;
···
213
tryToken(expect) {
214
let p = this.pos;
215
let t;
216
+
try { t = this.parseToken(); } catch (ignore) { /*ignore*/ }
217
// console.log('[debug] tryToken(' + expect + ') = ' + t);
218
if (t == expect)
219
return true;
···
343
let plicit = this.getRegEx('explicit/implicit', reTagType);
344
if (plicit == '') plicit = currentMod.tagDefault;
345
let x = this.parseType();
346
+
let name;
347
+
switch (tagClass) { // keep in sync with ASN1.typeName
348
+
case 'APPLICATION':
349
+
name = 'Application ' + t;
350
+
break;
351
+
case 'PRIVATE':
352
+
name = 'Private ' + t;
353
+
break;
354
+
case 'CONTEXT':
355
+
// fall through
356
+
default:
357
+
name = '[' + t + ']';
358
+
break;
359
+
}
360
return {
361
+
name,
362
type: 'tag',
363
'class': tagClass,
364
explicit: (plicit == 'EXPLICIT'),
···
371
let p = this.pos;
372
try {
373
return this.parseBuiltinType();
374
+
} catch (ignore) {
375
// console.log('[debug] parseAssignment failed on parseType', e);
376
this.pos = p;
377
let x = {
···
442
case 'NULL':
443
return null;
444
}
445
+
} catch (ignore) {
446
this.pos = p;
447
}
448
p = this.pos;
449
try {
450
return this.parseIdentifier();
451
+
} catch (ignore) {
452
this.pos = p;
453
}
454
this.exception('Unknown value type.');
+1115
pnpm-lock.yaml
+1115
pnpm-lock.yaml
···
···
1
+
lockfileVersion: 5.4
2
+
3
+
overrides:
4
+
rollup: npm:@rollup/wasm-node
5
+
6
+
specifiers:
7
+
'@eslint/eslintrc': ^3.3.1
8
+
'@eslint/js': ^9.38.0
9
+
'@rollup/wasm-node': ^4.52.5
10
+
diff: ^8.0.2
11
+
eslint: ^9.38.0
12
+
globals: ^16.4.0
13
+
htmlparser2: ^9.1.0
14
+
vite: ^7.1.12
15
+
vite-plugin-dom: ^1.0.5
16
+
vite-plugin-singlefile: ^2.3.0
17
+
18
+
devDependencies:
19
+
'@eslint/eslintrc': 3.3.1
20
+
'@eslint/js': 9.38.0
21
+
'@rollup/wasm-node': 4.52.5
22
+
diff: 8.0.2
23
+
eslint: 9.38.0
24
+
globals: 16.4.0
25
+
htmlparser2: 9.1.0
26
+
vite: 7.1.12
27
+
vite-plugin-dom: 1.0.5_vite@7.1.12
28
+
vite-plugin-singlefile: 2.3.0_vite@7.1.12
29
+
30
+
packages:
31
+
32
+
/@esbuild/aix-ppc64/0.25.11:
33
+
resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==}
34
+
engines: {node: '>=18'}
35
+
cpu: [ppc64]
36
+
os: [aix]
37
+
requiresBuild: true
38
+
dev: true
39
+
optional: true
40
+
41
+
/@esbuild/android-arm/0.25.11:
42
+
resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==}
43
+
engines: {node: '>=18'}
44
+
cpu: [arm]
45
+
os: [android]
46
+
requiresBuild: true
47
+
dev: true
48
+
optional: true
49
+
50
+
/@esbuild/android-arm64/0.25.11:
51
+
resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==}
52
+
engines: {node: '>=18'}
53
+
cpu: [arm64]
54
+
os: [android]
55
+
requiresBuild: true
56
+
dev: true
57
+
optional: true
58
+
59
+
/@esbuild/android-x64/0.25.11:
60
+
resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==}
61
+
engines: {node: '>=18'}
62
+
cpu: [x64]
63
+
os: [android]
64
+
requiresBuild: true
65
+
dev: true
66
+
optional: true
67
+
68
+
/@esbuild/darwin-arm64/0.25.11:
69
+
resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==}
70
+
engines: {node: '>=18'}
71
+
cpu: [arm64]
72
+
os: [darwin]
73
+
requiresBuild: true
74
+
dev: true
75
+
optional: true
76
+
77
+
/@esbuild/darwin-x64/0.25.11:
78
+
resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==}
79
+
engines: {node: '>=18'}
80
+
cpu: [x64]
81
+
os: [darwin]
82
+
requiresBuild: true
83
+
dev: true
84
+
optional: true
85
+
86
+
/@esbuild/freebsd-arm64/0.25.11:
87
+
resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==}
88
+
engines: {node: '>=18'}
89
+
cpu: [arm64]
90
+
os: [freebsd]
91
+
requiresBuild: true
92
+
dev: true
93
+
optional: true
94
+
95
+
/@esbuild/freebsd-x64/0.25.11:
96
+
resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==}
97
+
engines: {node: '>=18'}
98
+
cpu: [x64]
99
+
os: [freebsd]
100
+
requiresBuild: true
101
+
dev: true
102
+
optional: true
103
+
104
+
/@esbuild/linux-arm/0.25.11:
105
+
resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==}
106
+
engines: {node: '>=18'}
107
+
cpu: [arm]
108
+
os: [linux]
109
+
requiresBuild: true
110
+
dev: true
111
+
optional: true
112
+
113
+
/@esbuild/linux-arm64/0.25.11:
114
+
resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==}
115
+
engines: {node: '>=18'}
116
+
cpu: [arm64]
117
+
os: [linux]
118
+
requiresBuild: true
119
+
dev: true
120
+
optional: true
121
+
122
+
/@esbuild/linux-ia32/0.25.11:
123
+
resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==}
124
+
engines: {node: '>=18'}
125
+
cpu: [ia32]
126
+
os: [linux]
127
+
requiresBuild: true
128
+
dev: true
129
+
optional: true
130
+
131
+
/@esbuild/linux-loong64/0.25.11:
132
+
resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==}
133
+
engines: {node: '>=18'}
134
+
cpu: [loong64]
135
+
os: [linux]
136
+
requiresBuild: true
137
+
dev: true
138
+
optional: true
139
+
140
+
/@esbuild/linux-mips64el/0.25.11:
141
+
resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==}
142
+
engines: {node: '>=18'}
143
+
cpu: [mips64el]
144
+
os: [linux]
145
+
requiresBuild: true
146
+
dev: true
147
+
optional: true
148
+
149
+
/@esbuild/linux-ppc64/0.25.11:
150
+
resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==}
151
+
engines: {node: '>=18'}
152
+
cpu: [ppc64]
153
+
os: [linux]
154
+
requiresBuild: true
155
+
dev: true
156
+
optional: true
157
+
158
+
/@esbuild/linux-riscv64/0.25.11:
159
+
resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==}
160
+
engines: {node: '>=18'}
161
+
cpu: [riscv64]
162
+
os: [linux]
163
+
requiresBuild: true
164
+
dev: true
165
+
optional: true
166
+
167
+
/@esbuild/linux-s390x/0.25.11:
168
+
resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==}
169
+
engines: {node: '>=18'}
170
+
cpu: [s390x]
171
+
os: [linux]
172
+
requiresBuild: true
173
+
dev: true
174
+
optional: true
175
+
176
+
/@esbuild/linux-x64/0.25.11:
177
+
resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==}
178
+
engines: {node: '>=18'}
179
+
cpu: [x64]
180
+
os: [linux]
181
+
requiresBuild: true
182
+
dev: true
183
+
optional: true
184
+
185
+
/@esbuild/netbsd-arm64/0.25.11:
186
+
resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==}
187
+
engines: {node: '>=18'}
188
+
cpu: [arm64]
189
+
os: [netbsd]
190
+
requiresBuild: true
191
+
dev: true
192
+
optional: true
193
+
194
+
/@esbuild/netbsd-x64/0.25.11:
195
+
resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==}
196
+
engines: {node: '>=18'}
197
+
cpu: [x64]
198
+
os: [netbsd]
199
+
requiresBuild: true
200
+
dev: true
201
+
optional: true
202
+
203
+
/@esbuild/openbsd-arm64/0.25.11:
204
+
resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==}
205
+
engines: {node: '>=18'}
206
+
cpu: [arm64]
207
+
os: [openbsd]
208
+
requiresBuild: true
209
+
dev: true
210
+
optional: true
211
+
212
+
/@esbuild/openbsd-x64/0.25.11:
213
+
resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==}
214
+
engines: {node: '>=18'}
215
+
cpu: [x64]
216
+
os: [openbsd]
217
+
requiresBuild: true
218
+
dev: true
219
+
optional: true
220
+
221
+
/@esbuild/openharmony-arm64/0.25.11:
222
+
resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==}
223
+
engines: {node: '>=18'}
224
+
cpu: [arm64]
225
+
os: [openharmony]
226
+
requiresBuild: true
227
+
dev: true
228
+
optional: true
229
+
230
+
/@esbuild/sunos-x64/0.25.11:
231
+
resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==}
232
+
engines: {node: '>=18'}
233
+
cpu: [x64]
234
+
os: [sunos]
235
+
requiresBuild: true
236
+
dev: true
237
+
optional: true
238
+
239
+
/@esbuild/win32-arm64/0.25.11:
240
+
resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==}
241
+
engines: {node: '>=18'}
242
+
cpu: [arm64]
243
+
os: [win32]
244
+
requiresBuild: true
245
+
dev: true
246
+
optional: true
247
+
248
+
/@esbuild/win32-ia32/0.25.11:
249
+
resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==}
250
+
engines: {node: '>=18'}
251
+
cpu: [ia32]
252
+
os: [win32]
253
+
requiresBuild: true
254
+
dev: true
255
+
optional: true
256
+
257
+
/@esbuild/win32-x64/0.25.11:
258
+
resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==}
259
+
engines: {node: '>=18'}
260
+
cpu: [x64]
261
+
os: [win32]
262
+
requiresBuild: true
263
+
dev: true
264
+
optional: true
265
+
266
+
/@eslint-community/eslint-utils/4.9.0_eslint@9.38.0:
267
+
resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==}
268
+
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
269
+
peerDependencies:
270
+
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
271
+
dependencies:
272
+
eslint: 9.38.0
273
+
eslint-visitor-keys: 3.4.3
274
+
dev: true
275
+
276
+
/@eslint-community/regexpp/4.12.2:
277
+
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
278
+
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
279
+
dev: true
280
+
281
+
/@eslint/config-array/0.21.1:
282
+
resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==}
283
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
284
+
dependencies:
285
+
'@eslint/object-schema': 2.1.7
286
+
debug: 4.4.3
287
+
minimatch: 3.1.2
288
+
transitivePeerDependencies:
289
+
- supports-color
290
+
dev: true
291
+
292
+
/@eslint/config-helpers/0.4.2:
293
+
resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==}
294
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
295
+
dependencies:
296
+
'@eslint/core': 0.17.0
297
+
dev: true
298
+
299
+
/@eslint/core/0.16.0:
300
+
resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==}
301
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
302
+
dependencies:
303
+
'@types/json-schema': 7.0.15
304
+
dev: true
305
+
306
+
/@eslint/core/0.17.0:
307
+
resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
308
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
309
+
dependencies:
310
+
'@types/json-schema': 7.0.15
311
+
dev: true
312
+
313
+
/@eslint/eslintrc/3.3.1:
314
+
resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
315
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
316
+
dependencies:
317
+
ajv: 6.12.6
318
+
debug: 4.4.3
319
+
espree: 10.4.0
320
+
globals: 14.0.0
321
+
ignore: 5.3.2
322
+
import-fresh: 3.3.1
323
+
js-yaml: 4.1.0
324
+
minimatch: 3.1.2
325
+
strip-json-comments: 3.1.1
326
+
transitivePeerDependencies:
327
+
- supports-color
328
+
dev: true
329
+
330
+
/@eslint/js/9.38.0:
331
+
resolution: {integrity: sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==}
332
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
333
+
dev: true
334
+
335
+
/@eslint/object-schema/2.1.7:
336
+
resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
337
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
338
+
dev: true
339
+
340
+
/@eslint/plugin-kit/0.4.1:
341
+
resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
342
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
343
+
dependencies:
344
+
'@eslint/core': 0.17.0
345
+
levn: 0.4.1
346
+
dev: true
347
+
348
+
/@humanfs/core/0.19.1:
349
+
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
350
+
engines: {node: '>=18.18.0'}
351
+
dev: true
352
+
353
+
/@humanfs/node/0.16.7:
354
+
resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==}
355
+
engines: {node: '>=18.18.0'}
356
+
dependencies:
357
+
'@humanfs/core': 0.19.1
358
+
'@humanwhocodes/retry': 0.4.3
359
+
dev: true
360
+
361
+
/@humanwhocodes/module-importer/1.0.1:
362
+
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
363
+
engines: {node: '>=12.22'}
364
+
dev: true
365
+
366
+
/@humanwhocodes/retry/0.4.3:
367
+
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
368
+
engines: {node: '>=18.18'}
369
+
dev: true
370
+
371
+
/@rollup/wasm-node/4.52.5:
372
+
resolution: {integrity: sha512-ldY4tEzSMBHNwB8TfRpi7RRRjjyfKlwjdebw5pS1lu0xaY3g4RDc6ople2wEYulVOKVeH7ZJwRx0iw4pGtjMHg==}
373
+
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
374
+
hasBin: true
375
+
dependencies:
376
+
'@types/estree': 1.0.8
377
+
optionalDependencies:
378
+
fsevents: 2.3.3
379
+
dev: true
380
+
381
+
/@types/estree/1.0.8:
382
+
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
383
+
dev: true
384
+
385
+
/@types/json-schema/7.0.15:
386
+
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
387
+
dev: true
388
+
389
+
/acorn-jsx/5.3.2_acorn@8.15.0:
390
+
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
391
+
peerDependencies:
392
+
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
393
+
dependencies:
394
+
acorn: 8.15.0
395
+
dev: true
396
+
397
+
/acorn/8.15.0:
398
+
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
399
+
engines: {node: '>=0.4.0'}
400
+
hasBin: true
401
+
dev: true
402
+
403
+
/ajv/6.12.6:
404
+
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
405
+
dependencies:
406
+
fast-deep-equal: 3.1.3
407
+
fast-json-stable-stringify: 2.1.0
408
+
json-schema-traverse: 0.4.1
409
+
uri-js: 4.4.1
410
+
dev: true
411
+
412
+
/ansi-styles/4.3.0:
413
+
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
414
+
engines: {node: '>=8'}
415
+
dependencies:
416
+
color-convert: 2.0.1
417
+
dev: true
418
+
419
+
/argparse/2.0.1:
420
+
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
421
+
dev: true
422
+
423
+
/balanced-match/1.0.2:
424
+
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
425
+
dev: true
426
+
427
+
/brace-expansion/1.1.12:
428
+
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
429
+
dependencies:
430
+
balanced-match: 1.0.2
431
+
concat-map: 0.0.1
432
+
dev: true
433
+
434
+
/braces/3.0.3:
435
+
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
436
+
engines: {node: '>=8'}
437
+
dependencies:
438
+
fill-range: 7.1.1
439
+
dev: true
440
+
441
+
/callsites/3.1.0:
442
+
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
443
+
engines: {node: '>=6'}
444
+
dev: true
445
+
446
+
/chalk/4.1.2:
447
+
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
448
+
engines: {node: '>=10'}
449
+
dependencies:
450
+
ansi-styles: 4.3.0
451
+
supports-color: 7.2.0
452
+
dev: true
453
+
454
+
/color-convert/2.0.1:
455
+
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
456
+
engines: {node: '>=7.0.0'}
457
+
dependencies:
458
+
color-name: 1.1.4
459
+
dev: true
460
+
461
+
/color-name/1.1.4:
462
+
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
463
+
dev: true
464
+
465
+
/concat-map/0.0.1:
466
+
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
467
+
dev: true
468
+
469
+
/cross-spawn/7.0.6:
470
+
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
471
+
engines: {node: '>= 8'}
472
+
dependencies:
473
+
path-key: 3.1.1
474
+
shebang-command: 2.0.0
475
+
which: 2.0.2
476
+
dev: true
477
+
478
+
/debug/4.4.3:
479
+
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
480
+
engines: {node: '>=6.0'}
481
+
peerDependencies:
482
+
supports-color: '*'
483
+
peerDependenciesMeta:
484
+
supports-color:
485
+
optional: true
486
+
dependencies:
487
+
ms: 2.1.3
488
+
dev: true
489
+
490
+
/deep-is/0.1.4:
491
+
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
492
+
dev: true
493
+
494
+
/diff/8.0.2:
495
+
resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==}
496
+
engines: {node: '>=0.3.1'}
497
+
dev: true
498
+
499
+
/dom-serializer/2.0.0:
500
+
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
501
+
dependencies:
502
+
domelementtype: 2.3.0
503
+
domhandler: 5.0.3
504
+
entities: 4.5.0
505
+
dev: true
506
+
507
+
/domelementtype/2.3.0:
508
+
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
509
+
dev: true
510
+
511
+
/domhandler/5.0.3:
512
+
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
513
+
engines: {node: '>= 4'}
514
+
dependencies:
515
+
domelementtype: 2.3.0
516
+
dev: true
517
+
518
+
/domutils/3.2.2:
519
+
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
520
+
dependencies:
521
+
dom-serializer: 2.0.0
522
+
domelementtype: 2.3.0
523
+
domhandler: 5.0.3
524
+
dev: true
525
+
526
+
/entities/4.5.0:
527
+
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
528
+
engines: {node: '>=0.12'}
529
+
dev: true
530
+
531
+
/entities/6.0.1:
532
+
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
533
+
engines: {node: '>=0.12'}
534
+
dev: true
535
+
536
+
/esbuild/0.25.11:
537
+
resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==}
538
+
engines: {node: '>=18'}
539
+
hasBin: true
540
+
requiresBuild: true
541
+
optionalDependencies:
542
+
'@esbuild/aix-ppc64': 0.25.11
543
+
'@esbuild/android-arm': 0.25.11
544
+
'@esbuild/android-arm64': 0.25.11
545
+
'@esbuild/android-x64': 0.25.11
546
+
'@esbuild/darwin-arm64': 0.25.11
547
+
'@esbuild/darwin-x64': 0.25.11
548
+
'@esbuild/freebsd-arm64': 0.25.11
549
+
'@esbuild/freebsd-x64': 0.25.11
550
+
'@esbuild/linux-arm': 0.25.11
551
+
'@esbuild/linux-arm64': 0.25.11
552
+
'@esbuild/linux-ia32': 0.25.11
553
+
'@esbuild/linux-loong64': 0.25.11
554
+
'@esbuild/linux-mips64el': 0.25.11
555
+
'@esbuild/linux-ppc64': 0.25.11
556
+
'@esbuild/linux-riscv64': 0.25.11
557
+
'@esbuild/linux-s390x': 0.25.11
558
+
'@esbuild/linux-x64': 0.25.11
559
+
'@esbuild/netbsd-arm64': 0.25.11
560
+
'@esbuild/netbsd-x64': 0.25.11
561
+
'@esbuild/openbsd-arm64': 0.25.11
562
+
'@esbuild/openbsd-x64': 0.25.11
563
+
'@esbuild/openharmony-arm64': 0.25.11
564
+
'@esbuild/sunos-x64': 0.25.11
565
+
'@esbuild/win32-arm64': 0.25.11
566
+
'@esbuild/win32-ia32': 0.25.11
567
+
'@esbuild/win32-x64': 0.25.11
568
+
dev: true
569
+
570
+
/escape-string-regexp/4.0.0:
571
+
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
572
+
engines: {node: '>=10'}
573
+
dev: true
574
+
575
+
/eslint-scope/8.4.0:
576
+
resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
577
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
578
+
dependencies:
579
+
esrecurse: 4.3.0
580
+
estraverse: 5.3.0
581
+
dev: true
582
+
583
+
/eslint-visitor-keys/3.4.3:
584
+
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
585
+
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
586
+
dev: true
587
+
588
+
/eslint-visitor-keys/4.2.1:
589
+
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
590
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
591
+
dev: true
592
+
593
+
/eslint/9.38.0:
594
+
resolution: {integrity: sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==}
595
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
596
+
hasBin: true
597
+
peerDependencies:
598
+
jiti: '*'
599
+
peerDependenciesMeta:
600
+
jiti:
601
+
optional: true
602
+
dependencies:
603
+
'@eslint-community/eslint-utils': 4.9.0_eslint@9.38.0
604
+
'@eslint-community/regexpp': 4.12.2
605
+
'@eslint/config-array': 0.21.1
606
+
'@eslint/config-helpers': 0.4.2
607
+
'@eslint/core': 0.16.0
608
+
'@eslint/eslintrc': 3.3.1
609
+
'@eslint/js': 9.38.0
610
+
'@eslint/plugin-kit': 0.4.1
611
+
'@humanfs/node': 0.16.7
612
+
'@humanwhocodes/module-importer': 1.0.1
613
+
'@humanwhocodes/retry': 0.4.3
614
+
'@types/estree': 1.0.8
615
+
ajv: 6.12.6
616
+
chalk: 4.1.2
617
+
cross-spawn: 7.0.6
618
+
debug: 4.4.3
619
+
escape-string-regexp: 4.0.0
620
+
eslint-scope: 8.4.0
621
+
eslint-visitor-keys: 4.2.1
622
+
espree: 10.4.0
623
+
esquery: 1.6.0
624
+
esutils: 2.0.3
625
+
fast-deep-equal: 3.1.3
626
+
file-entry-cache: 8.0.0
627
+
find-up: 5.0.0
628
+
glob-parent: 6.0.2
629
+
ignore: 5.3.2
630
+
imurmurhash: 0.1.4
631
+
is-glob: 4.0.3
632
+
json-stable-stringify-without-jsonify: 1.0.1
633
+
lodash.merge: 4.6.2
634
+
minimatch: 3.1.2
635
+
natural-compare: 1.4.0
636
+
optionator: 0.9.4
637
+
transitivePeerDependencies:
638
+
- supports-color
639
+
dev: true
640
+
641
+
/espree/10.4.0:
642
+
resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
643
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
644
+
dependencies:
645
+
acorn: 8.15.0
646
+
acorn-jsx: 5.3.2_acorn@8.15.0
647
+
eslint-visitor-keys: 4.2.1
648
+
dev: true
649
+
650
+
/esquery/1.6.0:
651
+
resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
652
+
engines: {node: '>=0.10'}
653
+
dependencies:
654
+
estraverse: 5.3.0
655
+
dev: true
656
+
657
+
/esrecurse/4.3.0:
658
+
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
659
+
engines: {node: '>=4.0'}
660
+
dependencies:
661
+
estraverse: 5.3.0
662
+
dev: true
663
+
664
+
/estraverse/5.3.0:
665
+
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
666
+
engines: {node: '>=4.0'}
667
+
dev: true
668
+
669
+
/esutils/2.0.3:
670
+
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
671
+
engines: {node: '>=0.10.0'}
672
+
dev: true
673
+
674
+
/fast-deep-equal/3.1.3:
675
+
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
676
+
dev: true
677
+
678
+
/fast-json-stable-stringify/2.1.0:
679
+
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
680
+
dev: true
681
+
682
+
/fast-levenshtein/2.0.6:
683
+
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
684
+
dev: true
685
+
686
+
/fdir/6.5.0_picomatch@4.0.3:
687
+
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
688
+
engines: {node: '>=12.0.0'}
689
+
peerDependencies:
690
+
picomatch: ^3 || ^4
691
+
peerDependenciesMeta:
692
+
picomatch:
693
+
optional: true
694
+
dependencies:
695
+
picomatch: 4.0.3
696
+
dev: true
697
+
698
+
/file-entry-cache/8.0.0:
699
+
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
700
+
engines: {node: '>=16.0.0'}
701
+
dependencies:
702
+
flat-cache: 4.0.1
703
+
dev: true
704
+
705
+
/fill-range/7.1.1:
706
+
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
707
+
engines: {node: '>=8'}
708
+
dependencies:
709
+
to-regex-range: 5.0.1
710
+
dev: true
711
+
712
+
/find-up/5.0.0:
713
+
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
714
+
engines: {node: '>=10'}
715
+
dependencies:
716
+
locate-path: 6.0.0
717
+
path-exists: 4.0.0
718
+
dev: true
719
+
720
+
/flat-cache/4.0.1:
721
+
resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
722
+
engines: {node: '>=16'}
723
+
dependencies:
724
+
flatted: 3.3.3
725
+
keyv: 4.5.4
726
+
dev: true
727
+
728
+
/flatted/3.3.3:
729
+
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
730
+
dev: true
731
+
732
+
/fsevents/2.3.3:
733
+
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
734
+
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
735
+
os: [darwin]
736
+
requiresBuild: true
737
+
dev: true
738
+
optional: true
739
+
740
+
/glob-parent/6.0.2:
741
+
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
742
+
engines: {node: '>=10.13.0'}
743
+
dependencies:
744
+
is-glob: 4.0.3
745
+
dev: true
746
+
747
+
/globals/14.0.0:
748
+
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
749
+
engines: {node: '>=18'}
750
+
dev: true
751
+
752
+
/globals/16.4.0:
753
+
resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==}
754
+
engines: {node: '>=18'}
755
+
dev: true
756
+
757
+
/has-flag/4.0.0:
758
+
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
759
+
engines: {node: '>=8'}
760
+
dev: true
761
+
762
+
/htmlparser2/10.0.0:
763
+
resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==}
764
+
dependencies:
765
+
domelementtype: 2.3.0
766
+
domhandler: 5.0.3
767
+
domutils: 3.2.2
768
+
entities: 6.0.1
769
+
dev: true
770
+
771
+
/htmlparser2/9.1.0:
772
+
resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
773
+
dependencies:
774
+
domelementtype: 2.3.0
775
+
domhandler: 5.0.3
776
+
domutils: 3.2.2
777
+
entities: 4.5.0
778
+
dev: true
779
+
780
+
/ignore/5.3.2:
781
+
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
782
+
engines: {node: '>= 4'}
783
+
dev: true
784
+
785
+
/import-fresh/3.3.1:
786
+
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
787
+
engines: {node: '>=6'}
788
+
dependencies:
789
+
parent-module: 1.0.1
790
+
resolve-from: 4.0.0
791
+
dev: true
792
+
793
+
/imurmurhash/0.1.4:
794
+
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
795
+
engines: {node: '>=0.8.19'}
796
+
dev: true
797
+
798
+
/is-extglob/2.1.1:
799
+
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
800
+
engines: {node: '>=0.10.0'}
801
+
dev: true
802
+
803
+
/is-glob/4.0.3:
804
+
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
805
+
engines: {node: '>=0.10.0'}
806
+
dependencies:
807
+
is-extglob: 2.1.1
808
+
dev: true
809
+
810
+
/is-number/7.0.0:
811
+
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
812
+
engines: {node: '>=0.12.0'}
813
+
dev: true
814
+
815
+
/isexe/2.0.0:
816
+
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
817
+
dev: true
818
+
819
+
/js-yaml/4.1.0:
820
+
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
821
+
hasBin: true
822
+
dependencies:
823
+
argparse: 2.0.1
824
+
dev: true
825
+
826
+
/json-buffer/3.0.1:
827
+
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
828
+
dev: true
829
+
830
+
/json-schema-traverse/0.4.1:
831
+
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
832
+
dev: true
833
+
834
+
/json-stable-stringify-without-jsonify/1.0.1:
835
+
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
836
+
dev: true
837
+
838
+
/keyv/4.5.4:
839
+
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
840
+
dependencies:
841
+
json-buffer: 3.0.1
842
+
dev: true
843
+
844
+
/levn/0.4.1:
845
+
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
846
+
engines: {node: '>= 0.8.0'}
847
+
dependencies:
848
+
prelude-ls: 1.2.1
849
+
type-check: 0.4.0
850
+
dev: true
851
+
852
+
/locate-path/6.0.0:
853
+
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
854
+
engines: {node: '>=10'}
855
+
dependencies:
856
+
p-locate: 5.0.0
857
+
dev: true
858
+
859
+
/lodash.merge/4.6.2:
860
+
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
861
+
dev: true
862
+
863
+
/micromatch/4.0.8:
864
+
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
865
+
engines: {node: '>=8.6'}
866
+
dependencies:
867
+
braces: 3.0.3
868
+
picomatch: 2.3.1
869
+
dev: true
870
+
871
+
/minimatch/3.1.2:
872
+
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
873
+
dependencies:
874
+
brace-expansion: 1.1.12
875
+
dev: true
876
+
877
+
/ms/2.1.3:
878
+
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
879
+
dev: true
880
+
881
+
/nanoid/3.3.11:
882
+
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
883
+
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
884
+
hasBin: true
885
+
dev: true
886
+
887
+
/natural-compare/1.4.0:
888
+
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
889
+
dev: true
890
+
891
+
/optionator/0.9.4:
892
+
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
893
+
engines: {node: '>= 0.8.0'}
894
+
dependencies:
895
+
deep-is: 0.1.4
896
+
fast-levenshtein: 2.0.6
897
+
levn: 0.4.1
898
+
prelude-ls: 1.2.1
899
+
type-check: 0.4.0
900
+
word-wrap: 1.2.5
901
+
dev: true
902
+
903
+
/p-limit/3.1.0:
904
+
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
905
+
engines: {node: '>=10'}
906
+
dependencies:
907
+
yocto-queue: 0.1.0
908
+
dev: true
909
+
910
+
/p-locate/5.0.0:
911
+
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
912
+
engines: {node: '>=10'}
913
+
dependencies:
914
+
p-limit: 3.1.0
915
+
dev: true
916
+
917
+
/parent-module/1.0.1:
918
+
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
919
+
engines: {node: '>=6'}
920
+
dependencies:
921
+
callsites: 3.1.0
922
+
dev: true
923
+
924
+
/path-exists/4.0.0:
925
+
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
926
+
engines: {node: '>=8'}
927
+
dev: true
928
+
929
+
/path-key/3.1.1:
930
+
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
931
+
engines: {node: '>=8'}
932
+
dev: true
933
+
934
+
/picocolors/1.1.1:
935
+
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
936
+
dev: true
937
+
938
+
/picomatch/2.3.1:
939
+
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
940
+
engines: {node: '>=8.6'}
941
+
dev: true
942
+
943
+
/picomatch/4.0.3:
944
+
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
945
+
engines: {node: '>=12'}
946
+
dev: true
947
+
948
+
/postcss/8.5.6:
949
+
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
950
+
engines: {node: ^10 || ^12 || >=14}
951
+
dependencies:
952
+
nanoid: 3.3.11
953
+
picocolors: 1.1.1
954
+
source-map-js: 1.2.1
955
+
dev: true
956
+
957
+
/prelude-ls/1.2.1:
958
+
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
959
+
engines: {node: '>= 0.8.0'}
960
+
dev: true
961
+
962
+
/punycode/2.3.1:
963
+
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
964
+
engines: {node: '>=6'}
965
+
dev: true
966
+
967
+
/resolve-from/4.0.0:
968
+
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
969
+
engines: {node: '>=4'}
970
+
dev: true
971
+
972
+
/shebang-command/2.0.0:
973
+
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
974
+
engines: {node: '>=8'}
975
+
dependencies:
976
+
shebang-regex: 3.0.0
977
+
dev: true
978
+
979
+
/shebang-regex/3.0.0:
980
+
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
981
+
engines: {node: '>=8'}
982
+
dev: true
983
+
984
+
/source-map-js/1.2.1:
985
+
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
986
+
engines: {node: '>=0.10.0'}
987
+
dev: true
988
+
989
+
/strip-json-comments/3.1.1:
990
+
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
991
+
engines: {node: '>=8'}
992
+
dev: true
993
+
994
+
/supports-color/7.2.0:
995
+
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
996
+
engines: {node: '>=8'}
997
+
dependencies:
998
+
has-flag: 4.0.0
999
+
dev: true
1000
+
1001
+
/tinyglobby/0.2.15:
1002
+
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
1003
+
engines: {node: '>=12.0.0'}
1004
+
dependencies:
1005
+
fdir: 6.5.0_picomatch@4.0.3
1006
+
picomatch: 4.0.3
1007
+
dev: true
1008
+
1009
+
/to-regex-range/5.0.1:
1010
+
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1011
+
engines: {node: '>=8.0'}
1012
+
dependencies:
1013
+
is-number: 7.0.0
1014
+
dev: true
1015
+
1016
+
/type-check/0.4.0:
1017
+
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
1018
+
engines: {node: '>= 0.8.0'}
1019
+
dependencies:
1020
+
prelude-ls: 1.2.1
1021
+
dev: true
1022
+
1023
+
/uri-js/4.4.1:
1024
+
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
1025
+
dependencies:
1026
+
punycode: 2.3.1
1027
+
dev: true
1028
+
1029
+
/vite-plugin-dom/1.0.5_vite@7.1.12:
1030
+
resolution: {integrity: sha512-G3MbuH30FpBD800I26xlB6lUiDm7sCxvQkHPt9OAJyUEbyiO9UWrKADxVUhWbO65WqL/TGtH1OEez+w++TlfMw==}
1031
+
peerDependencies:
1032
+
vite: '>=4.0.0'
1033
+
dependencies:
1034
+
htmlparser2: 10.0.0
1035
+
vite: 7.1.12
1036
+
dev: true
1037
+
1038
+
/vite-plugin-singlefile/2.3.0_vite@7.1.12:
1039
+
resolution: {integrity: sha512-DAcHzYypM0CasNLSz/WG0VdKOCxGHErfrjOoyIPiNxTPTGmO6rRD/te93n1YL/s+miXq66ipF1brMBikf99c6A==}
1040
+
engines: {node: '>18.0.0'}
1041
+
peerDependencies:
1042
+
rollup: ^4.44.1
1043
+
vite: ^5.4.11 || ^6.0.0 || ^7.0.0
1044
+
dependencies:
1045
+
micromatch: 4.0.8
1046
+
vite: 7.1.12
1047
+
dev: true
1048
+
1049
+
/vite/7.1.12:
1050
+
resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==}
1051
+
engines: {node: ^20.19.0 || >=22.12.0}
1052
+
hasBin: true
1053
+
peerDependencies:
1054
+
'@types/node': ^20.19.0 || >=22.12.0
1055
+
jiti: '>=1.21.0'
1056
+
less: ^4.0.0
1057
+
lightningcss: ^1.21.0
1058
+
sass: ^1.70.0
1059
+
sass-embedded: ^1.70.0
1060
+
stylus: '>=0.54.8'
1061
+
sugarss: ^5.0.0
1062
+
terser: ^5.16.0
1063
+
tsx: ^4.8.1
1064
+
yaml: ^2.4.2
1065
+
peerDependenciesMeta:
1066
+
'@types/node':
1067
+
optional: true
1068
+
jiti:
1069
+
optional: true
1070
+
less:
1071
+
optional: true
1072
+
lightningcss:
1073
+
optional: true
1074
+
sass:
1075
+
optional: true
1076
+
sass-embedded:
1077
+
optional: true
1078
+
stylus:
1079
+
optional: true
1080
+
sugarss:
1081
+
optional: true
1082
+
terser:
1083
+
optional: true
1084
+
tsx:
1085
+
optional: true
1086
+
yaml:
1087
+
optional: true
1088
+
dependencies:
1089
+
esbuild: 0.25.11
1090
+
fdir: 6.5.0_picomatch@4.0.3
1091
+
picomatch: 4.0.3
1092
+
postcss: 8.5.6
1093
+
rollup: /@rollup/wasm-node/4.52.5
1094
+
tinyglobby: 0.2.15
1095
+
optionalDependencies:
1096
+
fsevents: 2.3.3
1097
+
dev: true
1098
+
1099
+
/which/2.0.2:
1100
+
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1101
+
engines: {node: '>= 8'}
1102
+
hasBin: true
1103
+
dependencies:
1104
+
isexe: 2.0.0
1105
+
dev: true
1106
+
1107
+
/word-wrap/1.2.5:
1108
+
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
1109
+
engines: {node: '>=0.10.0'}
1110
+
dev: true
1111
+
1112
+
/yocto-queue/0.1.0:
1113
+
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
1114
+
engines: {node: '>=10'}
1115
+
dev: true
+6
-5
release.sh
+6
-5
release.sh
···
1
#!/bin/sh
2
set -e
3
FILES="
4
-
asn1.js oids.js defs.js base64.js hex.js int10.js dom.js rfcdef.js test.js tags.js
5
-
context.js index.css index-dark.css index.js index.html index-local.html
6
favicon.svg tree-icon-light.svg tree-icon-dark.svg
7
-
README.md LICENSE
8
updateOID.sh check.sh
9
-
examples/*
10
"
11
mtn automate tags 'it.lapo.asn1js{,.*}' | \
12
awk '/^revision/ { print substr($2, 2, length($2) - 2)}' | \
···
29
type gsha256sum >/dev/null 2>/dev/null && SHA256=gsha256sum || SHA256=sha256sum
30
pnpm build
31
cp dist/index.html index-local.html
32
-
$SHA256 -t $FILES | gpg --clearsign > sha256sums.asc
33
7z a -tzip -mx=9 asn1js.zip $FILES sha256sums.asc
34
rsync -Pvrtz asn1js.zip $FILES lapo.it:www/asn1js/
···
1
#!/bin/sh
2
set -e
3
FILES="
4
+
asn1.js oids.js defs.js base64.js hex.js dom.js context.js theme.js
5
+
rfcdef.js test.js tags.js
6
+
index.html index.css index.js index-local.html
7
favicon.svg tree-icon-light.svg tree-icon-dark.svg
8
+
README.md LICENSE CHANGELOG.md
9
updateOID.sh check.sh
10
+
examples
11
"
12
mtn automate tags 'it.lapo.asn1js{,.*}' | \
13
awk '/^revision/ { print substr($2, 2, length($2) - 2)}' | \
···
30
type gsha256sum >/dev/null 2>/dev/null && SHA256=gsha256sum || SHA256=sha256sum
31
pnpm build
32
cp dist/index.html index-local.html
33
+
$SHA256 -t $FILES examples/* | gpg --clearsign > sha256sums.asc
34
7z a -tzip -mx=9 asn1js.zip $FILES sha256sums.asc
35
rsync -Pvrtz asn1js.zip $FILES lapo.it:www/asn1js/
+1503
-3
rfcdef.js
+1503
-3
rfcdef.js
···
1
-
// content parsed from ASN.1 definitions as found in the following RFCs: 5280 5208 3369 3161 2986 4211 4210 8017
2
// Copyright (C) The IETF Trust (2008)
3
// as far as I can tell this file is allowed under the following clause:
4
// It is acceptable under the current IETF rules (RFC 5378) to modify extracted code if necessary.
···
1983
"CountryName": {
1984
"name": "CountryName",
1985
"type": {
1986
-
"name": "[1]",
1987
"type": "tag",
1988
"class": "APPLICATION",
1989
"explicit": true,
···
2015
"AdministrationDomainName": {
2016
"name": "AdministrationDomainName",
2017
"type": {
2018
-
"name": "[2]",
2019
"type": "tag",
2020
"class": "APPLICATION",
2021
"explicit": true,
···
10369
"type": {
10370
"name": "AlgorithmIdentifier",
10371
"type": "defined"
10372
}
10373
}
10374
}
···
1
+
// content parsed from ASN.1 definitions as found in the following RFCs: 5280 5208 3369 3161 2986 4211 4210 8017 4511
2
// Copyright (C) The IETF Trust (2008)
3
// as far as I can tell this file is allowed under the following clause:
4
// It is acceptable under the current IETF rules (RFC 5378) to modify extracted code if necessary.
···
1983
"CountryName": {
1984
"name": "CountryName",
1985
"type": {
1986
+
"name": "Application 1",
1987
"type": "tag",
1988
"class": "APPLICATION",
1989
"explicit": true,
···
2015
"AdministrationDomainName": {
2016
"name": "AdministrationDomainName",
2017
"type": {
2018
+
"name": "Application 2",
2019
"type": "tag",
2020
"class": "APPLICATION",
2021
"explicit": true,
···
10369
"type": {
10370
"name": "AlgorithmIdentifier",
10371
"type": "defined"
10372
+
}
10373
+
}
10374
+
}
10375
+
},
10376
+
"1.3.6.1.1.18": {
10377
+
"name": "Lightweight-Directory-Access-Protocol-V3",
10378
+
"oid": "1.3.6.1.1.18",
10379
+
"source": "rfc4511.txt",
10380
+
"tagDefault": "IMPLICIT",
10381
+
"values": {
10382
+
"maxInt": {
10383
+
"name": "maxInt",
10384
+
"type": {
10385
+
"name": "INTEGER",
10386
+
"type": "builtin"
10387
+
},
10388
+
"value": 2147483647
10389
+
}
10390
+
},
10391
+
"types": {
10392
+
"LDAPMessage": {
10393
+
"name": "LDAPMessage",
10394
+
"type": {
10395
+
"name": "SEQUENCE",
10396
+
"type": "builtin",
10397
+
"content": [
10398
+
{
10399
+
"id": "messageID",
10400
+
"name": "MessageID",
10401
+
"type": "defined"
10402
+
},
10403
+
{
10404
+
"id": "protocolOp",
10405
+
"name": "CHOICE",
10406
+
"type": "builtin",
10407
+
"content": [
10408
+
{
10409
+
"id": "bindRequest",
10410
+
"name": "BindRequest",
10411
+
"type": "defined"
10412
+
},
10413
+
{
10414
+
"id": "bindResponse",
10415
+
"name": "BindResponse",
10416
+
"type": "defined"
10417
+
},
10418
+
{
10419
+
"id": "unbindRequest",
10420
+
"name": "UnbindRequest",
10421
+
"type": "defined"
10422
+
},
10423
+
{
10424
+
"id": "searchRequest",
10425
+
"name": "SearchRequest",
10426
+
"type": "defined"
10427
+
},
10428
+
{
10429
+
"id": "searchResEntry",
10430
+
"name": "SearchResultEntry",
10431
+
"type": "defined"
10432
+
},
10433
+
{
10434
+
"id": "searchResDone",
10435
+
"name": "SearchResultDone",
10436
+
"type": "defined"
10437
+
},
10438
+
{
10439
+
"id": "searchResRef",
10440
+
"name": "SearchResultReference",
10441
+
"type": "defined"
10442
+
},
10443
+
{
10444
+
"id": "modifyRequest",
10445
+
"name": "ModifyRequest",
10446
+
"type": "defined"
10447
+
},
10448
+
{
10449
+
"id": "modifyResponse",
10450
+
"name": "ModifyResponse",
10451
+
"type": "defined"
10452
+
},
10453
+
{
10454
+
"id": "addRequest",
10455
+
"name": "AddRequest",
10456
+
"type": "defined"
10457
+
},
10458
+
{
10459
+
"id": "addResponse",
10460
+
"name": "AddResponse",
10461
+
"type": "defined"
10462
+
},
10463
+
{
10464
+
"id": "delRequest",
10465
+
"name": "DelRequest",
10466
+
"type": "defined"
10467
+
},
10468
+
{
10469
+
"id": "delResponse",
10470
+
"name": "DelResponse",
10471
+
"type": "defined"
10472
+
},
10473
+
{
10474
+
"id": "modDNRequest",
10475
+
"name": "ModifyDNRequest",
10476
+
"type": "defined"
10477
+
},
10478
+
{
10479
+
"id": "modDNResponse",
10480
+
"name": "ModifyDNResponse",
10481
+
"type": "defined"
10482
+
},
10483
+
{
10484
+
"id": "compareRequest",
10485
+
"name": "CompareRequest",
10486
+
"type": "defined"
10487
+
},
10488
+
{
10489
+
"id": "compareResponse",
10490
+
"name": "CompareResponse",
10491
+
"type": "defined"
10492
+
},
10493
+
{
10494
+
"id": "abandonRequest",
10495
+
"name": "AbandonRequest",
10496
+
"type": "defined"
10497
+
},
10498
+
{
10499
+
"id": "extendedReq",
10500
+
"name": "ExtendedRequest",
10501
+
"type": "defined"
10502
+
},
10503
+
{
10504
+
"id": "extendedResp",
10505
+
"name": "ExtendedResponse",
10506
+
"type": "defined"
10507
+
},
10508
+
{
10509
+
"id": "intermediateResponse",
10510
+
"name": "IntermediateResponse",
10511
+
"type": "defined"
10512
+
}
10513
+
]
10514
+
},
10515
+
{
10516
+
"id": "controls",
10517
+
"name": "[0]",
10518
+
"type": "tag",
10519
+
"class": "CONTEXT",
10520
+
"explicit": false,
10521
+
"content": [
10522
+
{
10523
+
"name": "",
10524
+
"type": {
10525
+
"name": "Controls",
10526
+
"type": "defined"
10527
+
}
10528
+
}
10529
+
],
10530
+
"optional": true
10531
+
}
10532
+
]
10533
+
}
10534
+
},
10535
+
"MessageID": {
10536
+
"name": "MessageID",
10537
+
"type": {
10538
+
"name": "INTEGER",
10539
+
"type": "builtin",
10540
+
"range": [
10541
+
0,
10542
+
"maxInt"
10543
+
]
10544
+
}
10545
+
},
10546
+
"LDAPString": {
10547
+
"name": "LDAPString",
10548
+
"type": {
10549
+
"name": "OCTET STRING",
10550
+
"type": "builtin"
10551
+
}
10552
+
},
10553
+
"LDAPOID": {
10554
+
"name": "LDAPOID",
10555
+
"type": {
10556
+
"name": "OCTET STRING",
10557
+
"type": "builtin"
10558
+
}
10559
+
},
10560
+
"LDAPDN": {
10561
+
"name": "LDAPDN",
10562
+
"type": {
10563
+
"name": "LDAPString",
10564
+
"type": "defined"
10565
+
}
10566
+
},
10567
+
"RelativeLDAPDN": {
10568
+
"name": "RelativeLDAPDN",
10569
+
"type": {
10570
+
"name": "LDAPString",
10571
+
"type": "defined"
10572
+
}
10573
+
},
10574
+
"AttributeDescription": {
10575
+
"name": "AttributeDescription",
10576
+
"type": {
10577
+
"name": "LDAPString",
10578
+
"type": "defined"
10579
+
}
10580
+
},
10581
+
"AttributeValue": {
10582
+
"name": "AttributeValue",
10583
+
"type": {
10584
+
"name": "OCTET STRING",
10585
+
"type": "builtin"
10586
+
}
10587
+
},
10588
+
"AttributeValueAssertion": {
10589
+
"name": "AttributeValueAssertion",
10590
+
"type": {
10591
+
"name": "SEQUENCE",
10592
+
"type": "builtin",
10593
+
"content": [
10594
+
{
10595
+
"id": "attributeDesc",
10596
+
"name": "AttributeDescription",
10597
+
"type": "defined"
10598
+
},
10599
+
{
10600
+
"id": "assertionValue",
10601
+
"name": "AssertionValue",
10602
+
"type": "defined"
10603
+
}
10604
+
]
10605
+
}
10606
+
},
10607
+
"AssertionValue": {
10608
+
"name": "AssertionValue",
10609
+
"type": {
10610
+
"name": "OCTET STRING",
10611
+
"type": "builtin"
10612
+
}
10613
+
},
10614
+
"PartialAttribute": {
10615
+
"name": "PartialAttribute",
10616
+
"type": {
10617
+
"name": "SEQUENCE",
10618
+
"type": "builtin",
10619
+
"content": [
10620
+
{
10621
+
"id": "type",
10622
+
"name": "AttributeDescription",
10623
+
"type": "defined"
10624
+
},
10625
+
{
10626
+
"id": "vals",
10627
+
"name": "SET",
10628
+
"type": "builtin",
10629
+
"typeOf": 1,
10630
+
"size": [
10631
+
1,
10632
+
"MAX"
10633
+
],
10634
+
"content": [
10635
+
{
10636
+
"name": "AttributeValue",
10637
+
"type": "defined"
10638
+
}
10639
+
]
10640
+
}
10641
+
]
10642
+
}
10643
+
},
10644
+
"MatchingRuleId": {
10645
+
"name": "MatchingRuleId",
10646
+
"type": {
10647
+
"name": "LDAPString",
10648
+
"type": "defined"
10649
+
}
10650
+
},
10651
+
"LDAPResult": {
10652
+
"name": "LDAPResult",
10653
+
"type": {
10654
+
"name": "SEQUENCE",
10655
+
"type": "builtin",
10656
+
"content": [
10657
+
{
10658
+
"id": "resultCode",
10659
+
"name": "ENUMERATED",
10660
+
"type": "builtin",
10661
+
"content": {
10662
+
"success": 0,
10663
+
"operationsError": 1,
10664
+
"protocolError": 2,
10665
+
"timeLimitExceeded": 3,
10666
+
"sizeLimitExceeded": 4,
10667
+
"compareFalse": 5,
10668
+
"compareTrue": 6,
10669
+
"authMethodNotSupported": 7,
10670
+
"strongerAuthRequired": 8,
10671
+
"referral": 10,
10672
+
"adminLimitExceeded": 11,
10673
+
"unavailableCriticalExtension": 12,
10674
+
"confidentialityRequired": 13,
10675
+
"saslBindInProgress": 14,
10676
+
"noSuchAttribute": 16,
10677
+
"undefinedAttributeType": 17,
10678
+
"inappropriateMatching": 18,
10679
+
"constraintViolation": 19,
10680
+
"attributeOrValueExists": 20,
10681
+
"invalidAttributeSyntax": 21,
10682
+
"noSuchObject": 32,
10683
+
"aliasProblem": 33,
10684
+
"invalidDNSyntax": 34,
10685
+
"aliasDereferencingProblem": 36,
10686
+
"inappropriateAuthentication": 48,
10687
+
"invalidCredentials": 49,
10688
+
"insufficientAccessRights": 50,
10689
+
"busy": 51,
10690
+
"unavailable": 52,
10691
+
"unwillingToPerform": 53,
10692
+
"loopDetect": 54,
10693
+
"namingViolation": 64,
10694
+
"objectClassViolation": 65,
10695
+
"notAllowedOnNonLeaf": 66,
10696
+
"notAllowedOnRDN": 67,
10697
+
"entryAlreadyExists": 68,
10698
+
"objectClassModsProhibited": 69,
10699
+
"affectsMultipleDSAs": 71,
10700
+
"other": 80
10701
+
}
10702
+
},
10703
+
{
10704
+
"id": "matchedDN",
10705
+
"name": "LDAPDN",
10706
+
"type": "defined"
10707
+
},
10708
+
{
10709
+
"id": "diagnosticMessage",
10710
+
"name": "LDAPString",
10711
+
"type": "defined"
10712
+
},
10713
+
{
10714
+
"id": "referral",
10715
+
"name": "[3]",
10716
+
"type": "tag",
10717
+
"class": "CONTEXT",
10718
+
"explicit": false,
10719
+
"content": [
10720
+
{
10721
+
"name": "",
10722
+
"type": {
10723
+
"name": "Referral",
10724
+
"type": "defined"
10725
+
}
10726
+
}
10727
+
],
10728
+
"optional": true
10729
+
}
10730
+
]
10731
+
}
10732
+
},
10733
+
"Referral": {
10734
+
"name": "Referral",
10735
+
"type": {
10736
+
"name": "SEQUENCE",
10737
+
"type": "builtin",
10738
+
"typeOf": 1,
10739
+
"size": [
10740
+
1,
10741
+
"MAX"
10742
+
],
10743
+
"content": [
10744
+
{
10745
+
"name": "URI",
10746
+
"type": "defined"
10747
+
}
10748
+
]
10749
+
}
10750
+
},
10751
+
"URI": {
10752
+
"name": "URI",
10753
+
"type": {
10754
+
"name": "LDAPString",
10755
+
"type": "defined"
10756
+
}
10757
+
},
10758
+
"Controls": {
10759
+
"name": "Controls",
10760
+
"type": {
10761
+
"name": "SEQUENCE",
10762
+
"type": "builtin",
10763
+
"typeOf": 1,
10764
+
"content": [
10765
+
{
10766
+
"name": "Control",
10767
+
"type": "defined"
10768
+
}
10769
+
]
10770
+
}
10771
+
},
10772
+
"Control": {
10773
+
"name": "Control",
10774
+
"type": {
10775
+
"name": "SEQUENCE",
10776
+
"type": "builtin",
10777
+
"content": [
10778
+
{
10779
+
"id": "controlType",
10780
+
"name": "LDAPOID",
10781
+
"type": "defined"
10782
+
},
10783
+
{
10784
+
"id": "criticality",
10785
+
"name": "BOOLEAN",
10786
+
"type": "builtin",
10787
+
"default": false
10788
+
},
10789
+
{
10790
+
"id": "controlValue",
10791
+
"name": "OCTET STRING",
10792
+
"type": "builtin",
10793
+
"optional": true
10794
+
}
10795
+
]
10796
+
}
10797
+
},
10798
+
"BindRequest": {
10799
+
"name": "BindRequest",
10800
+
"type": {
10801
+
"name": "Application 0",
10802
+
"type": "tag",
10803
+
"class": "APPLICATION",
10804
+
"explicit": false,
10805
+
"content": [
10806
+
{
10807
+
"name": "",
10808
+
"type": {
10809
+
"name": "SEQUENCE",
10810
+
"type": "builtin",
10811
+
"content": [
10812
+
{
10813
+
"id": "version",
10814
+
"name": "INTEGER",
10815
+
"type": "builtin",
10816
+
"range": [
10817
+
1,
10818
+
127
10819
+
]
10820
+
},
10821
+
{
10822
+
"id": "name",
10823
+
"name": "LDAPDN",
10824
+
"type": "defined"
10825
+
},
10826
+
{
10827
+
"id": "authentication",
10828
+
"name": "AuthenticationChoice",
10829
+
"type": "defined"
10830
+
}
10831
+
]
10832
+
}
10833
+
}
10834
+
]
10835
+
}
10836
+
},
10837
+
"AuthenticationChoice": {
10838
+
"name": "AuthenticationChoice",
10839
+
"type": {
10840
+
"name": "CHOICE",
10841
+
"type": "builtin",
10842
+
"content": [
10843
+
{
10844
+
"id": "simple",
10845
+
"name": "[0]",
10846
+
"type": "tag",
10847
+
"class": "CONTEXT",
10848
+
"explicit": false,
10849
+
"content": [
10850
+
{
10851
+
"name": "",
10852
+
"type": {
10853
+
"name": "OCTET STRING",
10854
+
"type": "builtin"
10855
+
}
10856
+
}
10857
+
]
10858
+
},
10859
+
{
10860
+
"id": "sasl",
10861
+
"name": "[3]",
10862
+
"type": "tag",
10863
+
"class": "CONTEXT",
10864
+
"explicit": false,
10865
+
"content": [
10866
+
{
10867
+
"name": "",
10868
+
"type": {
10869
+
"name": "SaslCredentials",
10870
+
"type": "defined"
10871
+
}
10872
+
}
10873
+
]
10874
+
}
10875
+
]
10876
+
}
10877
+
},
10878
+
"SaslCredentials": {
10879
+
"name": "SaslCredentials",
10880
+
"type": {
10881
+
"name": "SEQUENCE",
10882
+
"type": "builtin",
10883
+
"content": [
10884
+
{
10885
+
"id": "mechanism",
10886
+
"name": "LDAPString",
10887
+
"type": "defined"
10888
+
},
10889
+
{
10890
+
"id": "credentials",
10891
+
"name": "OCTET STRING",
10892
+
"type": "builtin",
10893
+
"optional": true
10894
+
}
10895
+
]
10896
+
}
10897
+
},
10898
+
"BindResponse": {
10899
+
"name": "BindResponse",
10900
+
"type": {
10901
+
"name": "ANY",
10902
+
"type": "builtin"
10903
+
}
10904
+
},
10905
+
"UnbindRequest": {
10906
+
"name": "UnbindRequest",
10907
+
"type": {
10908
+
"name": "Application 2",
10909
+
"type": "tag",
10910
+
"class": "APPLICATION",
10911
+
"explicit": false,
10912
+
"content": [
10913
+
{
10914
+
"name": "",
10915
+
"type": {
10916
+
"name": "NULL",
10917
+
"type": "builtin"
10918
+
}
10919
+
}
10920
+
]
10921
+
}
10922
+
},
10923
+
"SearchRequest": {
10924
+
"name": "SearchRequest",
10925
+
"type": {
10926
+
"name": "Application 3",
10927
+
"type": "tag",
10928
+
"class": "APPLICATION",
10929
+
"explicit": false,
10930
+
"content": [
10931
+
{
10932
+
"name": "",
10933
+
"type": {
10934
+
"name": "SEQUENCE",
10935
+
"type": "builtin",
10936
+
"content": [
10937
+
{
10938
+
"id": "baseObject",
10939
+
"name": "LDAPDN",
10940
+
"type": "defined"
10941
+
},
10942
+
{
10943
+
"id": "scope",
10944
+
"name": "ENUMERATED",
10945
+
"type": "builtin",
10946
+
"content": {
10947
+
"baseObject": 0,
10948
+
"singleLevel": 1,
10949
+
"wholeSubtree": 2
10950
+
}
10951
+
},
10952
+
{
10953
+
"id": "derefAliases",
10954
+
"name": "ENUMERATED",
10955
+
"type": "builtin",
10956
+
"content": {
10957
+
"neverDerefAliases": 0,
10958
+
"derefInSearching": 1,
10959
+
"derefFindingBaseObj": 2,
10960
+
"derefAlways": 3
10961
+
}
10962
+
},
10963
+
{
10964
+
"id": "sizeLimit",
10965
+
"name": "INTEGER",
10966
+
"type": "builtin",
10967
+
"range": [
10968
+
0,
10969
+
"maxInt"
10970
+
]
10971
+
},
10972
+
{
10973
+
"id": "timeLimit",
10974
+
"name": "INTEGER",
10975
+
"type": "builtin",
10976
+
"range": [
10977
+
0,
10978
+
"maxInt"
10979
+
]
10980
+
},
10981
+
{
10982
+
"id": "typesOnly",
10983
+
"name": "BOOLEAN",
10984
+
"type": "builtin"
10985
+
},
10986
+
{
10987
+
"id": "filter",
10988
+
"name": "Filter",
10989
+
"type": "defined"
10990
+
},
10991
+
{
10992
+
"id": "attributes",
10993
+
"name": "AttributeSelection",
10994
+
"type": "defined"
10995
+
}
10996
+
]
10997
+
}
10998
+
}
10999
+
]
11000
+
}
11001
+
},
11002
+
"AttributeSelection": {
11003
+
"name": "AttributeSelection",
11004
+
"type": {
11005
+
"name": "SEQUENCE",
11006
+
"type": "builtin",
11007
+
"typeOf": 1,
11008
+
"content": [
11009
+
{
11010
+
"name": "LDAPString",
11011
+
"type": "defined"
11012
+
}
11013
+
]
11014
+
}
11015
+
},
11016
+
"Filter": {
11017
+
"name": "Filter",
11018
+
"type": {
11019
+
"name": "CHOICE",
11020
+
"type": "builtin",
11021
+
"content": [
11022
+
{
11023
+
"id": "and",
11024
+
"name": "[0]",
11025
+
"type": "tag",
11026
+
"class": "CONTEXT",
11027
+
"explicit": false,
11028
+
"content": [
11029
+
{
11030
+
"name": "",
11031
+
"type": {
11032
+
"name": "SET",
11033
+
"type": "builtin",
11034
+
"typeOf": 1,
11035
+
"size": [
11036
+
1,
11037
+
"MAX"
11038
+
],
11039
+
"content": [
11040
+
{
11041
+
"name": "Filter",
11042
+
"type": "defined"
11043
+
}
11044
+
]
11045
+
}
11046
+
}
11047
+
]
11048
+
},
11049
+
{
11050
+
"id": "or",
11051
+
"name": "[1]",
11052
+
"type": "tag",
11053
+
"class": "CONTEXT",
11054
+
"explicit": false,
11055
+
"content": [
11056
+
{
11057
+
"name": "",
11058
+
"type": {
11059
+
"name": "SET",
11060
+
"type": "builtin",
11061
+
"typeOf": 1,
11062
+
"size": [
11063
+
1,
11064
+
"MAX"
11065
+
],
11066
+
"content": [
11067
+
{
11068
+
"name": "Filter",
11069
+
"type": "defined"
11070
+
}
11071
+
]
11072
+
}
11073
+
}
11074
+
]
11075
+
},
11076
+
{
11077
+
"id": "not",
11078
+
"name": "[2]",
11079
+
"type": "tag",
11080
+
"class": "CONTEXT",
11081
+
"explicit": false,
11082
+
"content": [
11083
+
{
11084
+
"name": "",
11085
+
"type": {
11086
+
"name": "Filter",
11087
+
"type": "defined"
11088
+
}
11089
+
}
11090
+
]
11091
+
},
11092
+
{
11093
+
"id": "equalityMatch",
11094
+
"name": "[3]",
11095
+
"type": "tag",
11096
+
"class": "CONTEXT",
11097
+
"explicit": false,
11098
+
"content": [
11099
+
{
11100
+
"name": "",
11101
+
"type": {
11102
+
"name": "AttributeValueAssertion",
11103
+
"type": "defined"
11104
+
}
11105
+
}
11106
+
]
11107
+
},
11108
+
{
11109
+
"id": "substrings",
11110
+
"name": "[4]",
11111
+
"type": "tag",
11112
+
"class": "CONTEXT",
11113
+
"explicit": false,
11114
+
"content": [
11115
+
{
11116
+
"name": "",
11117
+
"type": {
11118
+
"name": "SubstringFilter",
11119
+
"type": "defined"
11120
+
}
11121
+
}
11122
+
]
11123
+
},
11124
+
{
11125
+
"id": "greaterOrEqual",
11126
+
"name": "[5]",
11127
+
"type": "tag",
11128
+
"class": "CONTEXT",
11129
+
"explicit": false,
11130
+
"content": [
11131
+
{
11132
+
"name": "",
11133
+
"type": {
11134
+
"name": "AttributeValueAssertion",
11135
+
"type": "defined"
11136
+
}
11137
+
}
11138
+
]
11139
+
},
11140
+
{
11141
+
"id": "lessOrEqual",
11142
+
"name": "[6]",
11143
+
"type": "tag",
11144
+
"class": "CONTEXT",
11145
+
"explicit": false,
11146
+
"content": [
11147
+
{
11148
+
"name": "",
11149
+
"type": {
11150
+
"name": "AttributeValueAssertion",
11151
+
"type": "defined"
11152
+
}
11153
+
}
11154
+
]
11155
+
},
11156
+
{
11157
+
"id": "present",
11158
+
"name": "[7]",
11159
+
"type": "tag",
11160
+
"class": "CONTEXT",
11161
+
"explicit": false,
11162
+
"content": [
11163
+
{
11164
+
"name": "",
11165
+
"type": {
11166
+
"name": "AttributeDescription",
11167
+
"type": "defined"
11168
+
}
11169
+
}
11170
+
]
11171
+
},
11172
+
{
11173
+
"id": "approxMatch",
11174
+
"name": "[8]",
11175
+
"type": "tag",
11176
+
"class": "CONTEXT",
11177
+
"explicit": false,
11178
+
"content": [
11179
+
{
11180
+
"name": "",
11181
+
"type": {
11182
+
"name": "AttributeValueAssertion",
11183
+
"type": "defined"
11184
+
}
11185
+
}
11186
+
]
11187
+
},
11188
+
{
11189
+
"id": "extensibleMatch",
11190
+
"name": "[9]",
11191
+
"type": "tag",
11192
+
"class": "CONTEXT",
11193
+
"explicit": false,
11194
+
"content": [
11195
+
{
11196
+
"name": "",
11197
+
"type": {
11198
+
"name": "MatchingRuleAssertion",
11199
+
"type": "defined"
11200
+
}
11201
+
}
11202
+
]
11203
+
}
11204
+
]
11205
+
}
11206
+
},
11207
+
"SubstringFilter": {
11208
+
"name": "SubstringFilter",
11209
+
"type": {
11210
+
"name": "SEQUENCE",
11211
+
"type": "builtin",
11212
+
"content": [
11213
+
{
11214
+
"id": "type",
11215
+
"name": "AttributeDescription",
11216
+
"type": "defined"
11217
+
},
11218
+
{
11219
+
"id": "substrings",
11220
+
"name": "SEQUENCE",
11221
+
"type": "builtin",
11222
+
"typeOf": 1,
11223
+
"size": [
11224
+
1,
11225
+
"MAX"
11226
+
],
11227
+
"content": [
11228
+
{
11229
+
"name": "CHOICE",
11230
+
"type": "builtin",
11231
+
"content": [
11232
+
{
11233
+
"id": "initial",
11234
+
"name": "[0]",
11235
+
"type": "tag",
11236
+
"class": "CONTEXT",
11237
+
"explicit": false,
11238
+
"content": [
11239
+
{
11240
+
"name": "",
11241
+
"type": {
11242
+
"name": "AssertionValue",
11243
+
"type": "defined"
11244
+
}
11245
+
}
11246
+
]
11247
+
},
11248
+
{
11249
+
"id": "any",
11250
+
"name": "[1]",
11251
+
"type": "tag",
11252
+
"class": "CONTEXT",
11253
+
"explicit": false,
11254
+
"content": [
11255
+
{
11256
+
"name": "",
11257
+
"type": {
11258
+
"name": "AssertionValue",
11259
+
"type": "defined"
11260
+
}
11261
+
}
11262
+
]
11263
+
},
11264
+
{
11265
+
"id": "final",
11266
+
"name": "[2]",
11267
+
"type": "tag",
11268
+
"class": "CONTEXT",
11269
+
"explicit": false,
11270
+
"content": [
11271
+
{
11272
+
"name": "",
11273
+
"type": {
11274
+
"name": "AssertionValue",
11275
+
"type": "defined"
11276
+
}
11277
+
}
11278
+
]
11279
+
}
11280
+
]
11281
+
}
11282
+
]
11283
+
}
11284
+
]
11285
+
}
11286
+
},
11287
+
"MatchingRuleAssertion": {
11288
+
"name": "MatchingRuleAssertion",
11289
+
"type": {
11290
+
"name": "SEQUENCE",
11291
+
"type": "builtin",
11292
+
"content": [
11293
+
{
11294
+
"id": "matchingRule",
11295
+
"name": "[1]",
11296
+
"type": "tag",
11297
+
"class": "CONTEXT",
11298
+
"explicit": false,
11299
+
"content": [
11300
+
{
11301
+
"name": "",
11302
+
"type": {
11303
+
"name": "MatchingRuleId",
11304
+
"type": "defined"
11305
+
}
11306
+
}
11307
+
],
11308
+
"optional": true
11309
+
},
11310
+
{
11311
+
"id": "type",
11312
+
"name": "[2]",
11313
+
"type": "tag",
11314
+
"class": "CONTEXT",
11315
+
"explicit": false,
11316
+
"content": [
11317
+
{
11318
+
"name": "",
11319
+
"type": {
11320
+
"name": "AttributeDescription",
11321
+
"type": "defined"
11322
+
}
11323
+
}
11324
+
],
11325
+
"optional": true
11326
+
},
11327
+
{
11328
+
"id": "matchValue",
11329
+
"name": "[3]",
11330
+
"type": "tag",
11331
+
"class": "CONTEXT",
11332
+
"explicit": false,
11333
+
"content": [
11334
+
{
11335
+
"name": "",
11336
+
"type": {
11337
+
"name": "AssertionValue",
11338
+
"type": "defined"
11339
+
}
11340
+
}
11341
+
]
11342
+
},
11343
+
{
11344
+
"id": "dnAttributes",
11345
+
"name": "[4]",
11346
+
"type": "tag",
11347
+
"class": "CONTEXT",
11348
+
"explicit": false,
11349
+
"content": [
11350
+
{
11351
+
"name": "",
11352
+
"type": {
11353
+
"name": "BOOLEAN",
11354
+
"type": "builtin"
11355
+
}
11356
+
}
11357
+
],
11358
+
"default": false
11359
+
}
11360
+
]
11361
+
}
11362
+
},
11363
+
"SearchResultEntry": {
11364
+
"name": "SearchResultEntry",
11365
+
"type": {
11366
+
"name": "Application 4",
11367
+
"type": "tag",
11368
+
"class": "APPLICATION",
11369
+
"explicit": false,
11370
+
"content": [
11371
+
{
11372
+
"name": "",
11373
+
"type": {
11374
+
"name": "SEQUENCE",
11375
+
"type": "builtin",
11376
+
"content": [
11377
+
{
11378
+
"id": "objectName",
11379
+
"name": "LDAPDN",
11380
+
"type": "defined"
11381
+
},
11382
+
{
11383
+
"id": "attributes",
11384
+
"name": "PartialAttributeList",
11385
+
"type": "defined"
11386
+
}
11387
+
]
11388
+
}
11389
+
}
11390
+
]
11391
+
}
11392
+
},
11393
+
"PartialAttributeList": {
11394
+
"name": "PartialAttributeList",
11395
+
"type": {
11396
+
"name": "SEQUENCE",
11397
+
"type": "builtin",
11398
+
"typeOf": 1,
11399
+
"content": [
11400
+
{
11401
+
"name": "PartialAttribute",
11402
+
"type": "defined"
11403
+
}
11404
+
]
11405
+
}
11406
+
},
11407
+
"SearchResultReference": {
11408
+
"name": "SearchResultReference",
11409
+
"type": {
11410
+
"name": "Application 19",
11411
+
"type": "tag",
11412
+
"class": "APPLICATION",
11413
+
"explicit": false,
11414
+
"content": [
11415
+
{
11416
+
"name": "",
11417
+
"type": {
11418
+
"name": "SEQUENCE",
11419
+
"type": "builtin",
11420
+
"typeOf": 1,
11421
+
"size": [
11422
+
1,
11423
+
"MAX"
11424
+
],
11425
+
"content": [
11426
+
{
11427
+
"name": "URI",
11428
+
"type": "defined"
11429
+
}
11430
+
]
11431
+
}
11432
+
}
11433
+
]
11434
+
}
11435
+
},
11436
+
"SearchResultDone": {
11437
+
"name": "SearchResultDone",
11438
+
"type": {
11439
+
"name": "Application 5",
11440
+
"type": "tag",
11441
+
"class": "APPLICATION",
11442
+
"explicit": false,
11443
+
"content": [
11444
+
{
11445
+
"name": "",
11446
+
"type": {
11447
+
"name": "LDAPResult",
11448
+
"type": "defined"
11449
+
}
11450
+
}
11451
+
]
11452
+
}
11453
+
},
11454
+
"ModifyRequest": {
11455
+
"name": "ModifyRequest",
11456
+
"type": {
11457
+
"name": "Application 6",
11458
+
"type": "tag",
11459
+
"class": "APPLICATION",
11460
+
"explicit": false,
11461
+
"content": [
11462
+
{
11463
+
"name": "",
11464
+
"type": {
11465
+
"name": "SEQUENCE",
11466
+
"type": "builtin",
11467
+
"content": [
11468
+
{
11469
+
"id": "object",
11470
+
"name": "LDAPDN",
11471
+
"type": "defined"
11472
+
},
11473
+
{
11474
+
"id": "changes",
11475
+
"name": "SEQUENCE",
11476
+
"type": "builtin",
11477
+
"typeOf": 1,
11478
+
"content": [
11479
+
{
11480
+
"name": "SEQUENCE",
11481
+
"type": "builtin",
11482
+
"content": [
11483
+
{
11484
+
"id": "operation",
11485
+
"name": "ENUMERATED",
11486
+
"type": "builtin",
11487
+
"content": {
11488
+
"add": 0,
11489
+
"delete": 1,
11490
+
"replace": 2
11491
+
}
11492
+
},
11493
+
{
11494
+
"id": "modification",
11495
+
"name": "PartialAttribute",
11496
+
"type": "defined"
11497
+
}
11498
+
]
11499
+
}
11500
+
]
11501
+
}
11502
+
]
11503
+
}
11504
+
}
11505
+
]
11506
+
}
11507
+
},
11508
+
"ModifyResponse": {
11509
+
"name": "ModifyResponse",
11510
+
"type": {
11511
+
"name": "Application 7",
11512
+
"type": "tag",
11513
+
"class": "APPLICATION",
11514
+
"explicit": false,
11515
+
"content": [
11516
+
{
11517
+
"name": "",
11518
+
"type": {
11519
+
"name": "LDAPResult",
11520
+
"type": "defined"
11521
+
}
11522
+
}
11523
+
]
11524
+
}
11525
+
},
11526
+
"AddRequest": {
11527
+
"name": "AddRequest",
11528
+
"type": {
11529
+
"name": "Application 8",
11530
+
"type": "tag",
11531
+
"class": "APPLICATION",
11532
+
"explicit": false,
11533
+
"content": [
11534
+
{
11535
+
"name": "",
11536
+
"type": {
11537
+
"name": "SEQUENCE",
11538
+
"type": "builtin",
11539
+
"content": [
11540
+
{
11541
+
"id": "entry",
11542
+
"name": "LDAPDN",
11543
+
"type": "defined"
11544
+
},
11545
+
{
11546
+
"id": "attributes",
11547
+
"name": "AttributeList",
11548
+
"type": "defined"
11549
+
}
11550
+
]
11551
+
}
11552
+
}
11553
+
]
11554
+
}
11555
+
},
11556
+
"AttributeList": {
11557
+
"name": "AttributeList",
11558
+
"type": {
11559
+
"name": "SEQUENCE",
11560
+
"type": "builtin",
11561
+
"typeOf": 1,
11562
+
"content": [
11563
+
{
11564
+
"name": "Attribute",
11565
+
"type": "defined"
11566
+
}
11567
+
]
11568
+
}
11569
+
},
11570
+
"AddResponse": {
11571
+
"name": "AddResponse",
11572
+
"type": {
11573
+
"name": "Application 9",
11574
+
"type": "tag",
11575
+
"class": "APPLICATION",
11576
+
"explicit": false,
11577
+
"content": [
11578
+
{
11579
+
"name": "",
11580
+
"type": {
11581
+
"name": "LDAPResult",
11582
+
"type": "defined"
11583
+
}
11584
+
}
11585
+
]
11586
+
}
11587
+
},
11588
+
"DelRequest": {
11589
+
"name": "DelRequest",
11590
+
"type": {
11591
+
"name": "Application 10",
11592
+
"type": "tag",
11593
+
"class": "APPLICATION",
11594
+
"explicit": false,
11595
+
"content": [
11596
+
{
11597
+
"name": "",
11598
+
"type": {
11599
+
"name": "LDAPDN",
11600
+
"type": "defined"
11601
+
}
11602
+
}
11603
+
]
11604
+
}
11605
+
},
11606
+
"DelResponse": {
11607
+
"name": "DelResponse",
11608
+
"type": {
11609
+
"name": "Application 11",
11610
+
"type": "tag",
11611
+
"class": "APPLICATION",
11612
+
"explicit": false,
11613
+
"content": [
11614
+
{
11615
+
"name": "",
11616
+
"type": {
11617
+
"name": "LDAPResult",
11618
+
"type": "defined"
11619
+
}
11620
+
}
11621
+
]
11622
+
}
11623
+
},
11624
+
"ModifyDNRequest": {
11625
+
"name": "ModifyDNRequest",
11626
+
"type": {
11627
+
"name": "Application 12",
11628
+
"type": "tag",
11629
+
"class": "APPLICATION",
11630
+
"explicit": false,
11631
+
"content": [
11632
+
{
11633
+
"name": "",
11634
+
"type": {
11635
+
"name": "SEQUENCE",
11636
+
"type": "builtin",
11637
+
"content": [
11638
+
{
11639
+
"id": "entry",
11640
+
"name": "LDAPDN",
11641
+
"type": "defined"
11642
+
},
11643
+
{
11644
+
"id": "newrdn",
11645
+
"name": "RelativeLDAPDN",
11646
+
"type": "defined"
11647
+
},
11648
+
{
11649
+
"id": "deleteoldrdn",
11650
+
"name": "BOOLEAN",
11651
+
"type": "builtin"
11652
+
},
11653
+
{
11654
+
"id": "newSuperior",
11655
+
"name": "[0]",
11656
+
"type": "tag",
11657
+
"class": "CONTEXT",
11658
+
"explicit": false,
11659
+
"content": [
11660
+
{
11661
+
"name": "",
11662
+
"type": {
11663
+
"name": "LDAPDN",
11664
+
"type": "defined"
11665
+
}
11666
+
}
11667
+
],
11668
+
"optional": true
11669
+
}
11670
+
]
11671
+
}
11672
+
}
11673
+
]
11674
+
}
11675
+
},
11676
+
"ModifyDNResponse": {
11677
+
"name": "ModifyDNResponse",
11678
+
"type": {
11679
+
"name": "Application 13",
11680
+
"type": "tag",
11681
+
"class": "APPLICATION",
11682
+
"explicit": false,
11683
+
"content": [
11684
+
{
11685
+
"name": "",
11686
+
"type": {
11687
+
"name": "LDAPResult",
11688
+
"type": "defined"
11689
+
}
11690
+
}
11691
+
]
11692
+
}
11693
+
},
11694
+
"CompareRequest": {
11695
+
"name": "CompareRequest",
11696
+
"type": {
11697
+
"name": "Application 14",
11698
+
"type": "tag",
11699
+
"class": "APPLICATION",
11700
+
"explicit": false,
11701
+
"content": [
11702
+
{
11703
+
"name": "",
11704
+
"type": {
11705
+
"name": "SEQUENCE",
11706
+
"type": "builtin",
11707
+
"content": [
11708
+
{
11709
+
"id": "entry",
11710
+
"name": "LDAPDN",
11711
+
"type": "defined"
11712
+
},
11713
+
{
11714
+
"id": "ava",
11715
+
"name": "AttributeValueAssertion",
11716
+
"type": "defined"
11717
+
}
11718
+
]
11719
+
}
11720
+
}
11721
+
]
11722
+
}
11723
+
},
11724
+
"CompareResponse": {
11725
+
"name": "CompareResponse",
11726
+
"type": {
11727
+
"name": "Application 15",
11728
+
"type": "tag",
11729
+
"class": "APPLICATION",
11730
+
"explicit": false,
11731
+
"content": [
11732
+
{
11733
+
"name": "",
11734
+
"type": {
11735
+
"name": "LDAPResult",
11736
+
"type": "defined"
11737
+
}
11738
+
}
11739
+
]
11740
+
}
11741
+
},
11742
+
"AbandonRequest": {
11743
+
"name": "AbandonRequest",
11744
+
"type": {
11745
+
"name": "Application 16",
11746
+
"type": "tag",
11747
+
"class": "APPLICATION",
11748
+
"explicit": false,
11749
+
"content": [
11750
+
{
11751
+
"name": "",
11752
+
"type": {
11753
+
"name": "MessageID",
11754
+
"type": "defined"
11755
+
}
11756
+
}
11757
+
]
11758
+
}
11759
+
},
11760
+
"ExtendedRequest": {
11761
+
"name": "ExtendedRequest",
11762
+
"type": {
11763
+
"name": "Application 23",
11764
+
"type": "tag",
11765
+
"class": "APPLICATION",
11766
+
"explicit": false,
11767
+
"content": [
11768
+
{
11769
+
"name": "",
11770
+
"type": {
11771
+
"name": "SEQUENCE",
11772
+
"type": "builtin",
11773
+
"content": [
11774
+
{
11775
+
"id": "requestName",
11776
+
"name": "[0]",
11777
+
"type": "tag",
11778
+
"class": "CONTEXT",
11779
+
"explicit": false,
11780
+
"content": [
11781
+
{
11782
+
"name": "",
11783
+
"type": {
11784
+
"name": "LDAPOID",
11785
+
"type": "defined"
11786
+
}
11787
+
}
11788
+
]
11789
+
},
11790
+
{
11791
+
"id": "requestValue",
11792
+
"name": "[1]",
11793
+
"type": "tag",
11794
+
"class": "CONTEXT",
11795
+
"explicit": false,
11796
+
"content": [
11797
+
{
11798
+
"name": "",
11799
+
"type": {
11800
+
"name": "OCTET STRING",
11801
+
"type": "builtin"
11802
+
}
11803
+
}
11804
+
],
11805
+
"optional": true
11806
+
}
11807
+
]
11808
+
}
11809
+
}
11810
+
]
11811
+
}
11812
+
},
11813
+
"ExtendedResponse": {
11814
+
"name": "ExtendedResponse",
11815
+
"type": {
11816
+
"name": "ANY",
11817
+
"type": "builtin"
11818
+
}
11819
+
},
11820
+
"IntermediateResponse": {
11821
+
"name": "IntermediateResponse",
11822
+
"type": {
11823
+
"name": "Application 25",
11824
+
"type": "tag",
11825
+
"class": "APPLICATION",
11826
+
"explicit": false,
11827
+
"content": [
11828
+
{
11829
+
"name": "",
11830
+
"type": {
11831
+
"name": "SEQUENCE",
11832
+
"type": "builtin",
11833
+
"content": [
11834
+
{
11835
+
"id": "responseName",
11836
+
"name": "[0]",
11837
+
"type": "tag",
11838
+
"class": "CONTEXT",
11839
+
"explicit": false,
11840
+
"content": [
11841
+
{
11842
+
"name": "",
11843
+
"type": {
11844
+
"name": "LDAPOID",
11845
+
"type": "defined"
11846
+
}
11847
+
}
11848
+
],
11849
+
"optional": true
11850
+
},
11851
+
{
11852
+
"id": "responseValue",
11853
+
"name": "[1]",
11854
+
"type": "tag",
11855
+
"class": "CONTEXT",
11856
+
"explicit": false,
11857
+
"content": [
11858
+
{
11859
+
"name": "",
11860
+
"type": {
11861
+
"name": "OCTET STRING",
11862
+
"type": "builtin"
11863
+
}
11864
+
}
11865
+
],
11866
+
"optional": true
11867
+
}
11868
+
]
11869
+
}
11870
+
}
11871
+
]
11872
}
11873
}
11874
}
+172
-38
test.js
+172
-38
test.js
···
1
#!/usr/bin/env node
2
3
-
import { ASN1 } from './asn1.js';
4
import { Hex } from './hex.js';
5
6
-
const
7
-
all = (process.argv[2] == 'all');
8
9
-
const tests = [
10
// RSA Laboratories technical notes from https://luca.ntop.org/Teaching/Appunti/asn1.html
11
['0304066E5DC0', '(18 bit)\n011011100101110111', 'ntop, bit string: DER encoding'],
12
['0304066E5DE0', '(18 bit)\n011011100101110111', 'ntop, bit string: padded with "100000"'],
···
75
['0D04C27B0302','8571.3.2', 'Relative OID from ISO/IEC 8825-1:2002 8.20.5'],
76
// UTF-8
77
['0C0E4C61706FE280997320F09F9A972E', 'Lapoโs ๐.', 'UTF-8 4-byte sequence'],
78
-
// T-REC-X.690-201508
79
['0307040A3B5F291CD0', '(44 bit)\n00001010001110110101111100101001000111001101', 'Example 8.6.4.2: bit string (primitive encoding)'],
80
['23800303000A3B0305045F291CD00000', '(44 bit)\n00001010001110110101111100101001000111001101', 'Example 8.6.4.2: bit string (constructed encoding)'],
81
// avoid past bugs
82
['23800303000A3B230A0302005F030404291CD00000', '(44 bit)\n00001010001110110101111100101001000111001101', 'Bit string (recursive constructed)'],
83
['0348003045022100DE601E573DAFB59BC551D58E3E7B9EDA0612DD0112805A2217B734759B884417022067C3FDE60780D41C1D7A3B90291F3D39C4DC2F206DCCBA2F982C06B67C09B232', '(568 bit)\n0011000001000101000000100010000100000000110111100110000000011110010101110011110110101111101101011001101111000101010100011101010110001110001111100111101110011110110110100000011000010010110111010000000100010010100000000101101000100010000101111011011100110100011101011001101110001000010001000001011100000010001000000110011111000011111111011110011000000111100000001101010000011100000111010111101000111011100100000010100100011111001111010011100111000100110111000010111100100000011011011100110010111010001011111001100000101100000001101011011001111100000010011011001000110010', 'not constructed, but contains structures'],
···
88
['181331393835313130363231303632372E332B3134', '1985-11-06 21:06:27.3 UTC+14:00', 'UTC offset +13 and +14'], // GitHub issue #54
89
['032100171E83C1B251803F86DD01E9CFA886BE89A7316D8372649AC2231EC669F81A84', n => { if (n.sub != null) return 'Should not decode content: ' + n.sub[0].content(); }, 'Key that resembles an UTCTime'], // GitHub issue #79
90
['171E83C1B251803F86DD01E9CFA886BE89A7316D8372649AC2231EC669F81A84', /^Exception:\nError: Unrecognized time: /, 'Invalid UTCTime'], // GitHub issue #79
91
-
];
92
93
-
let
94
-
run = 0,
95
-
expErr = 0,
96
-
error = 0;
97
-
tests.forEach(function (t) {
98
-
const input = t[0],
99
-
expected = t[1],
100
-
comment = t[2];
101
-
let result;
102
-
try {
103
-
let node = ASN1.decode(Hex.decode(input));
104
-
if (typeof expected == 'function')
105
-
result = expected(node);
106
-
else
107
-
result = node.content();
108
-
//TODO: check structure, not only first level content
109
-
} catch (e) {
110
-
result = 'Exception:\n' + e;
111
}
112
-
if (expected instanceof RegExp)
113
-
result = expected.test(result) ? null : 'does not match';
114
-
++run;
115
-
if (!result || result == expected) {
116
-
if (all) console.log('\x1B[1m\x1B[32mOK \x1B[39m\x1B[22m ' + comment);
117
-
} else {
118
-
++error;
119
-
console.log('\x1B[1m\x1B[31mERR\x1B[39m\x1B[22m ' + comment);
120
-
console.log(' \x1B[1m\x1B[34mEXP\x1B[39m\x1B[22m ' + expected.toString().replace(/\n/g, '\n '));
121
-
console.log(' \x1B[1m\x1B[33mGOT\x1B[39m\x1B[22m ' + result.replace(/\n/g, '\n '));
122
-
}
123
-
});
124
-
console.log(run + ' tested, ' + expErr + ' expected, ' + error + ' errors.');
125
-
process.exit(error ? 1 : 0);
···
1
#!/usr/bin/env node
2
3
+
import * as fs from 'fs'; // 'node:fs' doesn't work on NodeJS 14.5.0
4
+
import { ASN1, Stream } from './asn1.js';
5
+
import { Defs } from './defs.js';
6
import { Hex } from './hex.js';
7
+
import { Base64 } from './base64.js';
8
+
import { createPatch } from 'diff';
9
10
+
const all = (process.argv[2] == 'all');
11
+
12
+
/** @type {Array<Tests>} */
13
+
const tests = [];
14
+
15
+
const stats = {
16
+
run: 0,
17
+
error: 0,
18
+
};
19
+
20
+
function diff(str1, str2) {
21
+
let s = createPatch('test', str1, str2, null, null, { context: 2 });
22
+
s = s.slice(s.indexOf('@@'), -1);
23
+
s = s.replace(/^@@.*/mg, '\x1B[34m$&\x1B[39m');
24
+
s = s.replace(/^-.*/mg, '\x1B[31m$&\x1B[39m');
25
+
s = s.replace(/^\+.*/mg, '\x1B[32m$&\x1B[39m');
26
+
return s;
27
+
}
28
+
29
+
/**
30
+
* A class for managing and executing tests.
31
+
*/
32
+
class Tests {
33
+
/**
34
+
* The title of the test suite.
35
+
* @type {string}
36
+
*/
37
+
title;
38
+
39
+
/**
40
+
* An array to store test data.
41
+
* @type {Array<unknown>}
42
+
*/
43
+
data;
44
+
45
+
/**
46
+
* Checks a row of test data.
47
+
* @param {Function} t - How to test a row of data.
48
+
*/
49
+
checkRow;
50
+
51
+
/**
52
+
* Constructs a new Tests instance.
53
+
* @param {string} title - The title of the test suite.
54
+
* @param {Function} checkRow - A function to check each row of data.
55
+
* @param {Array<unknown>} data - The test data to be processed.
56
+
*/
57
+
constructor(title, checkRow, data) {
58
+
this.title = title;
59
+
this.checkRow = checkRow;
60
+
this.data = data;
61
+
}
62
63
+
/**
64
+
* Executes the tests and checks their results for all rows.
65
+
*/
66
+
checkAll() {
67
+
if (all) console.log('\x1B[1m\x1B[34m' + this.title + '\x1B[39m\x1B[22m');
68
+
for (const t of this.data)
69
+
this.checkRow(t);
70
+
}
71
+
72
+
/**
73
+
* Prints the result of a test, indicating if it passed or failed.
74
+
* @param {unknown} result The actual result of the test.
75
+
* @param {unknown} expected The expected result of the test.
76
+
* @param {string} comment A comment describing the test.
77
+
*/
78
+
checkResult(result, expected, comment) {
79
+
++stats.run;
80
+
if ((typeof expected != 'string' && !result) || result == expected) {
81
+
if (all) console.log('\x1B[1m\x1B[32mOK \x1B[39m\x1B[22m ' + comment);
82
+
} else {
83
+
++stats.error;
84
+
console.log('\x1B[1m\x1B[31mERR\x1B[39m\x1B[22m ' + comment);
85
+
if (!result) result = '(empty)';
86
+
if (typeof expected != 'string') {
87
+
console.log(' ' + result);
88
+
} else if (result.length > 100) {
89
+
console.log(' \x1B[1m\x1B[34mDIF\x1B[39m\x1B[22m ' + diff(result, expected.toString()).replace(/\n/g, '\n '));
90
+
} else {
91
+
console.log(' \x1B[1m\x1B[34mEXP\x1B[39m\x1B[22m ' + expected.toString().replace(/\n/g, '\n '));
92
+
console.log(' \x1B[1m\x1B[33mGOT\x1B[39m\x1B[22m ' + result.replace(/\n/g, '\n '));
93
+
}
94
+
}
95
+
}
96
+
}
97
+
98
+
tests.push(new Tests('ASN.1', function (t) {
99
+
const input = t[0],
100
+
expected = t[1],
101
+
comment = t[2];
102
+
let result;
103
+
try {
104
+
let node = ASN1.decode(Hex.decode(input));
105
+
if (typeof expected == 'function')
106
+
result = expected(node);
107
+
else
108
+
result = node.content();
109
+
//TODO: check structure, not only first level content
110
+
} catch (e) {
111
+
result = 'Exception:\n' + e;
112
+
}
113
+
if (expected instanceof RegExp)
114
+
result = expected.test(result) ? null : 'does not match';
115
+
this.checkResult(result, expected, comment);
116
+
}, [
117
// RSA Laboratories technical notes from https://luca.ntop.org/Teaching/Appunti/asn1.html
118
['0304066E5DC0', '(18 bit)\n011011100101110111', 'ntop, bit string: DER encoding'],
119
['0304066E5DE0', '(18 bit)\n011011100101110111', 'ntop, bit string: padded with "100000"'],
···
182
['0D04C27B0302','8571.3.2', 'Relative OID from ISO/IEC 8825-1:2002 8.20.5'],
183
// UTF-8
184
['0C0E4C61706FE280997320F09F9A972E', 'Lapoโs ๐.', 'UTF-8 4-byte sequence'],
185
+
// T-REC-X.690-202102
186
['0307040A3B5F291CD0', '(44 bit)\n00001010001110110101111100101001000111001101', 'Example 8.6.4.2: bit string (primitive encoding)'],
187
['23800303000A3B0305045F291CD00000', '(44 bit)\n00001010001110110101111100101001000111001101', 'Example 8.6.4.2: bit string (constructed encoding)'],
188
+
['0603883703', '2.999.3', 'Example 8.19.5: object identifier'],
189
+
// X.690 section 8.2.1 โThe contents octets shall consist of a single octet.โ
190
+
['010100', 'false', 'Boolean with correct length (false)'],
191
+
['010101', 'true', 'Boolean with correct length (true)'],
192
+
['0100', 'invalid length 0', 'Boolean with zero length'],
193
+
['01020000', 'invalid length 2', 'Boolean with excessive length'],
194
+
// X.690 section 8.3.1 โThe contents octets shall consist of one or more octets.โ
195
+
['020100', '0', 'Integer with correct length'],
196
+
['0200', 'invalid length 0', 'Integer with zero length'],
197
+
// X.690 section 8.19.4 kinda imples that the minimum number of components is 2
198
+
['0600', 'invalid length 0', 'Object identifier with zero length'],
199
+
['060100', '0.0', 'Object identifier with minimal (?) length'],
200
// avoid past bugs
201
['23800303000A3B230A0302005F030404291CD00000', '(44 bit)\n00001010001110110101111100101001000111001101', 'Bit string (recursive constructed)'],
202
['0348003045022100DE601E573DAFB59BC551D58E3E7B9EDA0612DD0112805A2217B734759B884417022067C3FDE60780D41C1D7A3B90291F3D39C4DC2F206DCCBA2F982C06B67C09B232', '(568 bit)\n0011000001000101000000100010000100000000110111100110000000011110010101110011110110101111101101011001101111000101010100011101010110001110001111100111101110011110110110100000011000010010110111010000000100010010100000000101101000100010000101111011011100110100011101011001101110001000010001000001011100000010001000000110011111000011111111011110011000000111100000001101010000011100000111010111101000111011100100000010100100011111001111010011100111000100110111000010111100100000011011011100110010111010001011111001100000101100000001101011011001111100000010011011001000110010', 'not constructed, but contains structures'],
···
207
['181331393835313130363231303632372E332B3134', '1985-11-06 21:06:27.3 UTC+14:00', 'UTC offset +13 and +14'], // GitHub issue #54
208
['032100171E83C1B251803F86DD01E9CFA886BE89A7316D8372649AC2231EC669F81A84', n => { if (n.sub != null) return 'Should not decode content: ' + n.sub[0].content(); }, 'Key that resembles an UTCTime'], // GitHub issue #79
209
['171E83C1B251803F86DD01E9CFA886BE89A7316D8372649AC2231EC669F81A84', /^Exception:\nError: Unrecognized time: /, 'Invalid UTCTime'], // GitHub issue #79
210
+
]));
211
212
+
tests.push(new Tests('Dump of examples', function () {
213
+
const examples = fs.readdirSync('examples/').filter(f => f.endsWith('.dump'));
214
+
for (const example of examples) {
215
+
const filename = example.slice(0, -5); // Remove '.dump' suffix
216
+
const expected = fs.readFileSync('examples/' + example, 'utf8');
217
+
let data = fs.readFileSync('examples/' + filename);
218
+
data = Base64.unarmor(data);
219
+
let node = ASN1.decode(data);
220
+
const types = Defs.commonTypes
221
+
.map(type => {
222
+
const stats = Defs.match(node, type);
223
+
return { type, match: stats.recognized / stats.total };
224
+
})
225
+
.sort((a, b) => b.match - a.match);
226
+
Defs.match(node, types[0].type);
227
+
let result = node.toPrettyString();
228
+
this.checkResult(result, expected, 'Dump of examples/' + filename);
229
}
230
+
}, [
231
+
[0],
232
+
]));
233
+
234
+
tests.push(new Tests('Base64', function (t) {
235
+
let bin = Base64.decode(t);
236
+
let url = new Stream(bin, 0).b64Dump(0, bin.length);
237
+
// check base64url encoding
238
+
this.checkResult(url, t.replace(/\n/g, '').replace(/=*$/g, ''), 'Base64url: ' + bin.length + ' bytes');
239
+
// check conversion from base64url to base64
240
+
let pretty = Base64.pretty(url);
241
+
this.checkResult(pretty, t, 'Base64pretty: ' + bin.length + ' bytes');
242
+
let std = new Stream(bin, 0).b64Dump(0, bin.length, 'std');
243
+
// check direct base64 encoding
244
+
this.checkResult(std, t.replace(/\n/g, ''), 'Base64: ' + bin.length + ' bytes');
245
+
}, [
246
+
'AA==',
247
+
'ABA=',
248
+
'ABCD',
249
+
'ABCDEA==',
250
+
'ABCDEFE=',
251
+
'ABCDEFGH',
252
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQR\nSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456w==',
253
+
]));
254
+
255
+
for (const t of tests)
256
+
t.checkAll();
257
+
258
+
console.log(stats.run + ' tested, ' + stats.error + ' errors.');
259
+
process.exit(stats.error ? 1 : 0);
+1
-1
testDefs.js
+1
-1
testDefs.js
+1
-1
updateRFC.sh
+1
-1
updateRFC.sh
+7
-1
vite.config.js
+7
-1
vite.config.js
···
16
};
17
};
18
19
export default defineConfig({
20
plugins: [
21
preventSVGEmit(),
···
25
if (removeNodes.includes(node.attribs.id))
26
DomUtils.removeElement(node);
27
else if (node.name == 'link' && node.attribs.rel == 'icon')
28
-
node.attribs.href = 'data:image/svg+xml;base64,' + btoa(fs.readFileSync('favicon.svg', 'ascii').replace(/^([^<]+|<[^s]|<s[^v]|<sv[^g])+/, '').trim());
29
},
30
}),
31
viteSingleFile(),
···
16
};
17
};
18
19
+
function massageSVG(str) {
20
+
return str.replace(/["<>#]/g, (c) => {
21
+
return '%' + c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0');
22
+
});
23
+
}
24
+
25
export default defineConfig({
26
plugins: [
27
preventSVGEmit(),
···
31
if (removeNodes.includes(node.attribs.id))
32
DomUtils.removeElement(node);
33
else if (node.name == 'link' && node.attribs.rel == 'icon')
34
+
node.attribs.href = 'data:image/svg+xml,' + massageSVG(fs.readFileSync('favicon.svg', 'ascii').replace(/^([^<]+|<[^s]|<s[^v]|<sv[^g])+/, '').trim());
35
},
36
}),
37
viteSingleFile(),