mirror of
				https://github.com/kepler155c/opus
				synced 2025-10-30 23:23:03 +00:00 
			
		
		
		
	security - final round?
This commit is contained in:
		| @@ -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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 kepler155c@gmail.com
					kepler155c@gmail.com