diff --git a/asn1.js b/asn1.js index 712d372..3082811 100644 --- a/asn1.js +++ b/asn1.js @@ -782,14 +782,19 @@ export class ASN1 { * @param {Stream|array|string} stream - The input data. * @param {number} [offset=0] - The offset to start decoding from. * @param {Function} [type=ASN1] - The class to instantiate. + * @param {Object} [options={maxDepth:100}] - Optional settings for decoding. + * @param {number} [depth=0] - The annidiation depth. * @returns {ASN1} The decoded ASN.1 element. * @throws {Error} If the decoding fails. */ - static decode(stream, offset, type = ASN1) { + static decode(stream, offset, type = ASN1, options = {}, depth = 0) { if (!(type == ASN1 || type.prototype instanceof ASN1)) throw new Error('Must pass a class that extends ASN1'); if (!(stream instanceof Stream)) stream = new Stream(stream, offset || 0); + const maxDepth = typeof(options.maxDepth) == 'number' ? options.maxDepth : 100; + if (depth > maxDepth) + throw new Error(`ASN.1 structure nesting exceeds maximum depth of ${maxDepth}`); let streamStart = new Stream(stream), tag = new ASN1Tag(stream), tagLen = stream.pos - streamStart.pos, @@ -803,14 +808,14 @@ export class ASN1 { if (len !== null) { // definite length while (stream.pos < end) - sub[sub.length] = type.decode(stream); + sub[sub.length] = type.decode(stream, null, type, options, depth + 1); if (stream.pos != end) throw new Error('Content size is not correct for container at offset ' + start); } else { // undefined length try { for (;;) { - let s = type.decode(stream); + let s = type.decode(stream, null, type, options, depth + 1); if (s.tag.isEOC()) break; sub[sub.length] = s; diff --git a/test.js b/test.js index d5f4851..2336d36 100755 --- a/test.js +++ b/test.js @@ -211,6 +211,8 @@ tests.push(new Tests('ASN.1', function (t) { ['181232303030313231353132333435362E313233', '2000-12-15 12:34:56.123', 'Generalized time with milliseconds'], // GitHub issue #107 ['181832303030313231353132333435362E313233343536373839', '2000-12-15 12:34:56.123456789', 'Generalized time with nanoseconds'], // GitHub issue #107 ['0484FFFFFFFF222222', 'Exception:\nError: Element at offset 6 has a length of 4294967295, which is past the end of the stream', 'Excessive length'], // GitHub issue #108 + ['3081EC3081E93081E63081E33081E03081DD3081DA3081D73081D43081D13081CE3081CB3081C83081C53081C23081BF3081BC3081B93081B63081B33081B03081AD3081AA3081A73081A43081A130819E30819B30819830819530819230818F30818C308189308186308183308180307E307C307A30783076307430723070306E306C306A30683066306430623060305E305C305A30583056305430523050304E304C304A30483046304430423040303E303C303A30383036303430323030302E302C302A30283026302430223020301E301C301A30183016301430123010300E300C300A30083006300430023000', '(1 elem)', '100 nested structures'], + ['3081EF3081EC3081E93081E63081E33081E03081DD3081DA3081D73081D43081D13081CE3081CB3081C83081C53081C23081BF3081BC3081B93081B63081B33081B03081AD3081AA3081A73081A43081A130819E30819B30819830819530819230818F30818C308189308186308183308180307E307C307A30783076307430723070306E306C306A30683066306430623060305E305C305A30583056305430523050304E304C304A30483046304430423040303E303C303A30383036303430323030302E302C302A30283026302430223020301E301C301A30183016301430123010300E300C300A30083006300430023000', 'Exception:\nError: ASN.1 structure nesting exceeds maximum depth of 100', '101 nested structures'], ])); tests.push(new Tests('Length', function (t) {