diff options
author | James Crayne <jim.crayne@gmail.com> | 2018-05-31 15:54:51 +0000 |
---|---|---|
committer | James Crayne <jim.crayne@gmail.com> | 2018-05-31 15:54:51 +0000 |
commit | 5edbd08b22598310839bb2ad4a779fc70c5c54b8 (patch) | |
tree | 050c8bc589f539f73c3107271ec2c11996d73dd2 /src | |
parent | 9045835b429e88e8cbcca2b41c126f664b53d471 (diff) |
{fresh,update}CryptoSession are now in STM
Diffstat (limited to 'src')
-rw-r--r-- | src/Crypto/Tox.hs | 1 | ||||
-rw-r--r-- | src/Network/Tox.hs | 23 | ||||
-rw-r--r-- | src/Network/Tox/Crypto/Handlers.hs | 210 | ||||
-rw-r--r-- | src/Network/Tox/DHT/Handlers.hs | 18 |
4 files changed, 129 insertions, 123 deletions
diff --git a/src/Crypto/Tox.hs b/src/Crypto/Tox.hs index 864e17df..71aa99c4 100644 --- a/src/Crypto/Tox.hs +++ b/src/Crypto/Tox.hs | |||
@@ -35,6 +35,7 @@ module Crypto.Tox | |||
35 | -- , computeSharedSecret | 35 | -- , computeSharedSecret |
36 | , lookupSharedSecret | 36 | , lookupSharedSecret |
37 | , lookupNonceFunction | 37 | , lookupNonceFunction |
38 | , lookupNonceFunctionSTM | ||
38 | , encrypt | 39 | , encrypt |
39 | , decrypt | 40 | , decrypt |
40 | , Nonce8(..) | 41 | , Nonce8(..) |
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs index 66a19097..c3e559d7 100644 --- a/src/Network/Tox.hs +++ b/src/Network/Tox.hs | |||
@@ -323,22 +323,13 @@ netCryptoWithBackoff millisecs tox myseckey theirpubkey = do | |||
323 | , hpTheirBaseNonce = Nothing | 323 | , hpTheirBaseNonce = Nothing |
324 | , hpTheirSessionKeyPublic = Nothing | 324 | , hpTheirSessionKeyPublic = Nothing |
325 | } | 325 | } |
326 | freshCryptoSession (toxCryptoSessions tox) saddr hp | 326 | newsession <- generateSecretKey |
327 | -- myhandshake <- do | 327 | timestamp <- getPOSIXTime |
328 | -- n24' <- atomically $ transportNewNonce crypto | 328 | -- (myhandshakeData,launchThreads) <- |
329 | -- dput XNetCrypto ("Handshake Nonce24: " <> show n24') | 329 | _ <- atomically $ freshCryptoSession (toxCryptoSessions tox) saddr newsession timestamp hp |
330 | -- newBaseNonce <- atomically $ transportNewNonce crypto | 330 | -- launchThreads |
331 | -- mbMyhandshakeData <- newHandShakeData crypto newBaseNonce hp saddr | 331 | -- forM myhandshake $ \response_handshake -> do |
332 | -- forM mbMyhandshakeData $ \hsdata -> do | 332 | -- sendHandshake sessions addr response_handshake |
333 | -- state <- lookupSharedSecret crypto myseckey theirpubkey n24' | ||
334 | -- return Handshake { handshakeCookie = cookie | ||
335 | -- , handshakeNonce = n24' | ||
336 | -- , handshakeData = encrypt state $ encodePlain hsdata | ||
337 | -- } | ||
338 | -- case myhandshake of | ||
339 | -- Nothing -> hPutStrLn stderr "netCrypto: failed to create HandshakeData." >> return [] | ||
340 | -- Just handshake -> do | ||
341 | -- sendMessage (toxCrypto tox) saddr (NetHandshake handshake) | ||
342 | let secnum :: Double | 333 | let secnum :: Double |
343 | secnum = fromIntegral millisecs / 1000000 | 334 | secnum = fromIntegral millisecs / 1000000 |
344 | delay = (millisecs * 5 `div` 4) | 335 | delay = (millisecs * 5 `div` 4) |
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs index eabbc9b0..722d8507 100644 --- a/src/Network/Tox/Crypto/Handlers.hs +++ b/src/Network/Tox/Crypto/Handlers.hs | |||
@@ -7,7 +7,7 @@ module Network.Tox.Crypto.Handlers where | |||
7 | import Network.Tox.NodeId | 7 | import Network.Tox.NodeId |
8 | import Network.Tox.Crypto.Transport | 8 | import Network.Tox.Crypto.Transport |
9 | import Network.Tox.DHT.Transport (Cookie(..),CookieData(..), CookieRequest(..), NoSpam(..)) | 9 | import Network.Tox.DHT.Transport (Cookie(..),CookieData(..), CookieRequest(..), NoSpam(..)) |
10 | import Network.Tox.DHT.Handlers (Client, cookieRequest, createCookie ) | 10 | import Network.Tox.DHT.Handlers (Client, cookieRequest, createCookieSTM ) |
11 | import Crypto.Tox | 11 | import Crypto.Tox |
12 | import Control.Arrow | 12 | import Control.Arrow |
13 | import Control.Concurrent.STM | 13 | import Control.Concurrent.STM |
@@ -395,25 +395,18 @@ data HandshakeParams | |||
395 | , hpCookieRemoteDhtkey :: PublicKey | 395 | , hpCookieRemoteDhtkey :: PublicKey |
396 | } | 396 | } |
397 | 397 | ||
398 | newHandShakeData :: TransportCrypto -> Nonce24 -> HandshakeParams -> SockAddr -> PublicKey -> IO (Maybe HandshakeData) | 398 | newHandShakeData :: POSIXTime -> TransportCrypto -> Nonce24 -> HandshakeParams -> SockAddr -> PublicKey -> STM (Maybe HandshakeData) |
399 | newHandShakeData crypto basenonce (HParam {hpOtherCookie,hpMySecretKey,hpCookieRemotePubkey,hpCookieRemoteDhtkey}) addr mySessionPublic | 399 | newHandShakeData timestamp crypto basenonce (HParam {hpOtherCookie,hpMySecretKey,hpCookieRemotePubkey,hpCookieRemoteDhtkey}) addr mySessionPublic |
400 | = do | 400 | = do |
401 | freshCookie | 401 | freshCookie |
402 | <- case nodeInfo (key2id hpCookieRemoteDhtkey) addr of | 402 | <- case nodeInfo (key2id hpCookieRemoteDhtkey) addr of |
403 | Right nodeinfo -> Just <$> createCookie crypto nodeinfo hpCookieRemotePubkey | 403 | Right nodeinfo -> Just <$> createCookieSTM timestamp crypto nodeinfo hpCookieRemotePubkey |
404 | Left er -> return Nothing | 404 | Left er -> return Nothing |
405 | let hinit = hashInit | 405 | let hinit = hashInit |
406 | Cookie n24 encrypted = hpOtherCookie | 406 | Cookie n24 encrypted = hpOtherCookie |
407 | hctx = hashUpdate hinit n24 | 407 | hctx = hashUpdate hinit n24 |
408 | hctx' = hashUpdate hctx encrypted | 408 | hctx' = hashUpdate hctx encrypted |
409 | digest = hashFinalize hctx' | 409 | digest = hashFinalize hctx' |
410 | -- parameters addr {--> SockAddr -} | ||
411 | -- mbcookie <- case hpOtherCookie of | ||
412 | -- Nothing -> case (nodeInfo hpCookieRemoteDhtkey addr) of | ||
413 | -- Right nodeinfo -> cookieRequest crypto netCryptoDHTClient (toPublic hpMySecretKey) nodeinfo | ||
414 | -- Left er -> return Nothing | ||
415 | -- Just c -> return (Just c) | ||
416 | |||
417 | return $ | 410 | return $ |
418 | fmap (\freshCookie' -> | 411 | fmap (\freshCookie' -> |
419 | HandshakeData | 412 | HandshakeData |
@@ -489,9 +482,11 @@ ncToWire getState seqno bufend pktno msg = do | |||
489 | -- then increment it regardless. (Keep addr in MinMaxPSQ in Roster.Contact) | 482 | -- then increment it regardless. (Keep addr in MinMaxPSQ in Roster.Contact) |
490 | -- | 483 | -- |
491 | -- This function sends a handshake response packet. | 484 | -- This function sends a handshake response packet. |
492 | freshCryptoSession :: NetCryptoSessions -> SockAddr -> HandshakeParams -> IO () | 485 | freshCryptoSession :: NetCryptoSessions -> SockAddr -> SecretKey -> POSIXTime -> HandshakeParams -> STM (Maybe (Handshake Encrypted),IO ()) |
493 | freshCryptoSession sessions | 486 | freshCryptoSession sessions |
494 | addr | 487 | addr |
488 | newsession | ||
489 | timestamp | ||
495 | hp@(HParam | 490 | hp@(HParam |
496 | { hpTheirBaseNonce = mbtheirBaseNonce | 491 | { hpTheirBaseNonce = mbtheirBaseNonce |
497 | , hpOtherCookie = otherCookie | 492 | , hpOtherCookie = otherCookie |
@@ -503,20 +498,20 @@ freshCryptoSession sessions | |||
503 | let crypto = transportCrypto sessions | 498 | let crypto = transportCrypto sessions |
504 | allsessions = netCryptoSessions sessions | 499 | allsessions = netCryptoSessions sessions |
505 | allsessionsByKey = netCryptoSessionsByKey sessions | 500 | allsessionsByKey = netCryptoSessionsByKey sessions |
506 | sessionId <- atomically $ do | 501 | dmsg msg = trace msg (return ()) |
502 | sessionId <- do | ||
507 | x <- readTVar (nextSessionId sessions) | 503 | x <- readTVar (nextSessionId sessions) |
508 | modifyTVar (nextSessionId sessions) (+1) | 504 | modifyTVar (nextSessionId sessions) (+1) |
509 | return x | 505 | return x |
510 | -- ncState0 <- atomically $ newTVar Accepted -- (InProgress AwaitingSessionPacket) | 506 | -- ncState0 <- newTVar Accepted -- (InProgress AwaitingSessionPacket) |
511 | ncState0 <- atomically $ newTVar (if isJust mbtheirBaseNonce | 507 | ncState0 <- newTVar (if isJust mbtheirBaseNonce |
512 | then InProgress AwaitingSessionPacket | 508 | then InProgress AwaitingSessionPacket |
513 | else InProgress AwaitingHandshake) | 509 | else InProgress AwaitingHandshake) |
514 | ncTheirBaseNonce0 <- atomically $ newTVar (frmMaybe mbtheirBaseNonce) | 510 | ncTheirBaseNonce0 <- newTVar (frmMaybe mbtheirBaseNonce) |
515 | n24 <- atomically $ transportNewNonce crypto | 511 | n24 <- transportNewNonce crypto |
516 | state <- lookupSharedSecret crypto key remotePublicKey n24 | 512 | state <- ($ n24) <$> lookupNonceFunctionSTM timestamp crypto key remotePublicKey |
517 | newBaseNonce <- atomically $ transportNewNonce crypto | 513 | newBaseNonce <- transportNewNonce crypto |
518 | newsession <- generateSecretKey | 514 | mbMyhandshakeData <- newHandShakeData timestamp crypto newBaseNonce hp addr (toPublic newsession) |
519 | mbMyhandshakeData <- newHandShakeData crypto newBaseNonce hp addr (toPublic newsession) | ||
520 | let encodeHandshake myhandshakeData = let plain = encodePlain myhandshakeData | 515 | let encodeHandshake myhandshakeData = let plain = encodePlain myhandshakeData |
521 | -- state = computeSharedSecret key remoteDhtPublicKey n24 | 516 | -- state = computeSharedSecret key remoteDhtPublicKey n24 |
522 | encrypted = encrypt state plain | 517 | encrypted = encrypt state plain |
@@ -525,16 +520,14 @@ freshCryptoSession sessions | |||
525 | , handshakeData = encrypted | 520 | , handshakeData = encrypted |
526 | } | 521 | } |
527 | let myhandshake= encodeHandshake <$> mbMyhandshakeData | 522 | let myhandshake= encodeHandshake <$> mbMyhandshakeData |
528 | ncHandShake0 <- atomically $ newTVar (frmMaybe myhandshake) | 523 | ncHandShake0 <- newTVar (frmMaybe myhandshake) |
529 | forM myhandshake $ \response_handshake -> do | 524 | ncMyPacketNonce0 <- newTVar newBaseNonce |
530 | sendHandshake sessions addr response_handshake | 525 | cookie0 <- newTVar (HaveCookie otherCookie) |
531 | ncMyPacketNonce0 <- atomically $ newTVar newBaseNonce | 526 | ncHooks0 <- newTVar (defaultHooks sessions) |
532 | cookie0 <- atomically $ newTVar (HaveCookie otherCookie) | 527 | ncUnrecognizedHook0 <- newTVar (defaultUnrecognizedHook sessions) |
533 | ncHooks0 <- atomically $ newTVar (defaultHooks sessions) | 528 | ncIncomingTypeArray0 <- newTVar (msgTypeArray sessions) |
534 | ncUnrecognizedHook0 <- atomically $ newTVar (defaultUnrecognizedHook sessions) | ||
535 | ncIncomingTypeArray0 <- atomically $ newTVar (msgTypeArray sessions) | ||
536 | let idMap = foldl (\mp (x,y) -> W64.insert x y mp) W64.empty (zip [0..255] [0..255]) | 529 | let idMap = foldl (\mp (x,y) -> W64.insert x y mp) W64.empty (zip [0..255] [0..255]) |
537 | (ncOutgoingIdMap0,lossyEscapeIdMap,losslessEscapeIdMap) <- atomically $ do | 530 | (ncOutgoingIdMap0,lossyEscapeIdMap,losslessEscapeIdMap) <- do |
538 | idmap <- emptySTMRangeMap | 531 | idmap <- emptySTMRangeMap |
539 | insertArrayAt idmap 0 (A.listArray (0,255) [0 .. 255]) | 532 | insertArrayAt idmap 0 (A.listArray (0,255) [0 .. 255]) |
540 | -- the 2 escape ranges are adjacent, so put them in one array: | 533 | -- the 2 escape ranges are adjacent, so put them in one array: |
@@ -546,21 +539,21 @@ freshCryptoSession sessions | |||
546 | lossyEsc <- newTVar $ A.listArray (0,255) [0 .. 255] | 539 | lossyEsc <- newTVar $ A.listArray (0,255) [0 .. 255] |
547 | losslessEsc <- newTVar $ A.listArray (0,255) [0 .. 255] | 540 | losslessEsc <- newTVar $ A.listArray (0,255) [0 .. 255] |
548 | return (idmap,lossyEsc,losslessEsc) | 541 | return (idmap,lossyEsc,losslessEsc) |
549 | ncView0 <- atomically $ newTVar (sessionView sessions) | 542 | ncView0 <- newTVar (sessionView sessions) |
550 | pktq <- atomically $ PQ.new (inboundQueueCapacity sessions) 0 | 543 | pktq <- PQ.new (inboundQueueCapacity sessions) 0 |
551 | bufstart <- atomically $ newTVar 0 | 544 | bufstart <- newTVar 0 |
552 | mbpktoq | 545 | mbpktoq |
553 | <- case mbtheirSessionKey of | 546 | <- case mbtheirSessionKey of |
554 | Nothing -> return NeedHandshake | 547 | Nothing -> return NeedHandshake |
555 | Just theirSessionKey -> createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 | 548 | Just theirSessionKey -> createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 |
556 | lastNQ <- atomically (CB.new 10 0 :: STM (CyclicBuffer (Bool,(ViewSnapshot,InOrOut CryptoMessage)))) | 549 | lastNQ <- CB.new 10 0 :: STM (CyclicBuffer (Bool,(ViewSnapshot,InOrOut CryptoMessage))) |
557 | listeners <- atomically $ newTVar IntMap.empty | 550 | listeners <- newTVar IntMap.empty |
558 | msgNum <- atomically $ newTVar 0 | 551 | msgNum <- newTVar 0 |
559 | dropNum <- atomically $ newTVar 0 | 552 | dropNum <- newTVar 0 |
560 | theirbasenonce <- atomically $ readTVar ncTheirBaseNonce0 | 553 | theirbasenonce <- readTVar ncTheirBaseNonce0 |
561 | dput XNetCrypto $ "freshCryptoSession: Session ncTheirBaseNonce=" ++ show theirbasenonce | 554 | dmsg $ "freshCryptoSession: Session ncTheirBaseNonce=" ++ show theirbasenonce |
562 | dput XNetCrypto $ "freshCryptoSession: My Session Public =" ++ show (key2id $ toPublic newsession) | 555 | dmsg $ "freshCryptoSession: My Session Public =" ++ show (key2id $ toPublic newsession) |
563 | ncTheirSessionPublic0 <- atomically $ newTVar (frmMaybe mbtheirSessionKey) | 556 | ncTheirSessionPublic0 <- newTVar (frmMaybe mbtheirSessionKey) |
564 | let netCryptoSession0 = | 557 | let netCryptoSession0 = |
565 | NCrypto { ncState = ncState0 | 558 | NCrypto { ncState = ncState0 |
566 | , ncMyPublicKey = toPublic key | 559 | , ncMyPublicKey = toPublic key |
@@ -590,9 +583,11 @@ freshCryptoSession sessions | |||
590 | , ncListeners = listeners | 583 | , ncListeners = listeners |
591 | } | 584 | } |
592 | addSessionToMapIfNotThere sessions addr netCryptoSession0 | 585 | addSessionToMapIfNotThere sessions addr netCryptoSession0 |
593 | case mbpktoq of | 586 | maybeLaunchMissles |
594 | NeedHandshake -> return () | 587 | <- case mbpktoq of |
595 | HaveHandshake pktoq -> runUponHandshake netCryptoSession0 addr pktoq | 588 | NeedHandshake -> return (return ()) |
589 | HaveHandshake pktoq -> return (runUponHandshake netCryptoSession0 addr pktoq) | ||
590 | return (myhandshake,maybeLaunchMissles) | ||
596 | 591 | ||
597 | type NetCryptoOutQueue = PQ.PacketOutQueue (State,Nonce24,RangeMap TArray Word8 TVar) | 592 | type NetCryptoOutQueue = PQ.PacketOutQueue (State,Nonce24,RangeMap TArray Word8 TVar) |
598 | CryptoMessage | 593 | CryptoMessage |
@@ -600,7 +595,7 @@ type NetCryptoOutQueue = PQ.PacketOutQueue (State,Nonce24,RangeMap TArray Word8 | |||
600 | CryptoData | 595 | CryptoData |
601 | 596 | ||
602 | createNetCryptoOutQueue :: NetCryptoSessions -> SecretKey -> PublicKey -> PacketQueue CryptoData | 597 | createNetCryptoOutQueue :: NetCryptoSessions -> SecretKey -> PublicKey -> PacketQueue CryptoData |
603 | -> TVar Nonce24 -> RangeMap TArray Word8 TVar -> IO (UponHandshake NetCryptoOutQueue) | 598 | -> TVar Nonce24 -> RangeMap TArray Word8 TVar -> STM (UponHandshake NetCryptoOutQueue) |
604 | createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 = do | 599 | createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce0 ncOutgoingIdMap0 = do |
605 | let crypto = transportCrypto sessions | 600 | let crypto = transportCrypto sessions |
606 | let toWireIO = do | 601 | let toWireIO = do |
@@ -613,33 +608,33 @@ createNetCryptoOutQueue sessions newsession theirSessionKey pktq ncMyPacketNonce | |||
613 | ++ "\n toWireIO: my public session key = " ++ show (key2id (toPublic newsession)) | 608 | ++ "\n toWireIO: my public session key = " ++ show (key2id (toPublic newsession)) |
614 | ) $ writeTVar ncMyPacketNonce0 n24plus1 | 609 | ) $ writeTVar ncMyPacketNonce0 n24plus1 |
615 | return (return (f n24, n24, ncOutgoingIdMap0)) | 610 | return (return (f n24, n24, ncOutgoingIdMap0)) |
616 | pktoq <- atomically $ PQ.newOutGoing pktq ncToWire toWireIO 0 (outboundQueueCapacity sessions) 0 | 611 | pktoq <- PQ.newOutGoing pktq ncToWire toWireIO 0 (outboundQueueCapacity sessions) 0 |
617 | return (HaveHandshake pktoq) | 612 | return (HaveHandshake pktoq) |
618 | 613 | ||
619 | -- | add this session to the lookup maps, unless its already in them | 614 | -- | add this session to the lookup maps, unless its already in them |
620 | addSessionToMapIfNotThere :: NetCryptoSessions -> SockAddr -> NetCryptoSession -> IO () | 615 | addSessionToMapIfNotThere :: NetCryptoSessions -> SockAddr -> NetCryptoSession -> STM () |
621 | addSessionToMapIfNotThere sessions addr netCryptoSession = do | 616 | addSessionToMapIfNotThere sessions addr netCryptoSession = do |
622 | dput XNetCrypto $ "addSessionToMapIfNotThere sockaddr = " ++ show addr ++ ", sessionid = " ++ show (ncSessionId netCryptoSession) | 617 | let dmsg msg = trace msg (return ()) |
623 | atomically $ do | 618 | dmsg $ "addSessionToMapIfNotThere sockaddr = " ++ show addr ++ ", sessionid = " ++ show (ncSessionId netCryptoSession) |
624 | let remotePublicKey = ncTheirPublicKey netCryptoSession | 619 | let remotePublicKey = ncTheirPublicKey netCryptoSession |
625 | allsessions = netCryptoSessions sessions | 620 | allsessions = netCryptoSessions sessions |
626 | allsessionsByKey= netCryptoSessionsByKey sessions | 621 | allsessionsByKey= netCryptoSessionsByKey sessions |
627 | byAddrResult <- readTVar allsessions >>= return . Map.lookup addr | 622 | byAddrResult <- readTVar allsessions >>= return . Map.lookup addr |
628 | case byAddrResult of | 623 | case byAddrResult of |
629 | Just (NCrypto { ncSessionId = staleId }) -> do | 624 | Just (NCrypto { ncSessionId = staleId }) -> do |
630 | -- manually remove the stale session from the by-key map | 625 | -- manually remove the stale session from the by-key map |
631 | modifyTVar allsessionsByKey (Map.map (filter ((/=staleId) . ncSessionId))) | 626 | modifyTVar allsessionsByKey (Map.map (filter ((/=staleId) . ncSessionId))) |
632 | Nothing -> return () -- nothing to remove | 627 | Nothing -> return () -- nothing to remove |
633 | -- write session to by-addr map regardless of whether one is in there, | 628 | -- write session to by-addr map regardless of whether one is in there, |
634 | -- it should overwrite on match | 629 | -- it should overwrite on match |
635 | modifyTVar allsessions (Map.insert addr netCryptoSession) | 630 | modifyTVar allsessions (Map.insert addr netCryptoSession) |
636 | -- Now insert new session into by-key map | 631 | -- Now insert new session into by-key map |
637 | byKeyResult <- readTVar allsessionsByKey >>= return . Map.lookup remotePublicKey | 632 | byKeyResult <- readTVar allsessionsByKey >>= return . Map.lookup remotePublicKey |
638 | case byKeyResult of | 633 | case byKeyResult of |
639 | Nothing -> modifyTVar allsessionsByKey (Map.insert remotePublicKey [netCryptoSession]) | 634 | Nothing -> modifyTVar allsessionsByKey (Map.insert remotePublicKey [netCryptoSession]) |
640 | Just xs -> do | 635 | Just xs -> do |
641 | -- in case we're using the same long term key on different IPs ... | 636 | -- in case we're using the same long term key on different IPs ... |
642 | modifyTVar allsessionsByKey (Map.insert remotePublicKey (netCryptoSession:xs)) | 637 | modifyTVar allsessionsByKey (Map.insert remotePublicKey (netCryptoSession:xs)) |
643 | 638 | ||
644 | runUponHandshake :: NetCryptoSession -> SockAddr -> NetCryptoOutQueue -> IO () | 639 | runUponHandshake :: NetCryptoSession -> SockAddr -> NetCryptoOutQueue -> IO () |
645 | runUponHandshake netCryptoSession0 addr pktoq = do | 640 | runUponHandshake netCryptoSession0 addr pktoq = do |
@@ -673,7 +668,7 @@ runUponHandshake netCryptoSession0 addr pktoq = do | |||
673 | -- update session with thread ids | 668 | -- update session with thread ids |
674 | let netCryptoSession = netCryptoSession0 {ncDequeueThread=Just threadid, ncPingMachine=Just pingMachine} | 669 | let netCryptoSession = netCryptoSession0 {ncDequeueThread=Just threadid, ncPingMachine=Just pingMachine} |
675 | -- add this session to the lookup maps | 670 | -- add this session to the lookup maps |
676 | addSessionToMapIfNotThere sessions addr netCryptoSession | 671 | -- atomically $ addSessionToMapIfNotThere sessions addr netCryptoSession |
677 | -- run announceNewSessionHooks | 672 | -- run announceNewSessionHooks |
678 | hooks <- atomically $ readTVar (announceNewSessionHooks sessions) | 673 | hooks <- atomically $ readTVar (announceNewSessionHooks sessions) |
679 | flip fix (hooks,netCryptoSession) $ \loop (hooks,session) -> | 674 | flip fix (hooks,netCryptoSession) $ \loop (hooks,session) -> |
@@ -691,10 +686,12 @@ runUponHandshake netCryptoSession0 addr pktoq = do | |||
691 | -- 2) handshake for new session (old session is lost?) | 686 | -- 2) handshake for new session (old session is lost?) |
692 | 687 | ||
693 | -- 3) we initiated, this a response | 688 | -- 3) we initiated, this a response |
694 | updateCryptoSession :: NetCryptoSessions -> SockAddr -> HandshakeParams -> NetCryptoSession -> Handshake Encrypted -> IO () | 689 | updateCryptoSession :: NetCryptoSessions -> SockAddr -> SecretKey -> POSIXTime -> HandshakeParams |
695 | updateCryptoSession sessions addr hp session handshake = do | 690 | -> NetCryptoSession -> Handshake Encrypted -> STM (Maybe (Handshake Encrypted), IO ()) |
696 | ncState0 <- atomically $ readTVar (ncState session) | 691 | updateCryptoSession sessions addr newsession timestamp hp session handshake = do |
697 | ncTheirBaseNonce0 <- atomically $ readTVar (ncTheirBaseNonce session) | 692 | let dmsg msg = trace msg (return ()) |
693 | ncState0 <- readTVar (ncState session) | ||
694 | ncTheirBaseNonce0 <- readTVar (ncTheirBaseNonce session) | ||
698 | if (ncState0 >= {-Accepted-}InProgress AwaitingSessionPacket) | 695 | if (ncState0 >= {-Accepted-}InProgress AwaitingSessionPacket) |
699 | -- If the nonce in the handshake and the dht key are both the same as | 696 | -- If the nonce in the handshake and the dht key are both the same as |
700 | -- the ones we have saved, assume we already handled this and this is a | 697 | -- the ones we have saved, assume we already handled this and this is a |
@@ -702,42 +699,31 @@ updateCryptoSession sessions addr hp session handshake = do | |||
702 | -- refresh all state. | 699 | -- refresh all state. |
703 | -- | 700 | -- |
704 | then do | 701 | then do |
705 | dput XNetCrypto "updateCryptoSession already accepted.." | 702 | dmsg "updateCryptoSession already accepted.." |
706 | dput XNetCrypto (" ncTheirBaseNonce0=" ++ show ncTheirBaseNonce0 | 703 | dmsg (" ncTheirBaseNonce0=" ++ show ncTheirBaseNonce0 |
707 | ++ bool "(/=)" "(==)" (toMaybe ncTheirBaseNonce0 == hpTheirBaseNonce hp) | 704 | ++ bool "(/=)" "(==)" (toMaybe ncTheirBaseNonce0 == hpTheirBaseNonce hp) |
708 | ++ "hpTheirBaseNonce=" ++ show (hpTheirBaseNonce hp)) | 705 | ++ "hpTheirBaseNonce=" ++ show (hpTheirBaseNonce hp)) |
709 | dput XNetCrypto (" ncTheirDHTKey=" ++ show (ncTheirDHTKey session) | 706 | dmsg (" ncTheirDHTKey=" ++ show (ncTheirDHTKey session) |
710 | ++ bool "{/=}" "{==}" (ncTheirDHTKey session == HaveDHTKey (hpCookieRemoteDhtkey hp)) | 707 | ++ bool "{/=}" "{==}" (ncTheirDHTKey session == HaveDHTKey (hpCookieRemoteDhtkey hp)) |
711 | ++ "hpCookieRemoteDhtkey=" ++ show (hpCookieRemoteDhtkey hp)) | 708 | ++ "hpCookieRemoteDhtkey=" ++ show (hpCookieRemoteDhtkey hp)) |
712 | when ( -- Just ncTheirBaseNonce0 /= hpTheirBaseNonce hp -- XXX: Do we really want to compare base nonce here? | 709 | if ( -- Just ncTheirBaseNonce0 /= hpTheirBaseNonce hp -- XXX: Do we really want to compare base nonce here? |
713 | -- || | 710 | -- || |
714 | ncTheirDHTKey session /= HaveDHTKey (hpCookieRemoteDhtkey hp) | 711 | ncTheirDHTKey session /= HaveDHTKey (hpCookieRemoteDhtkey hp) |
715 | ) $ freshCryptoSession sessions addr hp | 712 | ) |
716 | -- else do | 713 | then freshCryptoSession sessions addr newsession timestamp hp |
717 | -- atomically $ do | 714 | else return (Nothing,return ()) |
718 | -- writeTVar (ncTheirBaseNonce session) (frmMaybe (hpTheirBaseNonce hp)) | ||
719 | -- writeTVar (ncTheirSessionPublic session) (frmMaybe (hpTheirSessionKeyPublic hp)) | ||
720 | -- writeTVar (ncHandShake session) (HaveHandshake handshake) | ||
721 | -- case ncOutgoingQueue session of | ||
722 | -- NeedHandshake -> do | ||
723 | -- case hpTheirSessionKeyPublic hp of | ||
724 | -- Just sessionpubkey -> do | ||
725 | -- pktoq <- createNetCryptoOutQueue sessions (ncSessionSecret session) sessionpubkey | ||
726 | -- (ncPacketQueue session) (ncMyPacketNonce session) (ncOutgoingIdMap session) | ||
727 | -- case pktoq of | ||
728 | -- NeedHandshake -> dput XNetCrypto "Unexpectedly missing ncOutgoingQueue" | ||
729 | -- HaveHandshake pktoq -> runUponHandshake session addr pktoq | ||
730 | -- HaveHandshake pktoq -> runUponHandshake session addr pktoq | ||
731 | else do | 715 | else do |
732 | dput XNetCrypto "updateCryptoSession else clause" | 716 | dmsg "updateCryptoSession else clause" |
733 | dput XNetCrypto (" ncTheirBaseNonce0=" ++ show ncTheirBaseNonce0 | 717 | dmsg (" ncTheirBaseNonce0=" ++ show ncTheirBaseNonce0 |
734 | ++ bool "(/=)" "(==)" (toMaybe ncTheirBaseNonce0 == hpTheirBaseNonce hp) | 718 | ++ bool "(/=)" "(==)" (toMaybe ncTheirBaseNonce0 == hpTheirBaseNonce hp) |
735 | ++ "hpTheirBaseNonce=" ++ show (hpTheirBaseNonce hp)) | 719 | ++ "hpTheirBaseNonce=" ++ show (hpTheirBaseNonce hp)) |
736 | if ( ncTheirBaseNonce0 /= frmMaybe (hpTheirBaseNonce hp)) | 720 | if ( ncTheirBaseNonce0 /= frmMaybe (hpTheirBaseNonce hp)) |
737 | then do | 721 | then do |
738 | dput XNetCrypto "basenonce mismatch, trigger refresh" | 722 | dmsg "basenonce mismatch, trigger refresh" |
739 | freshCryptoSession sessions addr hp -- basenonce mismatch, trigger refresh | 723 | freshCryptoSession sessions addr newsession timestamp hp -- basenonce mismatch, trigger refresh |
740 | else atomically $ writeTVar (ncState session) {-Accepted-}(InProgress AwaitingSessionPacket) | 724 | else do |
725 | writeTVar (ncState session) {-Accepted-}(InProgress AwaitingSessionPacket) | ||
726 | return (Nothing,return ()) | ||
741 | 727 | ||
742 | anyRight :: Monad m => a -> [t] -> (t -> m (Either b b1)) -> m (Either a b1) | 728 | anyRight :: Monad m => a -> [t] -> (t -> m (Either b b1)) -> m (Either a b1) |
743 | anyRight e [] f = return $ Left e | 729 | anyRight e [] f = return $ Left e |
@@ -819,15 +805,25 @@ handshakeH sessions addr hshake@(Handshake (Cookie n24 ecookie) nonce24 encrypte | |||
819 | , hpCookieRemoteDhtkey = remoteDhtPublicKey | 805 | , hpCookieRemoteDhtkey = remoteDhtPublicKey |
820 | }) -> do | 806 | }) -> do |
821 | dput XNetCrypto ("(NetCrypto)handshakeH: hpTheirBaseNonce = " ++ show theirBaseNonce) | 807 | dput XNetCrypto ("(NetCrypto)handshakeH: hpTheirBaseNonce = " ++ show theirBaseNonce) |
822 | sessionsmap <- atomically $ readTVar allsessions | 808 | -- IO action to get a new session key in case we need it in transaction to come |
809 | newsession <- generateSecretKey | ||
823 | -- Do a lookup, so we can handle the update case differently | 810 | -- Do a lookup, so we can handle the update case differently |
824 | case Map.lookup addr sessionsmap of | 811 | let dmsg msg = trace msg (return ()) |
825 | Nothing -> do | 812 | timestamp <- getPOSIXTime |
826 | dput XNetCrypto "sockaddr not in session map, so freshCryptoSession" | 813 | (myhandshake,launchThreads) |
827 | freshCryptoSession sessions addr hp -- create new session | 814 | <- atomically $ do |
828 | Just session -> do | 815 | sessionsmap <- readTVar allsessions |
829 | dput XNetCrypto "sockaddr ALREADY in session map, so updateCryptoSession" | 816 | case Map.lookup addr sessionsmap of |
830 | updateCryptoSession sessions addr hp session hshake -- update existing session | 817 | Nothing -> do |
818 | dmsg "sockaddr not in session map, so freshCryptoSession" | ||
819 | freshCryptoSession sessions addr newsession timestamp hp -- create new session | ||
820 | Just session -> do | ||
821 | dmsg "sockaddr ALREADY in session map, so updateCryptoSession" | ||
822 | updateCryptoSession sessions addr newsession timestamp hp session hshake -- update existing session | ||
823 | launchThreads | ||
824 | forM myhandshake $ \response_handshake -> do | ||
825 | sendHandshake sessions addr response_handshake | ||
826 | return () | ||
831 | return Nothing | 827 | return Nothing |
832 | 828 | ||
833 | sessionPacketH :: NetCryptoSessions -> SockAddr -> CryptoPacket Encrypted -> IO (Maybe (x -> x)) | 829 | sessionPacketH :: NetCryptoSessions -> SockAddr -> CryptoPacket Encrypted -> IO (Maybe (x -> x)) |
diff --git a/src/Network/Tox/DHT/Handlers.hs b/src/Network/Tox/DHT/Handlers.hs index 238fb0d0..dd586430 100644 --- a/src/Network/Tox/DHT/Handlers.hs +++ b/src/Network/Tox/DHT/Handlers.hs | |||
@@ -5,6 +5,7 @@ | |||
5 | {-# LANGUAGE TupleSections #-} | 5 | {-# LANGUAGE TupleSections #-} |
6 | module Network.Tox.DHT.Handlers where | 6 | module Network.Tox.DHT.Handlers where |
7 | 7 | ||
8 | import Debug.Trace | ||
8 | import Network.Tox.DHT.Transport as DHTTransport | 9 | import Network.Tox.DHT.Transport as DHTTransport |
9 | import Network.QueryResponse as QR hiding (Client) | 10 | import Network.QueryResponse as QR hiding (Client) |
10 | import qualified Network.QueryResponse as QR (Client) | 11 | import qualified Network.QueryResponse as QR (Client) |
@@ -234,6 +235,23 @@ createCookie crypto ni remoteUserKey = do | |||
234 | dput XNetCrypto $ "Created cookie with n24 = 0x" ++ show n24 ++ "\n sym=" ++ show sym | 235 | dput XNetCrypto $ "Created cookie with n24 = 0x" ++ show n24 ++ "\n sym=" ++ show sym |
235 | return $ Cookie n24 edta | 236 | return $ Cookie n24 edta |
236 | 237 | ||
238 | createCookieSTM :: POSIXTime -> TransportCrypto -> NodeInfo -> PublicKey -> STM (Cookie Encrypted) | ||
239 | createCookieSTM now crypto ni remoteUserKey = do | ||
240 | let dmsg msg = trace msg (return ()) | ||
241 | (n24,sym) <- do | ||
242 | n24 <- transportNewNonce crypto | ||
243 | sym <- transportSymmetric crypto | ||
244 | return (n24,sym) | ||
245 | let timestamp = round (now * 1000000) | ||
246 | let dta = encodePlain $ CookieData | ||
247 | { cookieTime = timestamp | ||
248 | , longTermKey = remoteUserKey | ||
249 | , dhtKey = transportPublic crypto | ||
250 | } | ||
251 | edta = encryptSymmetric sym n24 dta | ||
252 | dmsg $ "(createCookieSTM) Created cookie with n24 = 0x" ++ show n24 ++ "\n sym=" ++ show sym | ||
253 | return $ Cookie n24 edta | ||
254 | |||
237 | cookieRequestH :: TransportCrypto -> NodeInfo -> CookieRequest -> IO (Cookie Encrypted) | 255 | cookieRequestH :: TransportCrypto -> NodeInfo -> CookieRequest -> IO (Cookie Encrypted) |
238 | cookieRequestH crypto ni (CookieRequest remoteUserKey) = do | 256 | cookieRequestH crypto ni (CookieRequest remoteUserKey) = do |
239 | dput XNetCrypto $ unlines | 257 | dput XNetCrypto $ unlines |