Class: GPGME::Ctx

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

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.

Class Method Summary collapse

Instance Method Summary collapse

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.

    • :pinentry_mode One of: PINENTRY_MODE_DEFAULT, PINENTRY_MODE_ASK, PINENTRY_MODE_CANCEL, PINENTRY_MODE_ERROR, or PINENTRY_MODE_LOOPBACK.

    • :offline if set to true, dirmngr will not contact external services

    • :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.

    • :status_callback A callback function. See #set_status_callback.

    • :status_callback_value An object passed to status_callback.


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

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]
  ctx.pinentry_mode = options[:pinentry_mode] if options[:pinentry_mode]
  ctx.offline       = options[:offline]       if options[:offline]

  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 options[:status_callback]
    ctx.set_status_callback options[:status_callback],
      options[:status_callback_value]
  end

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

Instance Method Details

#add_signer(*keys) ⇒ Object

Add keys to the list of signers.


461
462
463
464
465
466
467
# File 'lib/gpgme/ctx.rb', line 461

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.


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

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

#armor=(yes) ⇒ Object

Tell whether the output should be ASCII armored.


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

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

#clear_signersObject

Remove the list of signers from this object.


456
457
458
# File 'lib/gpgme/ctx.rb', line 456

def clear_signers
  GPGME::gpgme_signers_clear(self)
end

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

Decrypt the ciphertext and return the plaintext.


425
426
427
428
429
430
# File 'lib/gpgme/ctx.rb', line 425

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


439
440
441
# File 'lib/gpgme/ctx.rb', line 439

def decrypt_result
  GPGME::gpgme_op_decrypt_result(self)
end

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


432
433
434
435
436
437
# File 'lib/gpgme/ctx.rb', line 432

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.


396
397
398
399
400
# File 'lib/gpgme/ctx.rb', line 396

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.


305
306
307
308
309
310
311
312
313
314
# File 'lib/gpgme/ctx.rb', line 305

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.


412
413
414
415
416
# File 'lib/gpgme/ctx.rb', line 412

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.


404
405
406
407
408
# File 'lib/gpgme/ctx.rb', line 404

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.


485
486
487
488
489
490
# File 'lib/gpgme/ctx.rb', line 485

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


492
493
494
# File 'lib/gpgme/ctx.rb', line 492

def encrypt_result
  GPGME::gpgme_op_encrypt_result(self)
end

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


496
497
498
499
500
501
# File 'lib/gpgme/ctx.rb', line 496

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, mode = 0) ⇒ 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.


373
374
375
376
377
378
# File 'lib/gpgme/ctx.rb', line 373

def export_keys(recipients, keydata = Data.new, mode=0)
  err = GPGME::gpgme_op_export(self, recipients, mode, 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.


358
359
360
361
362
# File 'lib/gpgme/ctx.rb', line 358

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.


329
330
331
332
333
334
335
# File 'lib/gpgme/ctx.rb', line 329

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.


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

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

#import_resultObject


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

def import_result
  GPGME::gpgme_op_import_result(self)
end

#inspectObject


510
511
512
513
514
# File 'lib/gpgme/ctx.rb', line 510

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


292
293
294
295
296
# File 'lib/gpgme/ctx.rb', line 292

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.


149
150
151
# File 'lib/gpgme/ctx.rb', line 149

def keylist_mode
  GPGME::gpgme_get_keylist_mode(self)
end

#keylist_mode=(mode) ⇒ Object

Change the default behaviour of the key listing functions.


143
144
145
146
# File 'lib/gpgme/ctx.rb', line 143

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


281
282
283
284
285
286
287
# File 'lib/gpgme/ctx.rb', line 281

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


272
273
274
275
276
# File 'lib/gpgme/ctx.rb', line 272

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.


319
320
321
322
323
324
325
# File 'lib/gpgme/ctx.rb', line 319

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

#offlineObject

Return the current offline mode.


172
173
174
# File 'lib/gpgme/ctx.rb', line 172

def offline
  GPGME::gpgme_get_offline(self)
end

#offline=(mode) ⇒ Object

Change the default behaviour of the dirmngr that might require connections to external services.


166
167
168
169
# File 'lib/gpgme/ctx.rb', line 166

def offline=(mode)
  GPGME::gpgme_set_offline(self, mode)
  mode
end

#pinentry_modeObject

Return the current pinentry mode.


160
161
162
# File 'lib/gpgme/ctx.rb', line 160

def pinentry_mode
  GPGME::gpgme_get_pinentry_mode(self)
end

#pinentry_mode=(mode) ⇒ Object

Change the default behaviour of the pinentry invocation.


154
155
156
157
# File 'lib/gpgme/ctx.rb', line 154

def pinentry_mode=(mode)
  GPGME::gpgme_set_pinentry_mode(self, mode)
  mode
end

#protocolObject

Return the protocol used within this context.


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

def protocol
  GPGME::gpgme_get_protocol(self)
end

#protocol=(proto) ⇒ Object

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


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

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

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

def release
  GPGME::gpgme_release(self)
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))

Note that this function doesn't work with GnuPG 2.0. You can use either GnuPG 1.x, which can be installed in parallel with GnuPG 2.0, or GnuPG 2.1, which has loopback pinentry feature (see #pinentry_mode).

Examples:

this method will simply return maria as password.

def pass_function(obj, uid_hint, passphrase_info, prev_was_bad, fd)
  io = 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 = 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

226
227
228
# File 'lib/gpgme/ctx.rb', line 226

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))

241
242
243
# File 'lib/gpgme/ctx.rb', line 241

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

#set_status_callback(statusfunc, hook_value = nil) ⇒ Object Also known as: set_status_cb

Set the status callback with given hook value. statusfunc should respond to call with 3 arguments.

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

  • keyword the name of the status message

  • args any arguments for the status message

def status_function(obj, keyword, args)
  $stderr.puts("#{keyword} #{args}")
  return 0
end

258
259
260
# File 'lib/gpgme/ctx.rb', line 258

def set_status_callback(statusfunc, hook_value = nil)
  GPGME::gpgme_set_status_cb(self, statusfunc, 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.


472
473
474
475
476
477
# File 'lib/gpgme/ctx.rb', line 472

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


479
480
481
# File 'lib/gpgme/ctx.rb', line 479

def sign_result
  GPGME::gpgme_op_sign_result(self)
end

#spawn(file, argv, datain, dataout, dataerr, flags = 0) ⇒ Object


503
504
505
506
507
508
# File 'lib/gpgme/ctx.rb', line 503

def spawn(file, argv, datain, dataout, dataerr, flags = 0)
  err = GPGME::gpgme_op_spawn(self, file, argv, datain, dataout, dataerr,
                              flags)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end

#textmodeObject

Return true if canonical text mode is enabled.


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

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

#textmode=(yes) ⇒ Object

Tell whether canonical text mode should be used.


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

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.


444
445
446
447
448
449
# File 'lib/gpgme/ctx.rb', line 444

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


451
452
453
# File 'lib/gpgme/ctx.rb', line 451

def verify_result
  GPGME::gpgme_op_verify_result(self)
end