ber.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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 type = require('../core').type;
  20. var log = require('../core').log;
  21. var error = require('../core').error;
  22. /**
  23. * Parse tag(T) field of BER TLV
  24. * And check with expected tag
  25. * @param s {type.Stream}
  26. * @param tag {spec.tag}
  27. * @returns {Boolean} True for valid tag matching
  28. */
  29. function decodeTag(s, tag) {
  30. var nextTag = new type.UInt8().read(s).value;
  31. if (tag.tagNumber > 30) {
  32. nextTagNumber = new type.UInt8().read(s).value;
  33. }
  34. else {
  35. nextTagNumber = nextTag & 0x1F;
  36. }
  37. return ((nextTag & 0xE0) === (tag.tagClass | tag.tagFormat)) && (nextTagNumber === tag.tagNumber);
  38. };
  39. /**
  40. * Parse length(L) field of BER TLV
  41. * @param s {type.Stream}
  42. * @returns {integer}
  43. */
  44. function decodeLength(s) {
  45. var size = new type.UInt8().read(s).value;
  46. if(size & 0x80) {
  47. size &= ~0x80;
  48. if(size === 1) {
  49. size = new type.UInt8().read(s).value;
  50. }
  51. else if(size === 2) {
  52. size = new type.UInt16Be().read(s).value;
  53. }
  54. else{
  55. throw new error.ProtocolError('NODE_RDP_ASN1_BER_INVALID_LENGTH');
  56. }
  57. }
  58. return size;
  59. };
  60. /**
  61. * Decode tuple TLV (Tag Length Value) of BER
  62. * @param s {type.Stream}
  63. * @param tag {spec.Asn1Tag} expected tag
  64. * @returns {type.BinaryString} Value of tuple
  65. */
  66. function decode(s, tag) {
  67. if (!decodeTag(s, tag)) {
  68. throw new error.ProtocolError('NODE_RDP_ASN1_BER_INVALID_TAG');
  69. }
  70. var length = decodeLength(s);
  71. if (length === 0) {
  72. return new type.Stream(0);
  73. }
  74. return new type.BinaryString(null,{ readLength : new type.CallableValue(length) }).read(s);
  75. };
  76. function encodeTag(tag) {
  77. if(tag.tagNumber > 30) {
  78. return new type.Component([new type.UInt8(tag.tagClass | tag.tagFormat | 0x1F), new type.UInt8(tag.tagNumber)]);
  79. }
  80. else {
  81. return new type.UInt8((tag.tagClass | tag.tagFormat) | (tag.tagNumber & 0x1F));
  82. }
  83. }
  84. function encodeLength(length) {
  85. if(length > 0x7f) {
  86. return new type.Component([new type.UInt8(0x82), new type.UInt16Be(length)]);
  87. }
  88. else {
  89. return new type.UInt8(length);
  90. }
  91. }
  92. function encode(tag, buffer) {
  93. return new type.Component([encodeTag(tag), encodeLength(buffer.size()), buffer]);
  94. }
  95. /**
  96. * Module Export
  97. */
  98. module.exports = {
  99. decode : decode,
  100. encode : encode
  101. };