···521521 }
522522}
523523524524+/**
525525+ * ASN1 class for parsing ASN.1 encoded data.
526526+ * Instances of this class represent an ASN.1 element and provides methods to parse and display its content.
527527+ */
524528export class ASN1 {
529529+ /**
530530+ * Creates an ASN1 parser object.
531531+ * @param {Stream} stream - The stream containing the ASN.1 data.
532532+ * @param {number} header - The header length.
533533+ * @param {number} length - The length of the data.
534534+ * @param {ASN1Tag} tag - The ASN.1 tag.
535535+ * @param {number} tagLen - The length of the tag.
536536+ * @param {Array} sub - The sub-elements.
537537+ */
525538 constructor(stream, header, length, tag, tagLen, sub) {
526539 if (!(tag instanceof ASN1Tag)) throw new Error('Invalid tag value.');
527540 this.stream = stream;
···531544 this.tagLen = tagLen;
532545 this.sub = sub;
533546 }
547547+548548+ /**
549549+ * Get the type name of the ASN.1 element.
550550+ * @returns {string} The type name.
551551+ */
534552 typeName() {
535553 switch (this.tag.tagClass) {
536554 case 0: // universal
···570588 case 3: return 'Private_' + this.tag.tagNumber.toString();
571589 }
572590 }
573573- /** A string preview of the content (intended for humans). */
591591+592592+ /**
593593+ * Get a string preview of the content (intended for humans).
594594+ * @param {number} maxLength - The maximum length of the content.
595595+ * @returns {string|null} The content preview or null if not supported.
596596+ */
574597 content(maxLength) {
575598 if (this.tag === undefined)
576599 return null;
···638661 }
639662 return null;
640663 }
664664+665665+ /**
666666+ * Get a string representation of the ASN.1 element.
667667+ * @returns {string} The string representation.
668668+ */
641669 toString() {
642670 return this.typeName() + '@' + this.stream.pos + '[header:' + this.header + ',length:' + this.length + ',sub:' + ((this.sub === null) ? 'null' : this.sub.length) + ']';
643671 }
672672+673673+ /**
674674+ * Get a pretty string representation of the ASN.1 element.
675675+ * @param {string} indent - The indentation string.
676676+ * @returns {string} The pretty string representation.
677677+ */
644678 toPrettyString(indent) {
645679 if (indent === undefined) indent = '';
646680 let s = indent;
···671705 }
672706 return s;
673707 }
708708+709709+ /**
710710+ * Get the starting position of the element in the stream.
711711+ * @returns {number} The starting position.
712712+ */
674713 posStart() {
675714 return this.stream.pos;
676715 }
716716+717717+ /**
718718+ * Get the position of the content in the stream.
719719+ * @returns {number} The content position.
720720+ */
677721 posContent() {
678722 return this.stream.pos + this.header;
679723 }
724724+725725+ /**
726726+ * Get the ending position of the element in the stream.
727727+ * @returns {number} The ending position.
728728+ */
680729 posEnd() {
681730 return this.stream.pos + this.header + Math.abs(this.length);
682731 }
683683- /** Position of the length. */
732732+733733+ /**
734734+ * Get the position of the length in the stream.
735735+ * @returns {number} The length position.
736736+ */
684737 posLen() {
685738 return this.stream.pos + this.tagLen;
686739 }
687687- /** Hexadecimal dump of the node.
688688- * @param type 'raw', 'byte' or 'dump' */
740740+741741+ /**
742742+ * Get a hexadecimal dump of the node.
743743+ * @param {string} [type='raw'] - The dump type: 'raw', 'byte', or 'dump'.
744744+ * @returns {string} The hexadecimal dump.
745745+ */
689746 toHexString(type = 'raw') {
690747 return this.stream.hexDump(this.posStart(), this.posEnd(), type);
691748 }
692692- /** Base64url dump of the node (according to RFC 4648 section 5).
693693- * @param {string} type 'url' (default, section 5 without padding) or 'std' (section 4 with padding)
694694- */
749749+750750+ /**
751751+ * Get a base64url dump of the node (according to RFC 4648 section 5).
752752+ * @param {string} [type='url'] - The dump type: 'url' (section 5 without padding) or 'std' (section 4 with padding).
753753+ * @returns {string} The base64 encoded representation.
754754+ */
695755 toB64String(type = 'url') {
696756 return this.stream.b64Dump(this.posStart(), this.posEnd(), type);
697757 }
758758+759759+ /**
760760+ * Decode the length field of an ASN.1 element.
761761+ * @param {Stream} stream - The stream to read from.
762762+ * @returns {number|null} The decoded length, or null for indefinite length.
763763+ * @throws {Error} If the length is invalid or exceeds 48 bits.
764764+ */
698765 static decodeLength(stream) {
699766 const buf = stream.get(),
700767 len = buf & 0x7F;
···709776 value = (value << 8) | stream.get();
710777 return value;
711778 }
779779+780780+ /**
781781+ * Decode an ASN.1 element from a stream.
782782+ * @param {Stream|array|string} stream - The input data.
783783+ * @param {number} [offset=0] - The offset to start decoding from.
784784+ * @param {Function} [type=ASN1] - The class to instantiate.
785785+ * @returns {ASN1} The decoded ASN.1 element.
786786+ * @throws {Error} If the decoding fails.
787787+ */
712788 static decode(stream, offset, type = ASN1) {
713789 if (!(type == ASN1 || type.prototype instanceof ASN1))
714790 throw new Error('Must pass a class that extends ASN1');