I am using ruby gpgme gem (1.0.8). My passphrase callback isn\'t called:
def passfunc(*args)
fd = args.last
io = IO.for_fd(fd, \'w\')
io.puts \"mypassp
Here's another working example for you that doesn't use a detached signature. To test this, simply change 'user@host.name' to the identifier of your key and do this: GPG.decrypt(GPG.encrypt('some text', :armor => true))
require 'gpgme'
require 'highline/import'
module GPG
ENCRYPT_KEY = 'user@host.com'
@gpg = GPGME::Crypto.new
class << self
def decrypt(encrypted_data, options = {})
options = { :passphrase_callback => self.method(:passfunc) }.merge(options)
@gpg.decrypt(encrypted_data, options).read
end
def encrypt(data_to_encrypt, options = {})
options = { :passphrase_callback => self.method(:passfunc), :armor => true }.merge(options)
@gpg.encrypt(data_to_encrypt, options).read
end
private
def get_passphrase
ask("Enter passphrase for #{ENCRYPT_KEY}: ") { |q| q.echo = '*' }
end
def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
begin
system('stty -echo')
io = IO.for_fd(fd, 'w')
io.puts(get_passphrase)
io.flush
ensure
(0 ... $_.length).each do |i| $_[i] = ?0 end if $_
system('stty echo')
end
$stderr.puts
end
end
end
Cheers!,
-- Carl
Sample of callback you can find in the following working example. It signs a file in detached mode, i.e., the signature file is separated from the original file. It uses the default keyring at ~/.gnupg or something like that. To use a different directory for your keyring, set the environment variable ENV["GNUPGHOME"]="" before call GPGME::sign().
#!/usr/bin/ruby
require 'rubygems'
require 'gpgme'
puts "Signing #{ARGV[0]}"
input = File.open(ARGV[0],'r')
PASSWD = "abc"
def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
puts("Passphrase for #{uid_hint}: ")
io = IO.for_fd(fd, 'w')
io.write(PASSWD+"\n")
io.flush
end
output = File.open(ARGV[0]+'.asc','w')
sign = GPGME::sign(input, {
:passphrase_callback => method(:passfunc),
:mode => GPGME::SIG_MODE_DETACH
})
output.write(sign)
output.close
input.close
It is important to note that as of GnuPG 2.0 (and in 1.4 when the use-agent
option is used) pinentry
is used for passphrase collection. This means that the gpgme passphrase callback will not be invoked. This is described here and an example of usage can be found in the gpgme-tool
example.