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.

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



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
75
76
77
78
# File 'lib/gpgme/ctx.rb', line 42

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]

  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

Instance Method Details

#add_signer(*keys) ⇒ Object

Add keys to the list of signers.



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

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.



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

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

#armor=(yes) ⇒ Object

Tell whether the output should be ASCII armored.



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

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

#clear_signersObject

Remove the list of signers from this object.



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

def clear_signers
  GPGME::gpgme_signers_clear(self)
end

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

Decrypt the ciphertext and return the plaintext.



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

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



402
403
404
# File 'lib/gpgme/ctx.rb', line 402

def decrypt_result
  GPGME::gpgme_op_decrypt_result(self)
end

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



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

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.



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

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.



268
269
270
271
272
273
274
275
276
277
# File 'lib/gpgme/ctx.rb', line 268

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.



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

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.



367
368
369
370
371
# File 'lib/gpgme/ctx.rb', line 367

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.



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

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



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

def encrypt_result
  GPGME::gpgme_op_encrypt_result(self)
end

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



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

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.



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

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.



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

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.



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

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.



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

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

#import_resultObject



352
353
354
# File 'lib/gpgme/ctx.rb', line 352

def import_result
  GPGME::gpgme_op_import_result(self)
end

#inspectObject



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

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



255
256
257
258
259
# File 'lib/gpgme/ctx.rb', line 255

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.



141
142
143
# File 'lib/gpgme/ctx.rb', line 141

def keylist_mode
  GPGME::gpgme_get_keylist_mode(self)
end

#keylist_mode=(mode) ⇒ Object

Change the default behaviour of the key listing functions.



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

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



244
245
246
247
248
249
250
# File 'lib/gpgme/ctx.rb', line 244

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



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

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.



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

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

#pinentry_modeObject

Return the current pinentry mode.



152
153
154
# File 'lib/gpgme/ctx.rb', line 152

def pinentry_mode
  GPGME::gpgme_get_pinentry_mode(self)
end

#pinentry_mode=(mode) ⇒ Object

Change the default behaviour of the pinentry invocation.



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

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

#protocolObject

Return the protocol used within this context.



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

def protocol
  GPGME::gpgme_get_protocol(self)
end

#protocol=(proto) ⇒ Object

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



100
101
102
103
104
105
# File 'lib/gpgme/ctx.rb', line 100

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


90
91
92
# File 'lib/gpgme/ctx.rb', line 90

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


206
207
208
# File 'lib/gpgme/ctx.rb', line 206

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


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

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.



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

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



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

def sign_result
  GPGME::gpgme_op_sign_result(self)
end

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



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

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.



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

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

#textmode=(yes) ⇒ Object

Tell whether canonical text mode should be used.



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

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.



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

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



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

def verify_result
  GPGME::gpgme_op_verify_result(self)
end