diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Crypto/Tox.hs | 14 | ||||
-rw-r--r-- | src/Network/Tox.hs | 10 | ||||
-rw-r--r-- | src/Network/Tox/Onion/Handlers.hs | 37 |
3 files changed, 52 insertions, 9 deletions
diff --git a/src/Crypto/Tox.hs b/src/Crypto/Tox.hs index d6f63f18..b86a5395 100644 --- a/src/Crypto/Tox.hs +++ b/src/Crypto/Tox.hs | |||
@@ -49,6 +49,7 @@ module Crypto.Tox | |||
49 | ) where | 49 | ) where |
50 | 50 | ||
51 | import Control.Arrow | 51 | import Control.Arrow |
52 | import Control.Monad | ||
52 | import qualified Crypto.Cipher.ChaChaPoly1305 as Symmetric | 53 | import qualified Crypto.Cipher.ChaChaPoly1305 as Symmetric |
53 | import qualified Crypto.Cipher.Salsa as Salsa | 54 | import qualified Crypto.Cipher.Salsa as Salsa |
54 | import qualified Crypto.Cipher.XSalsa as XSalsa | 55 | import qualified Crypto.Cipher.XSalsa as XSalsa |
@@ -260,6 +261,7 @@ bin2hex = C8.unpack . Base16.encode . BA.convert | |||
260 | bin2base64 :: ByteArrayAccess bs => bs -> String | 261 | bin2base64 :: ByteArrayAccess bs => bs -> String |
261 | bin2base64 = C8.unpack . Base64.encode . BA.convert | 262 | bin2base64 = C8.unpack . Base64.encode . BA.convert |
262 | 263 | ||
264 | |||
263 | instance Show Nonce24 where | 265 | instance Show Nonce24 where |
264 | showsPrec d nonce = quoted (mappend $ bin2hex nonce) | 266 | showsPrec d nonce = quoted (mappend $ bin2hex nonce) |
265 | 267 | ||
@@ -298,6 +300,16 @@ newtype Nonce32 = Nonce32 ByteString | |||
298 | instance Show Nonce32 where | 300 | instance Show Nonce32 where |
299 | showsPrec d nonce = mappend $ bin2base64 nonce | 301 | showsPrec d nonce = mappend $ bin2base64 nonce |
300 | 302 | ||
303 | instance Read Nonce32 where | ||
304 | readsPrec _ str = either (const []) id $ do | ||
305 | let (ds,ss) = Prelude.splitAt 43 str | ||
306 | ss' <- case ss of | ||
307 | '=':xs -> Right xs -- optional terminating '=' | ||
308 | _ -> Right ss | ||
309 | bs <- Base64.decode (C8.pack $ ds ++ ['=']) | ||
310 | guard $ B.length bs == 32 | ||
311 | return [ (Nonce32 bs, ss') ] | ||
312 | |||
301 | instance Serialize Nonce32 where | 313 | instance Serialize Nonce32 where |
302 | get = Nonce32 <$> getBytes 32 | 314 | get = Nonce32 <$> getBytes 32 |
303 | put (Nonce32 bs) = putByteString bs | 315 | put (Nonce32 bs) = putByteString bs |
@@ -350,6 +362,8 @@ data TransportCrypto = TransportCrypto | |||
350 | , transportPublic :: PublicKey | 362 | , transportPublic :: PublicKey |
351 | , onionAliasSecret :: SecretKey | 363 | , onionAliasSecret :: SecretKey |
352 | , onionAliasPublic :: PublicKey | 364 | , onionAliasPublic :: PublicKey |
365 | , rendezvousSecret :: SecretKey | ||
366 | , rendezvousPublic :: PublicKey | ||
353 | , transportSymmetric :: STM SymmetricKey | 367 | , transportSymmetric :: STM SymmetricKey |
354 | , transportNewNonce :: STM Nonce24 | 368 | , transportNewNonce :: STM Nonce24 |
355 | } | 369 | } |
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs index 56c4b8e6..98e9691b 100644 --- a/src/Network/Tox.hs +++ b/src/Network/Tox.hs | |||
@@ -101,8 +101,10 @@ newCrypto :: IO TransportCrypto | |||
101 | newCrypto = do | 101 | newCrypto = do |
102 | secret <- generateSecretKey | 102 | secret <- generateSecretKey |
103 | alias <- generateSecretKey | 103 | alias <- generateSecretKey |
104 | let pubkey = toPublic secret | 104 | ralias <- generateSecretKey |
105 | aliaspub = toPublic alias | 105 | let pubkey = toPublic secret |
106 | aliaspub = toPublic alias | ||
107 | raliaspub = toPublic ralias | ||
106 | (symkey, drg) <- do | 108 | (symkey, drg) <- do |
107 | drg0 <- getSystemDRG | 109 | drg0 <- getSystemDRG |
108 | return $ randomBytesGenerate 32 drg0 :: IO (ByteString, SystemDRG) | 110 | return $ randomBytesGenerate 32 drg0 :: IO (ByteString, SystemDRG) |
@@ -115,6 +117,8 @@ newCrypto = do | |||
115 | , transportPublic = pubkey | 117 | , transportPublic = pubkey |
116 | , onionAliasSecret = alias | 118 | , onionAliasSecret = alias |
117 | , onionAliasPublic = aliaspub | 119 | , onionAliasPublic = aliaspub |
120 | , rendezvousSecret = ralias | ||
121 | , rendezvousPublic = raliaspub | ||
118 | , transportSymmetric = return $ SymmetricKey symkey | 122 | , transportSymmetric = return $ SymmetricKey symkey |
119 | , transportNewNonce = do | 123 | , transportNewNonce = do |
120 | drg1 <- readTVar noncevar | 124 | drg1 <- readTVar noncevar |
@@ -204,6 +208,7 @@ data Tox = Tox | |||
204 | , toxOnion :: Onion.Client RouteId | 208 | , toxOnion :: Onion.Client RouteId |
205 | , toxToRoute :: Transport String Onion.Rendezvous (Assym (Encrypted Onion.DataToRoute)) | 209 | , toxToRoute :: Transport String Onion.Rendezvous (Assym (Encrypted Onion.DataToRoute)) |
206 | , toxCrypto :: Transport String SockAddr NetCrypto | 210 | , toxCrypto :: Transport String SockAddr NetCrypto |
211 | , toxCryptoKeys :: TransportCrypto | ||
207 | , toxRouting :: DHT.Routing | 212 | , toxRouting :: DHT.Routing |
208 | , toxTokens :: TVar SessionTokens | 213 | , toxTokens :: TVar SessionTokens |
209 | , toxAnnouncedKeys :: TVar Onion.AnnouncedKeys | 214 | , toxAnnouncedKeys :: TVar Onion.AnnouncedKeys |
@@ -273,6 +278,7 @@ newTox keydb addr = do | |||
273 | , toxOnion = onionclient | 278 | , toxOnion = onionclient |
274 | , toxToRoute = dtacrypt | 279 | , toxToRoute = dtacrypt |
275 | , toxCrypto = cryptonet | 280 | , toxCrypto = cryptonet |
281 | , toxCryptoKeys = crypto | ||
276 | , toxRouting = routing | 282 | , toxRouting = routing |
277 | , toxTokens = toks | 283 | , toxTokens = toks |
278 | , toxAnnouncedKeys = keydb | 284 | , toxAnnouncedKeys = keydb |
diff --git a/src/Network/Tox/Onion/Handlers.hs b/src/Network/Tox/Onion/Handlers.hs index 439de709..9702cbb8 100644 --- a/src/Network/Tox/Onion/Handlers.hs +++ b/src/Network/Tox/Onion/Handlers.hs | |||
@@ -166,7 +166,7 @@ toxidSearch :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, | |||
166 | toxidSearch getTimeout client = Search | 166 | toxidSearch getTimeout client = Search |
167 | { searchSpace = toxSpace | 167 | { searchSpace = toxSpace |
168 | , searchNodeAddress = nodeIP &&& nodePort | 168 | , searchNodeAddress = nodeIP &&& nodePort |
169 | , searchQuery = announce getTimeout client | 169 | , searchQuery = getRendezvous getTimeout client |
170 | } | 170 | } |
171 | 171 | ||
172 | announceSerializer :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) | 172 | announceSerializer :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) |
@@ -221,16 +221,39 @@ unwrapAnnounceResponse ni (AnnounceResponse is_stored (SendNodes ns)) | |||
221 | -- started. | 221 | -- started. |
222 | 222 | ||
223 | 223 | ||
224 | announce :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) | 224 | sendOnion :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) |
225 | -> Client r | 225 | -> Client r |
226 | -> NodeId | 226 | -> AnnounceRequest |
227 | -> NodeInfo | 227 | -> NodeInfo |
228 | -> IO (Maybe ([NodeInfo],[Rendezvous],Maybe Nonce32)) | 228 | -> (NodeInfo -> AnnounceResponse -> t) |
229 | announce getTimeout client nid ni = | 229 | -> IO (Maybe t) |
230 | sendOnion getTimeout client req ni unwrap = | ||
230 | -- Four tries and then we tap out. | 231 | -- Four tries and then we tap out. |
231 | flip fix 4 $ \loop n -> do | 232 | flip fix 4 $ \loop n -> do |
232 | let oaddr = OnionDestination ni Nothing | 233 | let oaddr = OnionDestination ni Nothing |
233 | mb <- QR.sendQuery client (announceSerializer getTimeout) (AnnounceRequest zeros32 nid zeroID) oaddr | 234 | mb <- QR.sendQuery client (announceSerializer getTimeout) req oaddr |
234 | maybe (if n>0 then loop $! n - 1 else return Nothing) | 235 | maybe (if n>0 then loop $! n - 1 else return Nothing) |
235 | (return . Just . unwrapAnnounceResponse ni) | 236 | (return . Just . unwrap ni) |
236 | $ join mb | 237 | $ join mb |
238 | |||
239 | getRendezvous :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) | ||
240 | -> Client r | ||
241 | -> NodeId | ||
242 | -> NodeInfo | ||
243 | -> IO (Maybe ([NodeInfo],[Rendezvous],Maybe Nonce32)) | ||
244 | getRendezvous getTimeout client nid ni = | ||
245 | sendOnion getTimeout client (AnnounceRequest zeros32 nid zeroID) ni unwrapAnnounceResponse | ||
246 | |||
247 | putRendezvous :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) | ||
248 | -> TransportCrypto | ||
249 | -> Client r | ||
250 | -> PublicKey | ||
251 | -> Nonce32 | ||
252 | -> NodeInfo | ||
253 | -> IO (Maybe (Rendezvous, AnnounceResponse)) | ||
254 | putRendezvous getTimeout crypto client pubkey nonce32 ni = do | ||
255 | let longTermKey = key2id pubkey | ||
256 | rkey = rendezvousPublic crypto | ||
257 | rendezvousKey = key2id rkey | ||
258 | sendOnion getTimeout client (AnnounceRequest nonce32 longTermKey rendezvousKey) ni | ||
259 | $ \ni resp -> (Rendezvous rkey ni, resp) | ||