Class: GPGME::Ctx

Inherits:
Object
  • Object
show all
Defined in:
lib/gpgme/ctx.rb,
lib/gpgme/compat.rb,
lib/gpgme/ffi/ctx.rb

Overview

A context within which all cryptographic operations are performed.

More operations can be done which are not available in the higher level API. Note how to create a new instance of this class in Ctx.new.

Defined Under Namespace

Classes: Pointer

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#context_passphrase_callbackObject

Returns the value of attribute context_passphrase_callback.



3
4
5
# File 'lib/gpgme/ffi/ctx.rb', line 3

def context_passphrase_callback
  @context_passphrase_callback
end

#context_progress_callbackObject

Returns the value of attribute context_progress_callback.



4
5
6
# File 'lib/gpgme/ffi/ctx.rb', line 4

def context_progress_callback
  @context_progress_callback
end

Class Method Details

.new(options = {}) ⇒ Object

Create a new instance from the given options. Must be released either executing the operations inside a block, or executing #release afterwards.

Examples:

ctx = GPGME::Ctx.new
# operate on ctx
ctx.release
GPGME::Ctx.new do |ctx|
  # operate on ctx
end

Parameters:

  • options (Hash) (defaults to: {})

    The optional parameters are as follows:

    • :protocol Either PROTOCOL_OpenPGP or PROTOCOL_CMS.

    • :armor will return ASCII armored outputs if specified true.

    • :textmode if true, inform the recipient that the input is text.

    • :keylist_mode One of: KEYLIST_MODE_LOCAL, KEYLIST_MODE_EXTERN, KEYLIST_MODE_SIGS or KEYLIST_MODE_VALIDATE.

    • :password password of the passphrased password being used.

    • :passphrase_callback A callback function. See #set_passphrase_callback.

    • :passphrase_callback_value An object passed to passphrase_callback.

    • :progress_callback A callback function. See #set_progress_callback.

    • :progress_callback_value An object passed to progress_callback.



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
# File 'lib/gpgme/ctx.rb', line 39

def self.new(options = {})
  rctx = []
  err = GPGME::gpgme_new(rctx)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  ctx = rctx[0]

  ctx.protocol     = options[:protocol]     if options[:protocol]
  ctx.armor        = options[:armor]        if options[:armor]
  ctx.textmode     = options[:textmode]     if options[:textmode]
  ctx.keylist_mode = options[:keylist_mode] if options[:keylist_mode]

  if options[:password]
    ctx.set_passphrase_callback GPGME::Ctx.method(:pass_function),
      options[:password]
  else
    if options[:passphrase_callback]
      ctx.set_passphrase_callback options[:passphrase_callback],
        options[:passphrase_callback_value]
    end
  end
  if options[:progress_callback]
    ctx.set_progress_callback options[:progress_callback],
      options[:progress_callback_value]
  end

  if block_given?
    begin
      yield ctx
    ensure
      GPGME::gpgme_release(ctx)
    end
  else
    ctx
  end
end

.new_from_struct(pointer) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/gpgme/ffi/ctx.rb', line 12

def self.new_from_struct(pointer)
  instance = allocate

  instance.instance_exec do
    @context_passphrase_callback = [ nil, nil, nil ]
    @context_progress_callback   = [ nil, nil, nil ]

    @ptr = Pointer.new pointer
  end

  instance
end

Instance Method Details

#add_signer(*keys) ⇒ Object

Add keys to the list of signers.



405
406
407
408
409
410
411
# File 'lib/gpgme/ctx.rb', line 405

def add_signer(*keys)
  keys.each do |key|
    err = GPGME::gpgme_signers_add(self, key)
    exc = GPGME::error_to_exception(err)
    raise exc if exc
  end
end

#armorObject

Return true if the output is ASCII armored.



115
116
117
# File 'lib/gpgme/ctx.rb', line 115

def armor
  GPGME::gpgme_get_armor(self) == 1 ? true : false
end

#armor=(yes) ⇒ Object

Tell whether the output should be ASCII armored.



109
110
111
112
# File 'lib/gpgme/ctx.rb', line 109

def armor=(yes)
  GPGME::gpgme_set_armor(self, yes ? 1 : 0)
  yes
end

#clear_signersObject

Remove the list of signers from this object.



400
401
402
# File 'lib/gpgme/ctx.rb', line 400

def clear_signers
  GPGME::gpgme_signers_clear(self)
end

#context_pointerObject



31
32
33
34
# File 'lib/gpgme/ffi/ctx.rb', line 31

def context_pointer
  raise "context is already released" if @ptr.nil?
  @ptr
end

#decrypt(cipher, plain = Data.new) ⇒ Object

Decrypt the ciphertext and return the plaintext.



369
370
371
372
373
374
# File 'lib/gpgme/ctx.rb', line 369

def decrypt(cipher, plain = Data.new)
  err = GPGME::gpgme_op_decrypt(self, cipher, plain)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  plain
end

#decrypt_resultObject



383
384
385
# File 'lib/gpgme/ctx.rb', line 383

def decrypt_result
  GPGME::gpgme_op_decrypt_result(self)
end

#decrypt_verify(cipher, plain = Data.new) ⇒ Object



376
377
378
379
380
381
# File 'lib/gpgme/ctx.rb', line 376

def decrypt_verify(cipher, plain = Data.new)
  err = GPGME::gpgme_op_decrypt_verify(self, cipher, plain)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  plain
end

#delete_key(key, allow_secret = false) ⇒ Object Also known as: delete

Delete the key from the key ring. If allow_secret is false, only public keys are deleted, otherwise secret keys are deleted as well.



340
341
342
343
344
# File 'lib/gpgme/ctx.rb', line 340

def delete_key(key, allow_secret = false)
  err = GPGME::gpgme_op_delete(self, key, allow_secret ? 1 : 0)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end

#each_key(pattern = nil, secret_only = false, &block) ⇒ Object Also known as: each_keys

Convenient method to iterate over keys.

If pattern is nil, all available keys are returned. If secret_only is true, only secret keys are returned.

See Key.find for an example of how to use, or for an easier way to use.



249
250
251
252
253
254
255
256
257
258
# File 'lib/gpgme/ctx.rb', line 249

def each_key(pattern = nil, secret_only = false, &block)
  keylist_start(pattern, secret_only)
  begin
    loop { yield keylist_next }
  rescue EOFError
    # The last key in the list has already been returned.
  ensure
    keylist_end
  end
end

#edit_card_key(key, editfunc, hook_value = nil, out = Data.new) ⇒ Object Also known as: edit_card, card_edit

Edit attributes of the key on the card.



356
357
358
359
360
# File 'lib/gpgme/ctx.rb', line 356

def edit_card_key(key, editfunc, hook_value = nil, out = Data.new)
  err = GPGME::gpgme_op_card_edit(self, key, editfunc, hook_value, out)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end

#edit_key(key, editfunc, hook_value = nil, out = Data.new) ⇒ Object Also known as: edit

Edit attributes of the key in the local key ring.



348
349
350
351
352
# File 'lib/gpgme/ctx.rb', line 348

def edit_key(key, editfunc, hook_value = nil, out = Data.new)
  err = GPGME::gpgme_op_edit(self, key, editfunc, hook_value, out)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end

#encrypt(recp, plain, cipher = Data.new, flags = 0) ⇒ Object

Encrypt the plaintext in the data object for the recipients and return the ciphertext.



429
430
431
432
433
434
# File 'lib/gpgme/ctx.rb', line 429

def encrypt(recp, plain, cipher = Data.new, flags = 0)
  err = GPGME::gpgme_op_encrypt(self, recp, flags, plain, cipher)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  cipher
end

#encrypt_resultObject



436
437
438
# File 'lib/gpgme/ctx.rb', line 436

def encrypt_result
  GPGME::gpgme_op_encrypt_result(self)
end

#encrypt_sign(recp, plain, cipher = Data.new, flags = 0) ⇒ Object



440
441
442
443
444
445
# File 'lib/gpgme/ctx.rb', line 440

def encrypt_sign(recp, plain, cipher = Data.new, flags = 0)
  err = GPGME::gpgme_op_encrypt_sign(self, recp, flags, plain, cipher)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  cipher
end

#export_keys(recipients, keydata = Data.new) ⇒ Object Also known as: export

Extract the public keys that match the recipients. Returns a Data object which is not rewinded (should do seek(0) before reading).

Private keys cannot be exported due to GPGME restrictions.

If passed, the key will be exported to keydata, which must be a Data object.



317
318
319
320
321
322
# File 'lib/gpgme/ctx.rb', line 317

def export_keys(recipients, keydata = Data.new)
  err = GPGME::gpgme_op_export(self, recipients, 0, keydata)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  keydata
end

#generate_key(parms, pubkey = nil, seckey = nil) ⇒ Object Also known as: genkey

Generate a new key pair. parms is a string which looks like

<GnupgKeyParms format="internal">
Key-Type: DSA
Key-Length: 1024
Subkey-Type: ELG-E
Subkey-Length: 1024
Name-Real: Joe Tester
Name-Comment: with stupid passphrase
Name-Email: [email protected]
Expire-Date: 0
Passphrase: abc
</GnupgKeyParms>

If pubkey and seckey are both set to nil, it stores the generated key pair into your key ring.



302
303
304
305
306
# File 'lib/gpgme/ctx.rb', line 302

def generate_key(parms, pubkey = nil, seckey = nil)
  err = GPGME::gpgme_op_genkey(self, parms, pubkey, seckey)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end

#get_key(fingerprint, secret = false) ⇒ Object

Get the key with the fingerprint. If secret is true, secret key is returned.



273
274
275
276
277
278
279
# File 'lib/gpgme/ctx.rb', line 273

def get_key(fingerprint, secret = false)
  rkey = []
  err = GPGME::gpgme_get_key(self, fingerprint, rkey, secret ? 1 : 0)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  rkey[0]
end

#import_keys(keydata) ⇒ Object Also known as: import

Add the keys in the data buffer to the key ring.



326
327
328
329
330
# File 'lib/gpgme/ctx.rb', line 326

def import_keys(keydata)
  err = GPGME::gpgme_op_import(self, keydata)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end

#import_resultObject



333
334
335
# File 'lib/gpgme/ctx.rb', line 333

def import_result
  GPGME::gpgme_op_import_result(self)
end

#inspectObject



447
448
449
450
451
# File 'lib/gpgme/ctx.rb', line 447

def inspect
  "#<#{self.class} protocol=#{PROTOCOL_NAMES[protocol] || protocol}, \
armor=#{armor}, textmode=#{textmode}, \
keylist_mode=#{KEYLIST_MODE_NAMES[keylist_mode]}>"
end

#keylist_endObject

End a pending key list operation.

Used by #each_key



236
237
238
239
240
# File 'lib/gpgme/ctx.rb', line 236

def keylist_end
  err = GPGME::gpgme_op_keylist_end(self)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end

#keylist_modeObject

Return the current key listing mode.



137
138
139
# File 'lib/gpgme/ctx.rb', line 137

def keylist_mode
  GPGME::gpgme_get_keylist_mode(self)
end

#keylist_mode=(mode) ⇒ Object

Change the default behaviour of the key listing functions.



131
132
133
134
# File 'lib/gpgme/ctx.rb', line 131

def keylist_mode=(mode)
  GPGME::gpgme_set_keylist_mode(self, mode)
  mode
end

#keylist_nextObject

Advance to the next key in the key listing operation.

Used by #each_key



225
226
227
228
229
230
231
# File 'lib/gpgme/ctx.rb', line 225

def keylist_next
  rkey = []
  err = GPGME::gpgme_op_keylist_next(self, rkey)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  rkey[0]
end

#keylist_start(pattern = nil, secret_only = false) ⇒ Object

Initiate a key listing operation for given pattern. If pattern is nil, all available keys are returned. If secret_only< is true, only secret keys are returned.

Used by #each_key



216
217
218
219
220
# File 'lib/gpgme/ctx.rb', line 216

def keylist_start(pattern = nil, secret_only = false)
  err = GPGME::gpgme_op_keylist_start(self, pattern, secret_only ? 1 : 0)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end

#keys(pattern = nil, secret_only = nil) ⇒ Object

Returns the keys that match the pattern, or all if pattern is nil. Returns only secret keys if secret_only is true.



263
264
265
266
267
268
269
# File 'lib/gpgme/ctx.rb', line 263

def keys(pattern = nil, secret_only = nil)
  keys = []
  each_key(pattern, secret_only) do |key|
    keys << key
  end
  keys
end

#protocolObject

Return the protocol used within this context.



104
105
106
# File 'lib/gpgme/ctx.rb', line 104

def protocol
  GPGME::gpgme_get_protocol(self)
end

#protocol=(proto) ⇒ Object

Set the protocol used within this context. See new for possible values.



96
97
98
99
100
101
# File 'lib/gpgme/ctx.rb', line 96

def protocol=(proto)
  err = GPGME::gpgme_set_protocol(self, proto)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  proto
end

#releaseObject

Releases the Ctx instance. Must be called if it was initialized without a block.

Examples:

ctx = GPGME::Ctx.new
# operate on ctx
ctx.release


86
87
88
# File 'lib/gpgme/ctx.rb', line 86

def release
  GPGME::gpgme_release(self)
end

#release_pointerObject

Raises:

  • (ArgumentError)


25
26
27
28
29
# File 'lib/gpgme/ffi/ctx.rb', line 25

def release_pointer
  raise ArgumentError, "released ctx" if @ptr.nil?
  @ptr.free
  @ptr = nil
end

#rewindObject

Set the data pointer to the beginning.



26
27
28
# File 'lib/gpgme/compat.rb', line 26

def rewind
  seek(0)
end

#set_passphrase_callback(passfunc, hook_value = nil) ⇒ Object Also known as: set_passphrase_cb

Set the passphrase callback with given hook value. passfunc should respond to call with 5 arguments.

  • obj the parameter :passphrase_callback_value passed when creating the GPGME::Ctx object.

  • uid_hint hint as to what key are we asking the password for. Ex:

    CFB3294A50C2CFD7 Albert Llop <[email protected]>

  • passphrase_info

  • prev_was_bad 0 if it’s the first time the password is being asked, 1 otherwise.

  • fd file descriptor where the password must be written too.

Expects a Method object which can be obtained by the method method (really..).

ctx.set_passphrase_callback(MyModule.method(:passfunc))

Examples:

this method will simply return maria as password.

def pass_function(obj, uid_hint, passphrase_info, prev_was_bad, fd)
  io = ::FFI::IO.for_fd(fd, 'w')
  io.puts "maria"
  io.flush
end

this will interactively ask for the password

def passfunc(obj, uid_hint, passphrase_info, prev_was_bad, fd)
  $stderr.write("Passphrase for #{uid_hint}: ")
  $stderr.flush
  begin
    system('stty -echo')
    io = ::FFI::IO.for_fd(fd, 'w')
    io.puts(gets)
    io.flush
  ensure
    (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
    system('stty echo')
  end
  $stderr.puts
end


187
188
189
# File 'lib/gpgme/ctx.rb', line 187

def set_passphrase_callback(passfunc, hook_value = nil)
  GPGME::gpgme_set_passphrase_cb(self, passfunc, hook_value)
end

#set_progress_callback(progfunc, hook_value = nil) ⇒ Object Also known as: set_progress_cb

Set the progress callback with given hook value. progfunc should respond to call with 5 arguments.

def progfunc(hook, what, type, current, total)
  $stderr.write("#{what}: #{current}/#{total}\r")
  $stderr.flush
end

ctx.set_progress_callback(method(:progfunc))


202
203
204
# File 'lib/gpgme/ctx.rb', line 202

def set_progress_callback(progfunc, hook_value = nil)
  GPGME::gpgme_set_progress_cb(self, progfunc, hook_value)
end

#sign(plain, sig = Data.new, mode = GPGME::SIG_MODE_NORMAL) ⇒ Object

Create a signature for the text. plain is a data object which contains the text. sig is a data object where the generated signature is stored.



416
417
418
419
420
421
# File 'lib/gpgme/ctx.rb', line 416

def sign(plain, sig = Data.new, mode = GPGME::SIG_MODE_NORMAL)
  err = GPGME::gpgme_op_sign(self, plain, sig, mode)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  sig
end

#sign_resultObject



423
424
425
# File 'lib/gpgme/ctx.rb', line 423

def sign_result
  GPGME::gpgme_op_sign_result(self)
end

#textmodeObject

Return true if canonical text mode is enabled.



126
127
128
# File 'lib/gpgme/ctx.rb', line 126

def textmode
  GPGME::gpgme_get_textmode(self) == 1 ? true : false
end

#textmode=(yes) ⇒ Object

Tell whether canonical text mode should be used.



120
121
122
123
# File 'lib/gpgme/ctx.rb', line 120

def textmode=(yes)
  GPGME::gpgme_set_textmode(self, yes ? 1 : 0)
  yes
end

#verify(sig, signed_text = nil, plain = Data.new) ⇒ Object

Verify that the signature in the data object is a valid signature.



388
389
390
391
392
393
# File 'lib/gpgme/ctx.rb', line 388

def verify(sig, signed_text = nil, plain = Data.new)
  err = GPGME::gpgme_op_verify(self, sig, signed_text, plain)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  plain
end

#verify_resultObject



395
396
397
# File 'lib/gpgme/ctx.rb', line 395

def verify_result
  GPGME::gpgme_op_verify_result(self)
end