kasdimos
5 years ago
2 changed files with 159 additions and 0 deletions
@ -0,0 +1,41 @@ |
|||
|
|||
const secureSend = require('./secureSendClient.js'); |
|||
|
|||
const options = { |
|||
hmacKey: 'supersecure', |
|||
hashByteLength: 32, |
|||
randDataLength: 100, |
|||
port: 777, |
|||
ip: '192.168.0.6', |
|||
|
|||
onConnect: () => { |
|||
console.log('Connected'); |
|||
} |
|||
} |
|||
|
|||
const cmds = { |
|||
getGateState:{ |
|||
cmd: 0, |
|||
responses: [0x00, 0x01, 0x02] /* 0: Closed 1: Open 2: Middle */ |
|||
}, |
|||
switchGate: { |
|||
cmd: 1, |
|||
responses: [0x00] /* 0: Cmd received */ |
|||
}, |
|||
switchLight: { |
|||
cmd: 2, |
|||
responses: [0x00, 0x01] /* 0: now closed 1: now Open */ |
|||
} |
|||
}; |
|||
|
|||
secureSend(options, cmds.switchGate) |
|||
.then(res => { |
|||
console.log('The response ->'); |
|||
console.log(res); |
|||
}) |
|||
.catch(err => { |
|||
console.log('Catched Error ->'); |
|||
console.log(err); |
|||
}); |
|||
|
|||
setTimeout(()=>{},6000); |
@ -0,0 +1,118 @@ |
|||
|
|||
const net = require('net'); |
|||
var crypto = require('crypto'); |
|||
|
|||
|
|||
function secureSend(options, cmdSend, cb){ |
|||
const promise = new Promise(function(resolve, reject){ |
|||
|
|||
let reqHash = crypto.createHmac('sha256', options.hmacKey); |
|||
reqHash.setEncoding('binary'); |
|||
|
|||
let resHash = Buffer.allocUnsafe(options.hashByteLength); |
|||
let gotBytes = Buffer.allocUnsafe(options.randDataLength); |
|||
let gotBytesNum = 0; |
|||
|
|||
let res = null; // The final analyzed response
|
|||
|
|||
var client = new net.Socket(); |
|||
client.connect(options.port, options.ip, ()=>{ |
|||
gotBytesNum = 0; |
|||
if(typeof options.onConnect === 'function') options.onConnect(); |
|||
client.write('X'); //necessary for the arduino ethernet library
|
|||
}); |
|||
|
|||
client.on('error', (err) => { |
|||
reject(err); |
|||
}); |
|||
|
|||
client.on('close', function() { |
|||
if(res === null) reject(new Error('Connection closed before the response was sent.')); |
|||
else resolve(res); |
|||
}); |
|||
|
|||
client.on('data', (data) => { |
|||
gotBytesNum += data.length; |
|||
|
|||
if(gotBytesNum <= options.randDataLength){ |
|||
reqHash.update(Buffer.from(data), 'binary'); |
|||
for(i=0; i<data.length; i++){ |
|||
gotBytes[gotBytesNum - data.length + i] = data[i]; |
|||
} |
|||
} |
|||
|
|||
if(gotBytesNum == options.randDataLength){ |
|||
|
|||
reqHash.update(Buffer.from([cmdSend.cmd]), 'binary'); |
|||
reqHash.end(); // very important! You cannot read from the stream until you have called end()
|
|||
|
|||
var sha256sum = reqHash.read(); |
|||
client.write(sha256sum, 'binary'); |
|||
//printHash(sha256sum);
|
|||
} |
|||
|
|||
if(gotBytesNum > options.randDataLength){ |
|||
if (gotBytesNum > (options.randDataLength + options.hashByteLength)) reject(new Error('Server returned more bytes than expeced')); |
|||
|
|||
for(i=0; i<data.length; i++) |
|||
resHash[gotBytesNum - options.randDataLength - data.length + i] = data[i]; |
|||
|
|||
if (gotBytesNum == (options.randDataLength + options.hashByteLength)){ |
|||
res = analyzeResponse(options.hmacKey, cmdSend, gotBytes, resHash); |
|||
client.destroy(); // kill client after server's response
|
|||
} |
|||
} |
|||
}); |
|||
|
|||
}); |
|||
|
|||
if (cb && typeof cb == 'function'){ |
|||
promise.then(cb.bind(null, null), cb); |
|||
} |
|||
return promise; |
|||
} |
|||
|
|||
|
|||
function analyzeResponse(hmacKey, cmdSend, gotBytes, resHash){ |
|||
for(i=0; i<cmdSend.responses.length; i++){ |
|||
let testHash = Buffer.from(getHash(gotBytes, hmacKey, [cmdSend.responses[i]]), 'binary'); |
|||
if (hashesAreTheSame(resHash, testHash)){ |
|||
return cmdSend.responses[i]; |
|||
} |
|||
} |
|||
return undefined; |
|||
} |
|||
|
|||
function getHash(data, key, additionalData){ |
|||
let checkHash = crypto.createHmac('sha256', key); |
|||
checkHash.setEncoding('binary'); |
|||
checkHash.update(data, 'binary'); |
|||
|
|||
checkHash.update(Buffer.from(additionalData)); |
|||
|
|||
checkHash.end(); |
|||
return checkHash.read(); |
|||
} |
|||
|
|||
function hashesAreTheSame(hash1, hash2){ |
|||
if (hash1.length != hash2.length) return false; |
|||
for (j=0; j<hash1.length; j++) if(hash1[j] != hash2[j]) return false; |
|||
return true; |
|||
} |
|||
|
|||
// function printHash(hash){
|
|||
// let str = '';
|
|||
// for (i=0; i<hash.length; i++)
|
|||
// str += hash.charCodeAt(i).toString(16);
|
|||
// console.log(str);
|
|||
// }
|
|||
|
|||
// function toHexString(byteArray) {
|
|||
// return Array.from(byteArray, function(byte) {
|
|||
// return ('0' + (byte & 0xFF).toString(16)).slice(-2);
|
|||
// }).join('');
|
|||
// }
|
|||
|
|||
|
|||
module.exports = secureSend; |
|||
|
Loading…
Reference in new issue