module PrevActivity where import Types import Crypto import Control.Concurrent.STM -- | Remove the prevActivity from a message. Doing this before sending -- it over the wire saves transmitting that data, without weakening -- security at all. removePrevActivityHash :: AnyMessage -> AnyMessage removePrevActivityHash msg = case msg of User (ActivityMessage a) -> User (go a) Developer (ActivityMessage a) -> Developer (go a) _ -> msg where go a = ActivityMessage $ a { prevActivity = Nothing } type RecentActivity = STM (SigVerifier, [Hash]) noRecentActivity :: RecentActivity noRecentActivity = return (mempty, []) -- | Restore the prevActivity to a message received without one. -- This needs a RecentActivity cache, and it tries hashes from that cache -- as the prevActivity until it finds one that makes the message's -- signature verify. restorePrevActivityHash :: RecentActivity -> AnyMessage -> STM AnyMessage restorePrevActivityHash ra msg = case msg of User (ActivityMessage act) -> User . ActivityMessage <$> (go act =<< ra) Developer (ActivityMessage act) -> Developer . ActivityMessage <$> (go act =<< ra) User (ControlMessage {}) -> return msg Developer (ControlMessage {}) -> return msg where go act (_, []) = return act go act (sigverifier, (h:hs)) = do let act' = act { prevActivity = Just h } if verifySigned sigverifier act' then return act' else go act (sigverifier, hs)