diff options
Diffstat (limited to 'PrevActivity.hs')
-rw-r--r-- | PrevActivity.hs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/PrevActivity.hs b/PrevActivity.hs new file mode 100644 index 0000000..32e647d --- /dev/null +++ b/PrevActivity.hs @@ -0,0 +1,43 @@ +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) |