Advertisement
ds84182

FastSRT

Feb 2nd, 2014
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 25.84 KB | None | 0 0
  1. -- Rednet Tunneling
  2. -- By KillaVanilla
  3.  
  4. local function downloadAPI(code, name)
  5.     local webHandle = http.get("http://pastebin.com/raw.php?i="..code)
  6.     if webHandle then
  7.         local apiData = webHandle.readAll()
  8.         webHandle.close()
  9.         local apiHandle = fs.open(name, "w")
  10.         apiHandle.write(apiData)
  11.         apiHandle.close()
  12.         return true
  13.     else
  14.         print("Could not retrieve API: "..name.."!")
  15.         print("Ensure that the HTTP API is enabled.")
  16.         return false
  17.     end
  18. end
  19.  
  20. if (not AES) and (not fs.exists("AES")) then
  21.     downloadAPI("rCYDnCxn", "AES")
  22. end
  23.  
  24. if (not base64) and (not fs.exists("base64")) then
  25.     downloadAPI("pp3kpb19", "base64")
  26. end
  27.  
  28. if (not random) and (not fs.exists("random")) then
  29.     downloadAPI("D1th4Htw", "random")
  30. end
  31.  
  32. if not AES then
  33.     os.loadAPI("AES")
  34. end
  35.  
  36. if not base64 then
  37.     os.loadAPI("base64")
  38. end
  39.  
  40. if not random then
  41.     os.loadAPI("random")
  42. end
  43.  
  44.  
  45. local connFreq = 15 -- The key exchange is done on this frequency.
  46. local tunnelFreq = 20 -- Encrypted data is sent on this frequency.
  47. local connections = {} -- Temporary keys, for open connections.
  48. handlerRunning = false -- Make sure that we don't have two handler coroutines running at the same time
  49. local eventTimeout = 50
  50.  
  51. function mod_exp(base, exp, mod)
  52.     local result = 1
  53.     local runs = 1
  54.     while exp > 0 do
  55.         if (exp % 2) == 1 then
  56.             result = (result*base) % mod
  57.         end
  58.         exp = math.floor(exp/2)
  59.         base = (base*base) % mod
  60.         runs = runs+1
  61.         if runs%eventTimeout == 0 then
  62.             os.queueEvent("theres_a_hole_in_the_sky")
  63.             os.pullEvent()
  64.         end
  65.     end
  66.     --term.setCursorPos(x,y+1)
  67.     return result
  68. end
  69.  
  70. function fermat(n, k)
  71.     for i=1, k do
  72.         local a = random.random(1, n-1)
  73.         local e = mod_exp(a, n-1, n)
  74.         if e ~= 1 then
  75.             --print("a: "..a.." e: "..e)
  76.             return false
  77.         end
  78.         if i%eventTimeout == 0 then
  79.             os.queueEvent("theres_a_hole_in_the_sky")
  80.             os.pullEvent()
  81.         end
  82.     end
  83.     return true
  84. end
  85.  
  86. function miller_rabin(n, k)
  87.     local s, d = 0, 0
  88.     assert(n >= 2)
  89.     if n == 2 then
  90.         return true
  91.     end
  92.     if n%2 == 0 then
  93.         return false
  94.     end
  95.     -- Write n-1 as (2^s)*d, by repeatedly dividing n-1 by two:
  96.     d = n-1
  97.     while true do
  98.         local quot = math.floor(d / 2)
  99.         local rem = d % 2
  100.         if rem == 1 then
  101.             break
  102.         end
  103.         s = s+1
  104.         d = quot
  105.         if s%eventTimeout == 0 then
  106.             os.queueEvent("theres_a_hole_in_the_sky")
  107.             os.pullEvent()
  108.         end
  109.     end
  110.    
  111.     -- WitnessLoop:
  112.     local runs = 1
  113.     for i=1, k do
  114.         a = random.random(2, n-2)
  115.         local x = mod_exp(a, d, n)
  116.         if not (x == 1 or x == n-1) then -- If x == 1 or x == n-1 then continue
  117.             local continuing = false
  118.             for j=1, s-1 do
  119.                 x = (x*x) % n
  120.                 if x == 1 then -- if x == 1 then return COMPOSITE (false)
  121.                     return false
  122.                 end
  123.                 if x == n-1 then -- If x == n-1 then do next WitnessLoop...
  124.                     continuing = true
  125.                     break
  126.                 end
  127.                 if j%eventTimeout == 0 then
  128.                     os.queueEvent("theres_a_hole_in_the_sky")
  129.                     os.pullEvent()
  130.                 end
  131.             end
  132.             if not continuing then
  133.                 return false
  134.             end
  135.         end
  136.         runs = runs+1
  137.         if runs%eventTimeout == 0 then
  138.             os.queueEvent("theres_a_hole_in_the_sky")
  139.             os.pullEvent()
  140.         end
  141.     end
  142.     return true
  143. end
  144.  
  145. function generatePrime(k, debug) -- Generate somewhat-large primes (nowhere near big enough, but using BigInt will just slow things down too much)
  146.     random.generate_isaac()
  147.     local tries = 0
  148.     local x,y = term.getCursorPos()
  149.     while true do
  150.         local current = random.random(10000000, 90000000)
  151.         tries = tries+1
  152.         if debug then
  153.             term.setCursorPos(x,y)
  154.             term.clearLine()
  155.         end
  156.         if current % 2 == 0 then
  157.             current = current+1
  158.         end
  159.         if debug then
  160.             write("Attempt: "..tries..": "..current)
  161.         end
  162.         if fermat(current, k) then
  163.             if debug then
  164.                 term.setCursorPos(x,y+3)
  165.                 term.clearLine()
  166.                 write("Last Fermat Success: "..tries..": "..current)
  167.             end
  168.             if miller_rabin(current, k) then
  169.                 if debug then
  170.                     term.setCursorPos(1,y+4)
  171.                 end
  172.                 return current
  173.             else
  174.                 if debug then
  175.                     term.setCursorPos(x,y+2)
  176.                     term.clearLine()
  177.                     write("Last Miller-Rabin Failure: "..tries..": "..current)
  178.                 end
  179.             end
  180.         else
  181.             if debug then
  182.                 term.setCursorPos(x,y+1)
  183.                 term.clearLine()
  184.                 write("Last Fermat Failure: "..tries..": "..current)
  185.             end
  186.         end
  187.         if tries%eventTimeout == 0 then
  188.             os.queueEvent("theres_a_hole_in_the_sky")
  189.             os.pullEvent()
  190.         end
  191.     end
  192. end
  193.  
  194. local function listen(timeout)
  195.     local timer = {}
  196.     if timeout then
  197.         timer = os.startTimer(timeout)
  198.     end
  199.     while true do
  200.         local event = {os.pullEvent()}
  201.         if event[1] == "timer" then
  202.             if event[2] == timer then
  203.                 return
  204.             end
  205.         elseif event[1] == "modem_message" then
  206.             if textutils.unserialize(event[5]) then
  207.                 return event[3], event[4], textutils.unserialize(event[5])
  208.             end
  209.         end
  210.     end
  211. end
  212.  
  213. local function incrementBlock(blk, incAmt)
  214.     local cpy = {}
  215.     for i=1, 16 do
  216.         cpy[i] = blk[i] or 0
  217.     end
  218.     cpy[1] = cpy[1] + incAmt
  219.     for i=2, 16 do
  220.         if cpy[i-1] <= 255 then
  221.             break
  222.         end
  223.         local carry = cpy[i-1] - 255
  224.         cpy[i] = cpy[i]+carry
  225.     end
  226.     return cpy
  227. end
  228.  
  229. function getHandlerStatus()
  230.     return handlerRunning
  231. end
  232.  
  233. -- Connection Establishing:
  234. -- Client sends "Connect" message with a[1-4], base, and p, for Diffie-Hellman Key Exchange.
  235. -- Server calculates b[1-4] and s[1-4] and sends a "Connect_Key" message with b[1-4]. The server also encrypts a "test block" of all 0xFF's using s.
  236. -- Client calculates s[1-4], and encrypts a "test block" of all 0xFF's using s.
  237. -- Server sends the test block, which is checked by the client. If the blocks match, then the client sends a success message. All communications from here are encrypted using s.
  238. -- The server makes an entry in the connection table for the new connection, and sends the client the connection ID.
  239.  
  240. -- If any side of the connection is held up for more than 30 seconds, the connection is automatically torn down.
  241.  
  242. function connectionHandler(modem, debug)
  243.     if handlerRunning then
  244.         if debug then
  245.             print("connection_handler: another handler instance is already running!")
  246.         end
  247.         return false
  248.     end
  249.     handlerRunning = true
  250.     modem.open(connFreq)
  251.     modem.open(tunnelFreq)
  252.     while true do
  253.         local tFreq, rFreq, msg = listen()
  254.         if msg[1] == "Tunneling" then
  255.             local id = msg[2]
  256.             --print(msg[1].." : "..msg[3])
  257.             if msg[3] == "Connect" then
  258.                 if debug then
  259.                     print("connect_server: Incoming connection attempt by ID "..id.."...")
  260.                 end
  261.                
  262.                 local k1 = random.random()
  263.                 local k2 = random.random()
  264.                 local k3 = random.random()
  265.                 local k4 = random.random()
  266.                
  267.                 local iv_k1 = random.random()
  268.                 local iv_k2 = random.random()
  269.                 local iv_k3 = random.random()
  270.                 local iv_k4 = random.random()
  271.                
  272.                 local a1 = msg[4]
  273.                 local a2 = msg[5]
  274.                 local a3 = msg[6]
  275.                 local a4 = msg[7]
  276.                
  277.                 local iv_a1 = msg[8]
  278.                 local iv_a2 = msg[9]
  279.                 local iv_a3 = msg[10]
  280.                 local iv_a4 = msg[11]
  281.                
  282.                 local base = msg[12]
  283.                 local p = msg[13]
  284.                
  285.                 local b1 = mod_exp(base, k1, p)
  286.                 local b2 = mod_exp(base, k2, p)
  287.                 local b3 = mod_exp(base, k3, p)
  288.                 local b4 = mod_exp(base, k4, p)
  289.                
  290.                 local iv_b1 = mod_exp(base, iv_k1, p)
  291.                 local iv_b2 = mod_exp(base, iv_k2, p)
  292.                 local iv_b3 = mod_exp(base, iv_k3, p)
  293.                 local iv_b4 = mod_exp(base, iv_k4, p)
  294.                
  295.                 local s = {}
  296.                 local s1 = mod_exp(a1, k1, p)
  297.                 local s2 = mod_exp(a2, k2, p)
  298.                 local s3 = mod_exp(a3, k3, p)
  299.                 local s4 = mod_exp(a4, k4, p)
  300.                
  301.                 s[1] = bit.brshift(bit.band( s1, 0xFF000000 ), 24)
  302.                 s[2] = bit.brshift(bit.band( s1, 0x00FF0000 ), 16)
  303.                 s[3] = bit.brshift(bit.band( s1, 0x0000FF00 ), 8)
  304.                 s[4] = bit.band( s1, 0x000000FF )
  305.                
  306.                 s[5] = bit.brshift(bit.band( s2, 0xFF000000 ), 24)
  307.                 s[6] = bit.brshift(bit.band( s2, 0x00FF0000 ), 16)
  308.                 s[7] = bit.brshift(bit.band( s2, 0x0000FF00 ), 8)
  309.                 s[8] = bit.band( s2, 0x000000FF )
  310.                
  311.                 s[9] = bit.brshift(bit.band( s3, 0xFF000000 ), 24)
  312.                 s[10] = bit.brshift(bit.band( s3, 0x00FF0000 ), 16)
  313.                 s[11] = bit.brshift(bit.band( s3, 0x0000FF00 ), 8)
  314.                 s[12] = bit.band( s3, 0x000000FF )
  315.                
  316.                 s[13] = bit.brshift(bit.band( s4, 0xFF000000 ), 24)
  317.                 s[14] = bit.brshift(bit.band( s4, 0x00FF0000 ), 16)
  318.                 s[15] = bit.brshift(bit.band( s4, 0x0000FF00 ), 8)
  319.                 s[16] = bit.band( s4, 0x000000FF )
  320.                
  321.                 local iv = {}
  322.                 local iv1 = mod_exp(iv_a1, iv_k1, p)
  323.                 local iv2 = mod_exp(iv_a2, iv_k2, p)
  324.                 local iv3 = mod_exp(iv_a3, iv_k3, p)
  325.                 local iv4 = mod_exp(iv_a4, iv_k4, p)
  326.                
  327.                 iv[1] = bit.brshift(bit.band( iv1, 0xFF000000 ), 24)
  328.                 iv[2] = bit.brshift(bit.band( iv1, 0x00FF0000 ), 16)
  329.                 iv[3] = bit.brshift(bit.band( iv1, 0x0000FF00 ), 8)
  330.                 iv[4] = bit.band( iv1, 0x000000FF )
  331.                
  332.                 iv[5] = bit.brshift(bit.band( iv2, 0xFF000000 ), 24)
  333.                 iv[6] = bit.brshift(bit.band( iv2, 0x00FF0000 ), 16)
  334.                 iv[7] = bit.brshift(bit.band( iv2, 0x0000FF00 ), 8)
  335.                 iv[8] = bit.band( iv2, 0x000000FF )
  336.                
  337.                 iv[9] = bit.brshift(bit.band( iv3, 0xFF000000 ), 24)
  338.                 iv[10] = bit.brshift(bit.band( iv3, 0x00FF0000 ), 16)
  339.                 iv[11] = bit.brshift(bit.band( iv3, 0x0000FF00 ), 8)
  340.                 iv[12] = bit.band( iv3, 0x000000FF )
  341.                
  342.                 iv[13] = bit.brshift(bit.band( iv4, 0xFF000000 ), 24)
  343.                 iv[14] = bit.brshift(bit.band( iv4, 0x00FF0000 ), 16)
  344.                 iv[15] = bit.brshift(bit.band( iv4, 0x0000FF00 ), 8)
  345.                 iv[16] = bit.band( iv4, 0x000000FF )
  346.                
  347.                 if debug then
  348.                     print("connect_server: Numbers generated...")
  349.                 end
  350.                
  351.                 local test_block = {}
  352.                
  353.                 for i=1, 16 do
  354.                     test_block[i] = 0xFF
  355.                 end
  356.                
  357.                 test_block = AES.encrypt_bytestream(test_block, s, iv)
  358.                 if debug then
  359.                     print("connect_server: Sending our keys and the test block...")
  360.                 end
  361.                 modem.transmit( tFreq, rFreq, textutils.serialize({"Tunneling", os.computerID(), "Connect_Key", b1, b2, b3, b4, iv_b1, iv_b2, iv_b3, iv_b4, test_block}) )
  362.                 while true do
  363.                     local _, __, msg2 = listen(30)
  364.                     if msg2 == nil then
  365.                         break
  366.                     end
  367.                     if msg2[1] == "Tunneling" and msg2[2] == id and msg2[3] == "Connection_Established" then
  368.                         local newID = random.random()
  369.                         while true do
  370.                             if not connections[newID] then
  371.                                 break
  372.                             else
  373.                                 newID = random.random()
  374.                             end
  375.                         end
  376.                         if debug then
  377.                             print("connect_server: Connection established. Sending ID...")
  378.                         end
  379.                         local e_str = textutils.serialize({"Connection_ID", newID})
  380.                         local e = {}
  381.                         for i=1, #e_str do
  382.                             e[i] = string.byte(e_str, i, i)
  383.                         end
  384.                         e = AES.encrypt_bytestream(e, s, iv)
  385.                         e = base64.encode(e)
  386.                         modem.transmit( tFreq, rFreq, textutils.serialize({"Tunneling", os.computerID(), e}) )
  387.                         connections[ newID ] = {s, iv}
  388.                         os.queueEvent("secure_connection_open", id, newID)
  389.                         break
  390.                     end
  391.                 end
  392.             elseif msg[3] == "Data" then
  393.                 if debug then
  394.                     print("data_server: Incoming data on connection "..msg[5])
  395.                 end
  396.                 if connections[msg[5]] then
  397.                     local data_bytes = AES.decrypt_bytestream(base64.decode(msg[4]), connections[msg[5]][1], connections[msg[5]][2])
  398.                     local data_str = ""
  399.                     for i=1, #data_bytes do
  400.                         data_str = data_str..string.char(data_bytes[i])
  401.                     end
  402.                     if type(textutils.unserialize(data_str)) == "table" then
  403.                         local data_table = textutils.unserialize(data_str)
  404.                         local packetType = data_table[1]
  405.                         local senderID = data_table[2]
  406.                         connections[msg[5]][2] = data_table[3]
  407.                         local data1 = data_table[4]
  408.                         local data2 = data_table[5]
  409.                         local data3 = data_table[6]
  410.                         if debug then
  411.                             if packetType == "Message" then
  412.                                 print("data_server: Incoming data from "..senderID.." on connection "..msg[5].." : "..data1)
  413.                             elseif packetType == "fakeModemMsg" then
  414.                                 print("data_server: Incoming fake modem_message from "..senderID.." on connection "..msg[5]..": "..data1)
  415.                                 print("data_server: tFreq / rFreq: "..data2.."/"..data3)
  416.                             elseif packetType == "close" then
  417.                                 print("data_server: Closing connection: "..msg[5])
  418.                             elseif packetType == "newKey" then
  419.                                 print("data_server: New key sent by other party.")
  420.                             elseif packetType == "ack_pos" then
  421.                                 print("data_server: Positive acknowledgement received.")
  422.                             elseif packetType == "ack_neg" then
  423.                                 print("data_server: Negative acknowledgement received.")
  424.                             else
  425.                                 print("data_server: Unknown packet type: "..packetType)
  426.                             end
  427.                         end
  428.                         if packetType == "Message" then
  429.                             os.queueEvent("secure_receive", senderID, msg[5], data1)
  430.                         elseif packetType == "fakeModemMsg" then
  431.                             os.queueEvent("modem_message", "left", data2, data3, data1)
  432.                             os.queueEvent("secure_receive", senderID, msg[5], data1)
  433.                         elseif packetType == "close" then
  434.                             connections[msg[5]] = nil
  435.                             os.queueEvent("secure_connection_close", senderID, msg[5])
  436.                         elseif packetType == "newKey" then
  437.                             connections[msg[5]] = { data1, data2 }
  438.                             os.queueEvent("secure_connection_newKey", senderID, msg[5])
  439.                         elseif packetType == "newID" then
  440.                             if not connections[data1] then
  441.                                 if debug then
  442.                                     print("data_server: Switching connection "..msg[5].." to "..data1)
  443.                                 end
  444.                                 sendTunnel_raw(modem, msg[5], "ack_pos")
  445.                                 local cpy = {connections[msg[5]][1], connections[msg[5]][2]}
  446.                                 connections[data1] = cpy
  447.                                 connections[msg[5]] = nil
  448.                                 os.queueEvent("secure_connection_newID",  senderID, msg[5], data1)
  449.                             else
  450.                                 sendTunnel_raw(modem, msg[5], "ack_neg")
  451.                             end
  452.                         elseif packetType == "ack_pos" then
  453.                             os.queueEvent("secure_connection_ack", msg[5], senderID)
  454.                         elseif packetType == "ack_neg" then
  455.                             os.queueEvent("secure_connection_nak", msg[5], senderID)
  456.                         end
  457.                     end
  458.                 end
  459.             end
  460.         end
  461.     end
  462. end
  463.  
  464. function sendTunnel_raw(modem, id, packetType, data1, data2, data3)
  465.     if connections[id] then
  466.         local newIV = {}
  467.         for i=1, 16 do
  468.             newIV[i] = math.random(0, 255)
  469.         end
  470.         local enc_str = ""
  471.         local sec_msg = textutils.serialize({packetType, os.computerID(), newIV, data1, data2, data3})
  472.         local enc_bytes = {}
  473.         for i=1, #sec_msg do
  474.             enc_bytes[i] = string.byte(sec_msg, i, i)
  475.         end
  476.         enc_bytes = AES.encrypt_bytestream(enc_bytes, connections[id][1], connections[id][2])
  477.         enc_str = base64.encode(enc_bytes)
  478.         local data_str = textutils.serialize( {"Tunneling", math.random(1,0xFFFF), "Data", enc_str, id} )
  479.         connections[id][2] = {}
  480.         for i=1, 16 do
  481.             connections[id][2][i] = newIV[i]
  482.         end
  483.         modem.transmit(tunnelFreq, tunnelFreq, data_str)
  484.         return true
  485.     else
  486.         return false
  487.     end
  488. end
  489.  
  490.  
  491. function sendTunnel(modem, id, data)
  492.     --[[
  493.     if connections[id] then
  494.         local enc_str = ""
  495.         local sec_msg = textutils.serialize({"Message", os.computerID(), data})
  496.         local enc_bytes = {}
  497.         for i=1, #sec_msg do
  498.             enc_bytes[i] = string.byte(sec_msg, i, i)
  499.         end
  500.         enc_bytes = AES.encrypt_bytestream(enc_bytes, connections[id][1], connections[id][3])
  501.         enc_str = base64.encode(enc_bytes)
  502.         local data_str = textutils.serialize( {"Tunneling", math.random(1,0xFFFF), "Data", enc_str, id} )
  503.         modem.transmit(tunnelFreq, tunnelFreq, data_str)
  504.         return true
  505.     else
  506.         return false
  507.     end
  508.     ]]
  509.     return sendTunnel_raw(modem, id, "Message", data)
  510. end
  511.  
  512. function sendTunnel_withFreq(modem, id, data, tFreq, rFreq) -- Send a "fake" (but still encrypted) modem transmission.
  513.     --[[
  514.     if connections[id] then
  515.         local enc_str = ""
  516.         local sec_msg = textutils.serialize({os.computerID(), data, tFreq, rFreq})
  517.         local enc_bytes = {}
  518.         for i=1, #sec_msg do
  519.             enc_bytes[i] = string.byte(sec_msg, i, i)
  520.         end
  521.         enc_bytes = AES.encrypt_bytestream(enc_bytes, connections[id][1], connections[id][3])
  522.         enc_str = base64.encode(enc_bytes)
  523.         local data_str = textutils.serialize( {"Tunneling", math.random(1,0xFFFF), "Data", enc_str, id} )
  524.         modem.transmit(tunnelFreq, tunnelFreq, data_str)
  525.         return true
  526.     else
  527.         return false
  528.     end
  529.     ]]
  530.     return sendTunnel_raw(modem, id, "fakeModemMsg", data, tFreq, rFreq)
  531. end
  532.  
  533. function listenTunnel(id, timeout)
  534.     local timer = {}
  535.     if not connections[id] then
  536.         return false
  537.     end
  538.     if timeout then
  539.         timer = os.startTimer(timeout)
  540.     end
  541.     while true do
  542.         local event = {os.pullEvent()}
  543.         if event[1] == "timer" and event[2] == timer then
  544.             return nil
  545.         elseif event[1] == "secure_receive" and event[3] == id then
  546.             return event[2], event[4]
  547.         end
  548.     end
  549. end
  550.  
  551. function closeTunnel(modem, id)
  552.     if connections[id] then
  553.         --modem.transmit(tunnelFreq, tunnelFreq, textutils.serialize( {"Tunneling", os.computerID(), "Close", id} ))
  554.         sendTunnel_raw(modem, id, "close")
  555.         connections[id] = nil
  556.         os.queueEvent("secure_connection_close", id)
  557.         return true
  558.     end
  559.     return false
  560. end
  561.  
  562. function getAllOpenConnections()
  563.     local ids = {}
  564.     for i, v in pairs(connections) do
  565.         table.insert(ids, i)
  566.     end
  567.     return ids
  568. end
  569.  
  570. function getConnectionDetails(conn)
  571.     return {connections[conn][1], connections[conn][2]}
  572. end
  573.  
  574. function installTunnelAsModem(modem, id, side) -- Create a fake (wireless) "modem" peripheral. Cannot override (any) "real" modems.
  575.     if not peripheral.tunnelHijackInPlace then
  576.         peripheral.tunnelHijackInPlace = true
  577.         peripheral.old = {}
  578.         peripheral.tunnels = {}
  579.         for i,v in pairs(peripheral) do
  580.             if i ~= "old" then
  581.                 peripheral.old[i] = v
  582.             end
  583.         end
  584.         peripheral.isPresent = function(methodSide)
  585.             return peripheral.old.isPresent(methodSide) or (peripheral.tunnels[methodSide] ~= nil)
  586.         end
  587.         peripheral.getType = function(methodSide)
  588.             if peripheral.old.isPresent(methodSide) then
  589.                 return peripheral.old.getType(methodSide)
  590.             elseif peripheral.tunnels[methodSide] ~= nil then
  591.                 return "modem"
  592.             end
  593.         end
  594.         peripheral.wrap = function(methodSide)
  595.             if peripheral.old.isPresent(methodSide) then
  596.                 return peripheral.old.wrap(methodSide)
  597.             elseif peripheral.tunnels[methodSide] ~= nil then
  598.                 local copy = {}
  599.                 for i,v in pairs(peripheral.tunnels[methodSide]) do
  600.                     copy[i] = v
  601.                 end
  602.             end
  603.         end
  604.         peripheral.getMethods = function(methodSide)
  605.             if peripheral.old.isPresent(methodSide) then
  606.                 return peripheral.old.getMethods(methodSide)
  607.             elseif peripheral.tunnels[methodSide] ~= nil then
  608.                 local copy = {}
  609.                 local ctr = 1
  610.                 for i,v in pairs(peripheral.tunnels[methodSide]) do
  611.                     copy[ctr] = i
  612.                     ctr = ctr+1
  613.                 end
  614.                 return copy
  615.             end
  616.         end
  617.         peripheral.call = function(...)
  618.             local args = {...}
  619.             local side = args[1]
  620.             local method = args[2]
  621.             if peripheral.tunnels[side] ~= nil then
  622.                 if peripheral.tunnels[side][method] ~= nil then
  623.                     return peripheral.tunnels[side][method](unpack(args, 3))
  624.                 end
  625.             elseif peripheral.old.isPresent(side) then
  626.                 return peripheral.old.call(unpack(args))
  627.             end
  628.         end
  629.         peripheral.getNames = function()
  630.             local names = peripheral.old.getNames()
  631.             for i,v in pairs(peripheral.tunnels) do
  632.                 table.insert(names, i)
  633.             end
  634.             return names
  635.         end
  636.     end
  637.     peripheral.tunnels[side] = {}
  638.     peripheral.tunnels[side].id = id
  639.     peripheral.tunnels[side].modem = modem
  640.     peripheral.tunnels[side].isOpen = function()
  641.         return connections[peripheral.tunnels[side].id] ~= nil
  642.     end
  643.     peripheral.tunnels[side].open = function()
  644.         return true
  645.     end
  646.     peripheral.tunnels[side].close = function()
  647.         closeTunnel(peripheral.tunnels[side].modem, peripheral.tunnels[side].id)
  648.         return true
  649.     end
  650.     peripheral.tunnels[side].closeAll = function()
  651.         closeTunnel(peripheral.tunnels[side].modem, peripheral.tunnels[side].id)
  652.         return true
  653.     end
  654.     peripheral.tunnels[side].isWireless = function()
  655.         return true
  656.     end
  657.     peripheral.tunnels[side].transmit = function(tFreq, rFreq, data)
  658.         sendTunnel_withFreq(peripheral.tunnels[side].modem, peripheral.tunnels[side].id, data, tFreq, rFreq)
  659.     end
  660.     local copy = {}
  661.     for i,v in pairs(peripheral.tunnels[side]) do
  662.         copy[i] = v
  663.     end
  664.     return copy
  665. end
  666.  
  667. function switchConnectionID(modem, oldID, newID)
  668.     sendTunnel_raw(modem, oldID, "newID", newID)
  669.     local timer = os.startTimer(30)
  670.     while true do
  671.         local event, t = os.pullEvent()
  672.         if event == "timer" and t == timer then
  673.             return false
  674.         elseif event == "secure_connection_nak" and t == oldID then
  675.             return false
  676.         elseif event == "secure_connection_ack" and t == oldID then
  677.             connections[newID] = {connections[oldID][1], connections[oldID][2]}
  678.             connections[oldID] = nil
  679.             os.queueEvent("secure_connection_newID",  senderID, oldID, newID)
  680.             return true
  681.         end
  682.     end
  683.     return false
  684. end
  685.  
  686. function switchKey(modem, id, key, iv)
  687.     sendTunnel_raw(modem, id, "newKey", key, iv)
  688.     connections[id] = {key, iv}
  689.     os.queueEvent("secure_connection_newKey", id)
  690. end
  691.  
  692. function openConnectionRaw(connID, key, iv)
  693.     --[[
  694.     local tempID = openTunnel(modem, compID)
  695.     if switchConnectionID(modem, tempID, connID) then
  696.         sendTunnel_raw(modem, "newKey", key, iv)
  697.         return true
  698.     end
  699.     return false
  700.     ]]
  701.     connections[connID] = {key, iv}
  702. end
  703.  
  704. function openTunnel(modem, id, debug)
  705.     modem.open(connFreq)
  706.     modem.open(tunnelFreq)
  707.     local base = math.random(1, 3)
  708.     if base == 1 then
  709.         base = 2
  710.     elseif base == 2 then
  711.         base = 3
  712.     else
  713.         base = 5
  714.     end
  715.     -- Generate 8 different numbers, because AES needs 16 bytes of key, as well as 16 bytes for the IV.
  716.     -- We're running 8 different D-H exchanges with the same base.
  717.     local p = generatePrime(100, debug)
  718.    
  719.     local k1 = random.random()
  720.     local k2 = random.random()
  721.     local k3 = random.random()
  722.     local k4 = random.random()
  723.    
  724.     local iv1 = random.random()
  725.     local iv2 = random.random()
  726.     local iv3 = random.random()
  727.     local iv4 = random.random()
  728.    
  729.     local s1 = 0
  730.     local s2 = 0
  731.     local s3 = 0
  732.     local s4 = 0
  733.    
  734.     local iv_s1 = 0
  735.     local iv_s2 = 0
  736.     local iv_s3 = 0
  737.     local iv_s4 = 0
  738.    
  739.     local a1 = mod_exp(base, k1, p)
  740.     local a2 = mod_exp(base, k2, p)
  741.     local a3 = mod_exp(base, k3, p)
  742.     local a4 = mod_exp(base, k4, p)
  743.    
  744.     local iv_a1 = mod_exp(base, iv1, p)
  745.     local iv_a2 = mod_exp(base, iv2, p)
  746.     local iv_a3 = mod_exp(base, iv3, p)
  747.     local iv_a4 = mod_exp(base, iv4, p)
  748.     if debug then
  749.         print("connect: Numbers generated...")
  750.     end
  751.     modem.transmit(connFreq, connFreq, textutils.serialize({"Tunneling", os.computerID(), "Connect", a1, a2, a3, a4, iv_a1, iv_a2, iv_a3, iv_a4, base, p}))
  752.     while true do
  753.         local tFreq, rFreq, msg = listen(30)
  754.         if tFreq == nil then
  755.             return false
  756.         else
  757.             if tFreq == connFreq then
  758.                 if msg then
  759.                     if msg[1] == "Tunneling" and msg[2] == id and msg[3] == "Connect_Key" then
  760.                         if debug then
  761.                             print("connect: Server has sent its keys...")
  762.                         end
  763.                         s1 = mod_exp(msg[4], k1, p)
  764.                         s2 = mod_exp(msg[5], k2, p)
  765.                         s3 = mod_exp(msg[6], k3, p)
  766.                         s4 = mod_exp(msg[7], k4, p)
  767.                        
  768.                         iv_s1 = mod_exp(msg[8], iv1, p)
  769.                         iv_s2 = mod_exp(msg[9], iv2, p)
  770.                         iv_s3 = mod_exp(msg[10], iv3, p)
  771.                         iv_s4 = mod_exp(msg[11], iv4, p)
  772.                         local serv_test_block = msg[12]
  773.                         local our_test_block = {}
  774.                         for i=1, 16 do
  775.                             our_test_block[i] = 0xFF
  776.                         end
  777.                        
  778.                         local s = {}
  779.                         local iv = {}
  780.                        
  781.                         s[1] = bit.brshift(bit.band( s1, 0xFF000000 ), 24)
  782.                         s[2] = bit.brshift(bit.band( s1, 0x00FF0000 ), 16)
  783.                         s[3] = bit.brshift(bit.band( s1, 0x0000FF00 ), 8)
  784.                         s[4] = bit.band( s1, 0x000000FF )
  785.                        
  786.                         s[5] = bit.brshift(bit.band( s2, 0xFF000000 ), 24)
  787.                         s[6] = bit.brshift(bit.band( s2, 0x00FF0000 ), 16)
  788.                         s[7] = bit.brshift(bit.band( s2, 0x0000FF00 ), 8)
  789.                         s[8] = bit.band( s2, 0x000000FF )
  790.                        
  791.                         s[9] = bit.brshift(bit.band( s3, 0xFF000000 ), 24)
  792.                         s[10] = bit.brshift(bit.band( s3, 0x00FF0000 ), 16)
  793.                         s[11] = bit.brshift(bit.band( s3, 0x0000FF00 ), 8)
  794.                         s[12] = bit.band( s3, 0x000000FF )
  795.                        
  796.                         s[13] = bit.brshift(bit.band( s4, 0xFF000000 ), 24)
  797.                         s[14] = bit.brshift(bit.band( s4, 0x00FF0000 ), 16)
  798.                         s[15] = bit.brshift(bit.band( s4, 0x0000FF00 ), 8)
  799.                         s[16] = bit.band( s4, 0x000000FF )
  800.                        
  801.                         iv[1] = bit.brshift(bit.band( iv_s1, 0xFF000000 ), 24)
  802.                         iv[2] = bit.brshift(bit.band( iv_s1, 0x00FF0000 ), 16)
  803.                         iv[3] = bit.brshift(bit.band( iv_s1, 0x0000FF00 ), 8)
  804.                         iv[4] = bit.band( iv_s1, 0x000000FF )
  805.                        
  806.                         iv[5] = bit.brshift(bit.band( iv_s2, 0xFF000000 ), 24)
  807.                         iv[6] = bit.brshift(bit.band( iv_s2, 0x00FF0000 ), 16)
  808.                         iv[7] = bit.brshift(bit.band( iv_s2, 0x0000FF00 ), 8)
  809.                         iv[8] = bit.band( iv_s2, 0x000000FF )
  810.                        
  811.                         iv[9] = bit.brshift(bit.band( iv_s3, 0xFF000000 ), 24)
  812.                         iv[10] = bit.brshift(bit.band( iv_s3, 0x00FF0000 ), 16)
  813.                         iv[11] = bit.brshift(bit.band( iv_s3, 0x0000FF00 ), 8)
  814.                         iv[12] = bit.band( iv_s3, 0x000000FF )
  815.                        
  816.                         iv[13] = bit.brshift(bit.band( iv_s4, 0xFF000000 ), 24)
  817.                         iv[14] = bit.brshift(bit.band( iv_s4, 0x00FF0000 ), 16)
  818.                         iv[15] = bit.brshift(bit.band( iv_s4, 0x0000FF00 ), 8)
  819.                         iv[16] = bit.band( iv_s4, 0x000000FF )
  820.                        
  821.                         if debug then
  822.                             print("connect: Testing key..")
  823.                         end
  824.                         our_test_block = AES.encrypt_bytestream(our_test_block, s, iv)
  825.                         for i=1, 16 do
  826.                             if our_test_block[i] ~= serv_test_block[i] then
  827.                                 return false
  828.                             end
  829.                         end
  830.                         modem.transmit(connFreq, connFreq, textutils.serialize({"Tunneling", os.computerID(), "Connection_Established"}))
  831.                         if debug then
  832.                             print("connect: Connection established...")
  833.                         end
  834.                         while true do
  835.                             local _, __, msg2 = listen(30)
  836.                             if msg2 == nil then
  837.                                 return false
  838.                             elseif msg2[1] == "Tunneling" and msg2[2] == id then
  839.                                 local d = AES.decrypt_bytestream(base64.decode(msg2[3]), s, iv)
  840.                                 local d_str = ""
  841.                                 for i=1, #d do
  842.                                     d_str = d_str..string.char(d[i])
  843.                                 end
  844.                                 if textutils.unserialize(d_str) then
  845.                                     d = textutils.unserialize(d_str)
  846.                                     if d[1] == "Connection_ID" then
  847.                                         if debug then
  848.                                             print("connect: Recieved connection ID.")
  849.                                         end
  850.                                         connections[ d[2] ] = {s, iv}
  851.                                         os.queueEvent("secure_connection_open", id, d[2])
  852.                                         return d[2]
  853.                                     else
  854.                                         return false
  855.                                     end
  856.                                 else
  857.                                     return false
  858.                                 end
  859.                             end
  860.                         end
  861.                     end
  862.                 end
  863.             end
  864.         end
  865.     end
  866. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement