-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathKeyTest.hs
More file actions
208 lines (182 loc) · 8.02 KB
/
Copy pathKeyTest.hs
File metadata and controls
208 lines (182 loc) · 8.02 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
{-# LANGUAGE OverloadedStrings #-}
module KeyTest (tests, cbTests) where
import qualified Data.ByteString as BS
import Data.Maybe
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (testCase)
import Test.HUnit
import System.FilePath ((</>))
import System.Directory (removeDirectoryRecursive)
import Crypto.Gpgme
import TestUtil
tests :: [TestTree]
tests = [ testCase "getAlicePubFromAlice" getAlicePubFromAlice
, testCase "getBobPubFromAlice" getBobPubFromAlice
, testCase "aliceListPubKeys" aliceListPubKeys
, testCase "aliceListSecretKeys" aliceListSecretKeys
, testCase "aliceSearchPubKeys" aliceSearchPubKeys
, testCase "getInexistentFromAlice" getInexistentPubFromAlice
, testCase "checkAlicePubUserIds" checkAlicePubUserIds
, testCase "checkAlicePubSubkeys" checkAlicePubSubkeys
, testCase "removeAliceKey" removeAliceKey
, testCase "readFromFileWorks" readFromFileWorks
, testCase "readFromFileDoesn'tExist" readFromFileDoesn'tExist
, testCase "readFromBytesWorks" readFromBytesWorks
, testCase "exportAlicePubArmored" exportAlicePubArmored
, testCase "exportImportRoundtrip" exportImportRoundtrip
, testCase "exportInexistentIsEmpty" exportInexistentIsEmpty
, testCase "exportAllKeys" exportAllKeys
, testCase "exportMinimal" exportMinimal
]
cbTests :: IO TestTree
cbTests = do
supported <- withCtx "test/alice" "C" OpenPGP $ \ctx ->
return $ isPassphraseCbSupported ctx
if supported
then return $ testGroup "key-passphrase-cb"
[ testCase "exportAliceSecretArmored" exportAliceSecretArmored ]
else return $ testGroup "key-passphrase-cb" []
getAlicePubFromAlice :: Assertion
getAlicePubFromAlice = do
withCtx "test/alice" "C" OpenPGP $ \ctx ->
do key <- getKey ctx alicePubFpr NoSecret
isJust key @? "missing " ++ show alicePubFpr
getBobPubFromAlice :: Assertion
getBobPubFromAlice = do
withCtx "test/alice/" "C" OpenPGP $ \ctx ->
do key <- getKey ctx bobPubFpr NoSecret
isJust key @? "missing " ++ show bobPubFpr
aliceListPubKeys :: Assertion
aliceListPubKeys = do
withCtx "test/alice" "C" OpenPGP $ \ctx ->
do keys <- listKeys ctx NoSecret
length keys @?= 2
let keyIds = [["163EC68CCF3FBF8E","DD2469546C4FB8F2"],
["6B9809775CF91391","3BA69AA2EAACEB8A"]]
map (map subkeyKeyId . keySubKeys) keys @?= keyIds
aliceListSecretKeys :: Assertion
aliceListSecretKeys = do
withCtx "test/alice" "C" OpenPGP $ \ctx ->
do keys <- listKeys ctx WithSecret
length keys @?= 1
aliceSearchPubKeys :: Assertion
aliceSearchPubKeys = do
withCtx "test/alice" "C" OpenPGP $ \ctx ->
do keys <- searchKeys ctx NoSecret "alice@email.com"
length keys @?= 1
let keyIds = [["6B9809775CF91391","3BA69AA2EAACEB8A"]]
map (map subkeyKeyId . keySubKeys) keys @?= keyIds
getInexistentPubFromAlice :: Assertion
getInexistentPubFromAlice = do
let inexistentFpr = "ABCDEF"
withCtx "test/alice/" "C" OpenPGP $ \ctx ->
do key <- getKey ctx inexistentFpr NoSecret
isNothing key @? "existing " ++ show inexistentFpr
checkAlicePubUserIds :: Assertion
checkAlicePubUserIds = do
withCtx "test/alice" "C" OpenPGP $ \ctx ->
do Just key <- getKey ctx alicePubFpr NoSecret
case keyUserIds key of
[kuid] -> do
let uid = keyuserId kuid
keyuserValidity kuid @?= ValidityUltimate
userId uid @?= "Alice (Test User A) <alice@email.com>"
userName uid @?= "Alice"
userEmail uid @?= "alice@email.com"
userComment uid @?= "Test User A"
uids -> assertFailure $
"expected exactly one user id, got " ++ show (length uids)
checkAlicePubSubkeys :: Assertion
checkAlicePubSubkeys = do
withCtx "test/alice" "C" OpenPGP $ \ctx ->
do Just key <- getKey ctx alicePubFpr NoSecret
case keySubKeys key of
[sub, _] -> do
subkeyAlgorithm sub @?= Rsa
subkeyLength sub @?= 2048
subkeyKeyId sub @?= "6B9809775CF91391"
subkeyFpr sub @?= "3F10159E56ECB494ED42EFA36B9809775CF91391"
subs -> assertFailure $
"expected exactly two subkeys, got " ++ show (length subs)
removeAliceKey :: Assertion
removeAliceKey = do
tmpDir <- createTemporaryTestDir "removeAliceKey"
let aliceTmpDir = tmpDir </> "alice"
copyGpgHomedir "test/alice" aliceTmpDir
withCtx aliceTmpDir "C" OpenPGP $ \ctx ->
do key <- getKey ctx alicePubFpr WithSecret
startNum <- listKeys ctx WithSecret >>= \l -> return $ length l
startNum @?= 1
ret <- removeKey ctx (fromJust key) (RemoveKeyFlags True True)
endNum <- listKeys ctx WithSecret >>= \l -> return $ length l
endNum @?= 0
ret @?= Nothing
removeDirectoryRecursive tmpDir
readFromFileWorks :: Assertion
readFromFileWorks = do
withCtx "test/real-person" "C" OpenPGP $ \ctx -> do
mRet <- importKeyFromFile ctx "test/real-person/real-person.key"
mRet @?= Nothing
readFromFileDoesn'tExist :: Assertion
readFromFileDoesn'tExist = do
withCtx "test/real-person" "C" OpenPGP $ \ctx -> do
mRet <- importKeyFromFile ctx "this-file-doesn't-exist"
isJust mRet @? "shouldn't be able to read this file"
exportAlicePubArmored :: Assertion
exportAlicePubArmored =
withCtx "test/alice" "C" OpenPGP $ \ctx -> do
setArmor True ctx
key <- fromRight <$> exportKey ctx alicePubFpr
("-----BEGIN PGP PUBLIC KEY BLOCK-----" `BS.isPrefixOf` key)
@? "exported key must be armored"
exportImportRoundtrip :: Assertion
exportImportRoundtrip = do
key <- withCtx "test/alice" "C" OpenPGP $ \ctx ->
fromRight <$> exportKey ctx alicePubFpr
tmpDir <- createTemporaryTestDir "exportImportRoundtrip"
withCtx tmpDir "C" OpenPGP $ \ctx -> do
mErr <- importKeyFromBytes ctx key
mErr @?= Nothing
imported <- getKey ctx alicePubFpr NoSecret
isJust imported @? "imported key should be present"
removeDirectoryRecursive tmpDir
exportInexistentIsEmpty :: Assertion
exportInexistentIsEmpty =
withCtx "test/alice" "C" OpenPGP $ \ctx -> do
key <- fromRight <$> exportKey ctx "ABCDEF"
key @?= BS.empty
exportAllKeys :: Assertion
exportAllKeys =
withCtx "test/alice" "C" OpenPGP $ \ctx -> do
single <- fromRight <$> exportKeys ctx [] [alicePubFpr]
all' <- fromRight <$> exportKeys ctx [] []
(BS.length all' > BS.length single)
@? "exporting all keys must yield more than a single key"
exportMinimal :: Assertion
exportMinimal =
withCtx "test/bob" "C" OpenPGP $ \ctx -> do
full <- fromRight <$> exportKeys ctx [] [alicePubFpr]
minimal <- fromRight <$> exportKeys ctx [ExportMinimal] [alicePubFpr]
not (BS.null minimal) @? "minimal export must not be empty"
(BS.length minimal <= BS.length full)
@? "minimal export must not be larger than the full export"
exportAliceSecretArmored :: Assertion
exportAliceSecretArmored =
withCtx "test/alice" "C" OpenPGP $ \ctx -> do
setPassphraseCallback ctx (Just (\_ _ _ -> return (Just "alice123")))
setArmor True ctx
key <- fromRight <$> exportSecretKey ctx alicePubFpr
("-----BEGIN PGP PRIVATE KEY BLOCK-----" `BS.isPrefixOf` key)
@? "exported secret key must be armored"
readFromBytesWorks :: Assertion
readFromBytesWorks = do
key <- BS.readFile "test/real-person/real-person.key"
tmpDir <- createTemporaryTestDir "readFromBytesWorks"
withCtx tmpDir "C" OpenPGP $ \ctx -> do
before <- getKey ctx realPersonPubFpr NoSecret
isNothing before @? "key shouldn't be present before import"
mRet <- importKeyFromBytes ctx key
mRet @?= Nothing
after <- getKey ctx realPersonPubFpr NoSecret
isJust after @? "key should be present after import"
removeDirectoryRecursive tmpDir