mirror of
https://github.com/kepler155c/opus
synced 2024-12-31 19:00:27 +00:00
security - final round?
This commit is contained in:
parent
e75a357209
commit
1c29197983
@ -6,7 +6,6 @@
|
||||
]]--
|
||||
|
||||
local Event = require('opus.event')
|
||||
local SHA = require('opus.crypto.sha2')
|
||||
|
||||
local network = _G.network
|
||||
local os = _G.os
|
||||
@ -39,7 +38,7 @@ end
|
||||
|
||||
function transport.write(socket, data)
|
||||
socket.transmit(socket.dport, socket.dhost, data)
|
||||
socket.wseq = SHA.digest(socket.wseq):toHex()
|
||||
socket.wseq = socket.wrng:nextInt(5)
|
||||
end
|
||||
|
||||
function transport.ping(socket)
|
||||
@ -113,7 +112,8 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance)
|
||||
_syslog('got ' .. msg.seq)
|
||||
else
|
||||
socket.activityTimer = os.clock()
|
||||
socket.rseq = SHA.digest(socket.rseq):toHex()
|
||||
socket.rseq = socket.rrng:nextInt(5)
|
||||
|
||||
table.insert(socket.messages, { msg.data, distance })
|
||||
|
||||
if not socket.messages[2] then -- table size is 1
|
||||
|
@ -10,12 +10,13 @@ local bxor = bit32.bxor
|
||||
local band = bit32.band
|
||||
local blshift = bit32.lshift
|
||||
local brshift = bit32.arshift
|
||||
local os = _G.os
|
||||
local textutils = _G.textutils
|
||||
|
||||
local mod = 2^32
|
||||
local tau = {("expand 16-byte k"):byte(1,-1)}
|
||||
local sigma = {("expand 32-byte k"):byte(1,-1)}
|
||||
local null32 = {("A"):rep(32):byte(1,-1)}
|
||||
local null12 = {("A"):rep(12):byte(1,-1)}
|
||||
|
||||
local function rotl(n, b)
|
||||
local s = n/(2^(32-b))
|
||||
@ -164,7 +165,35 @@ local function decrypt(data, key)
|
||||
return textutils.unserialise(tostring(ptx))
|
||||
end
|
||||
|
||||
local obj = {}
|
||||
local mt = {['__index'] = obj}
|
||||
|
||||
function obj:nextInt(byte)
|
||||
if byte < 1 or byte > 6 then error("Can only return 1-6 bytes", 2) end
|
||||
local output = 0
|
||||
for i = 0, byte-1 do
|
||||
if #self.block == 0 then
|
||||
self.cnt = self.cnt + 1
|
||||
self.block = crypt(null32, self.seed, null12, self.cnt)
|
||||
end
|
||||
|
||||
local newByte = table.remove(self.block)
|
||||
output = output + (newByte * (2^(8*i)))
|
||||
end
|
||||
return output
|
||||
end
|
||||
|
||||
local function newRNG(seed)
|
||||
local o = {}
|
||||
o.seed = seed
|
||||
o.cnt = 0
|
||||
o.block = {}
|
||||
|
||||
return setmetatable(o, mt)
|
||||
end
|
||||
|
||||
return {
|
||||
encrypt = encrypt,
|
||||
decrypt = decrypt,
|
||||
newRNG = newRNG,
|
||||
}
|
||||
|
@ -64,13 +64,16 @@ function socketClass:ping()
|
||||
end
|
||||
|
||||
function socketClass:setupEncryption(x)
|
||||
local timer = Util.timer()
|
||||
self.rrng = Crypto.newRNG(
|
||||
SHA.pbkdf2(self.sharedKey, x and "3rseed" or "4sseed", 1))
|
||||
self.wrng = Crypto.newRNG(
|
||||
SHA.pbkdf2(self.sharedKey, x and "4sseed" or "3rseed", 1))
|
||||
|
||||
self.sharedKey = ECC.exchange(self.privKey, self.remotePubKey)
|
||||
self.enckey = SHA.pbkdf2(self.sharedKey, "1enc", 1)
|
||||
self.hmackey = SHA.pbkdf2(self.sharedKey, "2hmac", 1)
|
||||
self.rseq = SHA.pbkdf2(self.sharedKey, x and "3rseed" or "4sseed", 1):toHex()
|
||||
self.wseq = SHA.pbkdf2(self.sharedKey, x and "4sseed" or "3rseed", 1):toHex()
|
||||
_syslog('shared in ' .. timer())
|
||||
--self.enckey = SHA.pbkdf2(self.sharedKey, "1enc", 1)
|
||||
--self.hmackey = SHA.pbkdf2(self.sharedKey, "2hmac", 1)
|
||||
self.rseq = self.rrng:nextInt(5)
|
||||
self.wseq = self.wrng:nextInt(5)
|
||||
end
|
||||
|
||||
function socketClass:close()
|
||||
@ -99,8 +102,6 @@ local function newSocket(isLoopback)
|
||||
shost = os.getComputerID(),
|
||||
sport = i,
|
||||
transmit = device.wireless_modem.transmit,
|
||||
wseq = math.random(100, 100000),
|
||||
rseq = math.random(100, 100000),
|
||||
timers = { },
|
||||
messages = { },
|
||||
}
|
||||
@ -121,7 +122,7 @@ function Socket.connect(host, port, options)
|
||||
if not device.wireless_modem then
|
||||
return false, 'Wireless modem not found', 'NOMODEM'
|
||||
end
|
||||
local timer = Util.timer()
|
||||
|
||||
local socket = newSocket(host == os.getComputerID())
|
||||
socket.dhost = tonumber(host)
|
||||
socket.privKey, socket.pubKey = network.getKeyPair()
|
||||
@ -143,7 +144,8 @@ local timer = Util.timer()
|
||||
if e == 'modem_message' and
|
||||
sport == socket.sport and
|
||||
type(msg) == 'table' and
|
||||
msg.dhost == socket.shost then
|
||||
msg.dhost == socket.shost and
|
||||
type(msg.pk) == 'string' then
|
||||
|
||||
os.cancelTimer(timerId)
|
||||
|
||||
@ -152,10 +154,7 @@ local timer = Util.timer()
|
||||
socket.connected = true
|
||||
socket.remotePubKey = Util.hexToByteArray(msg.pk)
|
||||
socket:setupEncryption(true)
|
||||
-- Logger.log('socket', 'connection established to %d %d->%d',
|
||||
-- host, socket.sport, socket.dport)
|
||||
network.getTransport().open(socket)
|
||||
_syslog('connection in ' .. timer())
|
||||
return socket
|
||||
|
||||
elseif msg.type == 'NOPASS' then
|
||||
@ -181,24 +180,23 @@ local function trusted(socket, msg, options)
|
||||
|
||||
local identifier = options and options.identifier or getIdentifier()
|
||||
|
||||
if identifier and msg.t and type(msg.t) == 'table' then
|
||||
if identifier and type(msg.t) == 'table' then
|
||||
local data = Crypto.decrypt(msg.t, Util.hexToByteArray(identifier))
|
||||
|
||||
if data and data.ts and tonumber(data.ts) then
|
||||
_G._syslog('time diff ' .. math.abs(os.epoch('utc') - data.ts))
|
||||
if math.abs(os.epoch('utc') - data.ts) < 4096 then
|
||||
socket.remotePubKey = Util.hexToByteArray(data.pk)
|
||||
socket.privKey, socket.pubKey = network.getKeyPair()
|
||||
socket:setupEncryption()
|
||||
return true
|
||||
end
|
||||
_G._syslog('time diff ' .. math.abs(os.epoch('utc') - data.ts))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Socket.server(port, options)
|
||||
device.wireless_modem.open(port)
|
||||
-- Logger.log('socket', 'Waiting for connections on port ' .. port)
|
||||
|
||||
while true do
|
||||
local _, _, sport, dport, msg = os.pullEvent('modem_message')
|
||||
@ -212,8 +210,6 @@ function Socket.server(port, options)
|
||||
local socket = newSocket(msg.shost == os.getComputerID())
|
||||
socket.dport = dport
|
||||
socket.dhost = msg.shost
|
||||
socket.wseq = msg.wseq
|
||||
socket.rseq = msg.rseq
|
||||
socket.options = options
|
||||
|
||||
if not Security.hasPassword() then
|
||||
@ -233,8 +229,6 @@ function Socket.server(port, options)
|
||||
pk = Util.byteArrayToHex(socket.pubKey),
|
||||
})
|
||||
|
||||
-- Logger.log('socket', 'Connection established %d->%d', socket.sport, socket.dport)
|
||||
|
||||
network.getTransport().open(socket)
|
||||
return socket
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user