File: Tests.hs

package info (click to toggle)
haskell-cryptostore 0.3.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 964 kB
  • sloc: haskell: 8,241; makefile: 3
file content (120 lines) | stat: -rw-r--r-- 4,428 bytes parent folder | download
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
-- | PKCS #8 tests.
module PKCS8.Tests (pkcs8Tests) where

import qualified Data.ByteString as B
import           Data.String (fromString)

import Crypto.Store.PKCS8

import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck

import Util
import PKCS8.Instances ()

data KeyTestType = InnerOuter | OnlyOuter

keyTests :: KeyTestType -> String -> TestTree
keyTests InnerOuter prefix =
    testGroup "PrivateKey"
        [ testCase "read outer" $ do
              kOuter <- readKeyFile fOuter
              length kOuter @?= 1
        , testCase "read inner" $ do
              kInner <- readKeyFile fInner
              length kInner @?= 1
        , testCase "same key"   $ do
              kInner <- readKeyFile fInner
              kOuter <- readKeyFile fOuter
              assertBool "keys differ" $
                  let [Unprotected kI] = kInner
                      [Unprotected kO] = kOuter
                   in kI == kO
        , testCase "write outer" $ do
              bs <- B.readFile fOuter
              let kOuter = readKeyFileFromMemory bs
                  [Unprotected kO] = kOuter
              writeKeyFileToMemory PKCS8Format [kO] @?= bs
        , testCase "write inner" $ do
              bs <- B.readFile fInner
              let kInner = readKeyFileFromMemory bs
                  [Unprotected kI] = kInner
              writeKeyFileToMemory TraditionalFormat [kI] @?= bs
        ]
  where
    fInner = testFile (prefix ++ "-unencrypted-trad.pem")
    fOuter = testFile (prefix ++ "-unencrypted-pkcs8.pem")
keyTests OnlyOuter prefix =
    testGroup "PrivateKey"
        [ testCase "read" $ do
              kOuter <- readKeyFile fOuter
              length kOuter @?= 1
        , testCase "write" $ do
              bs <- B.readFile fOuter
              let kOuter = readKeyFileFromMemory bs
                  [Unprotected kO] = kOuter
              writeKeyFileToMemory PKCS8Format [kO] @?= bs
        ]
  where
    fOuter = testFile (prefix ++ "-unencrypted-pkcs8.pem")

encryptedKeyTests :: String -> TestTree
encryptedKeyTests prefix =
    testGroup "EncryptedPrivateKey"
        [ keyTest "PBES1"  "pbes1"  8
        , keyTest "PBKDF2" "pbkdf2" 7
        , keyTest "Scrypt" "scrypt" 3
        ]
  where
    pwd = fromString "dontchangeme"

    keyTest name suffix count =
        let fE = testFile (prefix ++ "-encrypted-" ++ suffix ++ ".pem")
            fU = testFile (prefix ++ "-unencrypted-pkcs8.pem")
         in testGroup name
                [ testCase "read unencrypted" $ do
                      kU <- readKeyFile fU
                      length kU @?= 1
                , testCase "read encrypted"   $ do
                      kE <- readKeyFile fE
                      length kE @?= count
                , testCase "same keys"        $ do
                      kE <- readKeyFile fE
                      kU <- readKeyFile fU
                      assertBool "some keys differ" $
                          let [Unprotected key] = kU
                           in all (\(Protected getKey) -> getKey pwd == Right key) kE
                ]

testType :: TestName -> KeyTestType -> String -> TestTree
testType name ty prefix =
    testGroup name
        [ keyTests ty prefix
        , encryptedKeyTests prefix
        ]

propertyTests :: TestTree
propertyTests = localOption (QuickCheckMaxSize 5) $ testGroup "properties"
    [ testProperty "marshalling" $ \fmt l ->
        let r = readKeyFileFromMemory $ writeKeyFileToMemory fmt l
        in map Right l === map (recover $ fromString "not-used") r
    , testProperty "marshalling with encryption" $ \es k -> do
        p <- arbitrary
        let r = readKeyFileFromMemory <$> writeEncryptedKeyFileToMemory es p k
        return $ Right [Right k] === (map (recover p) <$> r)
    ]

pkcs8Tests :: TestTree
pkcs8Tests =
    testGroup "PKCS8"
        [ testType "RSA"                        InnerOuter  "rsa"
        , testType "DSA"                        InnerOuter  "dsa"
        , testType "EC (named curve)"           InnerOuter  "ecdsa-p256"
        , testType "EC (explicit prime curve)"  InnerOuter  "ecdsa-epc"
        , testType "X25519"                     OnlyOuter   "x25519"
        , testType "X448"                       OnlyOuter   "x448"
        , testType "Ed25519"                    OnlyOuter   "ed25519"
        , testType "Ed448"                      OnlyOuter   "ed448"
        , propertyTests
        ]