summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/dhtd.hs12
-rw-r--r--src/Crypto/Tox.hs1
-rw-r--r--src/Network/QueryResponse.hs32
-rw-r--r--src/Network/Tox.hs4
-rw-r--r--src/Network/Tox/Onion/Transport.hs33
-rw-r--r--todo.txt2
6 files changed, 61 insertions, 23 deletions
diff --git a/examples/dhtd.hs b/examples/dhtd.hs
index bd2df9db..1e2c1467 100644
--- a/examples/dhtd.hs
+++ b/examples/dhtd.hs
@@ -45,7 +45,7 @@ import Control.Concurrent.Lifted
45import GHC.Conc (labelThread) 45import GHC.Conc (labelThread)
46#endif 46#endif
47 47
48import Crypto.Tox (zeros32,SecretKey,PublicKey, generateSecretKey, toPublic, encodeSecret, decodeSecret) 48import Crypto.Tox (zeros32,SecretKey,PublicKey, generateSecretKey, toPublic, encodeSecret, decodeSecret, userKeys)
49import Network.UPNP as UPNP 49import Network.UPNP as UPNP
50import Network.Address hiding (NodeId, NodeInfo(..)) 50import Network.Address hiding (NodeId, NodeInfo(..))
51import Network.Kademlia.Search 51import Network.Kademlia.Search
@@ -669,8 +669,9 @@ main = do
669 669
670 keysdb <- Tox.newKeysDatabase 670 keysdb <- Tox.newKeysDatabase
671 671
672 (quitTox,toxdhts,toxips,taddrs) <- case porttox opts of 672 (toxids,quitTox,toxdhts,toxips,taddrs) <- case porttox opts of
673 "" -> return (return (), Map.empty, return [],[]) 673 "" -> do keys <- atomically $ newTVar []
674 return (keys,return (), Map.empty, return [],[])
674 toxport -> do 675 toxport -> do
675 addrTox <- getBindAddress toxport (ip6tox opts) 676 addrTox <- getBindAddress toxport (ip6tox opts)
676 tox <- Tox.newTox keysdb addrTox 677 tox <- Tox.newTox keysdb addrTox
@@ -732,7 +733,7 @@ main = do
732 ips :: IO [SockAddr] 733 ips :: IO [SockAddr]
733 ips = readExternals Tox.nodeAddr [ Tox.routing4 $ Tox.toxRouting tox 734 ips = readExternals Tox.nodeAddr [ Tox.routing4 $ Tox.toxRouting tox
734 , Tox.routing6 $ Tox.toxRouting tox ] 735 , Tox.routing6 $ Tox.toxRouting tox ]
735 return (quitTox, dhts, ips, [addrTox]) 736 return (userKeys (Tox.toxCryptoKeys tox), quitTox, dhts, ips, [addrTox])
736 737
737 _ <- UPNP.requestPorts "dht-client" $ map (Datagram,) $ baddrs ++ taddrs 738 _ <- UPNP.requestPorts "dht-client" $ map (Datagram,) $ baddrs ++ taddrs
738 739
@@ -740,14 +741,13 @@ main = do
740 741
741 waitForSignal <- do 742 waitForSignal <- do
742 signalQuit <- newEmptyMVar 743 signalQuit <- newEmptyMVar
743 userkeys0 <- atomically (newTVar [])
744 let session = clientSession $ Session 744 let session = clientSession $ Session
745 { netname = concat $ take 1 $ Map.keys dhts -- initial default DHT 745 { netname = concat $ take 1 $ Map.keys dhts -- initial default DHT
746 , dhts = dhts -- all DHTs 746 , dhts = dhts -- all DHTs
747 , signalQuit = signalQuit 747 , signalQuit = signalQuit
748 , swarms = swarms 748 , swarms = swarms
749 , toxkeys = keysdb 749 , toxkeys = keysdb
750 , userkeys = userkeys0 750 , userkeys = toxids
751 , externalAddresses = liftM2 (++) btips toxips 751 , externalAddresses = liftM2 (++) btips toxips
752 } 752 }
753 srv <- streamServer (withSession session) (SockAddrUnix "dht.sock") 753 srv <- streamServer (withSession session) (SockAddrUnix "dht.sock")
diff --git a/src/Crypto/Tox.hs b/src/Crypto/Tox.hs
index b86a5395..645ca53e 100644
--- a/src/Crypto/Tox.hs
+++ b/src/Crypto/Tox.hs
@@ -366,6 +366,7 @@ data TransportCrypto = TransportCrypto
366 , rendezvousPublic :: PublicKey 366 , rendezvousPublic :: PublicKey
367 , transportSymmetric :: STM SymmetricKey 367 , transportSymmetric :: STM SymmetricKey
368 , transportNewNonce :: STM Nonce24 368 , transportNewNonce :: STM Nonce24
369 , userKeys :: TVar [(SecretKey,PublicKey)]
369 } 370 }
370 371
371getPublicKey :: S.Get PublicKey 372getPublicKey :: S.Get PublicKey
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs
index 27c89674..1901e164 100644
--- a/src/Network/QueryResponse.hs
+++ b/src/Network/QueryResponse.hs
@@ -53,24 +53,44 @@ data Transport err addr x = Transport
53-- packet representations. It could be used to change UDP 'ByteString's into 53-- packet representations. It could be used to change UDP 'ByteString's into
54-- bencoded syntax trees or to add an encryption layer in which addresses have 54-- bencoded syntax trees or to add an encryption layer in which addresses have
55-- associated public keys. 55-- associated public keys.
56layerTransport :: 56layerTransportM ::
57 (x -> addr -> Either err (x', addr')) 57 (x -> addr -> IO (Either err (x', addr')))
58 -- ^ Function that attempts to transform a low-level address/packet 58 -- ^ Function that attempts to transform a low-level address/packet
59 -- pair into a higher level representation. 59 -- pair into a higher level representation.
60 -> (x' -> addr' -> (x, addr)) 60 -> (x' -> addr' -> IO (x, addr))
61 -- ^ Function to encode a high-level address/packet into a lower level 61 -- ^ Function to encode a high-level address/packet into a lower level
62 -- representation. 62 -- representation.
63 -> Transport err addr x 63 -> Transport err addr x
64 -- ^ The low-level transport to be transformed. 64 -- ^ The low-level transport to be transformed.
65 -> Transport err addr' x' 65 -> Transport err addr' x'
66layerTransport parse encode tr = 66layerTransportM parse encode tr =
67 tr { awaitMessage = \kont -> 67 tr { awaitMessage = \kont ->
68 awaitMessage tr $ \m -> kont $ fmap (>>= uncurry parse) m 68 awaitMessage tr $ \m -> mapM (mapM $ uncurry parse) m >>= kont . fmap join
69 , sendMessage = \addr' msg' -> do 69 , sendMessage = \addr' msg' -> do
70 let (msg,addr) = encode msg' addr' 70 (msg,addr) <- encode msg' addr'
71 sendMessage tr addr msg 71 sendMessage tr addr msg
72 } 72 }
73 73
74
75-- | This function modifies a 'Transport' to use higher-level addresses and
76-- packet representations. It could be used to change UDP 'ByteString's into
77-- bencoded syntax trees or to add an encryption layer in which addresses have
78-- associated public keys.
79layerTransport ::
80 (x -> addr -> Either err (x', addr'))
81 -- ^ Function that attempts to transform a low-level address/packet
82 -- pair into a higher level representation.
83 -> (x' -> addr' -> (x, addr))
84 -- ^ Function to encode a high-level address/packet into a lower level
85 -- representation.
86 -> Transport err addr x
87 -- ^ The low-level transport to be transformed.
88 -> Transport err addr' x'
89layerTransport parse encode tr =
90 layerTransportM (\x addr -> return $ parse x addr)
91 (\x' addr' -> return $ encode x' addr')
92 tr
93
74-- | Paritions a 'Transport' into two higher-level transports. Note: An 'MVar' 94-- | Paritions a 'Transport' into two higher-level transports. Note: An 'MVar'
75-- is used to share the same underlying socket, so be sure to fork a thread for 95-- is used to share the same underlying socket, so be sure to fork a thread for
76-- both returned 'Transport's to avoid hanging. 96-- both returned 'Transport's to avoid hanging.
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs
index 98e9691b..f41b0f25 100644
--- a/src/Network/Tox.hs
+++ b/src/Network/Tox.hs
@@ -105,6 +105,7 @@ newCrypto = do
105 let pubkey = toPublic secret 105 let pubkey = toPublic secret
106 aliaspub = toPublic alias 106 aliaspub = toPublic alias
107 raliaspub = toPublic ralias 107 raliaspub = toPublic ralias
108 ukeys <- atomically $ newTVar []
108 (symkey, drg) <- do 109 (symkey, drg) <- do
109 drg0 <- getSystemDRG 110 drg0 <- getSystemDRG
110 return $ randomBytesGenerate 32 drg0 :: IO (ByteString, SystemDRG) 111 return $ randomBytesGenerate 32 drg0 :: IO (ByteString, SystemDRG)
@@ -125,6 +126,7 @@ newCrypto = do
125 let (nonce, drg2) = withDRG drg1 (Nonce24 <$> getRandomBytes 24) 126 let (nonce, drg2) = withDRG drg1 (Nonce24 <$> getRandomBytes 24)
126 writeTVar noncevar drg2 127 writeTVar noncevar drg2
127 return nonce 128 return nonce
129 , userKeys = ukeys
128 } 130 }
129 131
130updateIP :: TVar (R.BucketList NodeInfo) -> SockAddr -> STM () 132updateIP :: TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()
@@ -266,7 +268,7 @@ newTox keydb addr = do
266 nil <- nullSessionTokens 268 nil <- nullSessionTokens
267 atomically $ newTVar nil { maxInterval = 20 } -- 20 second timeout on announce ping-ids. 269 atomically $ newTVar nil { maxInterval = 20 } -- 20 second timeout on announce ping-ids.
268 oniondrg <- drgNew 270 oniondrg <- drgNew
269 let onionnet = layerTransport (Onion.decrypt crypto) (Onion.encrypt crypto) onioncrypt 271 let onionnet = layerTransportM (Onion.decrypt crypto) (Onion.encrypt crypto) onioncrypt
270 onionclient <- newClient oniondrg onionnet Onion.classify 272 onionclient <- newClient oniondrg onionnet Onion.classify
271 (getOnionAlias crypto $ R.thisNode <$> readTVar (DHT.routing4 routing)) 273 (getOnionAlias crypto $ R.thisNode <$> readTVar (DHT.routing4 routing))
272 (Onion.handlers onionnet routing toks keydb) 274 (Onion.handlers onionnet routing toks keydb)
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs
index 3e3596a6..34ba23f6 100644
--- a/src/Network/Tox/Onion/Transport.hs
+++ b/src/Network/Tox/Onion/Transport.hs
@@ -598,18 +598,31 @@ instance Sized OnionData where
598 ConstSize n -> n 598 ConstSize n -> n
599 VarSize f -> f req 599 VarSize f -> f req
600 600
601encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> (OnionMessage Encrypted, OnionDestination r) 601
602encrypt crypto msg rpath = ( transcode ( (. (runIdentity . either id assymData)) 602selectKey :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (SecretKey, PublicKey)
603 . encryptMessage skey okey) 603selectKey crypto
604 msg 604 (OnionAnnounce a@Assym { assymData = Identity (AnnounceRequest _ pkey akey, _) })
605 , rpath) 605 rpath
606 where 606 | (akey /= zeroID) = atomically $ do
607 skey = fst $ aliasKey crypto rpath 607 ks <- filter (\(sk,pk) -> pk == id2key pkey)
608 <$> readTVar (userKeys crypto)
609 maybe (return $ aliasKey crypto rpath)
610 return
611 (listToMaybe ks)
612selectKey crypto msg rpath = return $ aliasKey crypto rpath
613
614encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (OnionMessage Encrypted, OnionDestination r)
615encrypt crypto msg rpath = do
616 (skey,pkey) <- selectKey crypto msg rpath
617 let skey = fst $ aliasKey crypto rpath
608 618
609 -- The OnionToMe case shouldn't happen, but we'll use our own public 619 -- The OnionToMe case shouldn't happen, but we'll use our own public
610 -- key in this situation. 620 -- key in this situation.
611 okey = fromMaybe (transportPublic crypto) $ onionKey rpath 621 okey = fromMaybe (transportPublic crypto) $ onionKey rpath
612 622 return ( transcode ( (. (runIdentity . either id assymData))
623 . encryptMessage skey okey)
624 msg
625 , rpath)
613 626
614encryptMessage :: Serialize a => 627encryptMessage :: Serialize a =>
615 SecretKey -> PublicKey -> Nonce24 -> a -> Encrypted a 628 SecretKey -> PublicKey -> Nonce24 -> a -> Encrypted a
@@ -618,8 +631,8 @@ encryptMessage skey destKey n a = ToxCrypto.encrypt secret plain
618 secret = computeSharedSecret skey destKey n 631 secret = computeSharedSecret skey destKey n
619 plain = encodePlain a 632 plain = encodePlain a
620 633
621decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> Either String (OnionMessage Identity, OnionDestination r) 634decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> IO (Either String (OnionMessage Identity, OnionDestination r))
622decrypt crypto msg addr = do 635decrypt crypto msg addr = return $ do
623 msg <- sequenceMessage $ transcode (\n -> decryptMessage (aliasKey crypto addr) n . left (senderkey addr)) msg 636 msg <- sequenceMessage $ transcode (\n -> decryptMessage (aliasKey crypto addr) n . left (senderkey addr)) msg
624 Right (msg, addr) 637 Right (msg, addr)
625 638
diff --git a/todo.txt b/todo.txt
index 1a3bf8b4..287f276a 100644
--- a/todo.txt
+++ b/todo.txt
@@ -13,6 +13,8 @@ tox4: 6 buckets, tox6: 3 buckets
13 13
14handle exception: dhtd: Network.Socket.sendTo: does not exist (Network is unreachable 14handle exception: dhtd: Network.Socket.sendTo: does not exist (Network is unreachable
15 15
16tox: rename assym to asymm (short for asymmetric)
17
16tox: fallback to https://nodes.tox.chat/json 18tox: fallback to https://nodes.tox.chat/json
17 19
18tox: key search 20tox: key search