72 lines
2.1 KiB
Lua
72 lines
2.1 KiB
Lua
|
local ecc = require("ecc")
|
||
|
|
||
|
string.toHex = function(str)
|
||
|
return str:gsub(".", function(ch) return string.format("%02x", ch:byte()) end)
|
||
|
end
|
||
|
string.fromHex = function(hex)
|
||
|
return hex:gsub("%x%x", function(d) return string.char(tonumber(d, 16)) end)
|
||
|
end
|
||
|
|
||
|
local keypair = {}
|
||
|
if fs.exists("/.id_dh.json") then
|
||
|
local fp = io.open("/.id_dh.json", "r")
|
||
|
local d = textutils.unserializeJSON(fp:read())
|
||
|
keypair.sk = string.fromHex(d.secret)
|
||
|
keypair.pk = string.fromHex(d.public)
|
||
|
fp:close()
|
||
|
else
|
||
|
printError("no identity found, generating...")
|
||
|
local sk, pk = ecc.keypair(ecc.random.random())
|
||
|
io.open("/.id_dh.json", "w"):write(textutils.serializeJSON({
|
||
|
secret = string.toHex(sk),
|
||
|
public = string.toHex(pk)
|
||
|
})):close()
|
||
|
keypair.sk = string.char(table.unpack(sk))
|
||
|
keypair.pk = string.char(table.unpack(pk))
|
||
|
end
|
||
|
|
||
|
print("pubkey: "..string.toHex(keypair.pk))
|
||
|
|
||
|
local running = true
|
||
|
|
||
|
local known_hosts = {}
|
||
|
|
||
|
parallel.waitForAll(function() while running do -- dh:discover sender
|
||
|
rednet.broadcast(keypair.pk, "dh:discover")
|
||
|
os.sleep(10)
|
||
|
end end,
|
||
|
function() while running do -- dh:discover handler
|
||
|
local id, pk, proto = rednet.receive("dh:discover")
|
||
|
if proto == "dh:discover" then
|
||
|
print("DH discover from "..id.." with key "..pk)
|
||
|
local nonce = string.toHex(ecc.random.random())
|
||
|
local key = ecc.exchange(keypair.sk, pk)
|
||
|
known_hosts[id] = {
|
||
|
id = id,
|
||
|
pk = pk,
|
||
|
sk = key,
|
||
|
verified = false,
|
||
|
nonce = nonce,
|
||
|
t = os.clock()
|
||
|
}
|
||
|
known_hosts[pk] = known_hosts[id]
|
||
|
rednet.send(id, {
|
||
|
pk = keypair.pk,
|
||
|
msg = ecc.encrypt(nonce, key)
|
||
|
}, "dh:pair")
|
||
|
end
|
||
|
end end,
|
||
|
function() while running do -- dh:pair handler
|
||
|
local id, msg, proto = rednet.receive("dh:pair")
|
||
|
if proto == "dh:pair" then
|
||
|
local key = ecc.exchange(keypair.sk, msg.pk)
|
||
|
known_hosts[id] = {
|
||
|
id = id,
|
||
|
pk = msg.pk,
|
||
|
sk = key,
|
||
|
verified = false,
|
||
|
nonce = ecc.decrypt(msg.msg, msg.msg)
|
||
|
}
|
||
|
end
|
||
|
end end)
|