diff options
author | joe <joe@jerkface.net> | 2018-05-20 22:17:44 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2018-05-20 22:17:44 -0400 |
commit | 1661192a9c84ceaad6d372bd80820a7066fa1e10 (patch) | |
tree | 940dadd1b7dde155e4ed861cb00ea046f9ea0d3f /src | |
parent | d1ce5a1dad8faca6cab13ca4c2612c1208d52850 (diff) |
Allow non-JID (standard tox hex) input for NoSpamId.
Diffstat (limited to 'src')
-rw-r--r-- | src/Crypto/Tox.hs | 3 | ||||
-rw-r--r-- | src/Network/Tox/NodeId.hs | 16 |
2 files changed, 15 insertions, 4 deletions
diff --git a/src/Crypto/Tox.hs b/src/Crypto/Tox.hs index 8bb822d8..9b7e82c0 100644 --- a/src/Crypto/Tox.hs +++ b/src/Crypto/Tox.hs | |||
@@ -594,12 +594,13 @@ decodeSecret k64 = do | |||
594 | CryptoPassed x -> Just x | 594 | CryptoPassed x -> Just x |
595 | _ -> Nothing | 595 | _ -> Nothing |
596 | 596 | ||
597 | -- Treats byte pairs as big-endian. | ||
597 | xorsum :: ByteArrayAccess ba => ba -> Word16 | 598 | xorsum :: ByteArrayAccess ba => ba -> Word16 |
598 | xorsum bs = unsafeDupablePerformIO $ BA.withByteArray bs $ \ptr16 -> do | 599 | xorsum bs = unsafeDupablePerformIO $ BA.withByteArray bs $ \ptr16 -> do |
599 | let (wcnt,r) = BA.length bs `divMod` 2 | 600 | let (wcnt,r) = BA.length bs `divMod` 2 |
600 | loop cnt !ac = do | 601 | loop cnt !ac = do |
601 | ac' <- xor ac <$> peekElemOff ptr16 cnt | 602 | ac' <- xor ac <$> peekElemOff ptr16 cnt |
602 | case cnt of 0 -> return ac' | 603 | case cnt of 0 -> return $ fromBE16 ac' |
603 | _ -> loop (cnt - 1) ac' | 604 | _ -> loop (cnt - 1) ac' |
604 | loop (wcnt - 1) $ case r of | 605 | loop (wcnt - 1) $ case r of |
605 | 0 -> 0 | 606 | 0 -> 0 |
diff --git a/src/Network/Tox/NodeId.hs b/src/Network/Tox/NodeId.hs index b12487a4..2f3a2bb1 100644 --- a/src/Network/Tox/NodeId.hs +++ b/src/Network/Tox/NodeId.hs | |||
@@ -493,6 +493,7 @@ instance OnionPacket 3 where mkOnion = OnionResponse3 | |||
493 | data NoSpam = NoSpam !Word32 !(Maybe Word16) | 493 | data NoSpam = NoSpam !Word32 !(Maybe Word16) |
494 | deriving (Eq,Ord,Show) | 494 | deriving (Eq,Ord,Show) |
495 | 495 | ||
496 | -- Utilizes Data.Serialize format for Word32 nospam and Word16 checksum. | ||
496 | instance Read NoSpam where | 497 | instance Read NoSpam where |
497 | readsPrec d s = case break isSpace s of | 498 | readsPrec d s = case break isSpace s of |
498 | ('$':ws ,rs) | (length ws == 8) -> base64decode rs (NoSpam <$> get <*> (Just <$> get)) ws | 499 | ('$':ws ,rs) | (length ws == 8) -> base64decode rs (NoSpam <$> get <*> (Just <$> get)) ws |
@@ -535,16 +536,25 @@ instance Read NoSpamId where | |||
535 | nsid <- parseNoSpamId $ Text.pack jid | 536 | nsid <- parseNoSpamId $ Text.pack jid |
536 | return [(nsid,xs)] | 537 | return [(nsid,xs)] |
537 | 538 | ||
539 | parseNoSpamHex hex = Right $ NoSpamId (read $ "0x"++nospamsum) (id2key $ read hkey) | ||
540 | where | ||
541 | (hkey,nospamsum) = splitAt 64 $ Text.unpack hex | ||
542 | |||
538 | parseNoSpamId :: Text -> Either String NoSpamId | 543 | parseNoSpamId :: Text -> Either String NoSpamId |
539 | parseNoSpamId jid = do | 544 | parseNoSpamId spec | Text.length spec == 76 |
545 | , Text.all isHexDigit spec = parseNoSpamHex spec | ||
546 | | otherwise = parseNoSpamJID spec | ||
547 | |||
548 | parseNoSpamJID :: Text -> Either String NoSpamId | ||
549 | parseNoSpamJID jid = do | ||
540 | (Just u,h,_) <- Right $ splitJID jid | 550 | (Just u,h,_) <- Right $ splitJID jid |
541 | (base64,".tox") <- Right $ splitAt 43 $ Text.unpack h | 551 | (base64,".tox") <- Right $ splitAt 43 $ Text.unpack h |
542 | pub <- id2key <$> readEither base64 | 552 | pub <- id2key <$> readEither base64 |
543 | let ustr = Text.unpack u | 553 | let ustr = Text.unpack u |
544 | '$' : b64digits <- Right ustr -- TODO: support 0x prefix also. | 554 | '$' : b64digits <- Right ustr -- TODO: support 0x prefix also. |
545 | NoSpam nospam (Just x) <- readEither $ map (\case; '?' -> '0'; c -> c) ustr | 555 | NoSpam nospam (Just x) <- readEither $ map (\case; '?' -> '0'; c -> c) ustr |
546 | let nlo = fromIntegral nospam :: Word16 | 556 | let nlo = fromIntegral (0x0FFFF .&. nospam) :: Word16 |
547 | nhi = fromIntegral (nospam `shiftR` 16) :: Word16 | 557 | nhi = fromIntegral (0x0FFFF .&. (nospam `shiftR` 16)) :: Word16 |
548 | sum = x `xor` nlo `xor` nhi `xor` xorsum pub | 558 | sum = x `xor` nlo `xor` nhi `xor` xorsum pub |
549 | -- Find any question mark indices. | 559 | -- Find any question mark indices. |
550 | qs = catMaybes $ zipWith (\case; '?' -> Just ; _ -> const Nothing) b64digits [0..7] | 560 | qs = catMaybes $ zipWith (\case; '?' -> Just ; _ -> const Nothing) b64digits [0..7] |