/
crypto_test.rb
246 lines (202 loc) · 7.54 KB
/
crypto_test.rb
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# -*- encoding: utf-8 -*-
require 'test_helper'
require 'tempfile'
describe GPGME::Crypto do
before do
skip unless GPGME::Engine.check_version GPGME::PROTOCOL_OpenPGP
end
describe "default options functionality" do
it "allows operation from instances normally" do
crypto = GPGME::Crypto.new
encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
it "can set default options when using the instance way" do
crypto = GPGME::Crypto.new :always_trust => true
encrypted = crypto.encrypt TEXT[:plain], :recipients => KEYS.first[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
it "but they can still be overwritten" do
crypto = GPGME::Crypto.new :always_trust => false
encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
end
describe "roundtrip encryption/decryption" do
it "does the roundtrip encrypting" do
crypto = GPGME::Crypto.new
encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
it "does so even with armored encrypted stuff" do
crypto = GPGME::Crypto.new
encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :armor => true
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
end
describe :encrypt do
it "should raise an error if the recipients aren't trusted" do
assert_raises GPGME::Error::General do
GPGME::Crypto.new.encrypt TEXT[:plain]
end
end
it "doesn't raise an error and returns something when encrypting nothing" do
data = GPGME::Crypto.new.encrypt nil, :always_trust => true
refute_empty data.read
data = GPGME::Crypto.new.encrypt "", :always_trust => true
refute_empty data.read
end
it "can specify which key(s) to use for encrypting with a string" do
crypto = GPGME::Crypto.new :always_trust => true
key = KEYS.last
encrypted = crypto.encrypt TEXT[:plain], :recipients => key[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
remove_key key
encrypted.seek 0
assert_raises GPGME::Error::DecryptFailed do
crypto.decrypt(encrypted)
end
import_key key
end
it "can specify which key to use for encrypting with a Key object" do
crypto = GPGME::Crypto.new :always_trust => true
key = KEYS.last
real_key = GPGME::Key.find(:public, key[:sha]).first
encrypted = crypto.encrypt TEXT[:plain], :recipients => real_key
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
remove_key key
encrypted.seek 0
assert_raises GPGME::Error::DecryptFailed do
crypto.decrypt(encrypted)
end
import_key key
end
it "can also sign at the same time" do
crypto = GPGME::Crypto.new :always_trust => true
encrypted = crypto.encrypt TEXT[:plain], :sign => true
signatures = 0
crypto.verify(encrypted) do |signature|
assert_instance_of GPGME::Signature, signature
signatures += 1
end
assert_equal 1, signatures
end
it "can be signed by more than one person" do
crypto = GPGME::Crypto.new :always_trust => true
encrypted = crypto.encrypt TEXT[:plain], :sign => true, :signers => KEYS.map{|k| k[:sha]}
signatures = 0
crypto.verify(encrypted) do |signature|
assert_instance_of GPGME::Signature, signature
signatures += 1
end
assert_equal 4, signatures
end
it "outputs to a file if specified" do
crypto = GPGME::Crypto.new :always_trust => true
file = Tempfile.new "test"
crypto.encrypt TEXT[:plain], :output => file
file_contents = file.read
file.seek 0
refute_empty file_contents
assert_equal TEXT[:plain], crypto.decrypt(file).read
end
# TODO find how to test
# it "raises GPGME::Error::UnusablePublicKey"
# it "raises GPGME::Error::UnusableSecretKey"
end
describe "symmetric encryption/decryption" do
it "requires a password to encrypt" do
assert_raises GPGME::Error::BadPassphrase do
GPGME::Crypto.new.encrypt TEXT[:plain], :symmetric => true
end
end
it "requires a password to decrypt" do
crypto = GPGME::Crypto.new
encrypted_data = crypto.encrypt TEXT[:plain],
:symmetric => true, :password => "gpgme"
assert_raises GPGME::Error::BadPassphrase do
crypto.decrypt encrypted_data
end
end
it "can encrypt and decrypt with the same password" do
crypto = GPGME::Crypto.new :symmetric => true, :password => "gpgme"
encrypted_data = crypto.encrypt TEXT[:plain]
plain = crypto.decrypt encrypted_data
assert_equal "Hi there", plain.read
end
it "but breaks with different ones" do
crypto = GPGME::Crypto.new
encrypted_data = crypto.encrypt TEXT[:plain],
:symmetric => true, :password => "gpgme"
assert_raises GPGME::Error::DecryptFailed do
crypto.decrypt encrypted_data, :password => "wrong one"
end
end
end
describe :decrypt do
it "decrypts encrypted stuff" do
assert_equal TEXT[:plain], GPGME::Crypto.new.decrypt(TEXT[:encrypted]).read
end
it "will not get into the signatures block if there's none" do
GPGME::Crypto.new.decrypt(TEXT[:encrypted]) do |signature|
flunk "If I'm here means there was some signature"
end
pass
end
it "will get signature elements if the encrypted thing was signed" do
signatures = 0
GPGME::Crypto.new.decrypt(TEXT[:signed]) do |signature|
assert_instance_of GPGME::Signature, signature
signatures += 1
end
assert_equal 1, signatures
end
it "writes to the output if passed" do
buffer = GPGME::Data.new
GPGME::Crypto.new.decrypt(TEXT[:encrypted], :output => buffer)
assert_equal TEXT[:plain], buffer.read
end
# TODO find ways to test this
# it "raises UnsupportedAlgorithm"
# it "raises WrongKeyUsage"
it "raises DecryptFailed when the decrypting key isn't available" do
assert_raises GPGME::Error::DecryptFailed do
GPGME::Crypto.new.decrypt(TEXT[:unavailable])
end
end
end
describe :sign do
it "signs normal strings" do
crypto = GPGME::Crypto.new
signatures = 0
sign = crypto.sign "Hi there"
crypto.verify(sign) do |signature|
assert_instance_of GPGME::Signature, signature
assert signature.valid?
signatures += 1
end
assert_equal 1, signatures
end
# TODO Find how to import an expired public key
# it "raises an error if trying to sign with an expired key" do
# with_key EXPIRED_KEY do
# crypto = GPGME::Crypto.new
# assert_raises GPGME::Error::General do
# sign = crypto.sign "Hi there", :signer => EXPIRED_KEY[:sha]
# end
# end
# end
it "selects who to sign for" do
crypto = GPGME::Crypto.new
sign = crypto.sign "Hi there", :signer => KEYS.last[:sha]
key = GPGME::Key.get(KEYS.last[:sha])
signatures = 0
crypto.verify(sign) do |signature|
assert_instance_of GPGME::Signature, signature
assert_equal key, signature.key
signatures += 1
end
assert_equal 1, signatures
end
end
end