EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
univ.js
Go to the documentation of this file.
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
20var spec = require('./spec');
21var type = require('../core').type;
22var error = require('../core').error;
23var inherits = require('util').inherits;
24
25/**
26 * ASN.1 Universal tags
27 * @see http://www.obj-sys.com/asn1tutorial/node124.html
28 */
29var 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 */
54function 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
59inherits(Boolean, spec.Asn1Spec);
60
61/**
62 * @param s {type.Stream}
63 * @param decoder {ber.decoder}
64 * @returns {Boolean}
65 */
66Boolean.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 */
75Boolean.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 */
88function 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
93inherits(Integer, spec.Asn1Spec);
94
95/**
96 * @param s {type.Stream}
97 * @param decoder {ber.decoder}
98 * @returns {Integer}
99 */
100Integer.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 */
120Integer.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 */
136function Sequence(value) {
137 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Constructed, UniversalTag.Sequence));
138 this.value = value || [];
139}
140
141inherits(Sequence, spec.Asn1Spec);
142
143/**
144 * @param s {type.Stream}
145 * @param decoder {ber.decoder}
146 * @returns {Sequence}
147 */
148Sequence.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 */
169Sequence.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 */
182function 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
187inherits(Enumerate, spec.Asn1Spec);
188
189/**
190 * @param s {type.Stream}
191 * @param decoder {ber.decoder}
192 * @returns {Enumerate}
193 */
194Enumerate.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 */
204Enumerate.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 */
212function 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
217inherits(OctetString, spec.Asn1Spec);
218
219/**
220 * @param s {type.Stream}
221 * @param decoder {ber.decoder}
222 * @returns {OctetString}
223 */
224OctetString.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 */
234OctetString.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 */
242function 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
247inherits(ObjectIdentifier, spec.Asn1Spec);
248
249/**
250 * @param s {type.Stream}
251 * @param decoder {ber.decoder}
252 * @returns {ObjectIdentifier}
253 */
254ObjectIdentifier.prototype.decode = function(s, decoder) {
255 this.value = decoder.decode(s, this.tag).value;
256 return this;
257};
258
259/**
260 * Null type
261 */
262function Null() {
263 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Null));
264}
265
266inherits(Null, spec.Asn1Spec);
267
268/**
269 * @param s {type.Stream}
270 * @param decoder {ber.decoder}
271 * @returns {Null}
272 */
273Null.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 */
282function Choice(value) {
283 // not tagged type
284 spec.Asn1Spec.call(this, new spec.Asn1Tag());
285 this.value = value;
286}
287
288inherits(Choice, spec.Asn1Spec);
289
290/**
291 * @param s {type.Stream}
292 * @param decoder {ber.decoder}
293 * @returns {Choice}
294 */
295Choice.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 */
314function 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
321inherits(SetOf, spec.Asn1Spec);
322
323/**
324 * @param s {type.Stream}
325 * @param decoder {ber.decoder}
326 * @returns {SetOf}
327 */
328SetOf.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 */
341function 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
348inherits(SequenceOf, spec.Asn1Spec);
349
350/**
351 * @param s {type.Stream}
352 * @param decoder {ber.decoder}
353 * @returns {SequenceOf}
354 */
355SequenceOf.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 */
367function BitString(value) {
368 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.BitString));
369 this.value = [];
370}
371
372inherits(BitString, spec.Asn1Spec);
373
374/**
375 * @param s {type.Stream}
376 * @param decoder {ber.decoder}
377 * @returns {BitString}
378 */
379BitString.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 */
405BitString.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 */
422function T61String(value) {
423 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.T61String));
424 this.value = value;
425}
426
427inherits(T61String, spec.Asn1Spec);
428
429/**
430 * @param s {type.Stream}
431 * @param decoder {ber.decoder}
432 * @returns {T61String}
433 */
434T61String.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 */
443function PrintableString(value) {
444 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.PrintableString));
445 this.value = value;
446}
447
448inherits(PrintableString, spec.Asn1Spec);
449
450/**
451 * @param s {type.Stream}
452 * @param decoder {ber.decoder}
453 * @returns {PrintableString}
454 */
455PrintableString.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 */
464function UniversalString(value) {
465 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UniversalString));
466 this.value = value;
467}
468
469inherits(UniversalString, spec.Asn1Spec);
470
471/**
472 * @param s {type.Stream}
473 * @param decoder {ber.decoder}
474 * @returns {UniversalString}
475 */
476UniversalString.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 */
485function UTF8String(value) {
486 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UTF8String));
487 this.value = value;
488}
489
490inherits(UTF8String, spec.Asn1Spec);
491
492/**
493 * @param s {type.Stream}
494 * @param decoder {ber.decoder}
495 * @returns {UTF8String}
496 */
497UTF8String.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 */
506function BMPString(value) {
507 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.BMPString));
508 this.value = value;
509}
510
511inherits(BMPString, spec.Asn1Spec);
512
513/**
514 * @param s {type.Stream}
515 * @param decoder {ber.decoder}
516 * @returns {BMPString}
517 */
518BMPString.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 */
527function IA5String(value) {
528 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.IA5String));
529 this.value = value;
530}
531
532inherits(IA5String, spec.Asn1Spec);
533
534/**
535 * @param s {type.Stream}
536 * @param decoder {ber.decoder}
537 * @returns {IA5String}
538 */
539IA5String.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 */
548function UTCTime(value) {
549 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UTCTime));
550 this.value = value;
551}
552
553inherits(UTCTime, spec.Asn1Spec);
554
555/**
556 * @param s {type.Stream}
557 * @param decoder {ber.decoder}
558 * @returns {UTCTime}
559 */
560UTCTime.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 */
569function GeneralizedTime(value) {
570 spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.GeneralizedTime));
571 this.value = value;
572}
573
574inherits(GeneralizedTime, spec.Asn1Spec);
575
576/**
577 * @param s {type.Stream}
578 * @param decoder {ber.decoder}
579 * @returns {GeneralizedTime}
580 */
581GeneralizedTime.prototype.decode = function(s, decoder) {
582 this.value = decoder.decode(s, this.tag).value;
583 return this;
584};
585
586module.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};