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 } 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 <$> (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)