{- Copyright 2017 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} module PrevActivity where import Types import Crypto import Control.Concurrent.STM -- | Remove the hashes from a message. Doing this before sending -- it over the wire saves transmitting that data, without weakening -- security at all. removeHashes :: AnyMessage -> MissingHashes AnyMessage removeHashes msg = MissingHashes $ case msg of User (ActivityMessage a) -> User (go a) Developer (ActivityMessage a) -> Developer (go a) _ -> msg where go a = ActivityMessage $ a { prevActivity = Nothing , prevEntered = Nothing } type RecentActivity = STM (SigVerifier, [Hash]) -- | Restore the hashes to a message received. -- This needs a RecentActivity cache, and it tries hashes from that cache -- to find the one that was used when the message was sent, at which -- point the message's signature will verify. restoreHashes :: RecentActivity -> MissingHashes AnyMessage -> STM AnyMessage restoreHashes ra (MissingHashes msg) = case msg of User (ActivityMessage act) -> User . ActivityMessage <$> find act Developer (ActivityMessage act) -> Developer . ActivityMessage <$> find act User (ControlMessage {}) -> return msg Developer (ControlMessage {}) -> return msg where find act = do (sigverifier, l) <- ra let l' = Nothing : map Just l let ll = do ah <- l' eh <- l' return $ act { prevActivity = ah , prevEntered = eh } go act sigverifier ll go act _ [] = return act go act sigverifier (l:ls) = do if verifySigned sigverifier l then return l else go act sigverifier ls