aboutsummaryrefslogtreecommitdiff
path: root/node_modules/asn1.js/lib/asn1/decoders
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
commitde98e0b232509d5f40c135d540a70e415272ff85 (patch)
treea79222a5b58484ab3b80d18efcaaa7ccc4769b33 /node_modules/asn1.js/lib/asn1/decoders
parente0c9d480a73fa629c1e4a47d3e721f1d2d345406 (diff)
node_modules
Diffstat (limited to 'node_modules/asn1.js/lib/asn1/decoders')
-rw-r--r--node_modules/asn1.js/lib/asn1/decoders/der.js324
-rw-r--r--node_modules/asn1.js/lib/asn1/decoders/index.js4
-rw-r--r--node_modules/asn1.js/lib/asn1/decoders/pem.js49
3 files changed, 377 insertions, 0 deletions
diff --git a/node_modules/asn1.js/lib/asn1/decoders/der.js b/node_modules/asn1.js/lib/asn1/decoders/der.js
new file mode 100644
index 000000000..79a60acc2
--- /dev/null
+++ b/node_modules/asn1.js/lib/asn1/decoders/der.js
@@ -0,0 +1,324 @@
+var inherits = require('inherits');
+
+var asn1 = require('../../asn1');
+var base = asn1.base;
+var bignum = asn1.bignum;
+
+// Import DER constants
+var der = asn1.constants.der;
+
+function DERDecoder(entity) {
+ this.enc = 'der';
+ this.name = entity.name;
+ this.entity = entity;
+
+ // Construct base tree
+ this.tree = new DERNode();
+ this.tree._init(entity.body);
+};
+module.exports = DERDecoder;
+
+DERDecoder.prototype.decode = function decode(data, options) {
+ if (!(data instanceof base.DecoderBuffer))
+ data = new base.DecoderBuffer(data, options);
+
+ return this.tree._decode(data, options);
+};
+
+// Tree methods
+
+function DERNode(parent) {
+ base.Node.call(this, 'der', parent);
+}
+inherits(DERNode, base.Node);
+
+DERNode.prototype._peekTag = function peekTag(buffer, tag, any) {
+ if (buffer.isEmpty())
+ return false;
+
+ var state = buffer.save();
+ var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"');
+ if (buffer.isError(decodedTag))
+ return decodedTag;
+
+ buffer.restore(state);
+
+ return decodedTag.tag === tag || decodedTag.tagStr === tag ||
+ (decodedTag.tagStr + 'of') === tag || any;
+};
+
+DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) {
+ var decodedTag = derDecodeTag(buffer,
+ 'Failed to decode tag of "' + tag + '"');
+ if (buffer.isError(decodedTag))
+ return decodedTag;
+
+ var len = derDecodeLen(buffer,
+ decodedTag.primitive,
+ 'Failed to get length of "' + tag + '"');
+
+ // Failure
+ if (buffer.isError(len))
+ return len;
+
+ if (!any &&
+ decodedTag.tag !== tag &&
+ decodedTag.tagStr !== tag &&
+ decodedTag.tagStr + 'of' !== tag) {
+ return buffer.error('Failed to match tag: "' + tag + '"');
+ }
+
+ if (decodedTag.primitive || len !== null)
+ return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
+
+ // Indefinite length... find END tag
+ var state = buffer.save();
+ var res = this._skipUntilEnd(
+ buffer,
+ 'Failed to skip indefinite length body: "' + this.tag + '"');
+ if (buffer.isError(res))
+ return res;
+
+ len = buffer.offset - state.offset;
+ buffer.restore(state);
+ return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
+};
+
+DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) {
+ while (true) {
+ var tag = derDecodeTag(buffer, fail);
+ if (buffer.isError(tag))
+ return tag;
+ var len = derDecodeLen(buffer, tag.primitive, fail);
+ if (buffer.isError(len))
+ return len;
+
+ var res;
+ if (tag.primitive || len !== null)
+ res = buffer.skip(len)
+ else
+ res = this._skipUntilEnd(buffer, fail);
+
+ // Failure
+ if (buffer.isError(res))
+ return res;
+
+ if (tag.tagStr === 'end')
+ break;
+ }
+};
+
+DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder,
+ options) {
+ var result = [];
+ while (!buffer.isEmpty()) {
+ var possibleEnd = this._peekTag(buffer, 'end');
+ if (buffer.isError(possibleEnd))
+ return possibleEnd;
+
+ var res = decoder.decode(buffer, 'der', options);
+ if (buffer.isError(res) && possibleEnd)
+ break;
+ result.push(res);
+ }
+ return result;
+};
+
+DERNode.prototype._decodeStr = function decodeStr(buffer, tag) {
+ if (tag === 'bitstr') {
+ var unused = buffer.readUInt8();
+ if (buffer.isError(unused))
+ return unused;
+ return { unused: unused, data: buffer.raw() };
+ } else if (tag === 'bmpstr') {
+ var raw = buffer.raw();
+ if (raw.length % 2 === 1)
+ return buffer.error('Decoding of string type: bmpstr length mismatch');
+
+ var str = '';
+ for (var i = 0; i < raw.length / 2; i++) {
+ str += String.fromCharCode(raw.readUInt16BE(i * 2));
+ }
+ return str;
+ } else if (tag === 'numstr') {
+ var numstr = buffer.raw().toString('ascii');
+ if (!this._isNumstr(numstr)) {
+ return buffer.error('Decoding of string type: ' +
+ 'numstr unsupported characters');
+ }
+ return numstr;
+ } else if (tag === 'octstr') {
+ return buffer.raw();
+ } else if (tag === 'objDesc') {
+ return buffer.raw();
+ } else if (tag === 'printstr') {
+ var printstr = buffer.raw().toString('ascii');
+ if (!this._isPrintstr(printstr)) {
+ return buffer.error('Decoding of string type: ' +
+ 'printstr unsupported characters');
+ }
+ return printstr;
+ } else if (/str$/.test(tag)) {
+ return buffer.raw().toString();
+ } else {
+ return buffer.error('Decoding of string type: ' + tag + ' unsupported');
+ }
+};
+
+DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) {
+ var result;
+ var identifiers = [];
+ var ident = 0;
+ while (!buffer.isEmpty()) {
+ var subident = buffer.readUInt8();
+ ident <<= 7;
+ ident |= subident & 0x7f;
+ if ((subident & 0x80) === 0) {
+ identifiers.push(ident);
+ ident = 0;
+ }
+ }
+ if (subident & 0x80)
+ identifiers.push(ident);
+
+ var first = (identifiers[0] / 40) | 0;
+ var second = identifiers[0] % 40;
+
+ if (relative)
+ result = identifiers;
+ else
+ result = [first, second].concat(identifiers.slice(1));
+
+ if (values) {
+ var tmp = values[result.join(' ')];
+ if (tmp === undefined)
+ tmp = values[result.join('.')];
+ if (tmp !== undefined)
+ result = tmp;
+ }
+
+ return result;
+};
+
+DERNode.prototype._decodeTime = function decodeTime(buffer, tag) {
+ var str = buffer.raw().toString();
+ if (tag === 'gentime') {
+ var year = str.slice(0, 4) | 0;
+ var mon = str.slice(4, 6) | 0;
+ var day = str.slice(6, 8) | 0;
+ var hour = str.slice(8, 10) | 0;
+ var min = str.slice(10, 12) | 0;
+ var sec = str.slice(12, 14) | 0;
+ } else if (tag === 'utctime') {
+ var year = str.slice(0, 2) | 0;
+ var mon = str.slice(2, 4) | 0;
+ var day = str.slice(4, 6) | 0;
+ var hour = str.slice(6, 8) | 0;
+ var min = str.slice(8, 10) | 0;
+ var sec = str.slice(10, 12) | 0;
+ if (year < 70)
+ year = 2000 + year;
+ else
+ year = 1900 + year;
+ } else {
+ return buffer.error('Decoding ' + tag + ' time is not supported yet');
+ }
+
+ return Date.UTC(year, mon - 1, day, hour, min, sec, 0);
+};
+
+DERNode.prototype._decodeNull = function decodeNull(buffer) {
+ return null;
+};
+
+DERNode.prototype._decodeBool = function decodeBool(buffer) {
+ var res = buffer.readUInt8();
+ if (buffer.isError(res))
+ return res;
+ else
+ return res !== 0;
+};
+
+DERNode.prototype._decodeInt = function decodeInt(buffer, values) {
+ // Bigint, return as it is (assume big endian)
+ var raw = buffer.raw();
+ var res = new bignum(raw);
+
+ if (values)
+ res = values[res.toString(10)] || res;
+
+ return res;
+};
+
+DERNode.prototype._use = function use(entity, obj) {
+ if (typeof entity === 'function')
+ entity = entity(obj);
+ return entity._getDecoder('der').tree;
+};
+
+// Utility methods
+
+function derDecodeTag(buf, fail) {
+ var tag = buf.readUInt8(fail);
+ if (buf.isError(tag))
+ return tag;
+
+ var cls = der.tagClass[tag >> 6];
+ var primitive = (tag & 0x20) === 0;
+
+ // Multi-octet tag - load
+ if ((tag & 0x1f) === 0x1f) {
+ var oct = tag;
+ tag = 0;
+ while ((oct & 0x80) === 0x80) {
+ oct = buf.readUInt8(fail);
+ if (buf.isError(oct))
+ return oct;
+
+ tag <<= 7;
+ tag |= oct & 0x7f;
+ }
+ } else {
+ tag &= 0x1f;
+ }
+ var tagStr = der.tag[tag];
+
+ return {
+ cls: cls,
+ primitive: primitive,
+ tag: tag,
+ tagStr: tagStr
+ };
+}
+
+function derDecodeLen(buf, primitive, fail) {
+ var len = buf.readUInt8(fail);
+ if (buf.isError(len))
+ return len;
+
+ // Indefinite form
+ if (!primitive && len === 0x80)
+ return null;
+
+ // Definite form
+ if ((len & 0x80) === 0) {
+ // Short form
+ return len;
+ }
+
+ // Long form
+ var num = len & 0x7f;
+ if (num > 4)
+ return buf.error('length octect is too long');
+
+ len = 0;
+ for (var i = 0; i < num; i++) {
+ len <<= 8;
+ var j = buf.readUInt8(fail);
+ if (buf.isError(j))
+ return j;
+ len |= j;
+ }
+
+ return len;
+}
diff --git a/node_modules/asn1.js/lib/asn1/decoders/index.js b/node_modules/asn1.js/lib/asn1/decoders/index.js
new file mode 100644
index 000000000..e2583aa8a
--- /dev/null
+++ b/node_modules/asn1.js/lib/asn1/decoders/index.js
@@ -0,0 +1,4 @@
+var decoders = exports;
+
+decoders.der = require('./der');
+decoders.pem = require('./pem');
diff --git a/node_modules/asn1.js/lib/asn1/decoders/pem.js b/node_modules/asn1.js/lib/asn1/decoders/pem.js
new file mode 100644
index 000000000..301059cab
--- /dev/null
+++ b/node_modules/asn1.js/lib/asn1/decoders/pem.js
@@ -0,0 +1,49 @@
+var inherits = require('inherits');
+var Buffer = require('buffer').Buffer;
+
+var DERDecoder = require('./der');
+
+function PEMDecoder(entity) {
+ DERDecoder.call(this, entity);
+ this.enc = 'pem';
+};
+inherits(PEMDecoder, DERDecoder);
+module.exports = PEMDecoder;
+
+PEMDecoder.prototype.decode = function decode(data, options) {
+ var lines = data.toString().split(/[\r\n]+/g);
+
+ var label = options.label.toUpperCase();
+
+ var re = /^-----(BEGIN|END) ([^-]+)-----$/;
+ var start = -1;
+ var end = -1;
+ for (var i = 0; i < lines.length; i++) {
+ var match = lines[i].match(re);
+ if (match === null)
+ continue;
+
+ if (match[2] !== label)
+ continue;
+
+ if (start === -1) {
+ if (match[1] !== 'BEGIN')
+ break;
+ start = i;
+ } else {
+ if (match[1] !== 'END')
+ break;
+ end = i;
+ break;
+ }
+ }
+ if (start === -1 || end === -1)
+ throw new Error('PEM section not found for: ' + label);
+
+ var base64 = lines.slice(start + 1, end).join('');
+ // Remove excessive symbols
+ base64.replace(/[^a-z0-9\+\/=]+/gi, '');
+
+ var input = new Buffer(base64, 'base64');
+ return DERDecoder.prototype.decode.call(this, input, options);
+};