@iotize/device-client.js
Version:
IoTize Device client for Javascript
156 lines (155 loc) • 7.31 kB
JavaScript
;
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;