UNPKG

pp-certificate

Version:

A very simple script for encoding and decoding pkcs7/pkcs6/x509 certification in Javascript with node.js and web browser support

931 lines (816 loc) 31.6 kB
if (typeof require === "function") {var bigInt = require("big-integer");var ByteArray = require('pp-bytearray');var moment = require('moment');} var asn1 = {}; var der = asn1.der = {}; // class类型 der.CLASS_UNIVERSAL = 0; der.CLASS_APPLICATION = 1; der.CLASS_CONTEXT_SPECIFIC = 2; der.CLASS_PRIVATE = 3; // type der.TYPE_PRIMITIVE = 0; der.TYPE_CONSTRUCTED = 1; // Universal tag value der.TAG_VALUE_BOOLEAN = 1; der.TAG_VALUE_INTEGER = 2; der.TAG_VALUE_BIT_STRING = 3; der.TAG_VALUE_OCTET_STRING = 4; der.TAG_VALUE_NULL = 5; der.TAG_VALUE_OBJECT_IDENTIFIER = 6; der.TAG_VALUE_OBJECT_DESCRIPTION = 7; der.TAG_VALUE_EXTERNAL = 8; der.TAG_VALUE_REAL = 9; der.TAG_VALUE_ENUMERATED = 10; der.TAG_VALUE_EMBEDDED_PDV = 11; der.TAG_VALUE_UTF8_STRING = 12; der.TAG_VALUE_SEQUENCE = 16; der.TAG_VALUE_SET = 17; der.TAG_VALUE_NUMERIC_STRING = 18; der.TAG_VALUE_PRINTABLE_STRING = 19; der.TAG_VALUE_TELETEX_STRING = 20; der.TAG_VALUE_VIDEO_TEX_STRING = 21; der.TAG_VALUE_IA5_STRING = 22; der.TAG_VALUE_UTC_TIME = 23; der.TAG_VALUE_GENERALIZED_TIME = 24; der.TAG_VALUE_GRAPHIC_STRING = 25; der.TAG_VALUE_VISIBLE_STRING = 26; der.TAG_VALUE_GENERAL_STRING = 27; der.TAG_VALUE_UNIVERSAL_STRING = 28; der.TAG_VALUE_CHARACTER_STRING = 29; der.TAG_VALUE_BMP_STRING = 30; // Tag type der.TAG_TYPE_NORMAL = 0; der.TAG_TYPE_IMPLICIT = 1; der.TAG_TYPE_EXPLICIT = 2; der.oid = {}; der.oid.toBytes = function(oid) { if (typeof oid !== 'string') { throw "OID toBytes error, the oid is not a string"; } var av = oid.split('.'); var v = []; if (av.length < 2) { throw "OID toBytes error, the oid is not a valid oid:" + oid; } v.push(parseInt(av[0]) * 40 + parseInt(av[1])); for (var i = 2; i < av.length; i++) { var bi = bigInt(av[i]); if (bi.gt(127)) { var ba = bi.toArray(0x80).value; for (var j = 0; j < ba.length; j++) { if (j === ba.length - 1) { v.push(ba[j]); } else { v.push(0x80 | ba[j]); } } } else { v.push(bi.value); } } return v; }; der.oid.fromBytes = function(bytes) { if (bytes.length <= 0) return ''; var v = []; if (bytes[0] <= 39) { v.push(0); v.push(bytes[0]); } else if (bytes[0] <= 79) { v.push(1); v.push(bytes[0] - 40); } else { v.push(2); v.push(bytes[0] - 80); } var b = []; for (var i = 1; i < bytes.length; i++) { b.push(bytes[i] & 0x7f); if ((bytes[i] & 0x80) === 0) { v.push(bigInt.fromArray(b, 0x80).toString()); b = []; } } return v.join('.'); }; der.toHex = function(v) { var h = (v instanceof Array) ? bigInt.fromArray(v, 256).toString(16) : bigInt(v).toString(16); return h.length%2 === 0 ? h : '0' + h; } der.updateUtcTime = function(primitive) { if (primitive instanceof der.Primitive && (primitive.tag.value == der.TAG_VALUE_UTC_TIME || primitive.tag.value == der.TAG_VALUE_GENERALIZED_TIME)) { var year = moment(primitive.value, 'YYYY-MM-DD HH:mm:ss').utc().year(); primitive.tag.value = year >= 1950 && year <= 2049 ? der.TAG_VALUE_UTC_TIME : der.TAG_VALUE_GENERALIZED_TIME; } } der.Tag = (function() { "use strict"; function Tag(opt) { var o = typeof opt === 'undefined' ? {} : opt; var o = typeof o === 'object' ? o : {value:o}; this.class = o.class || der.CLASS_UNIVERSAL; this.type = o.type || der.TYPE_PRIMITIVE; this.value = o.value || 0; this.tagType = o.tagType || der.TAG_TYPE_NORMAL; this.tagValue = typeof o.tagValue === 'undefined' ? this.value : o.tagValue; // 当类型为implicit和explict时tag的value } Tag.prototype.encode = function(baBuf) { var t = []; while (true) { var v = bigInt(this.tagType === der.TAG_TYPE_IMPLICIT ? this.tagValue : this.value).shiftRight((8*t.length)).and(0xff).value; if (v === 0) {if(t.length === 0){t.push(v);}break;} t.push(v); } t.reverse(); baBuf.appendUint8((this.class << 6) | (this.type << 5) | t[0]); baBuf.appendBytes(t, 1); }; Tag.prototype.decode = function(baBuf, start, end) { end = typeof end === 'undefined' ? baBuf.length : end; if (end < start) { throw "Tag decode error, the message buffer is too short"; } var v = baBuf.getUint8(start); this.class = (v >> 6) & 3; this.type = (v >> 5) & 1; this.tagValue = v & 0x1f; if (this.tagValue === 0x1f) { // 多个八位组 var b = bigInt(this.tagValue); for (var i = start + 1; i < end; i++) { var tv = baBuf.getUint8(i); b.or(bigInt(tv).shiftLeft(8*(i-start))); if ((tv & 0x80) === 0) break; } this.tagValue = b.toString(); if (this.tagType != der.TAG_TYPE_IMPLICIT) this.value = this.tagValue; return Math.ceil(b.bitLength().value/8); } if (this.tagType != der.TAG_TYPE_IMPLICIT) this.value = this.tagValue; return Uint8Array.BYTES_PER_ELEMENT; }; Tag.prototype.fromJson = function(tag) { var o = tag || {}; this.class = o.class || der.CLASS_UNIVERSAL; this.type = o.type || der.TYPE_PRIMITIVE; this.value = o.value || 0; }; Tag.prototype.toJson = function() { return {class: this.class, type: this.type, value: this.value}; }; return Tag; })(); der.Length = (function() { "use strict"; function Length(len) { this.len = len || 0; } Length.prototype.encode = function(baBuf) { var b = bigInt(this.len); // 不定长度 if (b.lt(0)) { baBuf.appendUint8(0x80); } else if (b.leq(127)) { baBuf.appendUint8(this.len); } else { var v = bigInt(this.len).toArray(256).value; baBuf.appendUint8(0x80 | v.length); baBuf.appendBytes(v); } }; Length.prototype.decode = function(baBuf, start, end) { end = typeof end === 'undefined' ? baBuf.length : end; if (end < start) { throw "Length decode error, the message buffer is too short"; } var v = baBuf.getUint8(start); if (v === 0x80) { // TODO: this.len = -1; } else if ((v & 0x80) === 0) { this.len = v & 0x7f; } else { var l = v & 0x7f; if (end < start + 1 + l) { throw "Length decode error, the message buffer is too short"; } var b = baBuf.getBytes(start + 1, l); this.len = bigInt.fromArray(b, 256).value; return l + Uint8Array.BYTES_PER_ELEMENT; } return Uint8Array.BYTES_PER_ELEMENT; }; return Length; })(); der.Primitive = (function() { "use strict"; function Primitive(opt) { var o = opt || {}; this.tag = new der.Tag(o.tag); this.value = typeof o.value === 'undefined' ? 0 : o.value; this.padding = typeof o.padding === 'undefined' ? 0 : o.padding; this.optional = typeof o.optional === 'undefined' ? false : o.optional; this.present = typeof o.present === 'undefined' ? true : o.present; this.bits = o.bits || 0; this.explicitTag = o.explicitTag; } Primitive.prototype.encode = function(baBuf) { if (!this.present) return; var baMsg = this.tag.tagType === der.TAG_TYPE_EXPLICIT ? new ByteArray() : baBuf; // tag编码 this.tag.encode(baMsg); switch (this.tag.value) { case der.TAG_VALUE_NULL: // 如果是NULL,则只编码长度 baMsg.appendUint8(0); break; case der.TAG_VALUE_BOOLEAN: baMsg.appendUint8(1); baMsg.appendUint8(this.value ? 0xff : 0); break; case der.TAG_VALUE_REAL: throw "Primitive encode error, un-suport tag value 'real'"; //break; case der.TAG_VALUE_BIT_STRING: { if (this.value == 0) { baMsg.appendUint8(1); baMsg.appendUint8(0); } else { var b = bigInt(this.value); var bs = b.toString(2); var pl = 8 - bs.length%8; // padding length pl = this.padding === -1 || this.padding > pl ? pl : this.padding; var v = b.shiftLeft(pl).toArray(256).value; // bits长度 var bn = this.bits > v.length ? this.bits - v.length : 0; // 长度编码 new der.Length(v.length + 1 + bn).encode(baMsg); // padding编码 baMsg.appendUint8(pl); // 值编码 for (var i = 0; i < bn; i++) baMsg.appendUint8(0); baMsg.appendBytes(v); } break; } case der.TAG_VALUE_OBJECT_IDENTIFIER: { var v = der.oid.toBytes(this.value); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); break; } case der.TAG_VALUE_IA5_STRING: // ascii字符(IA5String类型的编码对象是ASCII集合中的大多数.包括NULL,BEL,TAB,NL,LF,CR以及32~126) case der.TAG_VALUE_PRINTABLE_STRING: { // 可打印字符串对象是ASCII集合的一个有限子集,这个子集包括32,39,40~41,43~58,61,63以及65~122. if (typeof this.value !== 'string') { throw "Primitive encode error, the value is not a string"; } var v = this.value.split('').map(function(c) {return c.charCodeAt();}); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); break; } case der.TAG_VALUE_INTEGER: case der.TAG_VALUE_ENUMERATED: { var b = bigInt(this.value); if (b.lt(0)) { throw "Primitive-integer encode error, un-suport negative value"; } else { var v = b.toArray(256).value; if ((v[0] & 0x80) === 0x80) { // 长度 new der.Length(v.length + 1).encode(baMsg); // 补0 baMsg.appendUint8(0); } else { new der.Length(v.length).encode(baMsg); } // 值编码 baMsg.appendBytes(v); } break; } case der.TAG_VALUE_UTF8_STRING: { var v = ByteArray.toUTF8(this.value); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); break; } case der.TAG_VALUE_UTC_TIME: {// 注意1950-2049年的时间用UTCTime,1950年前和2049年后的时间用GeneralizedTime var v = moment(this.value, 'YYYY-MM-DD HH:mm:ss').utc().format('YYMMDDHHmmss\\Z'); v = v.split('').map(function(c) {return c.charCodeAt();}); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); break; } case der.TAG_VALUE_GENERALIZED_TIME: {// 注意1950-2049年的时间用UTCTime,1950年前和2049年后的时间用GeneralizedTime var v = moment(this.value, 'YYYY-MM-DD HH:mm:ss').utc().format('YYYYMMDDHHmmss\\Z'); v = v.split('').map(function(c) {return c.charCodeAt();}); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); break; } case der.TAG_VALUE_OCTET_STRING: // 可以理解为字节数组 case der.TAG_VALUE_BMP_STRING: // 可以理解为字节数组 default: { // 长度编码 new der.Length(this.value.length).encode(baMsg); // 值编码 baMsg.appendBytes(this.value); break; } } if (this.tag.tagType === der.TAG_TYPE_EXPLICIT) { var v = baMsg.getBytes(); // explicit tag this.explicitTag.encode(baBuf); // Length new der.Length(v.length).encode(baBuf); // Value baBuf.appendBytes(v); } }; Primitive.prototype.decode = function(baBuf, start, end) { end = typeof end === 'undefined' ? baBuf.length : end; start = start || 0; var etaglen = 0; if (this.tag.tagType === der.TAG_TYPE_EXPLICIT) { var istart = start; start += this.explicitTag.decode(baBuf, start, end); start += new der.Length().decode(baBuf, start, end); etaglen = start - istart; } // tag解码 var tl = this.tag.decode(baBuf, start, end); // length解码 var len = new der.Length(); var ll = len.decode(baBuf, start + tl, end); var mlen = tl + ll + len.len; if (end < start + mlen) { throw "Primitive decode error, the message buffer is too short"; } // value解码 var b = baBuf.getBytes(start + tl + ll, len.len); switch (this.tag.value) { case der.TAG_VALUE_NULL: this.value = 0; break; case der.TAG_VALUE_BOOLEAN: this.value = bigInt.fromArray(b, 256).toString() === '0' ? false : true; break; case der.TAG_VALUE_REAL: throw "Primitive decode error, un-suport tag value 'real'"; case der.TAG_VALUE_BIT_STRING: { if (b.length <= 0 || (b.length === 1 && b[0] === 0)) { this.value = 0; } else { var pl = b[0]; this.value = bigInt.fromArray(b.slice(1), 256).shiftRight(pl).toString(); this.bits = b.length - 1; } break; } case der.TAG_VALUE_OBJECT_IDENTIFIER: { this.value = der.oid.fromBytes(b); break; } case der.TAG_VALUE_IA5_STRING: // ascii字符(IA5String类型的编码对象是ASCII集合中的大多数.包括NULL,BEL,TAB,NL,LF,CR以及32~126) case der.TAG_VALUE_PRINTABLE_STRING: { // 可打印字符串对象是ASCII集合的一个有限子集,这个子集包括32,39,40~41,43~58,61,63以及65~122. this.value = b.map(function(c) {return String.fromCharCode(c);}).join(''); break; } case der.TAG_VALUE_INTEGER: case der.TAG_VALUE_ENUMERATED: { if (b.length <= 0) { this.value = 0; break; } if ((b[0] & 0x80) !== 0) { throw "Primitive-integer decode error, un-suport negative value"; } this.value = bigInt.fromArray(b, 256).toString(); break; } case der.TAG_VALUE_UTF8_STRING: { this.value = ByteArray.fromUTF8(b); break; } case der.TAG_VALUE_UTC_TIME: { var v = b.map(function(c) {return String.fromCharCode(c);}).join(''); v = v >= '50' ? '19' + v : '20' + v; this.value = moment.utc(v, 'YYYYMMDDHHmmss\\Z').local().format('YYYY-MM-DD HH:mm:ss'); break; } case der.TAG_VALUE_GENERALIZED_TIME: { var v = b.map(function(c) {return String.fromCharCode(c);}).join(''); this.value = moment.utc(v, 'YYYYMMDDHHmmss\\Z').local().format('YYYY-MM-DD HH:mm:ss'); break; } case der.TAG_VALUE_OCTET_STRING: // 可以理解为字节数组 case der.TAG_VALUE_BMP_STRING: // 可以理解为字节数组 default: this.value = b; break; } return mlen + etaglen; }; Primitive.prototype.fromJson = function(bi) { var o = bi || {}; this.tag.fromJson(o.tag); this.value = typeof o.value === 'undefined' ? 0 : o.value; }; Primitive.prototype.toJson = function() { return {tag: this.tag.toJson(), value: this.value, /*hex: bigInt(this.value).toString(16)*/}; }; Primitive.prototype.toBytes = function() { var ba = new ByteArray(); this.encode(ba); return ba.getBytes(); }; Primitive.prototype.toString = function(encoding='base64') { return new Buffer(this.toBytes()).toString(encoding); }; return Primitive; })(); der.Sequence = (function() { "use strict"; function Sequence(opt) { var o = opt || {}; this.tag = new der.Tag(o.tag || { class: asn1.der.CLASS_UNIVERSAL, type: asn1.der.TYPE_CONSTRUCTED, value: asn1.der.TAG_VALUE_SEQUENCE }); this.optional = typeof o.optional === 'undefined' ? false : o.optional; this.present = typeof o.present === 'undefined' ? true : o.present; this.elements = o.elements || []; this.explicitTag = o.explicitTag; } Sequence.prototype.encode = function(baBuf) { if (!this.present) return; var baMsg = this.tag.tagType === der.TAG_TYPE_EXPLICIT ? new ByteArray() : baBuf; // 子元素编码 var baElm = new ByteArray(); this.elements.forEach(function(element) { element.encode(baElm); }); var v = baElm.length > 0 ? baElm.getBytes() : []; // tag编码 this.tag.encode(baMsg); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); if (this.tag.tagType === der.TAG_TYPE_EXPLICIT) { var v = baMsg.getBytes(); // explicit tag this.explicitTag.encode(baBuf); // Length new der.Length(v.length).encode(baBuf); // Value baBuf.appendBytes(v); } }; Sequence.prototype.decode = function(baBuf, start, end) { end = typeof end === 'undefined' ? baBuf.length : end; start = start || 0; var etaglen = 0; if (this.tag.tagType === der.TAG_TYPE_EXPLICIT) { var istart = start; start += this.explicitTag.decode(baBuf, start, end); start += new der.Length().decode(baBuf, start, end); etaglen = start - istart; } // tag解码 var tl = this.tag.decode(baBuf, start, end); // length解码 var len = new der.Length(); var ll = len.decode(baBuf, start + tl, end); var mlen = tl + ll + len.len; var elmEnd = start + mlen; if (end < elmEnd) { throw "Sequence decode error, the message buffer is too short"; } // elements解码 this.elements = []; if (len.len <= 0) return mlen + etaglen; start += tl + ll; var readLen = 0; var elmTag = new der.Tag(); while (readLen < len.len) { // 读子元素tag elmTag.decode(baBuf, start, elmEnd); var curElm = elmTag.type === der.TYPE_PRIMITIVE ? new der.Primitive() : new Sequence(); var elmLen = curElm.decode(baBuf, start, elmEnd); this.elements.push(curElm); readLen += elmLen; start += elmLen; } return mlen + etaglen; }; Sequence.prototype.fromJson = function(se) { var o = se || {}; this.tag.fromJson(se.tag || this.tag); this.elements = o.elements || []; }; Sequence.prototype.toJson = function() { var sequence = []; this.elements.forEach(function(element) { sequence.push(element.toJson()); }); return {tag: this.tag.toJson(), sequence}; }; Sequence.prototype.toBytes = function() { var ba = new ByteArray(); this.encode(ba); return ba.getBytes(); }; Sequence.prototype.toString = function(encoding='base64') { return new Buffer(this.toBytes()).toString(encoding); }; return Sequence; })(); der.Constructive = (function() { "use strict"; function Constructive(opt) { var o = opt || {}; this.tag = new asn1.der.Tag(o.tag || { class: asn1.der.CLASS_UNIVERSAL, type: asn1.der.TYPE_CONSTRUCTED, value: asn1.der.TAG_VALUE_SEQUENCE }); this.optional = typeof o.optional === 'undefined' ? false : o.optional; this.present = typeof o.present === 'undefined' ? true : o.present; this.elements = o.elements || []; this.explicitTag = o.explicitTag; } Constructive.prototype.encodeSubField = function(baBuf) { this.elements.forEach(function(element) { element.encode(baBuf); }); }; Constructive.prototype.encode = function(baBuf) { if (!this.present) return; var baMsg = this.tag.tagType === der.TAG_TYPE_EXPLICIT ? new ByteArray() : baBuf; // 子元素编码 var baElm = new ByteArray(); this.encodeSubField(baElm); var v = baElm.length > 0 ? baElm.getBytes() : []; // tag编码 this.tag.encode(baMsg); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); if (this.tag.tagType === der.TAG_TYPE_EXPLICIT) { var vv = baMsg.getBytes(); // explicit tag this.explicitTag.encode(baBuf); // Length new der.Length(vv.length).encode(baBuf); // Value baBuf.appendBytes(vv); } }; Constructive.prototype.decodeSubField = function(baBuf, start, end) { var tag = new der.Tag(); this.elements.forEach(function(element) { if (element.optional) { if (start >= end) { element.present = false; return; } var elmTag = element.tag.tagType === der.TAG_TYPE_EXPLICIT ? element.explicitTag.value : element.tag.tagValue; tag.decode(baBuf, start, end); if (tag.value != elmTag) { element.present = false; return; } } element.present = true; start += element.decode(baBuf, start, end); }); }; Constructive.prototype.decode = function(baBuf, start, end) { end = typeof end === 'undefined' ? baBuf.length : end; start = start || 0; var etaglen = 0; if (this.tag.tagType === der.TAG_TYPE_EXPLICIT) { var istart = start; start += this.explicitTag.decode(baBuf, start, end); start += new der.Length().decode(baBuf, start, end); etaglen = start - istart; } // tag解码 var tl = this.tag.decode(baBuf, start, end); // length解码 var len = new der.Length(); var ll = len.decode(baBuf, start + tl, end); var mlen = tl + ll + len.len; var elmEnd = start + mlen; if (end < elmEnd) { throw "Constructive decode error, the message buffer is too short"; } // elements解码 start += tl + ll; // 子元素解码 if (len.len > 0) this.decodeSubField(baBuf, start, elmEnd); return mlen + etaglen; }; Constructive.prototype.toBytes = function() { var ba = new ByteArray(); this.encode(ba); return ba.getBytes(); }; Constructive.prototype.toString = function(encoding='base64') { return new Buffer(this.toBytes()).toString(encoding); }; return Constructive; })(); der.Set = (function() { "use strict"; function Set(opt) { var o = opt || {}; this.sequence = o.sequence || false; this.tag = new asn1.der.Tag(o.tag || { class: asn1.der.CLASS_UNIVERSAL, type: asn1.der.TYPE_CONSTRUCTED, value: this.sequence ? asn1.der.TAG_VALUE_SEQUENCE : asn1.der.TAG_VALUE_SET }); this.optional = typeof o.optional === 'undefined' ? false : o.optional; this.present = typeof o.present === 'undefined' ? true : o.present; this.elements = o.elements || []; this.elementCreator = o.elementCreator || function() {return new der.Primitive();} this.explicitTag = o.explicitTag; } Set.prototype.encode = function(baBuf) { if (!this.present) return; var baMsg = this.tag.tagType === der.TAG_TYPE_EXPLICIT ? new ByteArray() : baBuf; if (this.sequence) { // 子元素编码 this.elements.forEach(function(element) { element.encode(baMsg); }); } else { if (this.tag.tagType === der.TAG_TYPE_IMPLICIT) { // 子元素编码 var baElm = new ByteArray(); this.elements.forEach(function(element) { element.encode(baElm); }); if (baElm.length > 0) { var v = baElm.getBytes(); // tag编码 this.tag.encode(baMsg); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); } } else { // 子元素编码 var baElm = new ByteArray(); var tag = this.tag; this.elements.forEach(function(element) { element.encode(baElm); if (baElm.length > 0) { var v = baElm.getBytes(); // tag编码 tag.encode(baMsg); // 长度编码 new der.Length(v.length).encode(baMsg); // 值编码 baMsg.appendBytes(v); // 重置 baElm.clear(); } }); // 没有元素的情况 if ((!this.optional || this.present) && this.elements.length === 0) { this.tag.encode(baMsg); new der.Length(0).encode(baMsg); } } } if (this.tag.tagType === der.TAG_TYPE_EXPLICIT) { var v = baMsg.getBytes(); // explicit tag this.explicitTag.encode(baBuf); // Length new der.Length(v.length).encode(baBuf); // Value baBuf.appendBytes(v); } }; Set.prototype.decode = function(baBuf, start, end) { end = typeof end === 'undefined' ? baBuf.length : end; start = start || 0; var etaglen = 0; if (this.tag.tagType === der.TAG_TYPE_EXPLICIT) { var istart = start; start += this.explicitTag.decode(baBuf, start, end); start += new der.Length().decode(baBuf, start, end); etaglen = start - istart; } this.elements = []; var mlen = 0; var tag = new der.Tag(); var len = new der.Length(); if (this.sequence) { while (start < end) { // tag解码 var tl = tag.decode(baBuf, start, end); if (tag.value !== this.tag.tagValue) { break; } var elm = this.elementCreator(); var elen = elm.decode(baBuf, start, end); this.elements.push(elm); mlen += elen; start += elen; } } else { if (this.tag.tagType === der.TAG_TYPE_IMPLICIT) { // tag解码 var tl = this.tag.decode(baBuf, start, end); // length解码 var ll = len.decode(baBuf, start + tl, end); var elen = tl + ll + len.len; if (end < start + elen) { throw "Set decode error, the message buffer is too short"; } // elements解码 start += tl + ll; mlen += tl + ll; if (len.len > 0) { var elmEnd = start + len.len; while (start < elmEnd) { var elm = this.elementCreator(); elen = elm.decode(baBuf, start, elmEnd); this.elements.push(elm); start += elen; mlen += elen; } } } else { while (start < end) { // tag解码 var tl = tag.decode(baBuf, start, end); if (tag.value !== this.tag.tagValue) { break; } // length解码 var ll = len.decode(baBuf, start + tl, end); if (len.len <= 0) { mlen += tl + ll; break; } var elen = tl + ll + len.len; if (end < start + elen) { throw "Set decode error, the message buffer is too short"; } // elements解码 start += tl + ll; var elm = this.elementCreator(); start += elm.decode(baBuf, start, end); this.elements.push(elm); mlen += elen; } } } return mlen + etaglen; }; Set.prototype.toJson = function() { var o = []; this.elements.forEach(function(element) { o.push(element.toJson()); }); return o; }; Set.prototype.toBytes = function() { var ba = new ByteArray(); this.encode(ba); return ba.getBytes(); }; Set.prototype.toString = function(encoding='base64') { return new Buffer(this.toBytes()).toString(encoding); }; return Set; })(); // Node.js check if (typeof module !== "undefined" && module.hasOwnProperty("exports")) { module.exports = asn1; } // amd check if (typeof define === "function" && define.amd) { define("asn-der", [], function() { return asn1; }); }