UNPKG

@iotize/device-client.js

Version:

IoTize Device client for Javascript

156 lines (155 loc) 7.31 kB
"use strict"; var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); var crypto_helper_1 = require("../config/crypto-helper"); var crypto_js_1 = require("crypto-js"); var format_helper_1 = require("../../core/format/format-helper"); var model_1 = require("../model"); var tap_stream_1 = require("../../client/impl/frame/tap-stream"); var aes_ecb_128_converter_1 = require("../../core/crypto/aes-ecb-128-converter"); var logger_1 = require("../../logger"); var logger = logger_1.default('SinglePacket'); tap_stream_1.TapStreamReader.prototype.readSinglePacketPayloadFullData = function () { var model = {}; model.logTime = this.readU4(); model.dataSize = this.readU2(); model.data = this.readBytes(-4); model.crc = this.readU4(); return model; }; var DefaultSinglePacketKeyGenerator = /** @class */ (function () { function DefaultSinglePacketKeyGenerator() { } /** * HMsg = UserName | IoTizeSN | PacketHeader1 */ DefaultSinglePacketKeyGenerator.prototype.generate = function (options) { var stream = new tap_stream_1.TapStreamWriter(); if (options.username.length > 16) { throw new Error("Invalid username too long: " + options.username); } stream.writeStr(options.username); if (options.serialNumber.length != 18) { // TODO constant throw new Error("Invalid sn: " + options.serialNumber + ". Length must be 18"); } stream.writeStr(options.serialNumber, 18); if (options.headerBytes.length != 12) { throw new Error("Invalid header length " + options.headerBytes.length + ". Expected 12"); } stream.writeBytes(options.headerBytes); var data = stream.toBytes; var wordArray = crypto_helper_1.CryptoHelper.sanitizeInput(data); var keyArray = crypto_helper_1.CryptoHelper.sanitizeInput(options.hashKey); var result = crypto_js_1.HmacSHA256(wordArray, keyArray); var key = crypto_helper_1.CryptoHelper.wordArrayToByteArray(result).slice(0, 16); return key; }; return DefaultSinglePacketKeyGenerator; }()); exports.DefaultSinglePacketKeyGenerator = DefaultSinglePacketKeyGenerator; var EncryptedSinglePacketConverter = /** @class */ (function () { function EncryptedSinglePacketConverter(options, encryptionAlgo, keyGenerator) { if (encryptionAlgo === void 0) { encryptionAlgo = new aes_ecb_128_converter_1.AesEcb128Converter(); } if (keyGenerator === void 0) { keyGenerator = new DefaultSinglePacketKeyGenerator(); } this.options = options; this.encryptionAlgo = encryptionAlgo; this.keyGenerator = keyGenerator; } // encode(packet: SinglePacketModel): Uint8Array { // let stream = new TapStreamWriter(packet.outerHeader.packetLength + 4); // let payload: Uint8Array = new TapStreamWriter().writeSinglePacketPayload(packet.payload).toBytes; // if (packet.outerHeader.encryption) { // let encryptionAlgo = this._getEncryptionAlgo(packet.outerHeader); // payload = encryptionAlgo.encode(payload); // } // stream.writeU4(packet.sendTime); // if (packet.outerHeader.encryption) { // packet.outerHeader.packetLength /= 16 // } // stream.writeSinglePacketOuterHeader(packet.outerHeader); // stream.writeBytes(payload); // return stream.toBytes; // } EncryptedSinglePacketConverter.prototype.encode = function (packet) { var stream = new tap_stream_1.TapStreamWriter(); stream.writeU4(packet.sendTime); stream.writeSinglePacketOuterHeader(packet.outerHeader); var payloadBytesPosition = stream.pos; stream.writeSinglePacketPayload(packet.payload); // let payloadBytes: Uint8Array = // new TapStreamWriter().writeSinglePacketPayload(packet.payload).toBytes; if (packet.outerHeader.encryption) { var encryptionAlgo = this._getEncryptionAlgo(packet.outerHeader); var encryptedPayloadBytes = stream.toBytes.slice(payloadBytesPosition); encryptedPayloadBytes = encryptionAlgo.encode(encryptedPayloadBytes); stream.pos = payloadBytesPosition; stream.writeBytes(encryptedPayloadBytes); } // if (packet.outerHeader.encryption) { // // If encryption packet length unit is 16bytes // packet.outerHeader.packetLength = Math.floor((packet.payload.data.length + 6 + 4) / 16) // } return stream.toBytes; }; EncryptedSinglePacketConverter.prototype.decode = function (packetData) { var stream = tap_stream_1.TapStreamReader.fromArray(packetData); var sendTime = stream.readU4(); var header = stream.readSinglePacketOuterHeader(); var payload; if (header.encryption) { var encryptedData = stream.readBytesFull(); var encryptionAlgo = this._getEncryptionAlgo(header); var decryptedData = encryptionAlgo.decode(encryptedData); var payloadStream = tap_stream_1.TapStreamReader.fromArray(decryptedData); if (header.messageType == model_1.SinglePacket.PacketType.CODE_EXEC) { payload = payloadStream.readSinglePacketPayloadFullData(); } else { payload = payloadStream.readSinglePacketPayload(); } } else { payload = stream.readSinglePacketPayload(); } var packet = { sendTime: sendTime, outerHeader: header, payload: payload }; // if (packet.outerHeader.messageType == SinglePacketModel.PacketType.CODE_EXEC) { // packet.outerHeader.packetLength *= 16; // } // TODO check CRC // if (packet.payload.crc){ // CRC.fromBytes() // } return packet; }; EncryptedSinglePacketConverter.prototype._getEncryptionAlgo = function (header) { var encryptionKey = this.computeKey(header); this.encryptionAlgo.setOptions({ iv: "00000000000000000000000000000000", key: format_helper_1.FormatHelper.toHexString(encryptionKey) }); return this.encryptionAlgo; }; EncryptedSinglePacketConverter.prototype.computeKey = function (header) { if (!(header instanceof Uint8Array)) { var stream = new tap_stream_1.TapStreamWriter(12); header = stream.writeSinglePacketOuterHeader(header).toBytes; } var generateOptions = __assign({}, this.options, { headerBytes: header }); var key = this.keyGenerator.generate(generateOptions); return key; }; return EncryptedSinglePacketConverter; }()); exports.EncryptedSinglePacketConverter = EncryptedSinglePacketConverter;