blob: 8ddbedfcf684eb4824127ae84ce875ede546be7f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
module Sproxy.Application.State (
decode
, encode
) where
import Data.ByteString (ByteString)
import Data.ByteString.Lazy (fromStrict, toStrict)
import Data.Digest.Pure.SHA (hmacSha1, bytestringDigest)
import Foreign.C.Types (CTime(..))
import System.Posix.Time (epochTime)
import qualified Data.ByteString.Base64 as Base64
import qualified Data.Serialize as DS
-- FIXME: Compress / decompress ?
encode :: ByteString -> Int -> ByteString -> IO (ByteString, CTime)
encode key shelflife payload = do
now <- epochTime
let expiry = now + (CTime . fromIntegral $ shelflife)
d = DS.encode (payload, (\(CTime i64) -> i64) expiry)
return (Base64.encode . DS.encode $ (d, digest key d), expiry)
decode :: ByteString -> ByteString -> IO (Either String ByteString)
decode key raw = do
(CTime now) <- epochTime
return $ do
(d, dgst) <- DS.decode =<< Base64.decode raw
if dgst /= digest key d then Left "junk"
else do
(payload, expiry) <- DS.decode d
if expiry < now then Left "expired"
else Right payload
digest :: ByteString -> ByteString -> ByteString
digest key payload = toStrict . bytestringDigest $ hmacSha1 (fromStrict key) (fromStrict payload)
|