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,364 @@
1
+
2
+ module GPGME
3
+
4
+ Meta.define_ffi_forwarder :gpgme_engine_check_version,
5
+ :gpgme_set_engine_info,
6
+ :gpgme_pubkey_algo_name,
7
+ :gpgme_hash_algo_name,
8
+ :gpgme_data_get_encoding,
9
+ :gpgme_data_set_encoding,
10
+ :gpgme_set_protocol,
11
+ :gpgme_get_protocol,
12
+ :gpgme_set_armor,
13
+ :gpgme_get_armor,
14
+ :gpgme_set_textmode,
15
+ :gpgme_get_textmode,
16
+ :gpgme_get_include_certs,
17
+ :gpgme_set_include_certs,
18
+ :gpgme_set_keylist_mode,
19
+ :gpgme_get_keylist_mode,
20
+ :gpgme_get_locale,
21
+ :gpgme_op_keylist_start,
22
+ :gpgme_op_keylist_ext_start,
23
+ :gpgme_op_keylist_end,
24
+ :gpgme_op_genkey,
25
+ :gpgme_op_genkey_start,
26
+ :gpgme_op_export,
27
+ :gpgme_op_export_start,
28
+ :gpgme_op_export_ext,
29
+ :gpgme_op_export_ext_start,
30
+ :gpgme_op_export_keys,
31
+ :gpgme_op_export_keys_start,
32
+ :gpgme_op_import,
33
+ :gpgme_op_import_start,
34
+ :gpgme_op_import_keys,
35
+ :gpgme_op_import_keys_start,
36
+ :gpgme_op_delete,
37
+ :gpgme_op_delete_start,
38
+ :gpgme_op_trustlist_start,
39
+ :gpgme_op_trustlist_end,
40
+ :gpgme_op_decrypt,
41
+ :gpgme_op_decrypt_start,
42
+ :gpgme_op_verify,
43
+ :gpgme_op_verify_start,
44
+ :gpgme_op_decrypt_verify,
45
+ :gpgme_op_decrypt_verify_start,
46
+ :gpgme_signers_clear,
47
+ :gpgme_signers_add,
48
+ :gpgme_op_sign,
49
+ :gpgme_op_sign_start,
50
+ :gpgme_op_encrypt,
51
+ :gpgme_op_encrypt_start,
52
+ :gpgme_op_encrypt_sign,
53
+ :gpgme_op_encrypt_sign_start
54
+
55
+ Meta.define_op_edit :gpgme_op_edit,
56
+ :gpgme_op_edit_start,
57
+ :gpgme_op_card_edit,
58
+ :gpgme_op_card_edit_start
59
+
60
+ def self.gpgme_check_version(required)
61
+ Library.gpgme_check_version_internal required, Library::Signature.offset_of(:validity)
62
+ end
63
+
64
+ def self.gpgme_get_engine_info(rinfo)
65
+ engine_info = Library::EngineInfo.new
66
+ err = Library.gpgme_get_engine_info engine_info.to_ptr
67
+
68
+ return err if gpgme_err_code(err) != GPG_ERR_NO_ERROR
69
+
70
+ ptr = engine_info.to_ptr
71
+ until ptr.null?
72
+ engine = Library::EngineInfo.new ptr
73
+
74
+ rinfo << EngineInfo.new_from_struct(engine)
75
+
76
+ ptr = engine[:next]
77
+ end
78
+
79
+ err
80
+ end
81
+
82
+
83
+ def self.gpgme_err_code(code)
84
+ code & GPG_ERR_CODE_MASK
85
+ end
86
+
87
+ def self.gpgme_err_source(code)
88
+ (code & GPG_ERR_SOURCE_MASK) >> GPG_ERR_SOURCE_SHIFT
89
+ end
90
+
91
+ def self.gpgme_err_make(source, code)
92
+ if code == GPG_ERR_NO_ERROR
93
+ return GPG_ERR_NO_ERROR
94
+ end
95
+
96
+ ((source << GPG_ERR_SOURCE_SHIFT) & GPG_ERR_SOURCE_MASK) | (code & GPG_ERR_CODE_MASK)
97
+ end
98
+
99
+ def self.gpgme_strerror(error)
100
+ Library.gpgme_strerror error
101
+ end
102
+
103
+ def self.gpgme_data_new(rdata)
104
+ buf = FFI::Buffer.new :pointer, 1
105
+ err = Library.gpgme_data_new buf
106
+
107
+ if gpgme_err_code(err) == GPG_ERR_NO_ERROR
108
+ rdata << Data.new_from_struct(buf.read_pointer)
109
+ end
110
+
111
+ err
112
+ end
113
+
114
+ def self.gpgme_data_new_from_mem(rdata, buffer, size)
115
+ buf = FFI::Buffer.new :pointer, 1
116
+ err = Library.gpgme_data_new_from_mem buf, buffer, size, 1
117
+
118
+ if gpgme_err_code(err) == GPG_ERR_NO_ERROR
119
+ rdata << Data.new_from_struct(buf.read_pointer)
120
+ end
121
+
122
+ err
123
+ end
124
+
125
+ if RUBY_PLATFORM == "java"
126
+ def self.gpgme_data_new_from_fd(rdata, fd)
127
+ raise NotImplementedError, "GPGME::gpgme_data_new_from_fd cannot be used on JRuby due to NIO API limitations."
128
+ end
129
+ else
130
+ def self.gpgme_data_new_from_fd(rdata, fd)
131
+ buf = FFI::Buffer.new :pointer, 1
132
+ err = Library.gpgme_data_new_from_fd buf, fd
133
+
134
+ if gpgme_err_code(err) == GPG_ERR_NO_ERROR
135
+ rdata << Data.new_from_struct(buf.read_pointer)
136
+ end
137
+
138
+ err
139
+ end
140
+ end
141
+
142
+ def self.gpgme_data_new_from_cbs(rdata, ruby_cbs, ruby_handle)
143
+ buf = FFI::Buffer.new :pointer, 1
144
+ cbs = Library::Callbacks.new
145
+
146
+ cbs[:read] = FFI::Function.new(:ssize_t, [ :pointer, :pointer, :size_t ]) do |handle, buffer, size|
147
+ data = ruby_cbs.read ruby_handle, size
148
+
149
+ if data.nil?
150
+ 0
151
+ else
152
+
153
+ buffer.write_bytes data, 0, data.length
154
+
155
+ data.length
156
+ end
157
+ end
158
+
159
+ cbs[:write] = FFI::Function.new(:ssize_t, [ :pointer, :pointer, :size_t ]) do |handle, buffer, size|
160
+ data = buffer.read_bytes size
161
+
162
+ ruby_cbs.write ruby_handle, data, size
163
+ end
164
+
165
+ cbs[:seek] = FFI::Function.new(:off_t, [ :pointer, :off_t, :int ]) do |handle, offset, whence|
166
+ ruby_cbs.seek ruby_handle, offset, whence
167
+ end
168
+
169
+ cbs[:release] = FFI::Pointer::NULL
170
+
171
+ err = Library.gpgme_data_new_from_cbs buf, cbs.to_ptr, FFI::Pointer::NULL
172
+ if gpgme_err_code(err) == GPG_ERR_NO_ERROR
173
+ rdata << Data.new_from_struct(buf.read_pointer, cbs)
174
+ end
175
+
176
+ err
177
+ end
178
+
179
+ def self.gpgme_data_read(data, length)
180
+ buf = FFI::Buffer.new(:uint8, (length > 0) ? length : 1)
181
+
182
+ bytes = Library.gpgme_data_read data.context_pointer, buf, length
183
+
184
+ if bytes == -1
185
+ raise "gpgme_data_read failed with error #{FFI.errno}"
186
+ end
187
+
188
+ return nil if bytes == 0
189
+
190
+ buf.read_bytes bytes
191
+ end
192
+
193
+ def self.gpgme_data_write(data, buffer, length)
194
+ buf = FFI::Buffer.new(:uint8, (length > 0) ? length : 1)
195
+ if length > 0
196
+ buf.write_bytes buffer, 0, length
197
+ end
198
+
199
+ bytes = Library.gpgme_data_write data.context_pointer, buf, length
200
+
201
+ if bytes == -1
202
+ raise "gpgme_data_write failed with error #{FFI.errno}"
203
+ end
204
+
205
+ bytes
206
+ end
207
+
208
+ def self.gpgme_data_seek(data, offset, whence)
209
+ pos = Library.gpgme_data_seek data.context_pointer, offset, whence
210
+
211
+ if pos == -1
212
+ raise "gpgme_data_seek failed with error #{FFI.errno}"
213
+ end
214
+
215
+ pos
216
+ end
217
+
218
+ def self.gpgme_new(rctx)
219
+ buf = FFI::Buffer.new :pointer, 1
220
+ err = Library.gpgme_new buf
221
+
222
+ if gpgme_err_code(err) == GPG_ERR_NO_ERROR
223
+ rctx << Ctx.new_from_struct(buf.read_pointer)
224
+ end
225
+
226
+ err
227
+ end
228
+
229
+ def self.gpgme_release(ctx)
230
+ ctx.release_pointer
231
+
232
+ nil
233
+ end
234
+
235
+ def self.gpgme_set_passphrase_cb(context, ruby_callback, ruby_hook_value)
236
+ callback = FFI::Function.new(:uint, [ :pointer, :string, :string, :int, :int ]) do |hook, uid_hint, passphrase_info, prev_was_bad, fd|
237
+ ruby_callback.call ruby_hook_value, uid_hint, passphrase_info, prev_was_bad, fd
238
+
239
+ gpgme_err_make GPG_ERR_SOURCE_USER_1, GPG_ERR_NO_ERROR
240
+ end
241
+
242
+ context.context_passphrase_callback = [ ruby_callback, ruby_hook_value, callback ]
243
+
244
+ Library.gpgme_set_passphrase_cb context.context_pointer, callback, FFI::Pointer::NULL
245
+ end
246
+
247
+ def self.gpgme_get_passphrase_cb(context, rruby_callback, rruby_hook_value)
248
+ ruby_callback, ruby_hook_value, ffi_wrapper = context.context_passphrase_callback
249
+
250
+ rruby_callback << ruby_callback
251
+ rruby_hook_value << ruby_hook_value
252
+
253
+ nil
254
+ end
255
+
256
+ def self.gpgme_set_progress_cb(context, ruby_callback, ruby_hook_value)
257
+ callback = FFI::Function.new(:void, [ :pointer, :string, :int, :int, :int ]) do |hook, what, type, current, total|
258
+ ruby_callback.call ruby_hook_value, what, type, current, total
259
+ end
260
+
261
+ context.context_progress_callback = [ ruby_callback, ruby_hook_value, callback ]
262
+
263
+ Library.gpgme_set_progress_cb context.context_pointer, callback, FFI::Pointer::NULL
264
+ end
265
+
266
+ def self.gpgme_get_progress_cb(context, rruby_callback, rruby_hook_value)
267
+ ruby_callback, ruby_hook_value, ffi_wrapper = context.context_progress_callback
268
+
269
+ rruby_callback << ruby_callback
270
+ rruby_hook_value << ruby_hook_value
271
+
272
+ nil
273
+ end
274
+
275
+ def self.gpgme_op_keylist_next(context, rkey)
276
+ key = FFI::Buffer.new :pointer, 1
277
+
278
+ ret = Library.gpgme_op_keylist_next context.context_pointer, key
279
+
280
+ if gpgme_err_code(ret) == GPG_ERR_NO_ERROR
281
+ rkey << Key.new_from_struct(key.read_pointer)
282
+ end
283
+
284
+ ret
285
+ end
286
+
287
+ def self.gpgme_get_key(context, fingerprint, rkey, secret)
288
+ key = FFI::Buffer.new :pointer, 1
289
+
290
+ ret = Library.gpgme_get_key context.context_pointer, fingerprint, key, secret
291
+
292
+ if gpgme_err_code(ret) == GPG_ERR_NO_ERROR
293
+ rkey << Key.new_from_struct(key.read_pointer)
294
+ end
295
+
296
+ ret
297
+ end
298
+
299
+ def self.gpgme_op_import_result(context)
300
+ result = Library::ImportResult.new Library.gpgme_op_import_result(context.context_pointer)
301
+
302
+ ImportResult.new_from_struct result
303
+ end
304
+
305
+
306
+ def self.gpgme_op_trustlist_next(context, ritem)
307
+ buf = FFI::Buffer.new :pointer, 1
308
+
309
+ err = Library.gpgme_op_trustlist_next context, buf
310
+
311
+ if gpgme_err_code(err) == GPG_ERR_NO_ERROR
312
+ ritem << TrustItem.new_from_struct(buf.read_pointer)
313
+ end
314
+
315
+ err
316
+ end
317
+
318
+ def self.gpgme_op_decrypt_result(context)
319
+ struct = Library::DecryptResult.new Library::gpgme_op_decrypt_result(context.context_pointer)
320
+
321
+ DecryptResult.new_from_struct struct
322
+ end
323
+
324
+
325
+ def self.gpgme_op_verify_result(context)
326
+ struct = Library::VerifyResult.new Library::gpgme_op_verify_result(context.context_pointer)
327
+
328
+ VerifyResult.new_from_struct struct
329
+ end
330
+
331
+ def self.gpgme_signers_enum(context, index)
332
+ ptr = Library.gpgme_signers_enum context.context_pointer, index
333
+
334
+ return nil if ptr.null?
335
+
336
+ Key.new_from_struct Library::Key.new(ptr)
337
+ end
338
+
339
+
340
+ def self.gpgme_op_sign_result(context)
341
+ struct = Library::SignResult.new Library::gpgme_op_verify_result(context.context_pointer)
342
+
343
+ SignResult.new_from_struct struct
344
+ end
345
+
346
+
347
+ def self.gpgme_op_encrypt_result(context)
348
+ struct = Library::EncryptResult.new Library::gpgme_op_encrypt_result(context.context_pointer)
349
+
350
+ EncryptResult.new_from_struct struct
351
+ end
352
+
353
+ def self.gpgme_wait(context, rstatus, hang)
354
+ buf = FFI::Buffer.new :uint, 1
355
+
356
+ rctx = Library.gpgme_wait Meta.ffize_value(context), buf, hang
357
+
358
+ return nil if rctx.null?
359
+
360
+ rstatus << buf.read_uint
361
+
362
+ Ctx.new_from_struct rctx
363
+ end
364
+ end
@@ -0,0 +1,35 @@
1
+ module GPGME
2
+ class ImportResult
3
+ def self.new_from_struct(struct)
4
+ instance = allocate
5
+
6
+ instance.instance_exec do
7
+ @considered = struct[:considered]
8
+ @no_user_id = struct[:no_user_id]
9
+ @imported = struct[:imported]
10
+ @imported_rsa = struct[:imported_rsa]
11
+ @unchanged = struct[:unchanged]
12
+ @new_user_ids = struct[:new_user_ids]
13
+ @new_sub_keys = struct[:new_sub_keys]
14
+ @new_signatures = struct[:new_signatures]
15
+ @new_revocations = struct[:new_revocations]
16
+ @secret_read = struct[:secret_read]
17
+ @secret_imported = struct[:secret_imported]
18
+ @secret_unchanged = struct[:secret_unchanged]
19
+ @not_imported = struct[:not_imported]
20
+
21
+ @imports = []
22
+ pointer = struct[:imports]
23
+ until pointer.null?
24
+ status = Library::ImportStatus.new pointer
25
+
26
+ @imports << ImportStatus.new_from_struct(status)
27
+
28
+ pointer = status[:next]
29
+ end
30
+ end
31
+
32
+ instance
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ module GPGME
2
+ class ImportStatus
3
+ def self.new_from_struct(struct)
4
+ instance = allocate
5
+
6
+ instance.instance_exec do
7
+ @fpr = struct[:fpr]
8
+ @result = struct[:result]
9
+ @status = struct[:status]
10
+ end
11
+
12
+ instance
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module GPGME
2
+ class InvalidKey
3
+ def self.new_from_struct(struct)
4
+ instance = allocate
5
+
6
+ instance.instance_exec do
7
+ @fpr = struct[:fpr]
8
+ @reason = struct[:reason]
9
+ end
10
+
11
+ instance
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,60 @@
1
+ module GPGME
2
+ class Key
3
+ class Pointer < FFI::AutoPointer
4
+ def self.release(ptr)
5
+ Library.gpgme_key_unref ptr
6
+ end
7
+ end
8
+
9
+ def self.new_from_struct(pointer)
10
+ instance = allocate
11
+
12
+ instance.instance_exec do
13
+ @ptr = Pointer.new pointer
14
+
15
+ struct = Library::Key.new @ptr
16
+ @keylist_mode = struct[:keylist_mode]
17
+ @revoked = (struct[:flags] >> 0) & 1
18
+ @expired = (struct[:flags] >> 1) & 1
19
+ @disabled = (struct[:flags] >> 2) & 1
20
+ @invalid = (struct[:flags] >> 3) & 1
21
+ @can_encrypt = (struct[:flags] >> 4) & 1
22
+ @can_sign = (struct[:flags] >> 5) & 1
23
+ @can_certify = (struct[:flags] >> 6) & 1
24
+ @secret = (struct[:flags] >> 7) & 1
25
+ @can_authenticate = (struct[:flags] >> 8) & 1
26
+ @protocol = struct[:protocol]
27
+ @issuer_serial = struct[:issuer_serial]
28
+ @issuer_name = struct[:issuer_name]
29
+ @chain_id = struct[:chain_id]
30
+ @owner_trust = struct[:owner_trust]
31
+
32
+ @subkeys = []
33
+ pointer = struct[:subkeys]
34
+ until pointer.null?
35
+ subkey = Library::SubKey.new pointer
36
+
37
+ @subkeys << SubKey.new_from_struct(subkey)
38
+
39
+ pointer = subkey[:next]
40
+ end
41
+
42
+ @uids = []
43
+ pointer = struct[:uids]
44
+ until pointer.null?
45
+ uid = Library::UserID.new pointer
46
+
47
+ @uids << UserID.new_from_struct(uid)
48
+
49
+ pointer = uid[:next]
50
+ end
51
+ end
52
+
53
+ instance
54
+ end
55
+
56
+ def context_pointer
57
+ @ptr
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,20 @@
1
+ module GPGME
2
+ class KeySig
3
+ def self.new_from_struct(struct)
4
+ instance = allocate
5
+
6
+ instance.instance_exec do
7
+ @revoked = (struct[:flags] >> 0) & 1
8
+ @expired = (struct[:flags] >> 1) & 1
9
+ @invalid = (struct[:invalid] >> 2) & 1
10
+ @exportable = (struct[:exportable] >> 3) & 1
11
+ @pubkey_algo = struct[:pubkey_algo]
12
+ @keyid = struct[:keyid]
13
+ @timestamp = struct[:timestamp]
14
+ @expires = struct[:expires]
15
+ end
16
+
17
+ instance
18
+ end
19
+ end
20
+ end