univ.js 14 KB

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