mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-03-09 15:40:18 +00:00
parent
f88d3063fe
commit
db06ec1975
37 changed files with 28174 additions and 44 deletions
606
rdp/asn1/univ.js
Normal file
606
rdp/asn1/univ.js
Normal file
|
@ -0,0 +1,606 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 Sylvain Peyrefitte
|
||||
*
|
||||
* This file is part of node-rdpjs.
|
||||
*
|
||||
* node-rdpjs is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
var spec = require('./spec');
|
||||
var type = require('../core').type;
|
||||
var error = require('../core').error;
|
||||
var inherits = require('util').inherits;
|
||||
|
||||
/**
|
||||
* ASN.1 Universal tags
|
||||
* @see http://www.obj-sys.com/asn1tutorial/node124.html
|
||||
*/
|
||||
var UniversalTag = {
|
||||
Boolean : 1,
|
||||
Integer : 2,
|
||||
BitString : 3,
|
||||
OctetString : 4,
|
||||
Null : 5,
|
||||
ObjectIdentifier : 6,
|
||||
ObjectDescriptor : 7,
|
||||
Enumerate : 10,
|
||||
UTF8String : 12,
|
||||
Sequence : 16,
|
||||
Set : 17,
|
||||
PrintableString : 19,
|
||||
T61String : 20,
|
||||
IA5String : 22,
|
||||
UTCTime : 23,
|
||||
GeneralizedTime : 24,
|
||||
UniversalString : 28,
|
||||
BMPString : 30
|
||||
};
|
||||
|
||||
/**
|
||||
* Boolean type
|
||||
* @param value {boolean} inner value
|
||||
*/
|
||||
function Boolean(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Boolean));
|
||||
this.value = value || false;
|
||||
}
|
||||
|
||||
inherits(Boolean, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
Boolean.prototype.decode = function(s, decoder) {
|
||||
this.value = new type.UInt8().read(new type.Stream(decoder.decode(s, this.tag).value)).value !== 0;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {type.*}
|
||||
*/
|
||||
Boolean.prototype.encode = function(encoder) {
|
||||
if(this.value) {
|
||||
return encoder.encode(this.tag, new type.UInt8(0xff));
|
||||
}
|
||||
else {
|
||||
return encoder.encode(this.tag, new type.UInt8(0));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Integer type
|
||||
* @param value {integer | Buffer}
|
||||
*/
|
||||
function Integer(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Integer));
|
||||
this.value = value || 0;
|
||||
}
|
||||
|
||||
inherits(Integer, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {Integer}
|
||||
*/
|
||||
Integer.prototype.decode = function(s, decoder) {
|
||||
var integerBuffer = decoder.decode(s, this.tag).value;
|
||||
if(integerBuffer.length < 5) {
|
||||
var integerStream = new type.Stream(integerBuffer);
|
||||
while (integerStream.availableLength() > 0) {
|
||||
this.value = this.value << 8;
|
||||
this.value |= new type.UInt8().read(integerStream).value;
|
||||
}
|
||||
}
|
||||
// bignum case
|
||||
else {
|
||||
this.value = integerBuffer;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param encoder {ber.decoder}
|
||||
* @returns {type.*}
|
||||
*/
|
||||
Integer.prototype.encode = function(encoder) {
|
||||
if(this.value <= 0xff) {
|
||||
return encoder.encode(this.tag, new type.UInt8(this.value));
|
||||
}
|
||||
else if(this.value <= 0xffff) {
|
||||
return encoder.encode(this.tag, new type.UInt16Be(this.value));
|
||||
}
|
||||
else {
|
||||
return encoder.encode(this.tag, new type.UInt32Be(this.value));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sequence type
|
||||
* @param value {object}
|
||||
*/
|
||||
function Sequence(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Constructed, UniversalTag.Sequence));
|
||||
this.value = value || [];
|
||||
}
|
||||
|
||||
inherits(Sequence, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {Sequence}
|
||||
*/
|
||||
Sequence.prototype.decode = function(s, decoder) {
|
||||
var sequenceStream = new type.Stream(decoder.decode(s, this.tag).value);
|
||||
for (var i in this.value) {
|
||||
var rec = sequenceStream.offset;
|
||||
try {
|
||||
this.value[i].decode(sequenceStream, decoder);
|
||||
} catch(e) {
|
||||
if ((e.message === 'NODE_RDP_ASN1_BER_INVALID_TAG') && !this.value[i].opt) {
|
||||
throw new error.ProtocolError('NODE_RDP_ASN1_UNIV_SEQUENCE_FIELD_NOT_PRESENT');
|
||||
}
|
||||
sequenceStream.offset = rec;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode sequence
|
||||
* @param encoder
|
||||
* @returns {type.Component}
|
||||
*/
|
||||
Sequence.prototype.encode = function(encoder) {
|
||||
var sequence = new type.Component([]);
|
||||
for (var i in this.value) {
|
||||
sequence.obj.push(this.value[i].encode(encoder))
|
||||
}
|
||||
return encoder.encode(this.tag, sequence);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enumerate type
|
||||
* @param value {integer}
|
||||
*/
|
||||
function Enumerate(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Enumerate));
|
||||
this.value = value || 0;
|
||||
}
|
||||
|
||||
inherits(Enumerate, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {Enumerate}
|
||||
*/
|
||||
Enumerate.prototype.decode = function(s, decoder) {
|
||||
this.value = new type.UInt8().read(new type.Stream(decoder.decode(s, this.tag).value)).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode enumerate type
|
||||
* @param encoder
|
||||
* @returns {type.Component}
|
||||
*/
|
||||
Enumerate.prototype.encode = function(encoder) {
|
||||
return encoder.encode(this.tag, new type.UInt8(this.value));
|
||||
};
|
||||
|
||||
/**
|
||||
* OctetString type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function OctetString(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.OctetString));
|
||||
this.value = value || Buffer.alloc(0);
|
||||
}
|
||||
|
||||
inherits(OctetString, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {OctetString}
|
||||
*/
|
||||
OctetString.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode Octet String
|
||||
* @param encoder
|
||||
* @returns {type.Component}
|
||||
*/
|
||||
OctetString.prototype.encode = function(encoder) {
|
||||
return encoder.encode(this.tag, new type.BinaryString(this.value));
|
||||
};
|
||||
|
||||
/**
|
||||
* ObjectIdentifier type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function ObjectIdentifier(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.ObjectIdentifier));
|
||||
this.value = value || Buffer.alloc(5);
|
||||
}
|
||||
|
||||
inherits(ObjectIdentifier, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {ObjectIdentifier}
|
||||
*/
|
||||
ObjectIdentifier.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Null type
|
||||
*/
|
||||
function Null() {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.Null));
|
||||
}
|
||||
|
||||
inherits(Null, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {Null}
|
||||
*/
|
||||
Null.prototype.decode = function(s, decoder) {
|
||||
decoder.decode(s, this.tag);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Choice type
|
||||
* @param value {object} list of available type
|
||||
*/
|
||||
function Choice(value) {
|
||||
// not tagged type
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag());
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(Choice, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {Choice}
|
||||
*/
|
||||
Choice.prototype.decode = function(s, decoder) {
|
||||
for (var i in this.value) {
|
||||
var rec = s.offset;
|
||||
try {
|
||||
this.value[i].decode(s, decoder);
|
||||
break;
|
||||
}
|
||||
catch(e) {
|
||||
s.offset = rec;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* SetOf type
|
||||
* @param factory {function} type builder
|
||||
* @param value {object} list of available type
|
||||
*/
|
||||
function SetOf(factory, value) {
|
||||
// not tagged type
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Constructed, UniversalTag.Set));
|
||||
this.factory = factory;
|
||||
this.value = value || [];
|
||||
}
|
||||
|
||||
inherits(SetOf, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {SetOf}
|
||||
*/
|
||||
SetOf.prototype.decode = function(s, decoder) {
|
||||
var setOfStream = new type.Stream(decoder.decode(s, this.tag).value);
|
||||
while (setOfStream.availableLength() > 0) {
|
||||
this.value.push(this.factory().decode(setOfStream, decoder));
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* SequenceOf type
|
||||
* @param factory {function} type builder
|
||||
* @param value {object} list of available type
|
||||
*/
|
||||
function SequenceOf(factory, value) {
|
||||
// not tagged type
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Constructed, UniversalTag.Sequence));
|
||||
this.factory = factory;
|
||||
this.value = value || [];
|
||||
}
|
||||
|
||||
inherits(SequenceOf, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {SequenceOf}
|
||||
*/
|
||||
SequenceOf.prototype.decode = function(s, decoder) {
|
||||
var sequenceOfStream = new type.Stream(decoder.decode(s, this.tag).value);
|
||||
while (sequenceOfStream.availableLength() > 0) {
|
||||
this.value.push(this.factory().decode(sequenceOfStream, decoder));
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* BitString type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function BitString(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.BitString));
|
||||
this.value = [];
|
||||
}
|
||||
|
||||
inherits(BitString, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {BitString}
|
||||
*/
|
||||
BitString.prototype.decode = function(s, decoder) {
|
||||
var bitStream = new type.Stream(decoder.decode(s, this.tag).value);
|
||||
var padding = new type.UInt8().read(bitStream).value;
|
||||
var value = [];
|
||||
for(var i = 0; i < padding; i++) {
|
||||
value.push(0);
|
||||
}
|
||||
|
||||
while(bitStream.availableLength() > 0) {
|
||||
var octet = new type.UInt8().read(bitStream).value;
|
||||
var currentPadding = 0;
|
||||
if(bitStream.availableLength() === 0) {
|
||||
currentPadding = padding;
|
||||
}
|
||||
for(var i = 7; i >= currentPadding; i--) {
|
||||
value.push(((octet >> i) & 1)?1:0);
|
||||
}
|
||||
}
|
||||
this.value = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert bit string to buffer object
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
BitString.prototype.toBuffer = function () {
|
||||
var length = this.value.length / 8;
|
||||
var resultStream = new type.Stream(length);
|
||||
for (var i = 0; i < length; i ++) {
|
||||
var currentOctet = 0;
|
||||
for (var j = 0; j < 8; j++) {
|
||||
currentOctet = currentOctet | (this.value[i * 8 + j] << (7 - j));
|
||||
}
|
||||
new type.UInt8(currentOctet).write(resultStream);
|
||||
}
|
||||
return resultStream.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* T61String type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function T61String(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.T61String));
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(T61String, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {T61String}
|
||||
*/
|
||||
T61String.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* PrintableString type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function PrintableString(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.PrintableString));
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(PrintableString, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {PrintableString}
|
||||
*/
|
||||
PrintableString.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* UniversalString type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function UniversalString(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UniversalString));
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(UniversalString, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {UniversalString}
|
||||
*/
|
||||
UniversalString.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* UTF8String type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function UTF8String(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UTF8String));
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(UTF8String, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {UTF8String}
|
||||
*/
|
||||
UTF8String.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* BMPString type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function BMPString(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.BMPString));
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(BMPString, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {BMPString}
|
||||
*/
|
||||
BMPString.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* IA5String type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function IA5String(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.IA5String));
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(IA5String, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {IA5String}
|
||||
*/
|
||||
IA5String.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* UTCTime type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function UTCTime(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.UTCTime));
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(UTCTime, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {UTCTime}
|
||||
*/
|
||||
UTCTime.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* GeneralizedTime type
|
||||
* @param value {Buffer}
|
||||
*/
|
||||
function GeneralizedTime(value) {
|
||||
spec.Asn1Spec.call(this, new spec.Asn1Tag(spec.TagClass.Universal, spec.TagFormat.Primitive, UniversalTag.GeneralizedTime));
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
inherits(GeneralizedTime, spec.Asn1Spec);
|
||||
|
||||
/**
|
||||
* @param s {type.Stream}
|
||||
* @param decoder {ber.decoder}
|
||||
* @returns {GeneralizedTime}
|
||||
*/
|
||||
GeneralizedTime.prototype.decode = function(s, decoder) {
|
||||
this.value = decoder.decode(s, this.tag).value;
|
||||
return this;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
Boolean : Boolean,
|
||||
Integer : Integer,
|
||||
Sequence : Sequence,
|
||||
Enumerate : Enumerate,
|
||||
OctetString : OctetString,
|
||||
ObjectIdentifier : ObjectIdentifier,
|
||||
Null : Null,
|
||||
Choice : Choice,
|
||||
SequenceOf : SequenceOf,
|
||||
SetOf : SetOf,
|
||||
BitString : BitString,
|
||||
T61String : T61String,
|
||||
PrintableString : PrintableString,
|
||||
UniversalString : UniversalString,
|
||||
UTF8String : UTF8String,
|
||||
BMPString : BMPString,
|
||||
IA5String : IA5String,
|
||||
UTCTime : UTCTime,
|
||||
GeneralizedTime : GeneralizedTime
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue