master
js 606 lines 14.1 KB
Raw
1 /*
2 * Copyright (c) 2014-2015 Sylvain Peyrefitte
3 *
4 * This file is part of node-rdpjs.
5 *
6 * node-rdpjs is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 var spec = require('./spec');
21 var type = require('../core').type;
22 var error = require('../core').error;
23 var inherits = require('util').inherits;
24
25 /**
26 * ASN.1 Universal tags
27 * @see http://www.obj-sys.com/asn1tutorial/node124.html
28 */
29 var UniversalTag = {
30 Boolean : 1,
31 Integer : 2,
32 BitString : 3,
33 OctetString : 4,
34 Null : 5,
35 ObjectIdentifier : 6,
36 ObjectDescriptor : 7,
37 Enumerate : 10,
38 UTF8String : 12,
39 Sequence : 16,
40 Set : 17,
41 PrintableString : 19,
42 T61String : 20,
43 IA5String : 22,
44 UTCTime : 23,
45 GeneralizedTime : 24,
46 UniversalString : 28,
47 BMPString : 30
48 };
49
50 /**
51 * Boolean type
52 * @param value {boolean} inner value
53 */
54 function Boolean(value) {
55 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Boolean));
56 this.value = value || false;
57 }
58
59 inherits(Boolean, spec.Asn1Spec);
60
61 /**
62 * @param s {type.Stream}
63 * @param decoder {ber.decoder}
64 * @returns {Boolean}
65 */
66 Boolean.prototype.decode = function(s, decoder) {
67 this.value = new type.UInt8().read(new type.Stream(decoder.decode(s, this.tag).value)).value !== 0;
68 return this;
69 };
70
71 /**
72 * @param decoder {ber.decoder}
73 * @returns {type.*}
74 */
75 Boolean.prototype.encode = function(encoder) {
76 if(this.value) {
77 return encoder.encode(this.tag, new type.UInt8(0xff));
78 }
79 else {
80 return encoder.encode(this.tag, new type.UInt8(0));
81 }
82 };
83
84 /**
85 * Integer type
86 * @param value {integer | Buffer}
87 */
88 function Integer(value) {
89 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Integer));
90 this.value = value || 0;
91 }
92
93 inherits(Integer, spec.Asn1Spec);
94
95 /**
96 * @param s {type.Stream}
97 * @param decoder {ber.decoder}
98 * @returns {Integer}
99 */
100 Integer.prototype.decode = function(s, decoder) {
101 var integerBuffer = decoder.decode(s, this.tag).value;
102 if(integerBuffer.length < 5) {
103 var integerStream = new type.Stream(integerBuffer);
104 while (integerStream.availableLength() > 0) {
105 this.value = this.value << 8;
106 this.value |= new type.UInt8().read(integerStream).value;
107 }
108 }
109 // bignum case
110 else {
111 this.value = integerBuffer;
112 }
113 return this;
114 };
115
116 /**
117 * @param encoder {ber.decoder}
118 * @returns {type.*}
119 */
120 Integer.prototype.encode = function(encoder) {
121 if(this.value <= 0xff) {
122 return encoder.encode(this.tag, new type.UInt8(this.value));
123 }
124 else if(this.value <= 0xffff) {
125 return encoder.encode(this.tag, new type.UInt16Be(this.value));
126 }
127 else {
128 return encoder.encode(this.tag, new type.UInt32Be(this.value));
129 }
130 };
131
132 /**
133 * Sequence type
134 * @param value {object}
135 */
136 function Sequence(value) {
137 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Constructed, UniversalTag.Sequence));
138 this.value = value || [];
139 }
140
141 inherits(Sequence, spec.Asn1Spec);
142
143 /**
144 * @param s {type.Stream}
145 * @param decoder {ber.decoder}
146 * @returns {Sequence}
147 */
148 Sequence.prototype.decode = function(s, decoder) {
149 var sequenceStream = new type.Stream(decoder.decode(s, this.tag).value);
150 for (var i in this.value) {
151 var rec = sequenceStream.offset;
152 try {
153 this.value[i].decode(sequenceStream, decoder);
154 } catch(e) {
155 if ((e.message === 'NODE_RDP_ASN1_BER_INVALID_TAG') && !this.value[i].opt) {
156 throw new error.ProtocolError('NODE_RDP_ASN1_UNIV_SEQUENCE_FIELD_NOT_PRESENT');
157 }
158 sequenceStream.offset = rec;
159 }
160 }
161 return this;
162 };
163
164 /**
165 * Encode sequence
166 * @param encoder
167 * @returns {type.Component}
168 */
169 Sequence.prototype.encode = function(encoder) {
170 var sequence = new type.Component([]);
171 for (var i in this.value) {
172 sequence.obj.push(this.value[i].encode(encoder))
173 }
174 return encoder.encode(this.tag, sequence);
175 };
176
177
178 /**
179 * Enumerate type
180 * @param value {integer}
181 */
182 function Enumerate(value) {
183 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Enumerate));
184 this.value = value || 0;
185 }
186
187 inherits(Enumerate, spec.Asn1Spec);
188
189 /**
190 * @param s {type.Stream}
191 * @param decoder {ber.decoder}
192 * @returns {Enumerate}
193 */
194 Enumerate.prototype.decode = function(s, decoder) {
195 this.value = new type.UInt8().read(new type.Stream(decoder.decode(s, this.tag).value)).value;
196 return this;
197 };
198
199 /**
200 * Encode enumerate type
201 * @param encoder
202 * @returns {type.Component}
203 */
204 Enumerate.prototype.encode = function(encoder) {
205 return encoder.encode(this.tag, new type.UInt8(this.value));
206 };
207
208 /**
209 * OctetString type
210 * @param value {Buffer}
211 */
212 function OctetString(value) {
213 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.OctetString));
214 this.value = value || Buffer.alloc(0);
215 }
216
217 inherits(OctetString, spec.Asn1Spec);
218
219 /**
220 * @param s {type.Stream}
221 * @param decoder {ber.decoder}
222 * @returns {OctetString}
223 */
224 OctetString.prototype.decode = function(s, decoder) {
225 this.value = decoder.decode(s, this.tag).value;
226 return this;
227 };
228
229 /**
230 * Encode Octet String
231 * @param encoder
232 * @returns {type.Component}
233 */
234 OctetString.prototype.encode = function(encoder) {
235 return encoder.encode(this.tag, new type.BinaryString(this.value));
236 };
237
238 /**
239 * ObjectIdentifier type
240 * @param value {Buffer}
241 */
242 function ObjectIdentifier(value) {
243 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.ObjectIdentifier));
244 this.value = value || Buffer.alloc(5);
245 }
246
247 inherits(ObjectIdentifier, spec.Asn1Spec);
248
249 /**
250 * @param s {type.Stream}
251 * @param decoder {ber.decoder}
252 * @returns {ObjectIdentifier}
253 */
254 ObjectIdentifier.prototype.decode = function(s, decoder) {
255 this.value = decoder.decode(s, this.tag).value;
256 return this;
257 };
258
259 /**
260 * Null type
261 */
262 function Null() {
263 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Null));
264 }
265
266 inherits(Null, spec.Asn1Spec);
267
268 /**
269 * @param s {type.Stream}
270 * @param decoder {ber.decoder}
271 * @returns {Null}
272 */
273 Null.prototype.decode = function(s, decoder) {
274 decoder.decode(s, this.tag);
275 return this;
276 };
277
278 /**
279 * Choice type
280 * @param value {object} list of available type
281 */
282 function Choice(value) {
283 // not tagged type
284 spec.Asn1Spec.call(this, new spec.Asn1Tag());
285 this.value = value;
286 }
287
288 inherits(Choice, spec.Asn1Spec);
289
290 /**
291 * @param s {type.Stream}
292 * @param decoder {ber.decoder}
293 * @returns {Choice}
294 */
295 Choice.prototype.decode = function(s, decoder) {
296 for (var i in this.value) {
297 var rec = s.offset;
298 try {
299 this.value[i].decode(s, decoder);
300 break;
301 }
302 catch(e) {
303 s.offset = rec;
304 }
305 }
306 return this;
307 };
308
309 /**
310 * SetOf type
311 * @param factory {function} type builder
312 * @param value {object} list of available type
313 */
314 function SetOf(factory, value) {
315 // not tagged type
316 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Constructed, UniversalTag.Set));
317 this.factory = factory;
318 this.value = value || [];
319 }
320
321 inherits(SetOf, spec.Asn1Spec);
322
323 /**
324 * @param s {type.Stream}
325 * @param decoder {ber.decoder}
326 * @returns {SetOf}
327 */
328 SetOf.prototype.decode = function(s, decoder) {
329 var setOfStream = new type.Stream(decoder.decode(s, this.tag).value);
330 while (setOfStream.availableLength() > 0) {
331 this.value.push(this.factory().decode(setOfStream, decoder));
332 }
333 return this;
334 };
335
336 /**
337 * SequenceOf type
338 * @param factory {function} type builder
339 * @param value {object} list of available type
340 */
341 function SequenceOf(factory, value) {
342 // not tagged type
343 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Constructed, UniversalTag.Sequence));
344 this.factory = factory;
345 this.value = value || [];
346 }
347
348 inherits(SequenceOf, spec.Asn1Spec);
349
350 /**
351 * @param s {type.Stream}
352 * @param decoder {ber.decoder}
353 * @returns {SequenceOf}
354 */
355 SequenceOf.prototype.decode = function(s, decoder) {
356 var sequenceOfStream = new type.Stream(decoder.decode(s, this.tag).value);
357 while (sequenceOfStream.availableLength() > 0) {
358 this.value.push(this.factory().decode(sequenceOfStream, decoder));
359 }
360 return this;
361 };
362
363 /**
364 * BitString type
365 * @param value {Buffer}
366 */
367 function BitString(value) {
368 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.BitString));
369 this.value = [];
370 }
371
372 inherits(BitString, spec.Asn1Spec);
373
374 /**
375 * @param s {type.Stream}
376 * @param decoder {ber.decoder}
377 * @returns {BitString}
378 */
379 BitString.prototype.decode = function(s, decoder) {
380 var bitStream = new type.Stream(decoder.decode(s, this.tag).value);
381 var padding = new type.UInt8().read(bitStream).value;
382 var value = [];
383 for(var i = 0; i < padding; i++) {
384 value.push(0);
385 }
386
387 while(bitStream.availableLength() > 0) {
388 var octet = new type.UInt8().read(bitStream).value;
389 var currentPadding = 0;
390 if(bitStream.availableLength() === 0) {
391 currentPadding = padding;
392 }
393 for(var i = 7; i >= currentPadding; i--) {
394 value.push(((octet >> i) & 1)?1:0);
395 }
396 }
397 this.value = value;
398 return this;
399 };
400
401 /**
402 * Convert bit string to buffer object
403 * @returns {Buffer}
404 */
405 BitString.prototype.toBuffer = function () {
406 var length = this.value.length / 8;
407 var resultStream = new type.Stream(length);
408 for (var i = 0; i < length; i ++) {
409 var currentOctet = 0;
410 for (var j = 0; j < 8; j++) {
411 currentOctet = currentOctet | (this.value[i * 8 + j] << (7 - j));
412 }
413 new type.UInt8(currentOctet).write(resultStream);
414 }
415 return resultStream.buffer;
416 }
417
418 /**
419 * T61String type
420 * @param value {Buffer}
421 */
422 function T61String(value) {
423 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.T61String));
424 this.value = value;
425 }
426
427 inherits(T61String, spec.Asn1Spec);
428
429 /**
430 * @param s {type.Stream}
431 * @param decoder {ber.decoder}
432 * @returns {T61String}
433 */
434 T61String.prototype.decode = function(s, decoder) {
435 this.value = decoder.decode(s, this.tag).value;
436 return this;
437 };
438
439 /**
440 * PrintableString type
441 * @param value {Buffer}
442 */
443 function PrintableString(value) {
444 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.PrintableString));
445 this.value = value;
446 }
447
448 inherits(PrintableString, spec.Asn1Spec);
449
450 /**
451 * @param s {type.Stream}
452 * @param decoder {ber.decoder}
453 * @returns {PrintableString}
454 */
455 PrintableString.prototype.decode = function(s, decoder) {
456 this.value = decoder.decode(s, this.tag).value;
457 return this;
458 };
459
460 /**
461 * UniversalString type
462 * @param value {Buffer}
463 */
464 function UniversalString(value) {
465 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UniversalString));
466 this.value = value;
467 }
468
469 inherits(UniversalString, spec.Asn1Spec);
470
471 /**
472 * @param s {type.Stream}
473 * @param decoder {ber.decoder}
474 * @returns {UniversalString}
475 */
476 UniversalString.prototype.decode = function(s, decoder) {
477 this.value = decoder.decode(s, this.tag).value;
478 return this;
479 };
480
481 /**
482 * UTF8String type
483 * @param value {Buffer}
484 */
485 function UTF8String(value) {
486 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UTF8String));
487 this.value = value;
488 }
489
490 inherits(UTF8String, spec.Asn1Spec);
491
492 /**
493 * @param s {type.Stream}
494 * @param decoder {ber.decoder}
495 * @returns {UTF8String}
496 */
497 UTF8String.prototype.decode = function(s, decoder) {
498 this.value = decoder.decode(s, this.tag).value;
499 return this;
500 };
501
502 /**
503 * BMPString type
504 * @param value {Buffer}
505 */
506 function BMPString(value) {
507 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.BMPString));
508 this.value = value;
509 }
510
511 inherits(BMPString, spec.Asn1Spec);
512
513 /**
514 * @param s {type.Stream}
515 * @param decoder {ber.decoder}
516 * @returns {BMPString}
517 */
518 BMPString.prototype.decode = function(s, decoder) {
519 this.value = decoder.decode(s, this.tag).value;
520 return this;
521 };
522
523 /**
524 * IA5String type
525 * @param value {Buffer}
526 */
527 function IA5String(value) {
528 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.IA5String));
529 this.value = value;
530 }
531
532 inherits(IA5String, spec.Asn1Spec);
533
534 /**
535 * @param s {type.Stream}
536 * @param decoder {ber.decoder}
537 * @returns {IA5String}
538 */
539 IA5String.prototype.decode = function(s, decoder) {
540 this.value = decoder.decode(s, this.tag).value;
541 return this;
542 };
543
544 /**
545 * UTCTime type
546 * @param value {Buffer}
547 */
548 function UTCTime(value) {
549 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UTCTime));
550 this.value = value;
551 }
552
553 inherits(UTCTime, spec.Asn1Spec);
554
555 /**
556 * @param s {type.Stream}
557 * @param decoder {ber.decoder}
558 * @returns {UTCTime}
559 */
560 UTCTime.prototype.decode = function(s, decoder) {
561 this.value = decoder.decode(s, this.tag).value;
562 return this;
563 };
564
565 /**
566 * GeneralizedTime type
567 * @param value {Buffer}
568 */
569 function GeneralizedTime(value) {
570 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.GeneralizedTime));
571 this.value = value;
572 }
573
574 inherits(GeneralizedTime, spec.Asn1Spec);
575
576 /**
577 * @param s {type.Stream}
578 * @param decoder {ber.decoder}
579 * @returns {GeneralizedTime}
580 */
581 GeneralizedTime.prototype.decode = function(s, decoder) {
582 this.value = decoder.decode(s, this.tag).value;
583 return this;
584 };
585
586 module.exports = {
587 Boolean : Boolean,
588 Integer : Integer,
589 Sequence : Sequence,
590 Enumerate : Enumerate,
591 OctetString : OctetString,
592 ObjectIdentifier : ObjectIdentifier,
593 Null : Null,
594 Choice : Choice,
595 SequenceOf : SequenceOf,
596 SetOf : SetOf,
597 BitString : BitString,
598 T61String : T61String,
599 PrintableString : PrintableString,
600 UniversalString : UniversalString,
601 UTF8String : UTF8String,
602 BMPString : BMPString,
603 IA5String : IA5String,
604 UTCTime : UTCTime,
605 GeneralizedTime : GeneralizedTime
606 };