gpgme-ffi 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/examples/edit.rb +77 -0
  2. data/examples/genkey.rb +55 -0
  3. data/examples/keylist.rb +7 -0
  4. data/examples/roundtrip.rb +42 -0
  5. data/examples/sign.rb +31 -0
  6. data/examples/verify.rb +8 -0
  7. data/ext/gpgme/Makefile.in +55 -0
  8. data/ext/gpgme/extconf.rb +8 -0
  9. data/ext/gpgme/extract_enums.rb +88 -0
  10. data/ext/gpgme/gpgme-1.3.1.tar.bz2 +0 -0
  11. data/ext/gpgme/libassuan-2.0.2.tar.bz2 +0 -0
  12. data/ext/gpgme/libgpg-error-1.10.tar.bz2 +0 -0
  13. data/ext/gpgme/libgpgme_gem.so +0 -0
  14. data/lib/gpgme/compat.rb +48 -0
  15. data/lib/gpgme/constants.rb +187 -0
  16. data/lib/gpgme/crypto.rb +357 -0
  17. data/lib/gpgme/ctx.rb +462 -0
  18. data/lib/gpgme/data.rb +189 -0
  19. data/lib/gpgme/engine.rb +76 -0
  20. data/lib/gpgme/error.rb +66 -0
  21. data/lib/gpgme/ffi/ctx.rb +36 -0
  22. data/lib/gpgme/ffi/data.rb +24 -0
  23. data/lib/gpgme/ffi/decrypt_result.rb +14 -0
  24. data/lib/gpgme/ffi/encrypt_result.rb +22 -0
  25. data/lib/gpgme/ffi/engine_info.rb +17 -0
  26. data/lib/gpgme/ffi/enums.rb +687 -0
  27. data/lib/gpgme/ffi/functions.rb +364 -0
  28. data/lib/gpgme/ffi/import_result.rb +35 -0
  29. data/lib/gpgme/ffi/import_status.rb +15 -0
  30. data/lib/gpgme/ffi/invalid_key.rb +14 -0
  31. data/lib/gpgme/ffi/key.rb +60 -0
  32. data/lib/gpgme/ffi/key_sig.rb +20 -0
  33. data/lib/gpgme/ffi/library.rb +279 -0
  34. data/lib/gpgme/ffi/meta.rb +57 -0
  35. data/lib/gpgme/ffi/new_signature.rb +18 -0
  36. data/lib/gpgme/ffi/sig_notation.rb +12 -0
  37. data/lib/gpgme/ffi/sign_result.rb +33 -0
  38. data/lib/gpgme/ffi/signature.rb +35 -0
  39. data/lib/gpgme/ffi/sub_key.rb +27 -0
  40. data/lib/gpgme/ffi/trust_item.rb +31 -0
  41. data/lib/gpgme/ffi/user_id.rb +30 -0
  42. data/lib/gpgme/ffi/verify_result.rb +22 -0
  43. data/lib/gpgme/ffi.rb +22 -0
  44. data/lib/gpgme/io_callbacks.rb +21 -0
  45. data/lib/gpgme/key.rb +242 -0
  46. data/lib/gpgme/key_common.rb +43 -0
  47. data/lib/gpgme/key_sig.rb +35 -0
  48. data/lib/gpgme/misc.rb +66 -0
  49. data/lib/gpgme/signature.rb +85 -0
  50. data/lib/gpgme/sub_key.rb +58 -0
  51. data/lib/gpgme/user_id.rb +20 -0
  52. data/lib/gpgme/version.rb +3 -0
  53. data/lib/gpgme.rb +106 -0
  54. data/test/crypto_test.rb +246 -0
  55. data/test/ctx_test.rb +432 -0
  56. data/test/data_test.rb +129 -0
  57. data/test/files/testkey_pub.gpg +52 -0
  58. data/test/files/testkey_sec.gpg +54 -0
  59. data/test/gpgme_test.rb +12 -0
  60. data/test/key_test.rb +209 -0
  61. data/test/signature_test.rb +52 -0
  62. data/test/sub_key_test.rb +48 -0
  63. data/test/support/resources.rb +516 -0
  64. data/test/test_helper.rb +84 -0
  65. metadata +203 -0
@@ -0,0 +1,246 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'test_helper'
3
+ require 'tempfile'
4
+
5
+ describe GPGME::Crypto do
6
+ before do
7
+ skip unless GPGME::Engine.check_version GPGME::PROTOCOL_OpenPGP
8
+ end
9
+
10
+ describe "default options functionality" do
11
+ it "allows operation from instances normally" do
12
+ crypto = GPGME::Crypto.new
13
+ encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
14
+ assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
15
+ end
16
+
17
+ it "can set default options when using the instance way" do
18
+ crypto = GPGME::Crypto.new :always_trust => true
19
+ encrypted = crypto.encrypt TEXT[:plain], :recipients => KEYS.first[:sha]
20
+ assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
21
+ end
22
+
23
+ it "but they can still be overwritten" do
24
+ crypto = GPGME::Crypto.new :always_trust => false
25
+ encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
26
+ assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
27
+ end
28
+ end
29
+
30
+ describe "roundtrip encryption/decryption" do
31
+ it "does the roundtrip encrypting" do
32
+ crypto = GPGME::Crypto.new
33
+ encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
34
+ assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
35
+ end
36
+
37
+ it "does so even with armored encrypted stuff" do
38
+ crypto = GPGME::Crypto.new
39
+ encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :armor => true
40
+ assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
41
+ end
42
+ end
43
+
44
+ describe :encrypt do
45
+ it "should raise an error if the recipients aren't trusted" do
46
+ assert_raises GPGME::Error::General do
47
+ GPGME::Crypto.new.encrypt TEXT[:plain]
48
+ end
49
+ end
50
+
51
+ it "doesn't raise an error and returns something when encrypting nothing" do
52
+ data = GPGME::Crypto.new.encrypt nil, :always_trust => true
53
+ refute_empty data.read
54
+ data = GPGME::Crypto.new.encrypt "", :always_trust => true
55
+ refute_empty data.read
56
+ end
57
+
58
+ it "can specify which key(s) to use for encrypting with a string" do
59
+ crypto = GPGME::Crypto.new :always_trust => true
60
+ key = KEYS.last
61
+ encrypted = crypto.encrypt TEXT[:plain], :recipients => key[:sha]
62
+ assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
63
+
64
+ remove_key key
65
+ encrypted.seek 0
66
+ assert_raises GPGME::Error::DecryptFailed do
67
+ crypto.decrypt(encrypted)
68
+ end
69
+ import_key key
70
+ end
71
+
72
+ it "can specify which key to use for encrypting with a Key object" do
73
+ crypto = GPGME::Crypto.new :always_trust => true
74
+ key = KEYS.last
75
+ real_key = GPGME::Key.find(:public, key[:sha]).first
76
+
77
+ encrypted = crypto.encrypt TEXT[:plain], :recipients => real_key
78
+ assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
79
+
80
+ remove_key key
81
+ encrypted.seek 0
82
+ assert_raises GPGME::Error::DecryptFailed do
83
+ crypto.decrypt(encrypted)
84
+ end
85
+ import_key key
86
+ end
87
+
88
+ it "can also sign at the same time" do
89
+ crypto = GPGME::Crypto.new :always_trust => true
90
+ encrypted = crypto.encrypt TEXT[:plain], :sign => true
91
+ signatures = 0
92
+
93
+ crypto.verify(encrypted) do |signature|
94
+ assert_instance_of GPGME::Signature, signature
95
+ signatures += 1
96
+ end
97
+
98
+ assert_equal 1, signatures
99
+ end
100
+
101
+ it "can be signed by more than one person" do
102
+ crypto = GPGME::Crypto.new :always_trust => true
103
+ encrypted = crypto.encrypt TEXT[:plain], :sign => true, :signers => KEYS.map{|k| k[:sha]}
104
+ signatures = 0
105
+
106
+ crypto.verify(encrypted) do |signature|
107
+ assert_instance_of GPGME::Signature, signature
108
+ signatures += 1
109
+ end
110
+
111
+ assert_equal 4, signatures
112
+ end
113
+
114
+ it "outputs to a file if specified" do
115
+ crypto = GPGME::Crypto.new :always_trust => true
116
+ file = Tempfile.new "test"
117
+ crypto.encrypt TEXT[:plain], :output => file
118
+ file_contents = file.read
119
+ file.seek 0
120
+
121
+ refute_empty file_contents
122
+ assert_equal TEXT[:plain], crypto.decrypt(file).read
123
+ end
124
+
125
+ # TODO find how to test
126
+ # it "raises GPGME::Error::UnusablePublicKey"
127
+ # it "raises GPGME::Error::UnusableSecretKey"
128
+ end
129
+
130
+ describe "symmetric encryption/decryption" do
131
+ it "requires a password to encrypt" do
132
+ assert_raises GPGME::Error::BadPassphrase do
133
+ GPGME::Crypto.new.encrypt TEXT[:plain], :symmetric => true
134
+ end
135
+ end
136
+
137
+ it "requires a password to decrypt" do
138
+ crypto = GPGME::Crypto.new
139
+ encrypted_data = crypto.encrypt TEXT[:plain],
140
+ :symmetric => true, :password => "gpgme"
141
+
142
+ assert_raises GPGME::Error::BadPassphrase do
143
+ crypto.decrypt encrypted_data
144
+ end
145
+ end
146
+
147
+ it "can encrypt and decrypt with the same password" do
148
+ crypto = GPGME::Crypto.new :symmetric => true, :password => "gpgme"
149
+ encrypted_data = crypto.encrypt TEXT[:plain]
150
+ plain = crypto.decrypt encrypted_data
151
+
152
+ assert_equal "Hi there", plain.read
153
+ end
154
+
155
+ it "but breaks with different ones" do
156
+ crypto = GPGME::Crypto.new
157
+ encrypted_data = crypto.encrypt TEXT[:plain],
158
+ :symmetric => true, :password => "gpgme"
159
+
160
+ assert_raises GPGME::Error::DecryptFailed do
161
+ crypto.decrypt encrypted_data, :password => "wrong one"
162
+ end
163
+ end
164
+ end
165
+
166
+ describe :decrypt do
167
+ it "decrypts encrypted stuff" do
168
+ assert_equal TEXT[:plain], GPGME::Crypto.new.decrypt(TEXT[:encrypted]).read
169
+ end
170
+
171
+ it "will not get into the signatures block if there's none" do
172
+ GPGME::Crypto.new.decrypt(TEXT[:encrypted]) do |signature|
173
+ flunk "If I'm here means there was some signature"
174
+ end
175
+ pass
176
+ end
177
+
178
+ it "will get signature elements if the encrypted thing was signed" do
179
+ signatures = 0
180
+ GPGME::Crypto.new.decrypt(TEXT[:signed]) do |signature|
181
+ assert_instance_of GPGME::Signature, signature
182
+ signatures += 1
183
+ end
184
+ assert_equal 1, signatures
185
+ end
186
+
187
+ it "writes to the output if passed" do
188
+ buffer = GPGME::Data.new
189
+ GPGME::Crypto.new.decrypt(TEXT[:encrypted], :output => buffer)
190
+ assert_equal TEXT[:plain], buffer.read
191
+ end
192
+
193
+ # TODO find ways to test this
194
+ # it "raises UnsupportedAlgorithm"
195
+ # it "raises WrongKeyUsage"
196
+
197
+ it "raises DecryptFailed when the decrypting key isn't available" do
198
+ assert_raises GPGME::Error::DecryptFailed do
199
+ GPGME::Crypto.new.decrypt(TEXT[:unavailable])
200
+ end
201
+ end
202
+ end
203
+
204
+ describe :sign do
205
+ it "signs normal strings" do
206
+ crypto = GPGME::Crypto.new
207
+ signatures = 0
208
+ sign = crypto.sign "Hi there"
209
+
210
+ crypto.verify(sign) do |signature|
211
+ assert_instance_of GPGME::Signature, signature
212
+ assert signature.valid?
213
+ signatures += 1
214
+ end
215
+
216
+ assert_equal 1, signatures
217
+ end
218
+
219
+ # TODO Find how to import an expired public key
220
+ # it "raises an error if trying to sign with an expired key" do
221
+ # with_key EXPIRED_KEY do
222
+ # crypto = GPGME::Crypto.new
223
+ # assert_raises GPGME::Error::General do
224
+ # sign = crypto.sign "Hi there", :signer => EXPIRED_KEY[:sha]
225
+ # end
226
+ # end
227
+ # end
228
+
229
+ it "selects who to sign for" do
230
+ crypto = GPGME::Crypto.new
231
+ sign = crypto.sign "Hi there", :signer => KEYS.last[:sha]
232
+ key = GPGME::Key.get(KEYS.last[:sha])
233
+
234
+ signatures = 0
235
+
236
+ crypto.verify(sign) do |signature|
237
+ assert_instance_of GPGME::Signature, signature
238
+ assert_equal key, signature.key
239
+ signatures += 1
240
+ end
241
+
242
+ assert_equal 1, signatures
243
+ end
244
+
245
+ end
246
+ end
data/test/ctx_test.rb ADDED
@@ -0,0 +1,432 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'test_helper'
3
+
4
+ describe GPGME::Ctx do
5
+ before do
6
+ skip unless GPGME::Engine.check_version GPGME::PROTOCOL_OpenPGP
7
+ end
8
+
9
+ it "can instantiate" do
10
+ assert_instance_of GPGME::Ctx, GPGME::Ctx.new
11
+ end
12
+
13
+ it "doesn't close itself" do
14
+ GPGME.expects(:gpgme_release).never
15
+ GPGME::Ctx.new
16
+ end
17
+
18
+ it "closes itself if called with a block" do
19
+ GPGME.expects(:gpgme_release).with(anything)
20
+ GPGME::Ctx.new { |ctx| }
21
+ end
22
+
23
+ it "can be closed with the release method" do
24
+ GPGME.expects(:gpgme_release).with(anything)
25
+ ctx = GPGME::Ctx.new
26
+ ctx.release
27
+ end
28
+
29
+ describe :new do
30
+ # We consider :armor, :protocol, :textmode and :keylist_mode as tested
31
+ # with the other tests of this file. Here we test the rest
32
+
33
+ it ":password sets the password for the key" do
34
+ with_key PASSWORD_KEY do
35
+ input = GPGME::Data.new(TEXT[:passwored])
36
+ output = GPGME::Data.new
37
+
38
+ GPGME::Ctx.new(:password => 'gpgme') do |ctx|
39
+ ctx.decrypt_verify input, output
40
+ end
41
+
42
+ output.seek 0
43
+ assert_equal "Hi there", output.read.chomp
44
+ end
45
+ end
46
+
47
+ it ":passphrase_callback sets the callback for the password" do
48
+ def test_pass_func(obj,par2,par3,prev_was_bad,fd)
49
+ # prev_was_bad is 0 the first time, 1 the rest
50
+ if @var == 0
51
+ assert_equal 0, prev_was_bad
52
+ else
53
+ assert_equal 1, prev_was_bad
54
+ end
55
+
56
+ @var += 1
57
+
58
+ io = ::FFI::IO.for_fd(fd, 'w')
59
+ io.puts "wrong pasword"
60
+ io.flush
61
+ end
62
+
63
+ def with_correct_pass_func(obj,par2,par3,prev_was_bad,fd)
64
+ io = ::FFI::IO.for_fd(fd, 'w')
65
+ io.puts "gpgme"
66
+ io.flush
67
+ end
68
+
69
+ with_key PASSWORD_KEY do
70
+ input = GPGME::Data.new(TEXT[:passwored])
71
+ output = GPGME::Data.new
72
+ @var = 0
73
+
74
+ assert_raises GPGME::Error::BadPassphrase do
75
+ GPGME::Ctx.new(:passphrase_callback => method(:test_pass_func)) do |ctx|
76
+ ctx.decrypt_verify input, output
77
+ end
78
+ end
79
+
80
+ # Since we request the key 3 times, we should've gone through the
81
+ # callback 3 times.
82
+ assert_equal 3, @var
83
+
84
+ input.seek 0
85
+ output.seek 0
86
+
87
+ # Shouldn't crash
88
+ GPGME::Ctx.new(:passphrase_callback => method(:with_correct_pass_func)) do |ctx|
89
+ ctx.decrypt_verify input, output
90
+ end
91
+ end
92
+ end
93
+
94
+ it ":passphrase_callback_value passes a value to the callback function" do
95
+ def checking_value(value,par2,par3,par4,fd)
96
+ assert_equal "superman", value
97
+ io = ::FFI::IO.for_fd(fd, 'w')
98
+ io.puts "gpgme"
99
+ io.flush
100
+ end
101
+
102
+ with_key PASSWORD_KEY do
103
+ input = GPGME::Data.new(TEXT[:passwored])
104
+ output = GPGME::Data.new
105
+
106
+ options = {
107
+ :passphrase_callback => method(:checking_value),
108
+ :passphrase_callback_value => "superman"
109
+ }
110
+
111
+ GPGME::Ctx.new(options) do |ctx|
112
+ ctx.decrypt_verify input, output
113
+ end
114
+ end
115
+ end
116
+
117
+ # TODO Don't know how to use them yet
118
+ # it ":progress_callback"
119
+ # it ":progress_callback_value"
120
+ end
121
+
122
+ describe :armor do
123
+ it "sets false by default" do
124
+ ctx = GPGME::Ctx.new
125
+ refute ctx.armor
126
+ end
127
+
128
+ it "can set" do
129
+ ctx = GPGME::Ctx.new
130
+ ctx.armor = true
131
+ assert ctx.armor
132
+ end
133
+
134
+ it "can set and get armor" do
135
+ ctx = GPGME::Ctx.new(:armor => false)
136
+ refute ctx.armor
137
+ ctx = GPGME::Ctx.new(:armor => true)
138
+ assert ctx.armor
139
+ end
140
+ end
141
+
142
+ describe :protocol do
143
+ it "sets 0 by default" do
144
+ ctx = GPGME::Ctx.new
145
+ assert_equal 0, ctx.protocol
146
+ end
147
+
148
+ it "can set" do
149
+ ctx = GPGME::Ctx.new
150
+ ctx.protocol = 1
151
+ assert_equal 1, ctx.protocol
152
+ end
153
+
154
+ it "can set and get protocol" do
155
+ ctx = GPGME::Ctx.new(:protocol => GPGME::PROTOCOL_OpenPGP)
156
+ assert_equal GPGME::PROTOCOL_OpenPGP, ctx.protocol
157
+ end
158
+
159
+ it "doesn't allow just any value" do
160
+ assert_raises GPGME::Error::InvalidValue do
161
+ ctx = GPGME::Ctx.new(:protocol => -200)
162
+ end
163
+ end
164
+ end
165
+
166
+ describe :textmode do
167
+ it "sets false by default" do
168
+ ctx = GPGME::Ctx.new
169
+ refute ctx.textmode
170
+ end
171
+
172
+ it "can set" do
173
+ ctx = GPGME::Ctx.new
174
+ ctx.textmode = true
175
+ assert ctx.textmode
176
+ end
177
+
178
+ it "can set and get textmode" do
179
+ ctx = GPGME::Ctx.new(:textmode => false)
180
+ refute ctx.textmode
181
+ ctx = GPGME::Ctx.new(:textmode => true)
182
+ assert ctx.textmode
183
+ end
184
+ end
185
+
186
+ describe :keylist_mode do
187
+ it "sets local by default" do
188
+ ctx = GPGME::Ctx.new
189
+ assert_equal GPGME::KEYLIST_MODE_LOCAL, ctx.keylist_mode
190
+ end
191
+
192
+ it "can set and get" do
193
+ ctx = GPGME::Ctx.new(:keylist_mode => GPGME::KEYLIST_MODE_SIGS)
194
+ assert_equal GPGME::KEYLIST_MODE_SIGS, ctx.keylist_mode
195
+ end
196
+
197
+ it "can set" do
198
+ ctx = GPGME::Ctx.new
199
+ ctx.keylist_mode = GPGME::KEYLIST_MODE_SIGS
200
+ assert_equal GPGME::KEYLIST_MODE_SIGS, ctx.keylist_mode
201
+ end
202
+
203
+ it "allows the four possible values" do
204
+ [GPGME::KEYLIST_MODE_LOCAL, GPGME::KEYLIST_MODE_EXTERN,
205
+ GPGME::KEYLIST_MODE_SIGS, GPGME::KEYLIST_MODE_VALIDATE].each do |mode|
206
+ GPGME::Ctx.new(:keylist_mode => mode)
207
+ end
208
+ end
209
+
210
+ # It's not crashing?
211
+ # it "crashes with other values" do
212
+ # GPGME::Ctx.new(:keylist_mode => -200)
213
+ # end
214
+ end
215
+
216
+ # describe :set_passphrase_callback do
217
+ # def test_pass_func(par1,par2,par3,par4,par5)
218
+ # par1
219
+ # end
220
+
221
+ # test "it sets the passphrase"
222
+
223
+ # end
224
+
225
+ describe "keylist operations" do
226
+ it "can return all of the keys" do
227
+ ctx = GPGME::Ctx.new
228
+ keys = ctx.keys
229
+ ctx.release
230
+
231
+ assert keys.size >= 4
232
+ KEYS.each do |key|
233
+ assert keys.map(&:email).include?(key[:sha])
234
+ end
235
+ end
236
+
237
+ it "can return keys filtering by a pattern" do
238
+ ctx = GPGME::Ctx.new
239
+ keys = ctx.keys(KEYS.first[:sha])
240
+ ctx.release
241
+
242
+ assert_equal 1, keys.size
243
+ assert_equal KEYS.first[:sha], keys.first.email
244
+ end
245
+
246
+ it "can return only secret keys" do
247
+ ctx = GPGME::Ctx.new
248
+ keys = ctx.keys(KEYS.first[:sha], true)
249
+ ctx.release
250
+
251
+ assert keys.all?(&:secret?)
252
+ end
253
+
254
+ it "can return only public keys" do
255
+ ctx = GPGME::Ctx.new
256
+ keys = ctx.keys(KEYS.first[:sha], false)
257
+ ctx.release
258
+
259
+ refute keys.any?(&:secret?)
260
+ end
261
+
262
+ it "returns only public keys by default" do
263
+ ctx = GPGME::Ctx.new
264
+ keys = ctx.keys(KEYS.first[:sha])
265
+ ctx.release
266
+
267
+ refute keys.any?(&:secret?)
268
+ end
269
+
270
+ it "can iterate through them returning only public keys" do
271
+ GPGME::Ctx.new do |ctx|
272
+ ctx.each_key do |key|
273
+ assert_instance_of GPGME::Key, key
274
+ refute key.secret?
275
+ end
276
+ end
277
+ end
278
+
279
+ it "can iterate through them getting only secret ones" do
280
+ GPGME::Ctx.new do |ctx|
281
+ ctx.each_key("", true) do |key|
282
+ assert_instance_of GPGME::Key, key
283
+ assert key.secret?
284
+ end
285
+ end
286
+ end
287
+
288
+ it "can iterate through them filtering by pattern" do
289
+ num = 0
290
+ GPGME::Ctx.new do |ctx|
291
+ ctx.each_key(KEYS.first[:sha]) do |key|
292
+ assert_instance_of GPGME::Key, key
293
+ assert_equal KEYS.first[:sha], key.email
294
+ num += 1
295
+ end
296
+ end
297
+ assert_equal 1, num
298
+ end
299
+
300
+ it "can get only a specific key" do
301
+ GPGME::Ctx.new do |ctx|
302
+ key = ctx.get_key(KEYS.first[:sha])
303
+ assert_instance_of GPGME::Key, key
304
+ assert_equal KEYS.first[:sha], key.email
305
+ end
306
+ end
307
+ end
308
+
309
+ describe "key generation" do
310
+ it "generates a key according to specifications" do
311
+ skip "long test" if ENV.include? "QUICK_TESTING"
312
+
313
+ key = <<-RUBY
314
+ <GnupgKeyParms format="internal">
315
+ Key-Type: DSA
316
+ Key-Length: 1024
317
+ Subkey-Type: ELG-E
318
+ Subkey-Length: 1024
319
+ Name-Real: Key Tester
320
+ Name-Comment: with some comments
321
+ Name-Email: test_generation@example.com
322
+ Expire-Date: 0
323
+ Passphrase: wadus
324
+ </GnupgKeyParms>
325
+ RUBY
326
+
327
+ keys_amount = GPGME::Key.find(:public).size
328
+ GPGME::Ctx.new do |ctx|
329
+ ctx.generate_key(key.chomp)
330
+ end
331
+
332
+ assert_equal keys_amount + 1, GPGME::Key.find(:public).size
333
+
334
+ GPGME::Key.find(:public, "test_generation@example.com").each do |k|
335
+ k.delete!(true)
336
+ end
337
+ end
338
+ end
339
+
340
+ describe "key export/import" do
341
+ it "exports and imports all keys when passing an empty string" do
342
+ original_keys = GPGME::Key.find(:public)
343
+ export = ""
344
+ GPGME::Ctx.new do |ctx|
345
+ export = ctx.export_keys("")
346
+ end
347
+ export.seek(0)
348
+
349
+ GPGME::Key.find(:public).each{|k| k.delete!(true)}
350
+ assert_equal 0, GPGME::Key.find(:public).size
351
+
352
+ result = GPGME::Key.import(export)
353
+ current_keys = GPGME::Key.find(:public)
354
+ assert_equal original_keys.size, current_keys.size
355
+ assert_equal result.imports.size, current_keys.size
356
+ assert result.imports.all?{|import| import.status == 1}
357
+
358
+ assert_equal original_keys.map(&:sha), original_keys.map(&:sha)
359
+
360
+ import_keys # If the test fails for some reason, it won't break others.
361
+ end
362
+
363
+ it "exports only one key" do
364
+ original_keys = GPGME::Key.find(:public)
365
+ key = original_keys.first
366
+ export = ""
367
+ GPGME::Ctx.new do |ctx|
368
+ export = ctx.export_keys(key.sha)
369
+ end
370
+ export.seek(0)
371
+
372
+ key.delete!(true)
373
+
374
+ result = GPGME::Key.import(export)
375
+ assert_equal 1, result.imports.size
376
+
377
+ import = result.imports.first
378
+
379
+ imported_key = GPGME::Key.find(:public, import.fpr).first
380
+ assert_equal key.sha, imported_key.sha
381
+ assert_equal key.email, imported_key.email
382
+ import_keys # If the test fails for some reason, it won't break others.
383
+ end
384
+
385
+ it "imports keys and can get a result object" do
386
+ without_key KEYS.last do
387
+ public_amount = GPGME::Key.find(:public).size
388
+ secret_amount = GPGME::Key.find(:secret).size
389
+
390
+ result = nil
391
+ GPGME::Ctx.new do |ctx|
392
+ ctx.import_keys(GPGME::Data.new(KEYS.last[:public]))
393
+ ctx.import_keys(GPGME::Data.new(KEYS.last[:secret]))
394
+
395
+ result = ctx.import_result
396
+ end
397
+
398
+ assert_equal secret_amount + 1, GPGME::Key.find(:secret).size
399
+ assert_equal public_amount + 1, GPGME::Key.find(:public).size
400
+ assert_instance_of GPGME::ImportResult, result
401
+ assert_instance_of GPGME::ImportStatus, result.imports.first
402
+ end
403
+ end
404
+ end
405
+
406
+ describe "deleting/editing of keys" do
407
+ it "can delete keys" do
408
+ original_keys = GPGME::Key.find(:public)
409
+ key = original_keys.first
410
+
411
+ GPGME::Ctx.new do |ctx|
412
+ ctx.delete_key key, true
413
+ end
414
+
415
+ assert_empty GPGME::Key.find(:public, key.sha)
416
+ import_keys
417
+ end
418
+
419
+ it "raises error if there's a secret key attached but secret key deletion isn't marked" do
420
+ original_keys = GPGME::Key.find(:public)
421
+ key = original_keys.first
422
+
423
+ assert_raises GPGME::Error::Conflict do
424
+ GPGME::Ctx.new do |ctx|
425
+ ctx.delete_key key
426
+ end
427
+ end
428
+ end
429
+ end
430
+
431
+ # Don't know how to test or use edit_key and edit_card
432
+ end