updated node.js net-snmp to latest version using ans1-ber; #2362
Costa Tsaousis (ktsaou) committed
Aug 25, 2017 at 18:33 UTC
6060c04181eb9a75164f2a00530a57d117e827c9
15 files changed
+664
-684
LICENSE-REDISTRIBUTED.md
+3
-2
@@ -127,10 +127,11 @@ connectivity is not available.
127
[MIT License](https://github.com/stephenwvickers/node-net-snmp)
128
129
130
-- [node-asn1](https://github.com/mcavage/node-asn1)
130
+- [node-asn1-ber](https://github.com/stephenwvickers/node-asn1-ber)
131
132
+ Copyright 2017, Stephen Vickers
133
Copyright 2011, Mark Cavage
133
- [MIT License](https://github.com/mcavage/node-asn1)
134
+ [MIT License](https://github.com/stephenwvickers/node-asn1-ber)
135
136
137
- [pixl-xml](https://github.com/jhuckaby/pixl-xml)
node.d/Makefile.am
+8
-8
@@ -15,14 +15,14 @@ dist_nodemodules_DATA = \
15
node_modules/extend.js \
16
node_modules/pixl-xml.js \
17
node_modules/net-snmp.js \
18
- node_modules/asn1.js \
18
+ node_modules/asn1-ber.js \
19
$(NULL)
20
21
-nodemodulesberdir=$(nodedir)/node_modules/ber
22
-dist_nodemodulesber_DATA = \
23
- node_modules/ber/index.js \
24
- node_modules/ber/errors.js \
25
- node_modules/ber/reader.js \
26
- node_modules/ber/types.js \
27
- node_modules/ber/writer.js \
21
+nodemoduleslibberdir=$(nodedir)/node_modules/lib/ber
22
+dist_nodemoduleslibber_DATA = \
23
+ node_modules/lib/ber/index.js \
24
+ node_modules/lib/ber/errors.js \
25
+ node_modules/lib/ber/reader.js \
26
+ node_modules/lib/ber/types.js \
27
+ node_modules/lib/ber/writer.js \
28
$(NULL)
node.d/node_modules/asn1-ber.js
new
+6
@@ -0,0 +1,6 @@
1
+
2
+var Ber = require('./lib/ber/index')
3
+
4
+exports.Ber = Ber
5
+exports.BerReader = Ber.Reader
6
+exports.BerWriter = Ber.Writer
node.d/node_modules/asn1.js
deleted
-20
@@ -1,20 +0,0 @@
1
-// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
2
-
3
-// If you have no idea what ASN.1 or BER is, see this:
4
-// ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc
5
-
6
-var Ber = require('./ber/index');
7
-
8
-
9
-
10
-///--- Exported API
11
-
12
-module.exports = {
13
-
14
- Ber: Ber,
15
-
16
- BerReader: Ber.Reader,
17
-
18
- BerWriter: Ber.Writer
19
-
20
-};
node.d/node_modules/ber/errors.js
deleted
-13
@@ -1,13 +0,0 @@
1
-// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
2
-
3
-
4
-module.exports = {
5
-
6
- newInvalidAsn1Error: function(msg) {
7
- var e = new Error();
8
- e.name = 'InvalidAsn1Error';
9
- e.message = msg || '';
10
- return e;
11
- }
12
-
13
-};
node.d/node_modules/ber/index.js
deleted
-27
@@ -1,27 +0,0 @@
1
-// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
2
-
3
-var errors = require('./errors');
4
-var types = require('./types');
5
-
6
-var Reader = require('./reader');
7
-var Writer = require('./writer');
8
-
9
-
10
-///--- Exports
11
-
12
-module.exports = {
13
-
14
- Reader: Reader,
15
-
16
- Writer: Writer
17
-
18
-};
19
-
20
-for (var t in types) {
21
- if (types.hasOwnProperty(t))
22
- module.exports[t] = types[t];
23
-}
24
-for (var e in errors) {
25
- if (errors.hasOwnProperty(e))
26
- module.exports[e] = errors[e];
27
-}
node.d/node_modules/ber/reader.js
deleted
-261
@@ -1,261 +0,0 @@
1
-// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
2
-
3
-var assert = require('assert');
4
-
5
-var ASN1 = require('./types');
6
-var errors = require('./errors');
7
-
8
-
9
-///--- Globals
10
-
11
-var newInvalidAsn1Error = errors.newInvalidAsn1Error;
12
-
13
-
14
-
15
-///--- API
16
-
17
-function Reader(data) {
18
- if (!data || !Buffer.isBuffer(data))
19
- throw new TypeError('data must be a node Buffer');
20
-
21
- this._buf = data;
22
- this._size = data.length;
23
-
24
- // These hold the "current" state
25
- this._len = 0;
26
- this._offset = 0;
27
-}
28
-
29
-Object.defineProperty(Reader.prototype, 'length', {
30
- enumerable: true,
31
- get: function () { return (this._len); }
32
-});
33
-
34
-Object.defineProperty(Reader.prototype, 'offset', {
35
- enumerable: true,
36
- get: function () { return (this._offset); }
37
-});
38
-
39
-Object.defineProperty(Reader.prototype, 'remain', {
40
- get: function () { return (this._size - this._offset); }
41
-});
42
-
43
-Object.defineProperty(Reader.prototype, 'buffer', {
44
- get: function () { return (this._buf.slice(this._offset)); }
45
-});
46
-
47
-
48
-/**
49
- * Reads a single byte and advances offset; you can pass in `true` to make this
50
- * a "peek" operation (i.e., get the byte, but don't advance the offset).
51
- *
52
- * @param {Boolean} peek true means don't move offset.
53
- * @return {Number} the next byte, null if not enough data.
54
- */
55
-Reader.prototype.readByte = function(peek) {
56
- if (this._size - this._offset < 1)
57
- return null;
58
-
59
- var b = this._buf[this._offset] & 0xff;
60
-
61
- if (!peek)
62
- this._offset += 1;
63
-
64
- return b;
65
-};
66
-
67
-
68
-Reader.prototype.peek = function() {
69
- return this.readByte(true);
70
-};
71
-
72
-
73
-/**
74
- * Reads a (potentially) variable length off the BER buffer. This call is
75
- * not really meant to be called directly, as callers have to manipulate
76
- * the internal buffer afterwards.
77
- *
78
- * As a result of this call, you can call `Reader.length`, until the
79
- * next thing called that does a readLength.
80
- *
81
- * @return {Number} the amount of offset to advance the buffer.
82
- * @throws {InvalidAsn1Error} on bad ASN.1
83
- */
84
-Reader.prototype.readLength = function(offset) {
85
- if (offset === undefined)
86
- offset = this._offset;
87
-
88
- if (offset >= this._size)
89
- return null;
90
-
91
- var lenB = this._buf[offset++] & 0xff;
92
- if (lenB === null)
93
- return null;
94
-
95
- if ((lenB & 0x80) == 0x80) {
96
- lenB &= 0x7f;
97
-
98
- if (lenB == 0)
99
- throw newInvalidAsn1Error('Indefinite length not supported');
100
-
101
- if (lenB > 4)
102
- throw newInvalidAsn1Error('encoding too long');
103
-
104
- if (this._size - offset < lenB)
105
- return null;
106
-
107
- this._len = 0;
108
- for (var i = 0; i < lenB; i++)
109
- this._len = (this._len << 8) + (this._buf[offset++] & 0xff);
110
-
111
- } else {
112
- // Wasn't a variable length
113
- this._len = lenB;
114
- }
115
-
116
- return offset;
117
-};
118
-
119
-
120
-/**
121
- * Parses the next sequence in this BER buffer.
122
- *
123
- * To get the length of the sequence, call `Reader.length`.
124
- *
125
- * @return {Number} the sequence's tag.
126
- */
127
-Reader.prototype.readSequence = function(tag) {
128
- var seq = this.peek();
129
- if (seq === null)
130
- return null;
131
- if (tag !== undefined && tag !== seq)
132
- throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
133
- ': got 0x' + seq.toString(16));
134
-
135
- var o = this.readLength(this._offset + 1); // stored in `length`
136
- if (o === null)
137
- return null;
138
-
139
- this._offset = o;
140
- return seq;
141
-};
142
-
143
-
144
-Reader.prototype.readInt = function() {
145
- return this._readTag(ASN1.Integer);
146
-};
147
-
148
-
149
-Reader.prototype.readBoolean = function() {
150
- return (this._readTag(ASN1.Boolean) === 0 ? false : true);
151
-};
152
-
153
-
154
-Reader.prototype.readEnumeration = function() {
155
- return this._readTag(ASN1.Enumeration);
156
-};
157
-
158
-
159
-Reader.prototype.readString = function(tag, retbuf) {
160
- if (!tag)
161
- tag = ASN1.OctetString;
162
-
163
- var b = this.peek();
164
- if (b === null)
165
- return null;
166
-
167
- if (b !== tag)
168
- throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
169
- ': got 0x' + b.toString(16));
170
-
171
- var o = this.readLength(this._offset + 1); // stored in `length`
172
-
173
- if (o === null)
174
- return null;
175
-
176
- if (this.length > this._size - o)
177
- return null;
178
-
179
- this._offset = o;
180
-
181
- if (this.length === 0)
182
- return retbuf ? new Buffer(0) : '';
183
-
184
- var str = this._buf.slice(this._offset, this._offset + this.length);
185
- this._offset += this.length;
186
-
187
- return retbuf ? str : str.toString('utf8');
188
-};
189
-
190
-Reader.prototype.readOID = function(tag) {
191
- if (!tag)
192
- tag = ASN1.OID;
193
-
194
- var b = this.readString(tag, true);
195
- if (b === null)
196
- return null;
197
-
198
- var values = [];
199
- var value = 0;
200
-
201
- for (var i = 0; i < b.length; i++) {
202
- var byte = b[i] & 0xff;
203
-
204
- value <<= 7;
205
- value += byte & 0x7f;
206
- if ((byte & 0x80) == 0) {
207
- values.push(value);
208
- value = 0;
209
- }
210
- }
211
-
212
- value = values.shift();
213
- values.unshift(value % 40);
214
- values.unshift((value / 40) >> 0);
215
-
216
- return values.join('.');
217
-};
218
-
219
-
220
-Reader.prototype._readTag = function(tag) {
221
- assert.ok(tag !== undefined);
222
-
223
- var b = this.peek();
224
-
225
- if (b === null)
226
- return null;
227
-
228
- if (b !== tag)
229
- throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
230
- ': got 0x' + b.toString(16));
231
-
232
- var o = this.readLength(this._offset + 1); // stored in `length`
233
- if (o === null)
234
- return null;
235
-
236
- if (this.length > 4)
237
- throw newInvalidAsn1Error('Integer too long: ' + this.length);
238
-
239
- if (this.length > this._size - o)
240
- return null;
241
- this._offset = o;
242
-
243
- var fb = this._buf[this._offset];
244
- var value = 0;
245
-
246
- for (var i = 0; i < this.length; i++) {
247
- value <<= 8;
248
- value |= (this._buf[this._offset++] & 0xff);
249
- }
250
-
251
- if ((fb & 0x80) == 0x80 && i !== 4)
252
- value -= (1 << (i * 8));
253
-
254
- return value >> 0;
255
-};
256
-
257
-
258
-
259
-///--- Exported API
260
-
261
-module.exports = Reader;
node.d/node_modules/ber/types.js
deleted
-36
@@ -1,36 +0,0 @@
1
-// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
2
-
3
-
4
-module.exports = {
5
- EOC: 0,
6
- Boolean: 1,
7
- Integer: 2,
8
- BitString: 3,
9
- OctetString: 4,
10
- Null: 5,
11
- OID: 6,
12
- ObjectDescriptor: 7,
13
- External: 8,
14
- Real: 9, // float
15
- Enumeration: 10,
16
- PDV: 11,
17
- Utf8String: 12,
18
- RelativeOID: 13,
19
- Sequence: 16,
20
- Set: 17,
21
- NumericString: 18,
22
- PrintableString: 19,
23
- T61String: 20,
24
- VideotexString: 21,
25
- IA5String: 22,
26
- UTCTime: 23,
27
- GeneralizedTime: 24,
28
- GraphicString: 25,
29
- VisibleString: 26,
30
- GeneralString: 28,
31
- UniversalString: 29,
32
- CharacterString: 30,
33
- BMPString: 31,
34
- Constructor: 32,
35
- Context: 128
36
-};
node.d/node_modules/ber/writer.js
deleted
-316
@@ -1,316 +0,0 @@
1
-// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
2
-
3
-var assert = require('assert');
4
-var ASN1 = require('./types');
5
-var errors = require('./errors');
6
-
7
-
8
-///--- Globals
9
-
10
-var newInvalidAsn1Error = errors.newInvalidAsn1Error;
11
-
12
-var DEFAULT_OPTS = {
13
- size: 1024,
14
- growthFactor: 8
15
-};
16
-
17
-
18
-///--- Helpers
19
-
20
-function merge(from, to) {
21
- assert.ok(from);
22
- assert.equal(typeof(from), 'object');
23
- assert.ok(to);
24
- assert.equal(typeof(to), 'object');
25
-
26
- var keys = Object.getOwnPropertyNames(from);
27
- keys.forEach(function(key) {
28
- if (to[key])
29
- return;
30
-
31
- var value = Object.getOwnPropertyDescriptor(from, key);
32
- Object.defineProperty(to, key, value);
33
- });
34
-
35
- return to;
36
-}
37
-
38
-
39
-
40
-///--- API
41
-
42
-function Writer(options) {
43
- options = merge(DEFAULT_OPTS, options || {});
44
-
45
- this._buf = new Buffer(options.size || 1024);
46
- this._size = this._buf.length;
47
- this._offset = 0;
48
- this._options = options;
49
-
50
- // A list of offsets in the buffer where we need to insert
51
- // sequence tag/len pairs.
52
- this._seq = [];
53
-}
54
-
55
-Object.defineProperty(Writer.prototype, 'buffer', {
56
- get: function () {
57
- if (this._seq.length)
58
- throw new InvalidAsn1Error(this._seq.length + ' unended sequence(s)');
59
-
60
- return (this._buf.slice(0, this._offset));
61
- }
62
-});
63
-
64
-Writer.prototype.writeByte = function(b) {
65
- if (typeof(b) !== 'number')
66
- throw new TypeError('argument must be a Number');
67
-
68
- this._ensure(1);
69
- this._buf[this._offset++] = b;
70
-};
71
-
72
-
73
-Writer.prototype.writeInt = function(i, tag) {
74
- if (typeof(i) !== 'number')
75
- throw new TypeError('argument must be a Number');
76
- if (typeof(tag) !== 'number')
77
- tag = ASN1.Integer;
78
-
79
- var sz = 4;
80
-
81
- while ((((i & 0xff800000) === 0) || ((i & 0xff800000) === 0xff800000 >> 0)) &&
82
- (sz > 1)) {
83
- sz--;
84
- i <<= 8;
85
- }
86
-
87
- if (sz > 4)
88
- throw new InvalidAsn1Error('BER ints cannot be > 0xffffffff');
89
-
90
- this._ensure(2 + sz);
91
- this._buf[this._offset++] = tag;
92
- this._buf[this._offset++] = sz;
93
-
94
- while (sz-- > 0) {
95
- this._buf[this._offset++] = ((i & 0xff000000) >>> 24);
96
- i <<= 8;
97
- }
98
-
99
-};
100
-
101
-
102
-Writer.prototype.writeNull = function() {
103
- this.writeByte(ASN1.Null);
104
- this.writeByte(0x00);
105
-};
106
-
107
-
108
-Writer.prototype.writeEnumeration = function(i, tag) {
109
- if (typeof(i) !== 'number')
110
- throw new TypeError('argument must be a Number');
111
- if (typeof(tag) !== 'number')
112
- tag = ASN1.Enumeration;
113
-
114
- return this.writeInt(i, tag);
115
-};
116
-
117
-
118
-Writer.prototype.writeBoolean = function(b, tag) {
119
- if (typeof(b) !== 'boolean')
120
- throw new TypeError('argument must be a Boolean');
121
- if (typeof(tag) !== 'number')
122
- tag = ASN1.Boolean;
123
-
124
- this._ensure(3);
125
- this._buf[this._offset++] = tag;
126
- this._buf[this._offset++] = 0x01;
127
- this._buf[this._offset++] = b ? 0xff : 0x00;
128
-};
129
-
130
-
131
-Writer.prototype.writeString = function(s, tag) {
132
- if (typeof(s) !== 'string')
133
- throw new TypeError('argument must be a string (was: ' + typeof(s) + ')');
134
- if (typeof(tag) !== 'number')
135
- tag = ASN1.OctetString;
136
-
137
- var len = Buffer.byteLength(s);
138
- this.writeByte(tag);
139
- this.writeLength(len);
140
- if (len) {
141
- this._ensure(len);
142
- this._buf.write(s, this._offset);
143
- this._offset += len;
144
- }
145
-};
146
-
147
-
148
-Writer.prototype.writeBuffer = function(buf, tag) {
149
- if (typeof(tag) !== 'number')
150
- throw new TypeError('tag must be a number');
151
- if (!Buffer.isBuffer(buf))
152
- throw new TypeError('argument must be a buffer');
153
-
154
- this.writeByte(tag);
155
- this.writeLength(buf.length);
156
- this._ensure(buf.length);
157
- buf.copy(this._buf, this._offset, 0, buf.length);
158
- this._offset += buf.length;
159
-};
160
-
161
-
162
-Writer.prototype.writeStringArray = function(strings) {
163
- if ((!strings instanceof Array))
164
- throw new TypeError('argument must be an Array[String]');
165
-
166
- var self = this;
167
- strings.forEach(function(s) {
168
- self.writeString(s);
169
- });
170
-};
171
-
172
-// This is really to solve DER cases, but whatever for now
173
-Writer.prototype.writeOID = function(s, tag) {
174
- if (typeof(s) !== 'string')
175
- throw new TypeError('argument must be a string');
176
- if (typeof(tag) !== 'number')
177
- tag = ASN1.OID;
178
-
179
- if (!/^([0-9]+\.){3,}[0-9]+$/.test(s))
180
- throw new Error('argument is not a valid OID string');
181
-
182
- function encodeOctet(bytes, octet) {
183
- if (octet < 128) {
184
- bytes.push(octet);
185
- } else if (octet < 16384) {
186
- bytes.push((octet >>> 7) | 0x80);
187
- bytes.push(octet & 0x7F);
188
- } else if (octet < 2097152) {
189
- bytes.push((octet >>> 14) | 0x80);
190
- bytes.push(((octet >>> 7) | 0x80) & 0xFF);
191
- bytes.push(octet & 0x7F);
192
- } else if (octet < 268435456) {
193
- bytes.push((octet >>> 21) | 0x80);
194
- bytes.push(((octet >>> 14) | 0x80) & 0xFF);
195
- bytes.push(((octet >>> 7) | 0x80) & 0xFF);
196
- bytes.push(octet & 0x7F);
197
- } else {
198
- bytes.push(((octet >>> 28) | 0x80) & 0xFF);
199
- bytes.push(((octet >>> 21) | 0x80) & 0xFF);
200
- bytes.push(((octet >>> 14) | 0x80) & 0xFF);
201
- bytes.push(((octet >>> 7) | 0x80) & 0xFF);
202
- bytes.push(octet & 0x7F);
203
- }
204
- }
205
-
206
- var tmp = s.split('.');
207
- var bytes = [];
208
- bytes.push(parseInt(tmp[0], 10) * 40 + parseInt(tmp[1], 10));
209
- tmp.slice(2).forEach(function(b) {
210
- encodeOctet(bytes, parseInt(b, 10));
211
- });
212
-
213
- var self = this;
214
- this._ensure(2 + bytes.length);
215
- this.writeByte(tag);
216
- this.writeLength(bytes.length);
217
- bytes.forEach(function(b) {
218
- self.writeByte(b);
219
- });
220
-};
221
-
222
-
223
-Writer.prototype.writeLength = function(len) {
224
- if (typeof(len) !== 'number')
225
- throw new TypeError('argument must be a Number');
226
-
227
- this._ensure(4);
228
-
229
- if (len <= 0x7f) {
230
- this._buf[this._offset++] = len;
231
- } else if (len <= 0xff) {
232
- this._buf[this._offset++] = 0x81;
233
- this._buf[this._offset++] = len;
234
- } else if (len <= 0xffff) {
235
- this._buf[this._offset++] = 0x82;
236
- this._buf[this._offset++] = len >> 8;
237
- this._buf[this._offset++] = len;
238
- } else if (len <= 0xffffff) {
239
- this._buf[this._offset++] = 0x83;
240
- this._buf[this._offset++] = len >> 16;
241
- this._buf[this._offset++] = len >> 8;
242
- this._buf[this._offset++] = len;
243
- } else {
244
- throw new InvalidAsn1ERror('Length too long (> 4 bytes)');
245
- }
246
-};
247
-
248
-Writer.prototype.startSequence = function(tag) {
249
- if (typeof(tag) !== 'number')
250
- tag = ASN1.Sequence | ASN1.Constructor;
251
-
252
- this.writeByte(tag);
253
- this._seq.push(this._offset);
254
- this._ensure(3);
255
- this._offset += 3;
256
-};
257
-
258
-
259
-Writer.prototype.endSequence = function() {
260
- var seq = this._seq.pop();
261
- var start = seq + 3;
262
- var len = this._offset - start;
263
-
264
- if (len <= 0x7f) {
265
- this._shift(start, len, -2);
266
- this._buf[seq] = len;
267
- } else if (len <= 0xff) {
268
- this._shift(start, len, -1);
269
- this._buf[seq] = 0x81;
270
- this._buf[seq + 1] = len;
271
- } else if (len <= 0xffff) {
272
- this._buf[seq] = 0x82;
273
- this._buf[seq + 1] = len >> 8;
274
- this._buf[seq + 2] = len;
275
- } else if (len <= 0xffffff) {
276
- this._shift(start, len, 1);
277
- this._buf[seq] = 0x83;
278
- this._buf[seq + 1] = len >> 16;
279
- this._buf[seq + 2] = len >> 8;
280
- this._buf[seq + 3] = len;
281
- } else {
282
- throw new InvalidAsn1Error('Sequence too long');
283
- }
284
-};
285
-
286
-
287
-Writer.prototype._shift = function(start, len, shift) {
288
- assert.ok(start !== undefined);
289
- assert.ok(len !== undefined);
290
- assert.ok(shift);
291
-
292
- this._buf.copy(this._buf, start + shift, start, start + len);
293
- this._offset += shift;
294
-};
295
-
296
-Writer.prototype._ensure = function(len) {
297
- assert.ok(len);
298
-
299
- if (this._size - this._offset < len) {
300
- var sz = this._size * this._options.growthFactor;
301
- if (sz - this._offset < len)
302
- sz += len;
303
-
304
- var buf = new Buffer(sz);
305
-
306
- this._buf.copy(buf, 0, 0, this._offset);
307
- this._buf = buf;
308
- this._size = sz;
309
- }
310
-};
311
-
312
-
313
-
314
-///--- Exported API
315
-
316
-module.exports = Writer;
node.d/node_modules/lib/ber/errors.js
new
+9
@@ -0,0 +1,9 @@
1
+
2
+module.exports = {
3
+ InvalidAsn1Error: function(msg) {
4
+ var e = new Error()
5
+ e.name = 'InvalidAsn1Error'
6
+ e.message = msg || ''
7
+ return e
8
+ }
9
+}
node.d/node_modules/lib/ber/index.js
new
+17
@@ -0,0 +1,17 @@
1
+
2
+var errors = require('./errors')
3
+var types = require('./types')
4
+
5
+var Reader = require('./reader')
6
+var Writer = require('./writer')
7
+
8
+for (var t in types)
9
+ if (types.hasOwnProperty(t))
10
+ exports[t] = types[t]
11
+
12
+for (var e in errors)
13
+ if (errors.hasOwnProperty(e))
14
+ exports[e] = errors[e]
15
+
16
+exports.Reader = Reader
17
+exports.Writer = Writer
node.d/node_modules/lib/ber/reader.js
new
+269
@@ -0,0 +1,269 @@
1
+
2
+var assert = require('assert');
3
+
4
+var ASN1 = require('./types');
5
+var errors = require('./errors');
6
+
7
+
8
+///--- Globals
9
+
10
+var InvalidAsn1Error = errors.InvalidAsn1Error;
11
+
12
+
13
+
14
+///--- API
15
+
16
+function Reader(data) {
17
+ if (!data || !Buffer.isBuffer(data))
18
+ throw new TypeError('data must be a node Buffer');
19
+
20
+ this._buf = data;
21
+ this._size = data.length;
22
+
23
+ // These hold the "current" state
24
+ this._len = 0;
25
+ this._offset = 0;
26
+}
27
+
28
+Object.defineProperty(Reader.prototype, 'length', {
29
+ enumerable: true,
30
+ get: function () { return (this._len); }
31
+});
32
+
33
+Object.defineProperty(Reader.prototype, 'offset', {
34
+ enumerable: true,
35
+ get: function () { return (this._offset); }
36
+});
37
+
38
+Object.defineProperty(Reader.prototype, 'remain', {
39
+ get: function () { return (this._size - this._offset); }
40
+});
41
+
42
+Object.defineProperty(Reader.prototype, 'buffer', {
43
+ get: function () { return (this._buf.slice(this._offset)); }
44
+});
45
+
46
+
47
+/**
48
+ * Reads a single byte and advances offset; you can pass in `true` to make this
49
+ * a "peek" operation (i.e., get the byte, but don't advance the offset).
50
+ *
51
+ * @param {Boolean} peek true means don't move offset.
52
+ * @return {Number} the next byte, null if not enough data.
53
+ */
54
+Reader.prototype.readByte = function(peek) {
55
+ if (this._size - this._offset < 1)
56
+ return null;
57
+
58
+ var b = this._buf[this._offset] & 0xff;
59
+
60
+ if (!peek)
61
+ this._offset += 1;
62
+
63
+ return b;
64
+};
65
+
66
+
67
+Reader.prototype.peek = function() {
68
+ return this.readByte(true);
69
+};
70
+
71
+
72
+/**
73
+ * Reads a (potentially) variable length off the BER buffer. This call is
74
+ * not really meant to be called directly, as callers have to manipulate
75
+ * the internal buffer afterwards.
76
+ *
77
+ * As a result of this call, you can call `Reader.length`, until the
78
+ * next thing called that does a readLength.
79
+ *
80
+ * @return {Number} the amount of offset to advance the buffer.
81
+ * @throws {InvalidAsn1Error} on bad ASN.1
82
+ */
83
+Reader.prototype.readLength = function(offset) {
84
+ if (offset === undefined)
85
+ offset = this._offset;
86
+
87
+ if (offset >= this._size)
88
+ return null;
89
+
90
+ var lenB = this._buf[offset++] & 0xff;
91
+ if (lenB === null)
92
+ return null;
93
+
94
+ if ((lenB & 0x80) == 0x80) {
95
+ lenB &= 0x7f;
96
+
97
+ if (lenB == 0)
98
+ throw InvalidAsn1Error('Indefinite length not supported');
99
+
100
+ if (lenB > 4)
101
+ throw InvalidAsn1Error('encoding too long');
102
+
103
+ if (this._size - offset < lenB)
104
+ return null;
105
+
106
+ this._len = 0;
107
+ for (var i = 0; i < lenB; i++)
108
+ this._len = (this._len << 8) + (this._buf[offset++] & 0xff);
109
+
110
+ } else {
111
+ // Wasn't a variable length
112
+ this._len = lenB;
113
+ }
114
+
115
+ return offset;
116
+};
117
+
118
+
119
+/**
120
+ * Parses the next sequence in this BER buffer.
121
+ *
122
+ * To get the length of the sequence, call `Reader.length`.
123
+ *
124
+ * @return {Number} the sequence's tag.
125
+ */
126
+Reader.prototype.readSequence = function(tag) {
127
+ var seq = this.peek();
128
+ if (seq === null)
129
+ return null;
130
+ if (tag !== undefined && tag !== seq)
131
+ throw InvalidAsn1Error('Expected 0x' + tag.toString(16) +
132
+ ': got 0x' + seq.toString(16));
133
+
134
+ var o = this.readLength(this._offset + 1); // stored in `length`
135
+ if (o === null)
136
+ return null;
137
+
138
+ this._offset = o;
139
+ return seq;
140
+};
141
+
142
+
143
+Reader.prototype.readInt = function(tag) {
144
+ if (typeof(tag) !== 'number')
145
+ tag = ASN1.Integer;
146
+
147
+ return this._readTag(ASN1.Integer);
148
+};
149
+
150
+
151
+Reader.prototype.readBoolean = function(tag) {
152
+ if (typeof(tag) !== 'number')
153
+ tag = ASN1.Boolean;
154
+
155
+ return (this._readTag(tag) === 0 ? false : true);
156
+};
157
+
158
+
159
+Reader.prototype.readEnumeration = function(tag) {
160
+ if (typeof(tag) !== 'number')
161
+ tag = ASN1.Enumeration;
162
+
163
+ return this._readTag(ASN1.Enumeration);
164
+};
165
+
166
+
167
+Reader.prototype.readString = function(tag, retbuf) {
168
+ if (!tag)
169
+ tag = ASN1.OctetString;
170
+
171
+ var b = this.peek();
172
+ if (b === null)
173
+ return null;
174
+
175
+ if (b !== tag)
176
+ throw InvalidAsn1Error('Expected 0x' + tag.toString(16) +
177
+ ': got 0x' + b.toString(16));
178
+
179
+ var o = this.readLength(this._offset + 1); // stored in `length`
180
+
181
+ if (o === null)
182
+ return null;
183
+
184
+ if (this.length > this._size - o)
185
+ return null;
186
+
187
+ this._offset = o;
188
+
189
+ if (this.length === 0)
190
+ return retbuf ? new Buffer(0) : '';
191
+
192
+ var str = this._buf.slice(this._offset, this._offset + this.length);
193
+ this._offset += this.length;
194
+
195
+ return retbuf ? str : str.toString('utf8');
196
+};
197
+
198
+Reader.prototype.readOID = function(tag) {
199
+ if (!tag)
200
+ tag = ASN1.OID;
201
+
202
+ var b = this.readString(tag, true);
203
+ if (b === null)
204
+ return null;
205
+
206
+ var values = [];
207
+ var value = 0;
208
+
209
+ for (var i = 0; i < b.length; i++) {
210
+ var byte = b[i] & 0xff;
211
+
212
+ value <<= 7;
213
+ value += byte & 0x7f;
214
+ if ((byte & 0x80) == 0) {
215
+ values.push(value >>> 0);
216
+ value = 0;
217
+ }
218
+ }
219
+
220
+ value = values.shift();
221
+ values.unshift(value % 40);
222
+ values.unshift((value / 40) >> 0);
223
+
224
+ return values.join('.');
225
+};
226
+
227
+
228
+Reader.prototype._readTag = function(tag) {
229
+ assert.ok(tag !== undefined);
230
+
231
+ var b = this.peek();
232
+
233
+ if (b === null)
234
+ return null;
235
+
236
+ if (b !== tag)
237
+ throw InvalidAsn1Error('Expected 0x' + tag.toString(16) +
238
+ ': got 0x' + b.toString(16));
239
+
240
+ var o = this.readLength(this._offset + 1); // stored in `length`
241
+ if (o === null)
242
+ return null;
243
+
244
+ if (this.length > 4)
245
+ throw InvalidAsn1Error('Integer too long: ' + this.length);
246
+
247
+ if (this.length > this._size - o)
248
+ return null;
249
+ this._offset = o;
250
+
251
+ var fb = this._buf[this._offset];
252
+ var value = 0;
253
+
254
+ for (var i = 0; i < this.length; i++) {
255
+ value <<= 8;
256
+ value |= (this._buf[this._offset++] & 0xff);
257
+ }
258
+
259
+ if ((fb & 0x80) == 0x80 && i !== 4)
260
+ value -= (1 << (i * 8));
261
+
262
+ return value >> 0;
263
+};
264
+
265
+
266
+
267
+///--- Exported API
268
+
269
+module.exports = Reader;
node.d/node_modules/lib/ber/types.js
new
+34
@@ -0,0 +1,34 @@
1
+
2
+module.exports = {
3
+ EOC: 0,
4
+ Boolean: 1,
5
+ Integer: 2,
6
+ BitString: 3,
7
+ OctetString: 4,
8
+ Null: 5,
9
+ OID: 6,
10
+ ObjectDescriptor: 7,
11
+ External: 8,
12
+ Real: 9,
13
+ Enumeration: 10,
14
+ PDV: 11,
15
+ Utf8String: 12,
16
+ RelativeOID: 13,
17
+ Sequence: 16,
18
+ Set: 17,
19
+ NumericString: 18,
20
+ PrintableString: 19,
21
+ T61String: 20,
22
+ VideotexString: 21,
23
+ IA5String: 22,
24
+ UTCTime: 23,
25
+ GeneralizedTime: 24,
26
+ GraphicString: 25,
27
+ VisibleString: 26,
28
+ GeneralString: 28,
29
+ UniversalString: 29,
30
+ CharacterString: 30,
31
+ BMPString: 31,
32
+ Constructor: 32,
33
+ Context: 128
34
+}
node.d/node_modules/lib/ber/writer.js
new
+317
@@ -0,0 +1,317 @@
1
+
2
+var assert = require('assert');
3
+var ASN1 = require('./types');
4
+var errors = require('./errors');
5
+
6
+
7
+///--- Globals
8
+
9
+var InvalidAsn1Error = errors.InvalidAsn1Error;
10
+
11
+var DEFAULT_OPTS = {
12
+ size: 1024,
13
+ growthFactor: 8
14
+};
15
+
16
+
17
+///--- Helpers
18
+
19
+function merge(from, to) {
20
+ assert.ok(from);
21
+ assert.equal(typeof(from), 'object');
22
+ assert.ok(to);
23
+ assert.equal(typeof(to), 'object');
24
+
25
+ var keys = Object.getOwnPropertyNames(from);
26
+ keys.forEach(function(key) {
27
+ if (to[key])
28
+ return;
29
+
30
+ var value = Object.getOwnPropertyDescriptor(from, key);
31
+ Object.defineProperty(to, key, value);
32
+ });
33
+
34
+ return to;
35
+}
36
+
37
+
38
+
39
+///--- API
40
+
41
+function Writer(options) {
42
+ options = merge(DEFAULT_OPTS, options || {});
43
+
44
+ this._buf = new Buffer(options.size || 1024);
45
+ this._size = this._buf.length;
46
+ this._offset = 0;
47
+ this._options = options;
48
+
49
+ // A list of offsets in the buffer where we need to insert
50
+ // sequence tag/len pairs.
51
+ this._seq = [];
52
+}
53
+
54
+Object.defineProperty(Writer.prototype, 'buffer', {
55
+ get: function () {
56
+ if (this._seq.length)
57
+ throw new InvalidAsn1Error(this._seq.length + ' unended sequence(s)');
58
+
59
+ return (this._buf.slice(0, this._offset));
60
+ }
61
+});
62
+
63
+Writer.prototype.writeByte = function(b) {
64
+ if (typeof(b) !== 'number')
65
+ throw new TypeError('argument must be a Number');
66
+
67
+ this._ensure(1);
68
+ this._buf[this._offset++] = b;
69
+};
70
+
71
+
72
+Writer.prototype.writeInt = function(i, tag) {
73
+ if (typeof(i) !== 'number')
74
+ throw new TypeError('argument must be a Number');
75
+ if (typeof(tag) !== 'number')
76
+ tag = ASN1.Integer;
77
+
78
+ var sz = 4;
79
+
80
+ while ((((i & 0xff800000) === 0) || ((i & 0xff800000) === 0xff800000 >> 0)) &&
81
+ (sz > 1)) {
82
+ sz--;
83
+ i <<= 8;
84
+ }
85
+
86
+ if (sz > 4)
87
+ throw new InvalidAsn1Error('BER ints cannot be > 0xffffffff');
88
+
89
+ this._ensure(2 + sz);
90
+ this._buf[this._offset++] = tag;
91
+ this._buf[this._offset++] = sz;
92
+
93
+ while (sz-- > 0) {
94
+ this._buf[this._offset++] = ((i & 0xff000000) >>> 24);
95
+ i <<= 8;
96
+ }
97
+
98
+};
99
+
100
+
101
+Writer.prototype.writeNull = function() {
102
+ this.writeByte(ASN1.Null);
103
+ this.writeByte(0x00);
104
+};
105
+
106
+
107
+Writer.prototype.writeEnumeration = function(i, tag) {
108
+ if (typeof(i) !== 'number')
109
+ throw new TypeError('argument must be a Number');
110
+ if (typeof(tag) !== 'number')
111
+ tag = ASN1.Enumeration;
112
+
113
+ return this.writeInt(i, tag);
114
+};
115
+
116
+
117
+Writer.prototype.writeBoolean = function(b, tag) {
118
+ if (typeof(b) !== 'boolean')
119
+ throw new TypeError('argument must be a Boolean');
120
+ if (typeof(tag) !== 'number')
121
+ tag = ASN1.Boolean;
122
+
123
+ this._ensure(3);
124
+ this._buf[this._offset++] = tag;
125
+ this._buf[this._offset++] = 0x01;
126
+ this._buf[this._offset++] = b ? 0xff : 0x00;
127
+};
128
+
129
+
130
+Writer.prototype.writeString = function(s, tag) {
131
+ if (typeof(s) !== 'string')
132
+ throw new TypeError('argument must be a string (was: ' + typeof(s) + ')');
133
+ if (typeof(tag) !== 'number')
134
+ tag = ASN1.OctetString;
135
+
136
+ var len = Buffer.byteLength(s);
137
+ this.writeByte(tag);
138
+ this.writeLength(len);
139
+ if (len) {
140
+ this._ensure(len);
141
+ this._buf.write(s, this._offset);
142
+ this._offset += len;
143
+ }
144
+};
145
+
146
+
147
+Writer.prototype.writeBuffer = function(buf, tag) {
148
+ if (!Buffer.isBuffer(buf))
149
+ throw new TypeError('argument must be a buffer');
150
+
151
+ // If no tag is specified we will assume `buf` already contains tag and length
152
+ if (typeof(tag) === 'number') {
153
+ this.writeByte(tag);
154
+ this.writeLength(buf.length);
155
+ }
156
+
157
+ this._ensure(buf.length);
158
+ buf.copy(this._buf, this._offset, 0, buf.length);
159
+ this._offset += buf.length;
160
+};
161
+
162
+
163
+Writer.prototype.writeStringArray = function(strings, tag) {
164
+ if (! (strings instanceof Array))
165
+ throw new TypeError('argument must be an Array[String]');
166
+
167
+ var self = this;
168
+ strings.forEach(function(s) {
169
+ self.writeString(s, tag);
170
+ });
171
+};
172
+
173
+// This is really to solve DER cases, but whatever for now
174
+Writer.prototype.writeOID = function(s, tag) {
175
+ if (typeof(s) !== 'string')
176
+ throw new TypeError('argument must be a string');
177
+ if (typeof(tag) !== 'number')
178
+ tag = ASN1.OID;
179
+
180
+ if (!/^([0-9]+\.){3,}[0-9]+$/.test(s))
181
+ throw new Error('argument is not a valid OID string');
182
+
183
+ function encodeOctet(bytes, octet) {
184
+ if (octet < 128) {
185
+ bytes.push(octet);
186
+ } else if (octet < 16384) {
187
+ bytes.push((octet >>> 7) | 0x80);
188
+ bytes.push(octet & 0x7F);
189
+ } else if (octet < 2097152) {
190
+ bytes.push((octet >>> 14) | 0x80);
191
+ bytes.push(((octet >>> 7) | 0x80) & 0xFF);
192
+ bytes.push(octet & 0x7F);
193
+ } else if (octet < 268435456) {
194
+ bytes.push((octet >>> 21) | 0x80);
195
+ bytes.push(((octet >>> 14) | 0x80) & 0xFF);
196
+ bytes.push(((octet >>> 7) | 0x80) & 0xFF);
197
+ bytes.push(octet & 0x7F);
198
+ } else {
199
+ bytes.push(((octet >>> 28) | 0x80) & 0xFF);
200
+ bytes.push(((octet >>> 21) | 0x80) & 0xFF);
201
+ bytes.push(((octet >>> 14) | 0x80) & 0xFF);
202
+ bytes.push(((octet >>> 7) | 0x80) & 0xFF);
203
+ bytes.push(octet & 0x7F);
204
+ }
205
+ }
206
+
207
+ var tmp = s.split('.');
208
+ var bytes = [];
209
+ bytes.push(parseInt(tmp[0], 10) * 40 + parseInt(tmp[1], 10));
210
+ tmp.slice(2).forEach(function(b) {
211
+ encodeOctet(bytes, parseInt(b, 10));
212
+ });
213
+
214
+ var self = this;
215
+ this._ensure(2 + bytes.length);
216
+ this.writeByte(tag);
217
+ this.writeLength(bytes.length);
218
+ bytes.forEach(function(b) {
219
+ self.writeByte(b);
220
+ });
221
+};
222
+
223
+
224
+Writer.prototype.writeLength = function(len) {
225
+ if (typeof(len) !== 'number')
226
+ throw new TypeError('argument must be a Number');
227
+
228
+ this._ensure(4);
229
+
230
+ if (len <= 0x7f) {
231
+ this._buf[this._offset++] = len;
232
+ } else if (len <= 0xff) {
233
+ this._buf[this._offset++] = 0x81;
234
+ this._buf[this._offset++] = len;
235
+ } else if (len <= 0xffff) {
236
+ this._buf[this._offset++] = 0x82;
237
+ this._buf[this._offset++] = len >> 8;
238
+ this._buf[this._offset++] = len;
239
+ } else if (len <= 0xffffff) {
240
+ this._buf[this._offset++] = 0x83;
241
+ this._buf[this._offset++] = len >> 16;
242
+ this._buf[this._offset++] = len >> 8;
243
+ this._buf[this._offset++] = len;
244
+ } else {
245
+ throw new InvalidAsn1Error('Length too long (> 4 bytes)');
246
+ }
247
+};
248
+
249
+Writer.prototype.startSequence = function(tag) {
250
+ if (typeof(tag) !== 'number')
251
+ tag = ASN1.Sequence | ASN1.Constructor;
252
+
253
+ this.writeByte(tag);
254
+ this._seq.push(this._offset);
255
+ this._ensure(3);
256
+ this._offset += 3;
257
+};
258
+
259
+
260
+Writer.prototype.endSequence = function() {
261
+ var seq = this._seq.pop();
262
+ var start = seq + 3;
263
+ var len = this._offset - start;
264
+
265
+ if (len <= 0x7f) {
266
+ this._shift(start, len, -2);
267
+ this._buf[seq] = len;
268
+ } else if (len <= 0xff) {
269
+ this._shift(start, len, -1);
270
+ this._buf[seq] = 0x81;
271
+ this._buf[seq + 1] = len;
272
+ } else if (len <= 0xffff) {
273
+ this._buf[seq] = 0x82;
274
+ this._buf[seq + 1] = len >> 8;
275
+ this._buf[seq + 2] = len;
276
+ } else if (len <= 0xffffff) {
277
+ this._shift(start, len, 1);
278
+ this._buf[seq] = 0x83;
279
+ this._buf[seq + 1] = len >> 16;
280
+ this._buf[seq + 2] = len >> 8;
281
+ this._buf[seq + 3] = len;
282
+ } else {
283
+ throw new InvalidAsn1Error('Sequence too long');
284
+ }
285
+};
286
+
287
+
288
+Writer.prototype._shift = function(start, len, shift) {
289
+ assert.ok(start !== undefined);
290
+ assert.ok(len !== undefined);
291
+ assert.ok(shift);
292
+
293
+ this._buf.copy(this._buf, start + shift, start, start + len);
294
+ this._offset += shift;
295
+};
296
+
297
+Writer.prototype._ensure = function(len) {
298
+ assert.ok(len);
299
+
300
+ if (this._size - this._offset < len) {
301
+ var sz = this._size * this._options.growthFactor;
302
+ if (sz - this._offset < len)
303
+ sz += len;
304
+
305
+ var buf = new Buffer(sz);
306
+
307
+ this._buf.copy(buf, 0, 0, this._offset);
308
+ this._buf = buf;
309
+ this._size = sz;
310
+ }
311
+};
312
+
313
+
314
+
315
+///--- Exported API
316
+
317
+module.exports = Writer;
node.d/node_modules/net-snmp.js
+1
-1
@@ -1,7 +1,7 @@
1
2
// Copyright 2013 Stephen Vickers <stephen.vickers.sv@gmail.com>
3
4
-var ber = require ("asn1").Ber;
4
+var ber = require ("asn1-ber").Ber;
5
var dgram = require ("dgram");
6
var events = require ("events");
7
var util = require ("util");