Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

asn1.js

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

asn1.js - npm Package Compare versions

Comparing version 0.1.5 to 0.2.0

lib/asn1/base/reporter.js

8

lib/asn1/api.js

@@ -31,14 +31,14 @@ var asn1 = require('../asn1');

Entity.prototype.decode = function decode(data, enc) {
Entity.prototype.decode = function decode(data, enc, options) {
// Lazily create decoder
if (!this.decoders.hasOwnProperty(enc))
this.decoders[enc] = this._createNamed(asn1.decoders[enc]);
return this.decoders[enc].decode(data);
return this.decoders[enc].decode(data, options);
};
Entity.prototype.encode = function encode(data, enc, /* internal */ path) {
Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) {
// Lazily create encoder
if (!this.encoders.hasOwnProperty(enc))
this.encoders[enc] = this._createNamed(asn1.encoders[enc]);
return this.encoders[enc].encode(data, path);
return this.encoders[enc].encode(data, reporter);
};
var assert = require('assert');
var util = require('util');
var Reporter = require('../base').Reporter;
var Buffer = require('buffer').Buffer;
function DecoderBuffer(base) {
assert(Buffer.isBuffer(base));
function DecoderBuffer(base, options) {
Reporter.call(this, options);
if (!Buffer.isBuffer(base)) {
this.error('Input not Buffer');
return;
}

@@ -11,2 +17,3 @@ this.base = base;

}
util.inherits(DecoderBuffer, Reporter);
exports.DecoderBuffer = DecoderBuffer;

@@ -33,10 +40,18 @@

DecoderBuffer.prototype.readUInt8 = function readUInt8() {
assert(this.offset + 1 <= this.length);
return this.base.readUInt8(this.offset++, true);
DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
if (this.offset + 1 <= this.length)
return this.base.readUInt8(this.offset++, true);
else
return this.error(fail || 'DecoderBuffer overrun');
}
DecoderBuffer.prototype.skip = function skip(bytes) {
assert(this.offset + bytes <= this.length);
DecoderBuffer.prototype.skip = function skip(bytes, fail) {
if (!(this.offset + bytes <= this.length))
return this.error(fail || 'DecoderBuffer overrun');
var res = new DecoderBuffer(this.base);
// Share reporter state
res._reporterState = this._reporterState;
res.offset = this.offset;

@@ -52,3 +67,3 @@ res.length = this.offset + bytes;

function EncoderBuffer(value) {
function EncoderBuffer(value, reporter) {
if (Array.isArray(value)) {

@@ -63,3 +78,4 @@ this.length = 0;

} else if (typeof value === 'number') {
assert(0 <= value && value <= 0xff, 'non-byte EncoderBuffer value');
if (!(0 <= value && value <= 0xff))
return reporter.error('non-byte EncoderBuffer value');
this.value = value;

@@ -74,3 +90,3 @@ this.length = 1;

} else {
assert(0, 'Unsupported type: ' + typeof value);
return reporter.error('Unsupporter type: ' + typeof value);
}

@@ -77,0 +93,0 @@ }

var base = exports;
base.EncoderError = require('./error').EncoderError;
base.Reporter = require('./reporter').Reporter;
base.DecoderBuffer = require('./buffer').DecoderBuffer;
base.EncoderBuffer = require('./buffer').EncoderBuffer;
base.Node = require('./node');
var assert = require('assert');
var Reporter = require('../base').Reporter;
var EncoderBuffer = require('../base').EncoderBuffer;
var EncoderError = require('../base').EncoderError;

@@ -240,3 +240,3 @@ // Supported tags

Node.prototype._decode = function decode(input, obj) {
Node.prototype._decode = function decode(input) {
var state = this._baseState;

@@ -246,3 +246,3 @@

if (state.parent === null)
return state.children[0]._decode(input);
return input.wrapResult(state.children[0]._decode(input));

@@ -252,2 +252,6 @@ var result = state['default'];

var prevKey;
if (state.key !== null)
prevKey = input.enterKey(state.key);
// Check if tag is there

@@ -261,18 +265,23 @@ if (state.optional) {

);
if (input.isError(present))
return present;
}
// Push object on stack
if (state.obj && present) {
var prevObj = obj;
obj = {};
}
var prevObj;
if (state.obj && present)
prevObj = input.enterObject();
if (present) {
// Unwrap explicit values
if (state.explicit !== null)
input = this._decodeTag(input, state.explicit);
if (state.explicit !== null) {
var explicit = this._decodeTag(input, state.explicit);
if (input.isError(explicit))
return explicit;
input = explicit;
}
// Unwrap implicit and normal values
if (state.use === null && !state.any && state.choice === null) {
input = this._decodeTag(
var body = this._decodeTag(
input,

@@ -282,2 +291,5 @@ state.implicit !== null ? state.implicit : state.tag,

);
if (input.isError(body))
return body;
input = body;
}

@@ -291,9 +303,15 @@

else
result = this._decodeChoice(input, obj);
result = this._decodeChoice(input);
if (input.isError(result))
return result;
// Decode children
if (!state.any && state.choice === null && state.children !== null) {
state.children.forEach(function decodeChildren(child) {
child._decode(input, obj);
var fail = state.children.some(function decodeChildren(child) {
// NOTE: We are ignoring errors here, to let parser continue with other
// parts of encoded data
child._decode(input);
});
if (fail)
return err;
}

@@ -303,10 +321,8 @@ }

// Pop object
if (state.obj && present) {
result = obj;
obj = prevObj;
}
if (state.obj && present)
result = input.leaveObject(prevObj);
// Set key
if (state.key !== null)
obj[state.key] = result;
input.leaveKey(prevKey, state.key, result);

@@ -340,3 +356,3 @@ return result;

else
assert(false, 'unknown tag: ' + tag);
return input.error('unknown tag: ' + tag);

@@ -346,3 +362,3 @@ return null;

Node.prototype._decodeChoice = function decodeChoice(input, obj) {
Node.prototype._decodeChoice = function decodeChoice(input) {
var state = this._baseState;

@@ -356,3 +372,7 @@ var result = null;

try {
result = { type: key, value: node._decode(input, obj) };
var value = node._decode(input);
if (input.isError(value))
return false;
result = { type: key, value: value };
match = true;

@@ -366,3 +386,5 @@ } catch (e) {

assert(match, 'Choice not matched');
if (!match)
return input.error('Choice not matched');
return result;

@@ -375,3 +397,7 @@ };

Node.prototype._encode = function encode(data, path) {
Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) {
return new EncoderBuffer(data, this.reporter);
};
Node.prototype._encode = function encode(data, reporter) {
var state = this._baseState;

@@ -381,3 +407,3 @@

if (state.parent === null)
return state.children[0]._encode(data, path || '');
return state.children[0]._encode(data, reporter || new Reporter());

@@ -387,2 +413,5 @@ var result = null;

// Set reporter to share it with a child class
this.reporter = reporter;
// Check if data is there

@@ -396,2 +425,5 @@ if (state.optional && data === undefined) {

// For error reporting
var prevKey;
// Encode children first

@@ -402,18 +434,16 @@ var content = null;

// Anything that was given is translated to buffer
result = new EncoderBuffer(data);
result = this._createEncoderBuffer(data);
} else if (state.children) {
content = state.children.map(function(child) {
assert(child._baseState.key !== null, 'Child should have a key');
if (child._baseState.key === null)
return reporter.error('Child should have a key');
var prevKey = reporter.enterKey(child._baseState.key);
// Maintain path for error reporting purposes
var newpath = path ? path + '.' + child._baseState.key :
child._baseState.key;
try {
return child._encode(data[child._baseState.key], newpath);
} catch (e) {
if (e instanceof EncoderError)
throw e;
else
throw new EncoderError(newpath, e);
}
if (typeof data !== 'object')
return reporter.error('Child expected, but input is not object');
var res = child._encode(data[child._baseState.key], reporter);
reporter.leaveKey(prevKey);
return res;
}, this).filter(function(child) {

@@ -423,14 +453,18 @@ return child;

content = new EncoderBuffer(content);
content = this._createEncoderBuffer(content);
} else {
if (state.choice === null) {
if (state.tag === 'seqof' || state.tag === 'setof') {
assert(state.args && state.args.length === 1);
assert(Array.isArray(data), 'seqof/setof, but data is not Array');
// TODO(indutny): this should be thrown on DSL level
if (!(state.args && state.args.length === 1))
return reporter.error('Too many args for : ' + state.tag);
content = new EncoderBuffer(data.map(function(item) {
return this._use(state.args[0], item, path);
if (!Array.isArray(data))
return reporter.error('seqof/setof, but data is not Array');
content = this._createEncoderBuffer(data.map(function(item) {
return this._use(state.args[0], item);
}, this));
} else if (state.use !== null) {
result = this._use(state.use, data, path);
result = this._use(state.use, data);
} else {

@@ -441,3 +475,3 @@ content = this._encodePrimitive(state.tag, data);

} else {
result = this._encodeChoice(data);
result = this._encodeChoice(data, reporter);
}

@@ -451,6 +485,8 @@ }

if (tag === null)
assert(state.use !== null, 'Tag could be ommited only for .use()');
else
if (tag === null) {
if (state.use === null)
reporter.error('Tag could be ommited only for .use()');
} else {
result = this._encodeComposite(tag, primitive, content);
}
}

@@ -465,7 +501,7 @@

Node.prototype._encodeChoice = function encodeChoice(data) {
Node.prototype._encodeChoice = function encodeChoice(data, reporter) {
var state = this._baseState;
var node = state.choice[data.type];
return node._encode(data.value);
return node._encode(data.value, reporter);
};

@@ -472,0 +508,0 @@

@@ -1,2 +0,1 @@

var assert = require('assert');
var util = require('util');

@@ -21,7 +20,7 @@

DERDecoder.prototype.decode = function decode(data) {
DERDecoder.prototype.decode = function decode(data, options) {
if (!(data instanceof base.DecoderBuffer))
data = new base.DecoderBuffer(data);
data = new base.DecoderBuffer(data, options);
return this.tree._decode(data);
return this.tree._decode(data, options);
};

@@ -41,3 +40,6 @@

var state = buffer.save();
var decodedTag = derDecodeTag(buffer);
var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"');
if (buffer.isError(decodedTag))
return decodedTag;
buffer.restore(state);

@@ -49,31 +51,55 @@

DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) {
var decodedTag = derDecodeTag(buffer);
var len = derDecodeLen(buffer, decodedTag.primitive);
var decodedTag = derDecodeTag(buffer,
'Failed to decode tag of "' + tag + '"');
if (buffer.isError(decodedTag))
return decodedTag;
if (!any) {
assert(decodedTag.tag === tag ||
decodedTag.tagStr === tag ||
decodedTag.tagStr + 'of' === tag,
'Failed to match tag: ' + tag);
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);
return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
// Indefinite length... find END tag
var state = buffer.save();
this._skipUntilEnd(buffer);
var res = this._skipUntilEnd(
buffer,
'Failed to skip indefinite length body: "' + this.tag + '"');
if (buffer.isError(res))
return res;
return buffer.restore(state);
};
DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer) {
DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) {
while (true) {
var tag = derDecodeTag(buffer);
var len = derDecodeLen(buffer, tag.primitive);
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)
buffer.skip(len)
res = buffer.skip(len)
else
this._skipUntilEnd(buffer);
res = this._skipUntilEnd(buffer, fail);
// Failure
if (buffer.isError(res))
return res;
if (tag.tagStr === 'end')

@@ -87,9 +113,10 @@ break;

while (!buffer.isEmpty()) {
try {
var possibleEnd = this._peekTag(buffer, 'end');
result.push(decoder.decode(buffer, 'der'));
} catch (e) {
if (possibleEnd)
break;
}
var possibleEnd = this._peekTag(buffer, 'end');
if (buffer.isError(possibleEnd))
return possibleEnd;
var res = decoder.decode(buffer, 'der');
if (buffer.isError(res) && possibleEnd)
break;
result.push(res);
}

@@ -105,3 +132,3 @@ return result;

else
assert(0, 'Decoding of string type: ' + tag + ' unsupported');
return this.error('Decoding of string type: ' + tag + ' unsupported');
};

@@ -159,3 +186,3 @@

} else {
assert(0, 'Decoding ' + tag + ' time is not supported yet');
return this.error('Decoding ' + tag + ' time is not supported yet');
}

@@ -171,3 +198,7 @@

DERNode.prototype._decodeBool = function decodeBool(buffer) {
return buffer.readUInt8() !== 0;
var res = buffer.readUInt8();
if (buffer.isError(res))
return res;
else
return res !== 0;
};

@@ -179,7 +210,10 @@

res <<= 8;
res |= buffer.readUInt8();
var i = buffer.readUInt8();
if (buffer.isError(i))
return i;
res |= i;
}
if (values)
res = values[res];
res = values[res] || res;
return res;

@@ -194,4 +228,6 @@ };

function derDecodeTag(buf) {
var tag = buf.readUInt8();
function derDecodeTag(buf, fail) {
var tag = buf.readUInt8(fail);
if (buf.isError(tag))
return tag;

@@ -206,3 +242,6 @@ var cls = der.tagClass[tag >> 6];

while ((oct & 0x80) === 0x80) {
oct = buf.readUInt8();
oct = buf.readUInt8(fail);
if (buf.isError(oct))
return oct;
tag <<= 7;

@@ -224,4 +263,6 @@ tag |= oct & 0x7f;

function derDecodeLen(buf, primitive) {
var len = buf.readUInt8();
function derDecodeLen(buf, primitive, fail) {
var len = buf.readUInt8(fail);
if (buf.isError(len))
return len;

@@ -240,7 +281,12 @@ // Indefinite form

var num = len & 0x7f;
assert(num < 4, 'length octect is too long');
if (num >= 4)
return buf.error('length octect is too long');
len = 0;
for (var i = 0; i < num; i++) {
len <<= 8;
len |= buf.readUInt8();
var j = buf.readUInt8(fail);
if (buf.isError(j))
return j;
len |= j;
}

@@ -247,0 +293,0 @@

@@ -1,2 +0,1 @@

var assert = require('assert');
var util = require('util');

@@ -22,4 +21,4 @@ var Buffer = require('buffer').Buffer;

DEREncoder.prototype.encode = function encode(data, path) {
return this.tree._encode(data, path).join();
DEREncoder.prototype.encode = function encode(data, reporter) {
return this.tree._encode(data, reporter).join();
};

@@ -37,3 +36,3 @@

content) {
var encodedTag = encodeTag(tag, primitive);
var encodedTag = encodeTag(tag, primitive, this.reporter);

@@ -45,3 +44,3 @@ // Short form

header[1] = content.length;
return new base.EncoderBuffer([ header, content ]);
return this._createEncoderBuffer([ header, content ]);
}

@@ -62,3 +61,3 @@

return new base.EncoderBuffer([ header, content ]);
return this._createEncoderBuffer([ header, content ]);
};

@@ -68,7 +67,7 @@

if (tag === 'octstr')
return new base.EncoderBuffer(str);
return this._createEncoderBuffer(str);
else if (tag === 'bitstr')
return new base.EncoderBuffer([ str.unused | 0, str.data ]);
else
assert(0, 'Encoding of string type: ' + tag + ' unsupported');
return this._createEncoderBuffer([ str.unused | 0, str.data ]);
return this.reporter.error('Encoding of string type: ' + tag +
' unsupported');
};

@@ -78,4 +77,6 @@

if (typeof id === 'string') {
assert(values, 'string objid given, but no values map found');
assert(values.hasOwnProperty(id), 'objid not found in values map');
if (!values)
return this.reporter.error('string objid given, but no values map found');
if (!values.hasOwnProperty(id))
return this.reporter.error('objid not found in values map');
id = values[id].split(/\s+/g);

@@ -86,7 +87,10 @@ for (var i = 0; i < id.length; i++)

assert(Array.isArray(id),
'objid() should be either array or string, got: ' +
JSON.stringify(id));
if (!Array.isArray(id)) {
return this.reporter.error('objid() should be either array or string, ' +
'got: ' + JSON.stringify(id));
}
if (!relative) {
assert(id[1] < 40, 'Second objid identifier OOB');
if (id[1] >= 40)
return this.reporter.error('Second objid identifier OOB');
id.splice(0, 2, id[0] * 40 + id[1]);

@@ -112,3 +116,3 @@ }

return new base.EncoderBuffer(objid);
return this._createEncoderBuffer(objid);
};

@@ -148,3 +152,3 @@

} else {
assert(0, 'Encoding ' + tag + ' time is not supported yet');
this.reporter.error('Encoding ' + tag + ' time is not supported yet');
}

@@ -156,3 +160,3 @@

DERNode.prototype._encodeNull = function encodeNull() {
return new base.EncoderBuffer('');
return this._createEncoderBuffer('');
};

@@ -162,5 +166,8 @@

if (typeof num === 'string') {
assert(values, 'String int or enum given, but no values map');
assert(values.hasOwnProperty(num),
'Values map doesn\'t contain: ' + JSON.stringify(num));
if (!values)
return this.reporter.error('String int or enum given, but no values map');
if (!values.hasOwnProperty(num)) {
return this.reporter.error('Values map doesn\'t contain: ' +
JSON.stringify(num));
}
num = values[num];

@@ -170,3 +177,3 @@ }

if (num < 0x100)
return new base.EncoderBuffer(num);
return this._createEncoderBuffer(num);

@@ -183,11 +190,11 @@ var size = 1;

return new base.EncoderBuffer(out);
return this._createEncoderBuffer(out);
};
DERNode.prototype._encodeBool = function encodeBool(value) {
return new base.EncoderBuffer(value ? 0xff : 0);
return this._createEncoderBuffer(value ? 0xff : 0);
};
DERNode.prototype._use = function use(encoder, data, path) {
return encoder.encode(data, 'der', path);
DERNode.prototype._use = function use(encoder, data) {
return encoder.encode(data, 'der', this.reporter);
};

@@ -197,3 +204,3 @@

function encodeTag(tag, primitive, cls) {
function encodeTag(tag, primitive, cls, reporter) {
var res;

@@ -211,5 +218,6 @@

else
throw new Error('Unknown tag: ' + tag);
return reporter.error('Unknown tag: ' + tag);
assert(res < 0x1f, 'Multi-octet tag encoding unsupported');
if (res >= 0x1f)
return reporter.error('Multi-octet tag encoding unsupported');

@@ -216,0 +224,0 @@ if (!primitive)

{
"name": "asn1.js",
"version": "0.1.5",
"version": "0.2.0",
"description": "ASN.1 encoder and decoder",

@@ -5,0 +5,0 @@ "main": "lib/asn1.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc