gpgme-loongson 2.0.18

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.
@@ -0,0 +1,525 @@
1
+ module GPGME
2
+
3
+ ##
4
+ # A context within which all cryptographic operations are performed.
5
+ #
6
+ # More operations can be done which are not available in the higher level
7
+ # API. Note how to create a new instance of this class in {GPGME::Ctx.new}.
8
+ #
9
+ class Ctx
10
+
11
+ ##
12
+ # Create a new instance from the given +options+. Must be released either
13
+ # executing the operations inside a block, or executing {GPGME::Ctx#release}
14
+ # afterwards.
15
+ #
16
+ # @param [Hash] options
17
+ # The optional parameters are as follows:
18
+ # * +:protocol+ Either +PROTOCOL_OpenPGP+ or +PROTOCOL_CMS+.
19
+ # * +:armor+ will return ASCII armored outputs if specified true.
20
+ # * +:textmode+ if +true+, inform the recipient that the input is text.
21
+ # * +:keylist_mode+ One of: +KEYLIST_MODE_LOCAL+, +KEYLIST_MODE_EXTERN+,
22
+ # +KEYLIST_MODE_SIGS+ or +KEYLIST_MODE_VALIDATE+.
23
+ # * +:pinentry_mode+ One of: +PINENTRY_MODE_DEFAULT+,
24
+ # +PINENTRY_MODE_ASK+, +PINENTRY_MODE_CANCEL+,
25
+ # +PINENTRY_MODE_ERROR+, or +PINENTRY_MODE_LOOPBACK+.
26
+ # * +:offline+ if set to true, dirmngr will not contact external services
27
+ # * +:password+ password of the passphrased password being used.
28
+ # * +:passphrase_callback+ A callback function. See {#set_passphrase_callback}.
29
+ # * +:passphrase_callback_value+ An object passed to passphrase_callback.
30
+ # * +:progress_callback+ A callback function. See {#set_progress_callback}.
31
+ # * +:progress_callback_value+ An object passed to progress_callback.
32
+ # * +:status_callback+ A callback function. See {#set_status_callback}.
33
+ # * +:status_callback_value+ An object passed to status_callback.
34
+ #
35
+ # @example
36
+ # ctx = GPGME::Ctx.new
37
+ # # operate on ctx
38
+ # ctx.release
39
+ #
40
+ # @example
41
+ # GPGME::Ctx.new do |ctx|
42
+ # # operate on ctx
43
+ # end
44
+ #
45
+ def self.new(options = {})
46
+ rctx = []
47
+ err = GPGME::gpgme_new(rctx)
48
+ exc = GPGME::error_to_exception(err)
49
+ raise exc if exc
50
+ ctx = rctx[0]
51
+
52
+ ctx.protocol = options[:protocol] if options[:protocol]
53
+ ctx.armor = options[:armor] if options[:armor]
54
+ ctx.textmode = options[:textmode] if options[:textmode]
55
+ ctx.keylist_mode = options[:keylist_mode] if options[:keylist_mode]
56
+ ctx.pinentry_mode = options[:pinentry_mode] if options[:pinentry_mode]
57
+ ctx.offline = options[:offline] if options[:offline]
58
+
59
+ if options[:password]
60
+ ctx.set_passphrase_callback GPGME::Ctx.method(:pass_function),
61
+ options[:password]
62
+ else
63
+ if options[:passphrase_callback]
64
+ ctx.set_passphrase_callback options[:passphrase_callback],
65
+ options[:passphrase_callback_value]
66
+ end
67
+ end
68
+ if options[:progress_callback]
69
+ ctx.set_progress_callback options[:progress_callback],
70
+ options[:progress_callback_value]
71
+ end
72
+ if options[:status_callback]
73
+ ctx.set_status_callback options[:status_callback],
74
+ options[:status_callback_value]
75
+ end
76
+
77
+ if block_given?
78
+ begin
79
+ yield ctx
80
+ ensure
81
+ GPGME::gpgme_release(ctx)
82
+ end
83
+ else
84
+ ctx
85
+ end
86
+ end
87
+
88
+
89
+ ##
90
+ # Releases the Ctx instance. Must be called if it was initialized without
91
+ # a block.
92
+ #
93
+ # @example
94
+ # ctx = GPGME::Ctx.new
95
+ # # operate on ctx
96
+ # ctx.release
97
+ #
98
+ def release
99
+ GPGME::gpgme_release(self)
100
+ end
101
+
102
+ ##
103
+ # Getters and setters
104
+ ##
105
+
106
+ # Set the +protocol+ used within this context. See {GPGME::Ctx.new} for
107
+ # possible values.
108
+ def protocol=(proto)
109
+ err = GPGME::gpgme_set_protocol(self, proto)
110
+ exc = GPGME::error_to_exception(err)
111
+ raise exc if exc
112
+ proto
113
+ end
114
+
115
+ # Return the +protocol+ used within this context.
116
+ def protocol
117
+ GPGME::gpgme_get_protocol(self)
118
+ end
119
+
120
+ # Tell whether the output should be ASCII armored.
121
+ def armor=(yes)
122
+ GPGME::gpgme_set_armor(self, yes ? 1 : 0)
123
+ yes
124
+ end
125
+
126
+ # Return true if the output is ASCII armored.
127
+ def armor
128
+ GPGME::gpgme_get_armor(self) == 1 ? true : false
129
+ end
130
+
131
+ # Tell whether canonical text mode should be used.
132
+ def textmode=(yes)
133
+ GPGME::gpgme_set_textmode(self, yes ? 1 : 0)
134
+ yes
135
+ end
136
+
137
+ # Return true if canonical text mode is enabled.
138
+ def textmode
139
+ GPGME::gpgme_get_textmode(self) == 1 ? true : false
140
+ end
141
+
142
+ # Change the default behaviour of the key listing functions.
143
+ def keylist_mode=(mode)
144
+ GPGME::gpgme_set_keylist_mode(self, mode)
145
+ mode
146
+ end
147
+
148
+ # Return the current key listing mode.
149
+ def keylist_mode
150
+ GPGME::gpgme_get_keylist_mode(self)
151
+ end
152
+
153
+ # Change the default behaviour of the pinentry invocation.
154
+ def pinentry_mode=(mode)
155
+ GPGME::gpgme_set_pinentry_mode(self, mode)
156
+ mode
157
+ end
158
+
159
+ # Return the current pinentry mode.
160
+ def pinentry_mode
161
+ GPGME::gpgme_get_pinentry_mode(self)
162
+ end
163
+
164
+ # Change the default behaviour of the dirmngr that might require
165
+ # connections to external services.
166
+ def offline=(mode)
167
+ GPGME::gpgme_set_offline(self, mode)
168
+ mode
169
+ end
170
+
171
+ # Return the current offline mode.
172
+ def offline
173
+ GPGME::gpgme_get_offline(self)
174
+ end
175
+
176
+ ##
177
+ # Passphrase and progress callbacks
178
+ ##
179
+
180
+ # Set the passphrase callback with given hook value.
181
+ # +passfunc+ should respond to +call+ with 5 arguments.
182
+ #
183
+ # * +obj+ the parameter +:passphrase_callback_value+ passed when creating
184
+ # the {GPGME::Ctx} object.
185
+ # * +uid_hint+ hint as to what key are we asking the password for. Ex:
186
+ #
187
+ # +CFB3294A50C2CFD7 Albert Llop <mrsimo@example.com>+
188
+ #
189
+ # * +passphrase_info+
190
+ # * +prev_was_bad+ 0 if it's the first time the password is being asked,
191
+ # 1 otherwise.
192
+ # * +fd+ file descriptor where the password must be written too.
193
+ #
194
+ # Expects a Method object which can be obtained by the +method+ method
195
+ # (really..).
196
+ #
197
+ # ctx.set_passphrase_callback(MyModule.method(:passfunc))
198
+ #
199
+ # @example this method will simply return +maria+ as password.
200
+ # def pass_function(obj, uid_hint, passphrase_info, prev_was_bad, fd)
201
+ # io = IO.for_fd(fd, 'w')
202
+ # io.puts "maria"
203
+ # io.flush
204
+ # end
205
+ #
206
+ # @example this will interactively ask for the password
207
+ # def passfunc(obj, uid_hint, passphrase_info, prev_was_bad, fd)
208
+ # $stderr.write("Passphrase for #{uid_hint}: ")
209
+ # $stderr.flush
210
+ # begin
211
+ # system('stty -echo')
212
+ # io = IO.for_fd(fd, 'w')
213
+ # io.puts(gets)
214
+ # io.flush
215
+ # ensure
216
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
217
+ # system('stty echo')
218
+ # end
219
+ # $stderr.puts
220
+ # end
221
+ #
222
+ # Note that this function doesn't work with GnuPG 2.0. You can
223
+ # use either GnuPG 1.x, which can be installed in parallel with
224
+ # GnuPG 2.0, or GnuPG 2.1, which has loopback pinentry feature (see
225
+ # {#pinentry_mode}).
226
+ def set_passphrase_callback(passfunc, hook_value = nil)
227
+ GPGME::gpgme_set_passphrase_cb(self, passfunc, hook_value)
228
+ end
229
+ alias set_passphrase_cb set_passphrase_callback
230
+
231
+ # Set the progress callback with given hook value.
232
+ # <i>progfunc</i> should respond to <code>call</code> with 5 arguments.
233
+ #
234
+ # def progfunc(hook, what, type, current, total)
235
+ # $stderr.write("#{what}: #{current}/#{total}\r")
236
+ # $stderr.flush
237
+ # end
238
+ #
239
+ # ctx.set_progress_callback(method(:progfunc))
240
+ #
241
+ def set_progress_callback(progfunc, hook_value = nil)
242
+ GPGME::gpgme_set_progress_cb(self, progfunc, hook_value)
243
+ end
244
+ alias set_progress_cb set_progress_callback
245
+
246
+ # Set the status callback with given hook value.
247
+ # +statusfunc+ should respond to +call+ with 3 arguments.
248
+ #
249
+ # * +obj+ the parameter +:status_callback_value+ passed when creating
250
+ # the {GPGME::Ctx} object.
251
+ # * +keyword+ the name of the status message
252
+ # * +args+ any arguments for the status message
253
+ #
254
+ # def status_function(obj, keyword, args)
255
+ # $stderr.puts("#{keyword} #{args}")
256
+ # return 0
257
+ # end
258
+ def set_status_callback(statusfunc, hook_value = nil)
259
+ GPGME::gpgme_set_status_cb(self, statusfunc, hook_value)
260
+ end
261
+ alias set_status_cb set_status_callback
262
+
263
+ ##
264
+ # Searching and iterating through keys. Used by {GPGME::Key.find}
265
+ ##
266
+
267
+ # Initiate a key listing operation for given pattern. If +pattern+ is
268
+ # +nil+, all available keys are returned. If +secret_only<+ is +true+,
269
+ # only secret keys are returned.
270
+ #
271
+ # Used by {GPGME::Ctx#each_key}
272
+ def keylist_start(pattern = nil, secret_only = false)
273
+ err = GPGME::gpgme_op_keylist_start(self, pattern, secret_only ? 1 : 0)
274
+ exc = GPGME::error_to_exception(err)
275
+ raise exc if exc
276
+ end
277
+
278
+ # Advance to the next key in the key listing operation.
279
+ #
280
+ # Used by {GPGME::Ctx#each_key}
281
+ def keylist_next
282
+ rkey = []
283
+ err = GPGME::gpgme_op_keylist_next(self, rkey)
284
+ exc = GPGME::error_to_exception(err)
285
+ raise exc if exc
286
+ rkey[0]
287
+ end
288
+
289
+ # End a pending key list operation.
290
+ #
291
+ # Used by {GPGME::Ctx#each_key}
292
+ def keylist_end
293
+ err = GPGME::gpgme_op_keylist_end(self)
294
+ exc = GPGME::error_to_exception(err)
295
+ raise exc if exc
296
+ end
297
+
298
+ # Convenient method to iterate over keys.
299
+ #
300
+ # If +pattern+ is +nil+, all available keys are returned. If +secret_only+
301
+ # is +true+, only secret keys are returned.
302
+ #
303
+ # See {GPGME::Key.find} for an example of how to use, or for an easier way
304
+ # to use.
305
+ def each_key(pattern = nil, secret_only = false, &block)
306
+ keylist_start(pattern, secret_only)
307
+ begin
308
+ loop { yield keylist_next }
309
+ rescue EOFError
310
+ # The last key in the list has already been returned.
311
+ ensure
312
+ keylist_end
313
+ end
314
+ end
315
+ alias each_keys each_key
316
+
317
+ # Returns the keys that match the +pattern+, or all if +pattern+ is nil.
318
+ # Returns only secret keys if +secret_only+ is true.
319
+ def keys(pattern = nil, secret_only = nil)
320
+ keys = []
321
+ each_key(pattern, secret_only) do |key|
322
+ keys << key
323
+ end
324
+ keys
325
+ end
326
+
327
+ # Get the key with the +fingerprint+.
328
+ # If +secret+ is +true+, secret key is returned.
329
+ def get_key(fingerprint, secret = false)
330
+ rkey = []
331
+ err = GPGME::gpgme_get_key(self, fingerprint, rkey, secret ? 1 : 0)
332
+ exc = GPGME::error_to_exception(err)
333
+ raise exc if exc
334
+ rkey[0]
335
+ end
336
+
337
+ ##
338
+ # Import/export and generation/deletion of keys
339
+ ##
340
+
341
+ # Generate a new key pair.
342
+ # +parms+ is a string which looks like
343
+ #
344
+ # <GnupgKeyParms format="internal">
345
+ # Key-Type: DSA
346
+ # Key-Length: 1024
347
+ # Subkey-Type: ELG-E
348
+ # Subkey-Length: 1024
349
+ # Name-Real: Joe Tester
350
+ # Name-Comment: with stupid passphrase
351
+ # Name-Email: joe@foo.bar
352
+ # Expire-Date: 0
353
+ # Passphrase: abc
354
+ # </GnupgKeyParms>
355
+ #
356
+ # If +pubkey+ and +seckey+ are both set to +nil+, it stores the generated
357
+ # key pair into your key ring.
358
+ def generate_key(parms, pubkey = nil, seckey = nil)
359
+ err = GPGME::gpgme_op_genkey(self, parms, pubkey, seckey)
360
+ exc = GPGME::error_to_exception(err)
361
+ raise exc if exc
362
+ end
363
+ alias genkey generate_key
364
+
365
+ # Extract the public keys that match the +recipients+. Returns a
366
+ # {GPGME::Data} object which is not rewinded (should do +seek(0)+
367
+ # before reading).
368
+ #
369
+ # Private keys cannot be exported due to GPGME restrictions.
370
+ #
371
+ # If passed, the key will be exported to +keydata+, which must be
372
+ # a {GPGME::Data} object.
373
+ def export_keys(recipients, keydata = Data.new)
374
+ err = GPGME::gpgme_op_export(self, recipients, 0, keydata)
375
+ exc = GPGME::error_to_exception(err)
376
+ raise exc if exc
377
+ keydata
378
+ end
379
+ alias export export_keys
380
+
381
+ # Add the keys in the data buffer to the key ring.
382
+ def import_keys(keydata)
383
+ err = GPGME::gpgme_op_import(self, keydata)
384
+ exc = GPGME::error_to_exception(err)
385
+ raise exc if exc
386
+ end
387
+ alias import import_keys
388
+
389
+ def import_result
390
+ GPGME::gpgme_op_import_result(self)
391
+ end
392
+
393
+ # Delete the key from the key ring.
394
+ # If allow_secret is false, only public keys are deleted,
395
+ # otherwise secret keys are deleted as well.
396
+ def delete_key(key, allow_secret = false)
397
+ err = GPGME::gpgme_op_delete(self, key, allow_secret ? 1 : 0)
398
+ exc = GPGME::error_to_exception(err)
399
+ raise exc if exc
400
+ end
401
+ alias delete delete_key
402
+
403
+ # Edit attributes of the key in the local key ring.
404
+ def edit_key(key, editfunc, hook_value = nil, out = Data.new)
405
+ err = GPGME::gpgme_op_edit(self, key, editfunc, hook_value, out)
406
+ exc = GPGME::error_to_exception(err)
407
+ raise exc if exc
408
+ end
409
+ alias edit edit_key
410
+
411
+ # Edit attributes of the key on the card.
412
+ def edit_card_key(key, editfunc, hook_value = nil, out = Data.new)
413
+ err = GPGME::gpgme_op_card_edit(self, key, editfunc, hook_value, out)
414
+ exc = GPGME::error_to_exception(err)
415
+ raise exc if exc
416
+ end
417
+ alias edit_card edit_card_key
418
+ alias card_edit edit_card_key
419
+
420
+ ##
421
+ # Crypto operations
422
+ ##
423
+
424
+ # Decrypt the ciphertext and return the plaintext.
425
+ def decrypt(cipher, plain = Data.new)
426
+ err = GPGME::gpgme_op_decrypt(self, cipher, plain)
427
+ exc = GPGME::error_to_exception(err)
428
+ raise exc if exc
429
+ plain
430
+ end
431
+
432
+ def decrypt_verify(cipher, plain = Data.new)
433
+ err = GPGME::gpgme_op_decrypt_verify(self, cipher, plain)
434
+ exc = GPGME::error_to_exception(err)
435
+ raise exc if exc
436
+ plain
437
+ end
438
+
439
+ def decrypt_result
440
+ GPGME::gpgme_op_decrypt_result(self)
441
+ end
442
+
443
+ # Verify that the signature in the data object is a valid signature.
444
+ def verify(sig, signed_text = nil, plain = Data.new)
445
+ err = GPGME::gpgme_op_verify(self, sig, signed_text, plain)
446
+ exc = GPGME::error_to_exception(err)
447
+ raise exc if exc
448
+ plain
449
+ end
450
+
451
+ def verify_result
452
+ GPGME::gpgme_op_verify_result(self)
453
+ end
454
+
455
+ # Remove the list of signers from this object.
456
+ def clear_signers
457
+ GPGME::gpgme_signers_clear(self)
458
+ end
459
+
460
+ # Add _keys_ to the list of signers.
461
+ def add_signer(*keys)
462
+ keys.each do |key|
463
+ err = GPGME::gpgme_signers_add(self, key)
464
+ exc = GPGME::error_to_exception(err)
465
+ raise exc if exc
466
+ end
467
+ end
468
+
469
+ # Create a signature for the text.
470
+ # +plain+ is a data object which contains the text.
471
+ # +sig+ is a data object where the generated signature is stored.
472
+ def sign(plain, sig = Data.new, mode = GPGME::SIG_MODE_NORMAL)
473
+ err = GPGME::gpgme_op_sign(self, plain, sig, mode)
474
+ exc = GPGME::error_to_exception(err)
475
+ raise exc if exc
476
+ sig
477
+ end
478
+
479
+ def sign_result
480
+ GPGME::gpgme_op_sign_result(self)
481
+ end
482
+
483
+ # Encrypt the plaintext in the data object for the recipients and
484
+ # return the ciphertext.
485
+ def encrypt(recp, plain, cipher = Data.new, flags = 0)
486
+ err = GPGME::gpgme_op_encrypt(self, recp, flags, plain, cipher)
487
+ exc = GPGME::error_to_exception(err)
488
+ raise exc if exc
489
+ cipher
490
+ end
491
+
492
+ def encrypt_result
493
+ GPGME::gpgme_op_encrypt_result(self)
494
+ end
495
+
496
+ def encrypt_sign(recp, plain, cipher = Data.new, flags = 0)
497
+ err = GPGME::gpgme_op_encrypt_sign(self, recp, flags, plain, cipher)
498
+ exc = GPGME::error_to_exception(err)
499
+ raise exc if exc
500
+ cipher
501
+ end
502
+
503
+ def spawn(file, argv, datain, dataout, dataerr, flags = 0)
504
+ err = GPGME::gpgme_op_spawn(self, file, argv, datain, dataout, dataerr,
505
+ flags)
506
+ exc = GPGME::error_to_exception(err)
507
+ raise exc if exc
508
+ end
509
+
510
+ def inspect
511
+ "#<#{self.class} protocol=#{PROTOCOL_NAMES[protocol] || protocol}, \
512
+ armor=#{armor}, textmode=#{textmode}, \
513
+ keylist_mode=#{KEYLIST_MODE_NAMES[keylist_mode]}>"
514
+ end
515
+
516
+ private
517
+
518
+ def self.pass_function(pass, uid_hint, passphrase_info, prev_was_bad, fd)
519
+ io = IO.for_fd(fd, 'w')
520
+ io.puts pass
521
+ io.flush
522
+ end
523
+
524
+ end
525
+ end