File: runtests.hs

package info (click to toggle)
haskell-clientsession 0.9.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 96 kB
  • sloc: haskell: 305; makefile: 5
file content (103 lines) | stat: -rw-r--r-- 3,688 bytes parent folder | download | duplicates (5)
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
import Test.HUnit (assertBool)
import Test.Hspec
import Test.QuickCheck
import Control.Monad (replicateM)

import qualified Data.ByteString as S
import qualified Data.ByteString.Char8 as S8

import Web.ClientSession
import System.IO.Unsafe

import qualified Data.Set as Set
import Control.Monad.Trans.State.Strict (evalStateT, get, put)
import Control.Monad.Trans.Class (lift)
import Control.Monad (replicateM_)

import Data.Serialize (encode, decode)

main :: IO ()
main = hspec $ describe "client session" $ do
    it "encrypt/decrypt success" $ property propEncDec
    it "encrypt/decrypt success (environment key)" $ property propEncDecEnv
    it "encrypt/decrypt failure" $ property propEncDecFailure
    it "AES encrypt/decrypt success" $ property propAES
    it "AES encryption changes bs" $ property propAESChanges
    it "specific values" caseSpecific
    it "randomIV is really random" caseRandomIV
    it "serialize instance" $ property propSerialize

propEncDec :: S.ByteString -> Bool
propEncDec bs = unsafePerformIO $ do
    key <- getDefaultKey
    s <- encryptIO key bs
    let bs' = decrypt key s
    return $ Just bs == bs'

propEncDecEnv :: S.ByteString -> Bool
propEncDecEnv bs = unsafePerformIO $ do
    key <- getKeyEnv "SESSION_KEY"
    s <- encryptIO key bs
    let bs' = decrypt key s
    return $ Just bs == bs'

propEncDecFailure :: S.ByteString -> Bool
propEncDecFailure bs = unsafePerformIO $ do
    key <- getDefaultKey
    s <- encryptIO key bs
    let bs' = decrypt key $ (S.head s + 1) `S.cons` S.drop 1 s
    return $ Just bs /= bs'

propAES :: MyKey -> MyIV -> S.ByteString -> Bool
propAES (MyKey key) (MyIV iv) bs = decrypt key (encrypt key iv bs) == Just bs

propAESChanges :: MyKey -> MyIV -> S.ByteString -> Bool
propAESChanges (MyKey key) (MyIV iv) bs = encrypt key iv bs /= bs

caseSpecific :: Expectation
caseSpecific = do
    let s = S8.pack $ show [("lo\ENQ\143XAq","\DC2\207\226\DC1;.z56|\203\222"),("\USnu#\139\ETXB\201 ","l"),("\RS\b,zM2U\184\191F)\EOT\220S\NUL","O\\\GSd\247\246\n\EOT\SYN\182U2G"),("\219\NAK\217\CAN\252","ym\STX\188\232?\\\145"),("\239k","\vRZP\a\DC2F>"),("\FS\180P &\RS\174zSL\\?@","p\170\237vZ|\GS>\SYNk\176n\r"),("","\199D\DC3\200m)"),("6\152tVhB\246)9","\ENQdfU\SUB"),("I\ACK\181\NUL","\129\&6s\130q\US)oR1\197\FSp\US\SYN0"),("\183\200<\250","\211  \131g4\207N\155"),("\248O6k\CANK\135\234.","`\205!+&Z&9\DLE\244\214HP\SI\161"),("\"I'\ACK\149 \CAN\197","\141N\201\SO\204\\o.\128\148")]
    key <- getDefaultKey
    iv <- randomIV
    decrypt key (encrypt key iv s) `shouldBe` Just s
    let s' = S.concat $ replicate 500 s
    decrypt key (encrypt key iv s') `shouldBe` Just s'

caseRandomIV :: Expectation
caseRandomIV = do
    evalStateT (replicateM_ 10000 go) Set.empty
  where
    go = do
        val <- lift randomIV
        set <- get
        lift $ assertBool "No duplicated keys" (not $ val `Set.member` set)
        put $ Set.insert val set

propSerialize :: MyKey -> Bool
propSerialize (MyKey key) = Right key == decode (encode key)

instance Arbitrary S.ByteString where
    arbitrary = S.pack `fmap` arbitrary

newtype MyKey = MyKey Key

instance Arbitrary MyKey where
    arbitrary = do
        ws <- replicateM 96 arbitrary
        either error (return . MyKey) $ initKey $ S.pack ws

instance Show MyKey where
    show (MyKey key) = "MyKey:" ++ show (encode key)

newtype MyIV = MyIV IV

instance Arbitrary MyIV where
    arbitrary = do
        ws <- replicateM 16 arbitrary
        maybe (error "Invalid IV") (return . MyIV) $ mkIV $ S.pack ws

instance Show MyIV where
    show _ = "<Iv>"