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
87
# 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]
  ctx.ignore_mdc_error  = options[:ignore_mdc_error]  if options[:ignore_mdc_error]

  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.



515
516
517
518
519
520
521
# File 'lib/gpgme/ctx.rb', line 515

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.



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

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

#armor=(yes) ⇒ Object

Tell whether the output should be ASCII armored.



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

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

#clear_signersObject

Remove the list of signers from this object.



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

def clear_signers
  GPGME::gpgme_signers_clear(self)
end

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

Decrypt the ciphertext and return the plaintext.



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

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



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

def decrypt_result
  GPGME::gpgme_op_decrypt_result(self)
end

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



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

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.



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

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.



359
360
361
362
363
364
365
366
367
368
# File 'lib/gpgme/ctx.rb', line 359

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.



466
467
468
469
470
# File 'lib/gpgme/ctx.rb', line 466

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.



458
459
460
461
462
# File 'lib/gpgme/ctx.rb', line 458

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.



539
540
541
542
543
544
# File 'lib/gpgme/ctx.rb', line 539

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



546
547
548
# File 'lib/gpgme/ctx.rb', line 546

def encrypt_result
  GPGME::gpgme_op_encrypt_result(self)
end

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



550
551
552
553
554
555
# File 'lib/gpgme/ctx.rb', line 550

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.



427
428
429
430
431
432
# File 'lib/gpgme/ctx.rb', line 427

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.



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

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_ctx_flag(flag_name) ⇒ Object

Get the value of the Ctx flag with the given name.

Allowed flag names may include:

  • ‘redraw’

  • ‘full-status’

  • ‘raw-description’

  • ‘export-session-key’

  • ‘override-session-key’

  • ‘include-key-block’

  • ‘auto-key-import’

  • ‘auto-key-retrieve’

  • ‘request-origin’

  • ‘no-symkey-cache’

  • ‘ignore-mdc-error’

  • ‘auto-key-locate’

  • ‘trust-model’

  • ‘extended-edit’

  • ‘cert-expire’

  • ‘key-origin’

  • ‘import-filter’

  • ‘no-auto-check-trustdb’

Please consult the GPGPME documentation for more details



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

def get_ctx_flag(flag_name)
  GPGME::gpgme_get_ctx_flag(self, flag_name.to_s)
end

#get_key(fingerprint, secret = false) ⇒ Object

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



383
384
385
386
387
388
389
# File 'lib/gpgme/ctx.rb', line 383

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

#ignore_mdc_errorObject

Return true if the MDC integrity protection is disabled.



181
182
183
# File 'lib/gpgme/ctx.rb', line 181

def ignore_mdc_error
  GPGME::gpgme_get_ignore_mdc_error(self) == 1 ? true : false
end

#ignore_mdc_error=(yes) ⇒ Object

This option ignores a MDC integrity protection failure. It is required to decrypt old messages which did not use an MDC. It may also be useful if a message is partially garbled, but it is necessary to get as much data as possible out of that garbled message. Be aware that a missing or failed MDC can be an indication of an attack. Use with great caution.



175
176
177
178
# File 'lib/gpgme/ctx.rb', line 175

def ignore_mdc_error=(yes)
  GPGME::gpgme_set_ignore_mdc_error(self, yes ? 1 : 0)
  yes
end

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

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



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

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

#import_resultObject



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

def import_result
  GPGME::gpgme_op_import_result(self)
end

#inspectObject



564
565
566
567
568
# File 'lib/gpgme/ctx.rb', line 564

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



346
347
348
349
350
# File 'lib/gpgme/ctx.rb', line 346

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.



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

def keylist_mode
  GPGME::gpgme_get_keylist_mode(self)
end

#keylist_mode=(mode) ⇒ Object

Change the default behaviour of the key listing functions.



197
198
199
200
# File 'lib/gpgme/ctx.rb', line 197

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



335
336
337
338
339
340
341
# File 'lib/gpgme/ctx.rb', line 335

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



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

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.



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

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.



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

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.



220
221
222
223
# File 'lib/gpgme/ctx.rb', line 220

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

#pinentry_modeObject

Return the current pinentry mode.



214
215
216
# File 'lib/gpgme/ctx.rb', line 214

def pinentry_mode
  GPGME::gpgme_get_pinentry_mode(self)
end

#pinentry_mode=(mode) ⇒ Object

Change the default behaviour of the pinentry invocation.



208
209
210
211
# File 'lib/gpgme/ctx.rb', line 208

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

#protocolObject

Return the protocol used within this context.



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

def protocol
  GPGME::gpgme_get_protocol(self)
end

#protocol=(proto) ⇒ Object

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



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

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


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

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_ctx_flag(flag_name, val) ⇒ Object

Set the Ctx flag with the given name to the given value.



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

def set_ctx_flag(flag_name, val)
  err = GPGME::gpgme_set_ctx_flag(self, flag_name.to_s, val.to_s)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
  val
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


280
281
282
# File 'lib/gpgme/ctx.rb', line 280

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


295
296
297
# File 'lib/gpgme/ctx.rb', line 295

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


312
313
314
# File 'lib/gpgme/ctx.rb', line 312

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.



526
527
528
529
530
531
# File 'lib/gpgme/ctx.rb', line 526

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



533
534
535
# File 'lib/gpgme/ctx.rb', line 533

def sign_result
  GPGME::gpgme_op_sign_result(self)
end

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



557
558
559
560
561
562
# File 'lib/gpgme/ctx.rb', line 557

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.



192
193
194
# File 'lib/gpgme/ctx.rb', line 192

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

#textmode=(yes) ⇒ Object

Tell whether canonical text mode should be used.



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

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.



498
499
500
501
502
503
# File 'lib/gpgme/ctx.rb', line 498

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



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

def verify_result
  GPGME::gpgme_op_verify_result(self)
end