JavaScript generic ASN.1 parser (mirror)

Compare changes

Choose any two refs to compare.

+10
.editorconfig
··· 1 + root = true 2 + end_of_line = lf 3 + max_line_length = 120 4 + 5 + [*.{js,css}] 6 + charset = utf-8 7 + indent_size = 4 8 + indent_style = space 9 + insert_final_newline = true 10 + trim_trailing_whitespace = true
+9 -5
.github/workflows/node.js.yml
··· 12 12 13 13 strategy: 14 14 matrix: 15 - node-version: [ 12.20.0, latest ] 15 + node-version: [ 14.6.0, latest ] 16 16 17 17 steps: 18 18 - uses: actions/checkout@v4 19 + - name: Use pnpm 20 + uses: pnpm/action-setup@v4 21 + with: 22 + run_install: false 19 23 - name: Use Node.js ${{ matrix.node-version }} 20 24 uses: actions/setup-node@v4 21 25 with: 22 26 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 + cache: pnpm 28 + - run: pnpm install 29 + - run: node test all 30 + - run: pnpm run lint 27 31 if: matrix.node-version == 'latest'
-1
.gitignore
··· 4 4 node_modules/ 5 5 dist/ 6 6 package-lock.json 7 - pnpm-lock.yaml 8 7 # Artifacts from release.sh 9 8 index-local.html 10 9 sha256sums.asc
+1 -2
.mtn-ignore
··· 3 3 node_modules$ 4 4 dist$ 5 5 package-lock[.]json 6 - pnpm-lock[.]yaml 7 6 # Artifacts from release.sh 8 7 index-local.html 9 8 sha256sums[.]asc ··· 12 11 git-[^.]*[.]txt 13 12 # Artifacts from updateOID.sh 14 13 dumpasn1[.]cfg 15 - # Artifacts from parseRFC.js 14 + # Artifacts from updateRFC.sh / parseRFC.js 16 15 rfc$ 17 16 rfcdef[.]json
+25 -1
.vscode/launch.json
··· 7 7 { 8 8 "type": "node", 9 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", 10 20 "name": "dumpASN1", 11 21 "skipFiles": [ 12 22 "<node_internals>/**" ··· 32 42 { 33 43 "type": "node", 34 44 "request": "launch", 35 - "name": "dumpASN1 cert", 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", 36 60 "skipFiles": [ 37 61 "<node_internals>/**" 38 62 ],
+2 -2
.vscode/settings.json
··· 1 1 { 2 2 "editor.insertSpaces": true, 3 3 "editor.tabSize": 8, 4 - "editor.indentSize": 2, 4 + "editor.indentSize": 4, 5 5 "editor.stickyScroll.enabled": true, 6 6 "explorer.excludeGitIgnore": true, 7 7 "files.eol": "\n", 8 8 "git.openRepositoryInParentFolders": "never" 9 - } 9 + }
+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
+5 -3
README.md
··· 101 101 links 102 102 ----- 103 103 104 - - [official website](https://lapo.it/asn1js/) 105 - - [dedicated domain](https://asn1js.eu/) 106 - - [InDefero tracker](http://idf.lapo.it/p/asn1js/) 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) 107 108 - [GitHub mirror](https://github.com/lapo-luchini/asn1js) 109 + - [ChangeLog on GitHub](https://github.com/lapo-luchini/asn1js/blob/trunk/CHANGELOG.md) 108 110 - [Ohloh code stats](https://www.openhub.net/p/asn1js)
+275 -71
asn1.js
··· 13 13 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 14 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 16 - import { Int10 } from './int10.js'; 17 16 import { oids } from './oids.js'; 18 17 19 18 const ··· 42 41 ['CDELNRSTZcdelnrstz', 'ฤŒฤŽฤšฤฝล‡ล˜ล ลคลฝฤฤฤ›ฤพลˆล™ลกลฅลพ'], // Caron 43 42 ]; 44 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 + */ 45 50 function stringCut(str, len) { 46 51 if (str.length > len) 47 52 str = str.substring(0, len) + ellipsis; 48 53 return str; 49 54 } 50 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 + */ 51 61 function checkPrintable(s) { 52 62 let i, v; 53 63 for (i = 0; i < s.length; ++i) { ··· 57 67 } 58 68 } 59 69 60 - /** Class to manage a stream of bytes, with a zero-copy approach. 61 - * It uses an existing array or binary string and advances a position index. */ 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 + */ 62 74 export class Stream { 63 75 64 76 /** 77 + * Creates a new Stream object. 65 78 * @param {Stream|array|string} enc data (will not be copied) 66 79 * @param {?number} pos starting position (mandatory when `end` is not a Stream) 67 80 */ ··· 75 88 } 76 89 if (typeof this.pos != 'number') 77 90 throw new Error('"pos" must be a numeric value'); 91 + // Set up the raw byte access function based on the type of data 78 92 if (typeof this.enc == 'string') 79 93 this.getRaw = pos => this.enc.charCodeAt(pos); 80 94 else if (typeof this.enc[0] == 'number') ··· 82 96 else 83 97 throw new Error('"enc" must be a numeric array or a string'); 84 98 } 85 - /** Get the byte at current position (and increment it) or at a specified position (and avoid moving current position). 86 - * @param {?number} pos read position if specified, else current position (and increment it) */ 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 + */ 87 105 get(pos) { 88 106 if (pos === undefined) 89 107 pos = this.pos++; ··· 91 109 throw new Error('Requesting byte offset ' + pos + ' on a stream of length ' + this.enc.length); 92 110 return this.getRaw(pos); 93 111 } 94 - /** Convert a single byte to an hexadcimal string (of length 2). 95 - * @param {number} b */ 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 + */ 96 118 static hexByte(b) { 97 119 return hexDigits.charAt((b >> 4) & 0xF) + hexDigits.charAt(b & 0xF); 98 120 } 99 - /** Hexadecimal dump of a specified region of the stream. 100 - * @param {number} start starting position (included) 101 - * @param {number} end ending position (excluded) 102 - * @param {string} type 'raw', 'byte' or 'dump' (default) */ 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 + */ 103 129 hexDump(start, end, type = 'dump') { 104 130 let s = ''; 105 131 for (let i = start; i < end; ++i) { ··· 115 141 } 116 142 return s; 117 143 } 118 - /** Base64url dump of a specified region of the stream (according to RFC 4648 section 5). 119 - * @param {number} start starting position (included) 120 - * @param {number} end ending position (excluded) 121 - * @param {string} type 'url' (default, section 5 without padding) or 'std' (section 4 with padding) */ 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 + */ 122 152 b64Dump(start, end, type = 'url') { 123 - const b64 = type === 'url' ? b64URL : b64Std; 124 - let extra = (end - start) % 3, 125 - s = '', 153 + const b64 = type === 'url' ? b64URL : b64Std, 154 + extra = (end - start) % 3; 155 + let s = '', 126 156 i, c; 127 157 for (i = start; i + 2 < end; i += 3) { 128 158 c = this.get(i) << 16 | this.get(i + 1) << 8 | this.get(i + 2); ··· 141 171 } 142 172 return s; 143 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 + */ 144 181 isASCII(start, end) { 145 182 for (let i = start; i < end; ++i) { 146 183 let c = this.get(i); ··· 149 186 } 150 187 return true; 151 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 + */ 152 197 parseStringISO(start, end, maxLength) { 153 198 let s = ''; 154 199 for (let i = start; i < end; ++i) 155 200 s += String.fromCharCode(this.get(i)); 156 201 return { size: s.length, str: stringCut(s, maxLength) }; 157 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 + */ 158 211 parseStringT61(start, end, maxLength) { 159 212 // warning: this code is not very well tested so far 160 213 function merge(c, d) { 161 - let t = tableT61[c - 0xC0]; 162 - let i = t[0].indexOf(String.fromCharCode(d)); 214 + const t = tableT61[c - 0xC0]; 215 + const i = t[0].indexOf(String.fromCharCode(d)); 163 216 return (i < 0) ? '\0' : t[1].charAt(i); 164 217 } 165 218 let s = '', c; ··· 176 229 } 177 230 return { size: s.length, str: stringCut(s, maxLength) }; 178 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 + */ 179 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 + */ 180 246 function ex(c) { // must be 10xxxxxx 181 247 if ((c < 0x80) || (c >= 0xC0)) 182 248 throw new Error('Invalid UTF-8 continuation byte: ' + c); 183 249 return (c & 0x3F); 184 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 + */ 185 256 function surrogate(cp) { 186 257 if (cp < 0x10000) 187 258 throw new Error('UTF-8 overlong encoding, codepoint encoded in 4 bytes: ' + cp); ··· 191 262 } 192 263 let s = ''; 193 264 for (let i = start; i < end; ) { 194 - let c = this.get(i++); 265 + const c = this.get(i++); 195 266 if (c < 0x80) // 0xxxxxxx (7 bit) 196 267 s += String.fromCharCode(c); 197 268 else if (c < 0xC0) ··· 207 278 } 208 279 return { size: s.length, str: stringCut(s, maxLength) }; 209 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 + */ 210 289 parseStringBMP(start, end, maxLength) { 211 290 let s = '', hi, lo; 212 291 for (let i = start; i < end; ) { ··· 216 295 } 217 296 return { size: s.length, str: stringCut(s, maxLength) }; 218 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 + */ 219 306 parseTime(start, end, shortYear) { 220 307 let s = this.parseStringISO(start, end).str, 221 308 m = (shortYear ? reTimeS : reTimeL).exec(s); ··· 243 330 } 244 331 return s; 245 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 + */ 246 340 parseInteger(start, end) { 247 341 let v = this.get(start), 248 - neg = (v > 127), 249 - pad = neg ? 255 : 0, 250 - len, 251 342 s = ''; 343 + const neg = (v > 127), 344 + pad = neg ? 255 : 0; 252 345 // skip unuseful bits (not allowed in DER) 253 346 while (v == pad && ++start < end) 254 347 v = this.get(start); 255 - len = end - start; 348 + const len = end - start; 256 349 if (len === 0) 257 350 return neg ? '-1' : '0'; 258 351 // show bit length of huge integers 259 352 if (len > 4) { 260 - s = v; 261 - len <<= 3; 262 - while (((s ^ pad) & 0x80) == 0) { 263 - s <<= 1; 264 - --len; 353 + let v2 = v, 354 + lenBit = len << 3; 355 + while (((v2 ^ pad) & 0x80) == 0) { 356 + v2 <<= 1; 357 + --lenBit; 265 358 } 266 - s = '(' + len + ' bit)\n'; 359 + s = '(' + lenBit + ' bit)\n'; 267 360 } 268 361 // decode the integer 269 362 if (neg) v = v - 256; 270 - let n = new Int10(v); 363 + let n = BigInt(v); 271 364 for (let i = start + 1; i < end; ++i) 272 - n.mulAdd(256, this.get(i)); 273 - return s + n.toString(); 365 + n = (n << 8n) | BigInt(this.get(i)); 366 + return s + n; 274 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 + */ 275 376 parseBitString(start, end, maxLength) { 276 - let unusedBits = this.get(start); 377 + const unusedBits = this.get(start); 277 378 if (unusedBits > 7) 278 379 throw new Error('Invalid BitString with unusedBits=' + unusedBits); 279 - let lenBit = ((end - start - 1) << 3) - unusedBits, 280 - s = ''; 380 + const lenBit = ((end - start - 1) << 3) - unusedBits; 381 + let s = ''; 281 382 for (let i = start + 1; i < end; ++i) { 282 383 let b = this.get(i), 283 384 skip = (i == end - 1) ? unusedBits : 0; ··· 288 389 } 289 390 return { size: lenBit, str: s }; 290 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 + */ 291 400 parseOctetString(start, end, maxLength) { 292 - let len = end - start, 293 - s; 294 401 try { 295 - s = this.parseStringUTF(start, end, maxLength); 402 + let s = this.parseStringUTF(start, end, maxLength); 296 403 checkPrintable(s.str); 297 404 return { size: end - start, str: s.str }; 298 - } catch (e) { 299 - // ignore 405 + } catch (ignore) { 406 + // If UTF-8 parsing fails, fall back to hexadecimal dump 300 407 } 408 + const len = end - start; 301 409 maxLength /= 2; // we work in bytes 302 410 if (len > maxLength) 303 411 end = start + maxLength; 304 - s = ''; 412 + let s = ''; 305 413 for (let i = start; i < end; ++i) 306 414 s += Stream.hexByte(this.get(i)); 307 415 if (len > maxLength) 308 416 s += ellipsis; 309 417 return { size: len, str: s }; 310 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 + */ 311 428 parseOID(start, end, maxLength, isRelative) { 312 429 let s = '', 313 - n = new Int10(), 430 + n = 0n, 314 431 bits = 0; 315 432 for (let i = start; i < end; ++i) { 316 433 let v = this.get(i); 317 - n.mulAdd(128, v & 0x7F); 434 + // Shift bits and add the lower 7 bits of the byte 435 + n = (n << 7n) | BigInt(v & 0x7F); 318 436 bits += 7; 437 + // If the most significant bit is 0, this is the last byte of the OID component 319 438 if (!(v & 0x80)) { // finished 439 + // If this is the first component, handle it specially 320 440 if (s === '') { 321 - n = n.simplify(); 322 441 if (isRelative) { 323 - s = (n instanceof Int10) ? n.toString() : '' + n; 324 - } else if (n instanceof Int10) { 325 - n.sub(80); 326 - s = '2.' + n.toString(); 442 + s = n.toString(); 327 443 } else { 328 - let m = n < 80 ? n < 40 ? 0 : 1 : 2; 329 - s = m + '.' + (n - m * 40); 444 + let m = n < 80 ? n < 40 ? 0n : 1n : 2n; 445 + s = m + '.' + (n - m * 40n); 330 446 } 331 447 } else 332 - s += '.' + n.toString(); 448 + s += '.' + n; 333 449 if (s.length > maxLength) 334 450 return stringCut(s, maxLength); 335 - n = new Int10(); 451 + n = 0n; 336 452 bits = 0; 337 453 } 338 454 } 339 455 if (bits > 0) 340 456 s += '.incomplete'; 457 + // If OIDs mapping is available and the OID is absolute, try to resolve it 341 458 if (typeof oids === 'object' && !isRelative) { 342 459 let oid = oids[s]; 343 460 if (oid) { ··· 348 465 } 349 466 return s; 350 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 + */ 351 476 parseRelativeOID(start, end, maxLength) { 352 477 return this.parseOID(start, end, maxLength, true); 353 478 } ··· 380 505 this.tagConstructed = ((buf & 0x20) !== 0); 381 506 this.tagNumber = buf & 0x1F; 382 507 if (this.tagNumber == 0x1F) { // long tag 383 - let n = new Int10(); 508 + let n = 0n; 384 509 do { 385 510 buf = stream.get(); 386 - n.mulAdd(128, buf & 0x7F); 511 + n = (n << 7n) | BigInt(buf & 0x7F); 387 512 } while (buf & 0x80); 388 - this.tagNumber = n.simplify(); 513 + this.tagNumber = n <= Number.MAX_SAFE_INTEGER ? Number(n) : n; 389 514 } 390 515 } 391 516 isUniversal() { ··· 396 521 } 397 522 } 398 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 + */ 399 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 + */ 400 538 constructor(stream, header, length, tag, tagLen, sub) { 401 539 if (!(tag instanceof ASN1Tag)) throw new Error('Invalid tag value.'); 402 540 this.stream = stream; ··· 406 544 this.tagLen = tagLen; 407 545 this.sub = sub; 408 546 } 547 + 548 + /** 549 + * Get the type name of the ASN.1 element. 550 + * @returns {string} The type name. 551 + */ 409 552 typeName() { 410 553 switch (this.tag.tagClass) { 411 554 case 0: // universal ··· 445 588 case 3: return 'Private_' + this.tag.tagNumber.toString(); 446 589 } 447 590 } 448 - /** A string preview of the content (intended for humans). */ 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 + */ 449 597 content(maxLength) { 450 598 if (this.tag === undefined) 451 599 return null; 452 600 if (maxLength === undefined) 453 601 maxLength = Infinity; 454 - let content = this.posContent(), 602 + const content = this.posContent(), 455 603 len = Math.abs(this.length); 456 604 if (!this.tag.isUniversal()) { 457 605 if (this.sub !== null) ··· 461 609 } 462 610 switch (this.tag.tagNumber) { 463 611 case 0x01: // BOOLEAN 612 + if (len != 1) return 'invalid length ' + len; 464 613 return (this.stream.get(content) === 0) ? 'false' : 'true'; 465 614 case 0x02: // INTEGER 615 + if (len < 1) return 'invalid length ' + len; 466 616 return this.stream.parseInteger(content, content + len); 467 617 case 0x03: { // BIT_STRING 468 618 let d = recurse(this, 'parseBitString', maxLength); ··· 474 624 } 475 625 //case 0x05: // NULL 476 626 case 0x06: // OBJECT_IDENTIFIER 627 + if (len < 1) return 'invalid length ' + len; // pgut001's dumpasn1.c enforces a minimum lenght of 3 477 628 return this.stream.parseOID(content, content + len, maxLength); 478 629 //case 0x07: // ObjectDescriptor 479 630 //case 0x08: // EXTERNAL ··· 510 661 } 511 662 return null; 512 663 } 664 + 665 + /** 666 + * Get a string representation of the ASN.1 element. 667 + * @returns {string} The string representation. 668 + */ 513 669 toString() { 514 670 return this.typeName() + '@' + this.stream.pos + '[header:' + this.header + ',length:' + this.length + ',sub:' + ((this.sub === null) ? 'null' : this.sub.length) + ']'; 515 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 + */ 516 678 toPrettyString(indent) { 517 679 if (indent === undefined) indent = ''; 518 680 let s = indent; ··· 543 705 } 544 706 return s; 545 707 } 708 + 709 + /** 710 + * Get the starting position of the element in the stream. 711 + * @returns {number} The starting position. 712 + */ 546 713 posStart() { 547 714 return this.stream.pos; 548 715 } 716 + 717 + /** 718 + * Get the position of the content in the stream. 719 + * @returns {number} The content position. 720 + */ 549 721 posContent() { 550 722 return this.stream.pos + this.header; 551 723 } 724 + 725 + /** 726 + * Get the ending position of the element in the stream. 727 + * @returns {number} The ending position. 728 + */ 552 729 posEnd() { 553 730 return this.stream.pos + this.header + Math.abs(this.length); 554 731 } 555 - /** Position of the length. */ 732 + 733 + /** 734 + * Get the position of the length in the stream. 735 + * @returns {number} The length position. 736 + */ 556 737 posLen() { 557 738 return this.stream.pos + this.tagLen; 558 739 } 559 - /** Hexadecimal dump of the node. 560 - * @param type 'raw', 'byte' or 'dump' */ 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 + */ 561 746 toHexString(type = 'raw') { 562 747 return this.stream.hexDump(this.posStart(), this.posEnd(), type); 563 748 } 564 - /** Base64url dump of the node (according to RFC 4648 section 5). 565 - * @param {string} type 'url' (default, section 5 without padding) or 'std' (section 4 with padding) 566 - */ 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 + */ 567 755 toB64String(type = 'url') { 568 756 return this.stream.b64Dump(this.posStart(), this.posEnd(), type); 569 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 + */ 570 765 static decodeLength(stream) { 571 - let buf = stream.get(), 766 + const buf = stream.get(), 572 767 len = buf & 0x7F; 573 768 if (len == buf) // first bit was 0, short form 574 769 return len; 575 770 if (len === 0) // long form with length 0 is a special case 576 771 return null; // undefined length 577 - if (len > 6) // no reason to use Int10, as it would be a huge buffer anyways 772 + if (len > 6) // no reason to use BigInt, as it would be a huge buffer anyways 578 773 throw new Error('Length over 48 bits not supported at position ' + (stream.pos - 1)); 579 - buf = 0; 774 + let value = 0; 580 775 for (let i = 0; i < len; ++i) 581 - buf = (buf * 256) + stream.get(); 582 - return buf; 776 + value = (value << 8) | stream.get(); 777 + return value; 583 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 + */ 584 788 static decode(stream, offset, type = ASN1) { 585 789 if (!(type == ASN1 || type.prototype instanceof ASN1)) 586 790 throw new Error('Must pass a class that extends ASN1'); ··· 638 842 throw new Error('Unable to parse content: ' + e); 639 843 } 640 844 } 641 - } catch (e) { 845 + } catch (ignore) { 642 846 // but silently ignore when they don't 643 847 sub = null; 644 848 //DEBUG console.log('Could not decode structure at ' + start + ':', e);
+9 -6
defs.js
··· 23 23 try { 24 24 // hope current OIDs contain the type name (will need to parse from RFC itself) 25 25 def = Defs.searchType(firstUpper(stats.defs[def.definedBy][1])); 26 - } catch (e) { /*ignore*/ } 26 + } catch (ignore) { /*ignore*/ } 27 27 while (def?.type == 'defined' || def?.type?.type == 'defined') { 28 28 const name = def?.type?.type ? def.type.name : def.name; 29 29 def = Object.assign({}, def); ··· 35 35 c = translate(c); 36 36 if (tn == c.type.name || tn == c.name) { 37 37 def = Object.assign({}, def); 38 - if (c.id) def.id = c.id; 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; 39 40 def.type = c.type.name ? c.type : c; 40 41 break; 41 42 } ··· 69 70 70 71 static match(value, def, stats = { total: 0, recognized: 0, defs: {} }) { 71 72 value.def = {}; 72 - let tn = value.typeName().replaceAll('_', ' '); 73 + let tn = value.typeName().replace(/_/g, ' '); 73 74 def = translate(def, tn, stats); 74 75 ++stats.total; 75 76 if (def?.type) { ··· 90 91 if (def.typeOf) 91 92 type = def.content[0]; 92 93 else { 93 - let tn = subval.typeName().replaceAll('_', ' '); 94 + let tn = subval.typeName().replace(/_/g, ' '); 94 95 for (;;) { 95 96 type = def.content[j++]; 96 97 if (!type || typeof type != 'object') break; 97 98 if (type?.type?.type) 98 - type = type.type; 99 + // type = type.type; 100 + type = Object.assign({}, type.type, {id: type.id}); 99 101 if (type.type == 'defined') { 100 102 let t2 = translate(type, tn); 101 103 if (t2.type.name == tn) break; // exact match ··· 113 115 } else if (type?.definedBy && stats.defs?.[type.definedBy]?.[1]) { // hope current OIDs contain the type name (will need to parse from RFC itself) 114 116 try { 115 117 type = Defs.searchType(firstUpper(stats.defs[type.definedBy][1])); 116 - } catch (e) { /*ignore*/ } 118 + } catch (ignore) { /*ignore*/ } 117 119 } 118 120 } 119 121 } ··· 138 140 [ 'PKCS#10 certification request', '1.2.840.113549.1.10.1.1', 'CertificationRequest' ], 139 141 [ 'CMP PKI Message', '1.3.6.1.5.5.7.0.16', 'PKIMessage' ], 140 142 [ 'LDAP Message', '1.3.6.1.1.18', 'LDAPMessage' ], 143 + [ 'Time Stamp Request', '1.3.6.1.5.5.7.0.13', 'TimeStampReq' ], 141 144 ].map(arr => ({ description: arr[0], ...Defs.moduleAndType(rfcdef[arr[1]], arr[2]) }));
+1 -1
dumpASN1.js
··· 52 52 : fs.readFileSync(filename); 53 53 try { // try PEM first 54 54 content = Base64.unarmor(content); 55 - } catch (e) { // try DER/BER then 55 + } catch (ignore) { // try DER/BER then 56 56 } 57 57 let result = ASN1.decode(content); 58 58 content = null;
+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 + ];
+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
··· 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
+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
··· 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
··· 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
··· 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
··· 1 + RFC3161 TimeStamp Request 2 + 3 + begin-base64 644 timestamp-req.der 4 + ME4CAQEwLzALBglghkgBZQMEAgEEIEbUJK38SA8/2dz78XnG7DJfIYsSer3shYMmZa1VLFIRAhUA 5 + /1AduFa4EwRirIpvChE2VrV/JWYBAf8=
+1 -3
index.css
··· 1 1 html { 2 2 --main-bg-color: #C0C0C0; 3 3 --main-text-color: #000000; 4 - --id-text-color: #7d5900; 5 4 --headline-text-color: #8be9fd; 6 5 --button-border-color: #767676; 7 6 --button-bg-color: #efefef; ··· 36 35 html[data-theme="dark"] { 37 36 --main-bg-color: #0d1116; 38 37 --main-text-color: #f8f8f2; 39 - --id-text-color: #9d7c2d; 40 38 --headline-text-color: #8be9fd; 41 39 --button-border-color: #505050; 42 40 --button-bg-color: #303030; ··· 188 186 color: var(--preview-border-color); 189 187 } 190 188 .name.id { 191 - color: var(--id-text-color); 189 + color: var(--main-text-color); 192 190 } 193 191 .value { 194 192 display: none;
+2
index.html
··· 61 61 <option value="crl-rfc5280.b64">CRL example (RFC 5280)</option> 62 62 <option value="cmpv2.b64">CMP PKI message (RFC 4210)</option> 63 63 <option value="ldapmessage.b64">LDAP message (RFC 4511)</option> 64 + <option value="timestamp-req.b64">TimeStamp request (RFC 3161)</option> 64 65 </select> 65 66 <input id="butExample" type="button" value="load"><br> 66 67 </td></tr> ··· 107 108 <li>previous versions on githack: <select id="tags"><option>[select tag]</option></select></li> 108 109 <li><a href="http://idf.lapo.it/p/asn1js/">InDefero tracker</a> (currently offline)</li> 109 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> 110 112 <li><a href="https://www.openhub.net/p/asn1js">OpenHub code stats</a></li> 111 113 </ul> 112 114 </div>
+2 -2
index.js
··· 86 86 if (area.value === '') area.value = Base64.pretty(b64); 87 87 try { 88 88 window.location.hash = hash = '#' + b64; 89 - } catch (e) { 89 + } catch (ignore) { 90 90 // fails with "Access Denied" on IE with URLs longer than ~2048 chars 91 91 window.location.hash = hash = '#'; 92 92 } ··· 122 122 else if (Base64.re.test(str)) der = Base64.unarmor(str); 123 123 else der = str; 124 124 decode(der); 125 - } catch (e) { 125 + } catch (ignore) { 126 126 text(tree, 'Cannot decode file.'); 127 127 dump.innerHTML = ''; 128 128 }
-112
int10.js
··· 1 - // Big integer base-10 printing library 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 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 - /** Biggest 10^n integer that can still fit 2^53 when multiplied by 256. */ 17 - const max = 10000000000000; 18 - 19 - export class Int10 { 20 - /** 21 - * Arbitrary length base-10 value. 22 - * @param {number} value - Optional initial value (will be 0 otherwise). 23 - */ 24 - constructor(value) { 25 - this.buf = [+value || 0]; 26 - } 27 - 28 - /** 29 - * Multiply value by m and add c. 30 - * @param {number} m - multiplier, must be 0<m<=256 31 - * @param {number} c - value to add, must be c>=0 32 - */ 33 - mulAdd(m, c) { 34 - // assert(m > 0) 35 - // assert(m <= 256) 36 - // assert(c >= 0) 37 - let b = this.buf, 38 - l = b.length, 39 - i, t; 40 - for (i = 0; i < l; ++i) { 41 - t = b[i] * m + c; 42 - if (t < max) 43 - c = 0; 44 - else { 45 - c = 0|(t / max); 46 - t -= c * max; 47 - } 48 - b[i] = t; 49 - } 50 - if (c > 0) 51 - b[i] = c; 52 - } 53 - 54 - /** 55 - * Subtract value. 56 - * @param {number} c - value to subtract 57 - */ 58 - sub(c) { 59 - let b = this.buf, 60 - l = b.length, 61 - i, t; 62 - for (i = 0; i < l; ++i) { 63 - t = b[i] - c; 64 - if (t < 0) { 65 - t += max; 66 - c = 1; 67 - } else 68 - c = 0; 69 - b[i] = t; 70 - } 71 - while (b[b.length - 1] === 0) 72 - b.pop(); 73 - } 74 - 75 - /** 76 - * Convert to decimal string representation. 77 - * @param {number} [base=10] - optional value, only value accepted is 10 78 - * @returns {string} The decimal string representation. 79 - */ 80 - toString(base = 10) { 81 - if (base != 10) 82 - throw new Error('only base 10 is supported'); 83 - let b = this.buf, 84 - s = b[b.length - 1].toString(); 85 - for (let i = b.length - 2; i >= 0; --i) 86 - s += (max + b[i]).toString().substring(1); 87 - return s; 88 - } 89 - 90 - /** 91 - * Convert to Number value representation. 92 - * Will probably overflow 2^53 and thus become approximate. 93 - * @returns {number} The numeric value. 94 - */ 95 - valueOf() { 96 - let b = this.buf, 97 - v = 0; 98 - for (let i = b.length - 1; i >= 0; --i) 99 - v = v * max + b[i]; 100 - return v; 101 - } 102 - 103 - /** 104 - * Return value as a simple Number (if it is <= 10000000000000), or return this. 105 - * @returns {number | Int10} The simplified value. 106 - */ 107 - simplify() { 108 - let b = this.buf; 109 - return (b.length == 1) ? b[0] : this; 110 - } 111 - 112 - }
+32 -76
package.json
··· 1 1 { 2 2 "name": "@lapo/asn1js", 3 - "version": "2.0.6", 3 + "version": "2.1.1", 4 4 "description": "Generic ASN.1 parser/decoder that can decode any valid ASN.1 DER or BER structures.", 5 5 "type": "module", 6 6 "main": "asn1.js", ··· 8 8 "type": "git", 9 9 "url": "git+https://github.com/lapo-luchini/asn1js.git" 10 10 }, 11 - "keywords": [ "asn1", "ber", "der", "pem" ], 11 + "keywords": [ 12 + "asn1", 13 + "ber", 14 + "der", 15 + "pem" 16 + ], 12 17 "author": "Lapo Luchini <lapo@lapo.it>", 13 18 "license": "ISC", 14 - "bugs": { "url": "https://github.com/lapo-luchini/asn1js/issues" }, 19 + "bugs": { 20 + "url": "https://github.com/lapo-luchini/asn1js/issues" 21 + }, 15 22 "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" ], 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 + ], 17 33 "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", 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", 19 35 "lint-action": "npx @action-validator/cli .github/workflows/node.js.yml", 20 36 "build": "vite build", 21 37 "serve": "npx -p local-web-server ws", ··· 26 42 "dumpASN1": "./dumpASN1.js" 27 43 }, 28 44 "engines": { 29 - "node": ">=12.20.0" 45 + "node": ">=14.6.0" 30 46 }, 47 + "packageManager": "pnpm@7.33.7", 31 48 "devDependencies": { 32 - "@rollup/wasm-node": "^4.25.0", 33 - "eslint": "^8.57.1", 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", 34 55 "htmlparser2": "^9.1.0", 35 - "vite": "^5.4.10", 36 - "vite-plugin-dom": "^1.0.4", 37 - "vite-plugin-singlefile": "^2.0.3" 56 + "vite": "^7.1.12", 57 + "vite-plugin-dom": "^1.0.5", 58 + "vite-plugin-singlefile": "^2.3.0" 38 59 }, 39 60 "overrides": { 40 61 "rollup": "npm:@rollup/wasm-node" ··· 43 64 "overrides": { 44 65 "rollup": "npm:@rollup/wasm-node" 45 66 } 46 - }, 47 - "eslintConfig": { 48 - "env": { 49 - "es6": true, 50 - "browser": true, 51 - "node": true 52 - }, 53 - "parserOptions": { 54 - "ecmaVersion": 2015, 55 - "sourceType": "module" 56 - }, 57 - "extends": [ "eslint:recommended" ], 58 - "globals": { 59 - "Uint8Array": "readonly" 60 - }, 61 - "rules": { 62 - "strict": [ "error", "function" ], 63 - "indent": [ "error", 4 ], 64 - "no-trailing-spaces": [ "error" ], 65 - "linebreak-style": [ "error", "unix" ], 66 - "eol-last": [ "error", "always" ], 67 - "semi": [ "warn", "always" ], 68 - "quotes": [ "error", "single", { "avoidEscape": true } ], 69 - "no-var": [ "warn" ], 70 - "comma-dangle": [ "error", "always-multiline" ] 71 - }, 72 - "overrides": [ 73 - { 74 - "files": [ "defs.js" ], 75 - "parserOptions": { 76 - "ecmaVersion": 2020 77 - } 78 - }, { 79 - "files": [ "test.js", "parseRFC.js", "dumpASN1.js" ], 80 - "parserOptions": { 81 - "ecmaVersion": 2021 82 - }, 83 - "rules": { 84 - "strict": [ "error", "global" ] 85 - } 86 - }, { 87 - "files": [ "oids.js" ], 88 - "rules": { 89 - "indent": "off", 90 - "quotes": [ "warn", "double" ] 91 - } 92 - }, { 93 - "files": [ "tags.js", "rfcdef.js" ], 94 - "rules": { 95 - "indent": [ "error", 2, { "ignoredNodes": [ "Program > ExpressionStatement > CallExpression > FunctionExpression > BlockStatement > ExpressionStatement[directive='use strict']:first-child" ] } ], 96 - "comma-dangle": "off", 97 - "quotes": [ "warn", "double" ] 98 - } 99 - }, { 100 - "files": [ "defs.js" ], 101 - "parserOptions": { 102 - "ecmaVersion": 2021 103 - } 104 - }, { 105 - "files": [ "testDefs.js" ], 106 - "parserOptions": { 107 - "ecmaVersion": 2022 108 - } 109 - } 110 - ] 111 67 } 112 68 }
+4 -4
parseRFC.js
··· 213 213 tryToken(expect) { 214 214 let p = this.pos; 215 215 let t; 216 - try { t = this.parseToken(); } catch (e) { /*ignore*/ } 216 + try { t = this.parseToken(); } catch (ignore) { /*ignore*/ } 217 217 // console.log('[debug] tryToken(' + expect + ') = ' + t); 218 218 if (t == expect) 219 219 return true; ··· 371 371 let p = this.pos; 372 372 try { 373 373 return this.parseBuiltinType(); 374 - } catch (e) { 374 + } catch (ignore) { 375 375 // console.log('[debug] parseAssignment failed on parseType', e); 376 376 this.pos = p; 377 377 let x = { ··· 442 442 case 'NULL': 443 443 return null; 444 444 } 445 - } catch (e) { 445 + } catch (ignore) { 446 446 this.pos = p; 447 447 } 448 448 p = this.pos; 449 449 try { 450 450 return this.parseIdentifier(); 451 - } catch (e) { 451 + } catch (ignore) { 452 452 this.pos = p; 453 453 } 454 454 this.exception('Unknown value type.');
+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
+2 -2
release.sh
··· 1 1 #!/bin/sh 2 2 set -e 3 3 FILES=" 4 - asn1.js oids.js defs.js base64.js hex.js int10.js dom.js context.js theme.js 4 + asn1.js oids.js defs.js base64.js hex.js dom.js context.js theme.js 5 5 rfcdef.js test.js tags.js 6 6 index.html index.css index.js index-local.html 7 7 favicon.svg tree-icon-light.svg tree-icon-dark.svg 8 - README.md LICENSE 8 + README.md LICENSE CHANGELOG.md 9 9 updateOID.sh check.sh 10 10 examples 11 11 "
+3
tags.js
··· 1 1 export const tags = { 2 + "2.1.1": "2025-10-24", 3 + "2.1.0": "2025-08-03", 4 + "2.0.6": "2025-07-28", 2 5 "2.0.5": "2025-04-12", 3 6 "2.0.4": "2024-05-08", 4 7 "2.0.3": "2024-05-06",
+69 -29
test.js
··· 1 1 #!/usr/bin/env node 2 2 3 + import * as fs from 'fs'; // 'node:fs' doesn't work on NodeJS 14.5.0 3 4 import { ASN1, Stream } from './asn1.js'; 5 + import { Defs } from './defs.js'; 4 6 import { Hex } from './hex.js'; 5 7 import { Base64 } from './base64.js'; 6 - import { Int10 } from './int10.js'; 8 + import { createPatch } from 'diff'; 7 9 8 10 const all = (process.argv[2] == 'all'); 9 11 ··· 14 16 run: 0, 15 17 error: 0, 16 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 + } 17 28 18 29 /** 19 30 * A class for managing and executing tests. 20 31 */ 21 32 class Tests { 22 33 /** 34 + * The title of the test suite. 35 + * @type {string} 36 + */ 37 + title; 38 + 39 + /** 23 40 * An array to store test data. 24 41 * @type {Array<unknown>} 25 42 */ ··· 33 50 34 51 /** 35 52 * Constructs a new Tests instance. 53 + * @param {string} title - The title of the test suite. 36 54 * @param {Function} checkRow - A function to check each row of data. 37 55 * @param {Array<unknown>} data - The test data to be processed. 38 56 */ 39 - constructor(checkRow, data) { 57 + constructor(title, checkRow, data) { 58 + this.title = title; 40 59 this.checkRow = checkRow; 41 60 this.data = data; 42 61 } ··· 45 64 * Executes the tests and checks their results for all rows. 46 65 */ 47 66 checkAll() { 67 + if (all) console.log('\x1B[1m\x1B[34m' + this.title + '\x1B[39m\x1B[22m'); 48 68 for (const t of this.data) 49 69 this.checkRow(t); 50 70 } ··· 57 77 */ 58 78 checkResult(result, expected, comment) { 59 79 ++stats.run; 60 - if (!result || result == expected) { 80 + if ((typeof expected != 'string' && !result) || result == expected) { 61 81 if (all) console.log('\x1B[1m\x1B[32mOK \x1B[39m\x1B[22m ' + comment); 62 82 } else { 63 83 ++stats.error; 64 84 console.log('\x1B[1m\x1B[31mERR\x1B[39m\x1B[22m ' + comment); 65 - console.log(' \x1B[1m\x1B[34mEXP\x1B[39m\x1B[22m ' + expected.toString().replace(/\n/g, '\n ')); 66 - console.log(' \x1B[1m\x1B[33mGOT\x1B[39m\x1B[22m ' + result.replace(/\n/g, '\n ')); 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 + } 67 94 } 68 95 } 69 96 } 70 97 71 - tests.push(new Tests(function (t) { 98 + tests.push(new Tests('ASN.1', function (t) { 72 99 const input = t[0], 73 100 expected = t[1], 74 101 comment = t[2]; ··· 155 182 ['0D04C27B0302','8571.3.2', 'Relative OID from ISO/IEC 8825-1:2002 8.20.5'], 156 183 // UTF-8 157 184 ['0C0E4C61706FE280997320F09F9A972E', 'Lapoโ€™s ๐Ÿš—.', 'UTF-8 4-byte sequence'], 158 - // T-REC-X.690-201508 185 + // T-REC-X.690-202102 159 186 ['0307040A3B5F291CD0', '(44 bit)\n00001010001110110101111100101001000111001101', 'Example 8.6.4.2: bit string (primitive encoding)'], 160 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'], 161 200 // avoid past bugs 162 201 ['23800303000A3B230A0302005F030404291CD00000', '(44 bit)\n00001010001110110101111100101001000111001101', 'Bit string (recursive constructed)'], 163 202 ['0348003045022100DE601E573DAFB59BC551D58E3E7B9EDA0612DD0112805A2217B734759B884417022067C3FDE60780D41C1D7A3B90291F3D39C4DC2F206DCCBA2F982C06B67C09B232', '(568 bit)\n0011000001000101000000100010000100000000110111100110000000011110010101110011110110101111101101011001101111000101010100011101010110001110001111100111101110011110110110100000011000010010110111010000000100010010100000000101101000100010000101111011011100110100011101011001101110001000010001000001011100000010001000000110011111000011111111011110011000000111100000001101010000011100000111010111101000111011100100000010100100011111001111010011100111000100110111000010111100100000011011011100110010111010001011111001100000101100000001101011011001111100000010011011001000110010', 'not constructed, but contains structures'], ··· 170 209 ['171E83C1B251803F86DD01E9CFA886BE89A7316D8372649AC2231EC669F81A84', /^Exception:\nError: Unrecognized time: /, 'Invalid UTCTime'], // GitHub issue #79 171 210 ])); 172 211 173 - tests.push(new Tests(function (t) { 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) { 174 235 let bin = Base64.decode(t); 175 236 let url = new Stream(bin, 0).b64Dump(0, bin.length); 176 237 // check base64url encoding ··· 189 250 'ABCDEFE=', 190 251 'ABCDEFGH', 191 252 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQR\nSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456w==', 192 - ])); 193 - 194 - tests.push(new Tests(function (t) { 195 - this.row = (0|this.row) + 1; 196 - this.num = this.num || new Int10(); 197 - this.num.mulAdd(t[0], t[1]); 198 - this.checkResult(this.num.toString(), t[2], 'Int10 row ' + this.row); 199 - }, [ 200 - [0, 1000000000, '1000000000'], 201 - [256, 23, '256000000023'], 202 - [256, 23, '65536000005911'], 203 - [256, 23, '16777216001513239'], 204 - [256, 23, '4294967296387389207'], 205 - [256, 23, '1099511627875171637015'], 206 - [256, 23, '281474976736043939075863'], 207 - [253, 1, '71213169114219116586193340'], 208 - [253, 1, '18016931785897436496306915021'], 209 - [253, 1, '4558283741832051433565649500314'], 210 - [253, 1, '1153245786683509012692109323579443'], 211 - [253, 1, '291771184030927780211103658865599080'], 212 - [1, 0, '291771184030927780211103658865599080'], 213 253 ])); 214 254 215 255 for (const t of tests)
+1 -1
testDefs.js
··· 11 11 try { 12 12 try { // try PEM first 13 13 content = Base64.unarmor(content); 14 - } catch (e) { // try DER/BER then 14 + } catch (ignore) { // try DER/BER then 15 15 } 16 16 let result = ASN1.decode(content); 17 17 content = null;
+7 -1
vite.config.js
··· 16 16 }; 17 17 }; 18 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 + 19 25 export default defineConfig({ 20 26 plugins: [ 21 27 preventSVGEmit(), ··· 25 31 if (removeNodes.includes(node.attribs.id)) 26 32 DomUtils.removeElement(node); 27 33 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()); 34 + node.attribs.href = 'data:image/svg+xml,' + massageSVG(fs.readFileSync('favicon.svg', 'ascii').replace(/^([^<]+|<[^s]|<s[^v]|<sv[^g])+/, '').trim()); 29 35 }, 30 36 }), 31 37 viteSingleFile(),