summaryrefslogtreecommitdiff
path: root/src/Network/DatagramServer
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-07-10 20:30:10 -0400
committerjoe <joe@jerkface.net>2017-07-10 20:30:10 -0400
commit2fdb0342f8cfcaf4924a0ce43e7fccb236eb0d5e (patch)
treefe013b9d665d6a6c03f6a35af017851f105115c0 /src/Network/DatagramServer
parentc565ec07f37006a5abb7b3bc5a1b08013fbeb5d7 (diff)
Fixed Tox decryption.
Diffstat (limited to 'src/Network/DatagramServer')
-rw-r--r--src/Network/DatagramServer/Tox.hs125
1 files changed, 112 insertions, 13 deletions
diff --git a/src/Network/DatagramServer/Tox.hs b/src/Network/DatagramServer/Tox.hs
index 5003f3a4..9d60d066 100644
--- a/src/Network/DatagramServer/Tox.hs
+++ b/src/Network/DatagramServer/Tox.hs
@@ -51,6 +51,10 @@ import Text.PrettyPrint.HughesPJClass hiding (($$), (<>))
51import qualified Data.ByteArray as BA 51import qualified Data.ByteArray as BA
52import Data.ByteArray ( Bytes, convert ) 52import Data.ByteArray ( Bytes, convert )
53import Data.Monoid 53import Data.Monoid
54import System.Endian
55import qualified Data.ByteString.Base16 as Base16
56import qualified Data.ByteString.Char8 as C8
57import qualified Data.ByteString.Char8 as C8
54 58
55 59
56type Key32 = Word256 -- 32 byte key 60type Key32 = Word256 -- 32 byte key
@@ -119,9 +123,14 @@ data Message a = Message
119 , msgNonce :: TransactionID Message 123 , msgNonce :: TransactionID Message
120 , msgPayload :: a 124 , msgPayload :: a
121 } 125 }
122 deriving (Show, Generic, Functor, Foldable, Traversable) 126 deriving (Eq, Show, Generic, Functor, Foldable, Traversable)
123 127
124deriving instance Show (NodeId Message) -- TODO: print as hex 128instance Show (NodeId Message) where
129 showsPrec d pubkey s =
130 "NodeId \"" ++ C8.unpack (Base16.encode $ convert pubkey) ++ '"':s
131
132instance Show (TransactionID Message) where
133 showsPrec d nonce = mappend "TID " . quoted (mappend $ bin2hex nonce)
125 134
126isQuery :: Message a -> Bool 135isQuery :: Message a -> Bool
127isQuery (Message { msgType = SendNodes }) = False 136isQuery (Message { msgType = SendNodes }) = False
@@ -231,13 +240,26 @@ data ToxCipherContext = ToxCipherContext
231 240
232data Ciphered = Ciphered { cipheredMAC :: Poly1305.Auth 241data Ciphered = Ciphered { cipheredMAC :: Poly1305.Auth
233 , cipheredBytes :: ByteString } 242 , cipheredBytes :: ByteString }
243 deriving Eq
244
245quoted shows s = '"':shows ('"':s)
246
247bin2hex :: ByteArrayAccess bs => bs -> String
248bin2hex = C8.unpack . Base16.encode . convert
249
250instance Show Ciphered where
251 showsPrec d (Ciphered (Poly1305.Auth mac) bytes) =
252 mappend "Ciphered (Auth "
253 . quoted (mappend $ bin2hex mac)
254 . (") " ++)
255 . quoted (mappend $ bin2hex bytes)
234 256
235getMessage :: Get (Message Ciphered) 257getMessage :: Get (Message Ciphered)
236getMessage = do 258getMessage = do
237 typ <- get 259 typ <- get
238 nid <- get 260 nid <- get
239 tid <- get 261 tid <- get
240 mac <- Poly1305.Auth . convert <$> getBytes 2 262 mac <- Poly1305.Auth . convert <$> getBytes 16
241 cnt <- remaining 263 cnt <- remaining
242 bs <- getBytes cnt 264 bs <- getBytes cnt
243 return Message { msgType = typ 265 return Message { msgType = typ
@@ -254,11 +276,19 @@ putMessage (Message {..}) = do
254 putByteString (convert mac) 276 putByteString (convert mac)
255 putByteString bs 277 putByteString bs
256 278
279-- XXX: assumes ByteArray is little-endian
257id2key :: NodeId Message -> PublicKey 280id2key :: NodeId Message -> PublicKey
258id2key recipient = case publicKey recipient of 281id2key recipient = case publicKey recipient of
259 CryptoPassed key -> key 282 CryptoPassed key -> key
260 CryptoFailed e -> error ("id2key: "++show e) 283 CryptoFailed e -> error ("id2key: "++show e)
261 284
285-- XXX: S.decode is Big-endian
286-- TODO: implement ByteArray instance, avoid S.decode
287key2id :: PublicKey -> NodeId Message
288key2id pk = case S.decode (BA.convert pk) of
289 Left _ -> error "key2id"
290 Right nid -> nid
291
262 292
263zeros32 :: Bytes 293zeros32 :: Bytes
264zeros32 = BA.replicate 32 0 294zeros32 = BA.replicate 32 0
@@ -305,6 +335,11 @@ encipherAndHash hash crypt m = Ciphered a c
305 335
306decipherAndAuth :: Poly1305.State -> XSalsa.State -> Ciphered -> Either String ByteString 336decipherAndAuth :: Poly1305.State -> XSalsa.State -> Ciphered -> Either String ByteString
307decipherAndAuth hash crypt (Ciphered mac c) 337decipherAndAuth hash crypt (Ciphered mac c)
338 {-
339 | C8.length m /= C8.length c = Left $ "Unequal lengths: "++show (C8.length m, C8.length c)
340 -- | C8.length c /= 40 = Left $ "Unexpected c length: " ++ show (C8.length c, bin2hex c)
341 | otherwise = Right m
342 -}
308 | (a == mac) = Right m 343 | (a == mac) = Right m
309 | otherwise = Left "decipherAndAuth: auth fail" 344 | otherwise = Left "decipherAndAuth: auth fail"
310 where 345 where
@@ -340,14 +375,16 @@ curve25519 = CurveFP (CurvePrime prime curvecommon)
340 375
341instance Envelope Message where 376instance Envelope Message where
342 newtype TransactionID Message = TID Nonce24 377 newtype TransactionID Message = TID Nonce24
343 deriving (Eq,Ord,Show,Serialize) -- Read 378 deriving (Eq,Ord) -- Read
344 379
345 newtype NodeId Message = NodeId Word256 380 newtype NodeId Message = NodeId Word256
346 deriving (Serialize, Eq, Ord, Bits, FiniteBits) 381 deriving (Eq, Ord, Bits, FiniteBits)
347 382
348 type QueryMethod Message = MessageType 383 type QueryMethod Message = MessageType
349 384
350 newtype QueryExtra Message = QueryNonce { qryNonce :: Nonce8 } 385 newtype QueryExtra Message = QueryNonce { qryNonce :: Nonce8 }
386 deriving (Eq, Ord, Show)
387
351 newtype ResponseExtra Message = ResponseNonce { rspNonce :: Nonce8 } 388 newtype ResponseExtra Message = ResponseNonce { rspNonce :: Nonce8 }
352 389
353 data PacketDestination Message = ToxAddr { toxID :: NodeId Message 390 data PacketDestination Message = ToxAddr { toxID :: NodeId Message
@@ -381,23 +418,83 @@ instance Envelope Message where
381 $ S.decode $ Char8.pack (take 24 $ show cnt ++ repeat ' ') 418 $ S.decode $ Char8.pack (take 24 $ show cnt ++ repeat ' ')
382 419
383 420
421{-
422instance Serialize (TransactionID Message) where
423 get = do
424 lo <- getWord64le
425 mid <- getWord64le
426 hi <- getWord64le
427 return $ TID (LargeKey lo
428 (LargeKey mid hi))
429
430 put (TID (LargeKey lo (LargeKey mid hi))) = do
431 putWord64le lo
432 putWord64le mid
433 putWord64le hi
434
435instance Serialize (NodeId Message) where
436 get = do
437 lo <- getWord64le
438 mid <- getWord64le
439 hi <- getWord64le
440 highest <- getWord64le
441 return $ NodeId (LargeKey lo
442 (LargeKey mid
443 (LargeKey hi highest)))
444 put (NodeId (LargeKey lo (LargeKey mid (LargeKey hi highest)))) = do
445 putWord64le lo
446 putWord64le mid
447 putWord64le hi
448 putWord64le highest
449
450-}
451
452instance Serialize (TransactionID Message) where
453 get = do
454 hi <- getWord64be
455 mid <- getWord64be
456 lo <- getWord64be
457 return $ TID (LargeKey lo
458 (LargeKey mid hi))
459
460 put (TID (LargeKey lo (LargeKey mid hi))) = do
461 putWord64be hi
462 putWord64be mid
463 putWord64be lo
464
465instance Serialize (NodeId Message) where
466 get = do
467 highest <- getWord64be
468 hi <- getWord64be
469 mid <- getWord64be
470 lo <- getWord64be
471 return $ NodeId (LargeKey lo
472 (LargeKey mid
473 (LargeKey hi highest)))
474 put (NodeId (LargeKey lo (LargeKey mid (LargeKey hi highest)))) = do
475 putWord64be highest
476 putWord64be hi
477 putWord64be mid
478 putWord64be lo
479
480
384staticAssert isLittleEndian -- assumed by 'withWord64Ptr' 481staticAssert isLittleEndian -- assumed by 'withWord64Ptr'
385 482
386with3Word64Ptr :: Nonce24 -> (Ptr Word64 -> IO a) -> IO a 483with3Word64Ptr :: Nonce24 -> (Ptr Word64 -> IO a) -> IO a
387with3Word64Ptr (LargeKey wlo (LargeKey wmid whi)) kont = 484with3Word64Ptr (LargeKey wlo (LargeKey wmid whi)) kont =
388 allocaBytes (sizeOf wlo * 3) $ \p -> do 485 allocaBytes (sizeOf wlo * 3) $ \p -> do
389 pokeElemOff p 0 wlo 486 pokeElemOff p 2 $ toBE64 wlo
390 pokeElemOff p 1 wmid 487 pokeElemOff p 1 $ toBE64 wmid
391 pokeElemOff p 2 whi 488 pokeElemOff p 0 $ toBE64 whi
392 kont p 489 kont p
393 490
394with4Word64Ptr :: Key32 -> (Ptr Word64 -> IO a) -> IO a 491with4Word64Ptr :: Key32 -> (Ptr Word64 -> IO a) -> IO a
395with4Word64Ptr (LargeKey wlo (LargeKey wmid (LargeKey whi whighest))) kont = 492with4Word64Ptr (LargeKey wlo (LargeKey wmid (LargeKey whi whighest))) kont =
396 allocaBytes (sizeOf wlo * 4) $ \p -> do 493 allocaBytes (sizeOf wlo * 4) $ \p -> do
397 pokeElemOff p 0 wlo 494 pokeElemOff p 3 $ toBE64 wlo
398 pokeElemOff p 1 wmid 495 pokeElemOff p 2 $ toBE64 wmid
399 pokeElemOff p 2 whi 496 pokeElemOff p 1 $ toBE64 whi
400 pokeElemOff p 3 whighest 497 pokeElemOff p 0 $ toBE64 whighest
401 kont p 498 kont p
402 499
403 500
@@ -440,13 +537,15 @@ instance WireFormat ByteString Message where
440 537
441 initializeServerState _ _ = do 538 initializeServerState _ _ = do
442 k <- generateSecretKey 539 k <- generateSecretKey
540 {-
443 nid <- withByteArray (toPublic k) $ \p -> do 541 nid <- withByteArray (toPublic k) $ \p -> do
444 wlo <- peekElemOff p 0 542 wlo <- peekElemOff p 0
445 wmid <- peekElemOff p 1 543 wmid <- peekElemOff p 1
446 whi <- peekElemOff p 2 544 whi <- peekElemOff p 2
447 whigest <- peekElemOff p 3 545 whigest <- peekElemOff p 3
448 return $ LargeKey wlo (LargeKey wmid (LargeKey whi whigest)) 546 return $ LargeKey wlo (LargeKey wmid (LargeKey whi whigest))
449 return (NodeId nid, ToxCipherContext k) 547 -}
548 return (key2id $ toPublic k, ToxCipherContext k)
450 549
451 550
452instance Read (NodeId Message) where readsPrec d s = map (\(w,xs) -> (NodeId w, xs)) $ decodeHex s 551instance Read (NodeId Message) where readsPrec d s = map (\(w,xs) -> (NodeId w, xs)) $ decodeHex s