GPGME gem - cannot figure out how to decrypt data

Hello,

I’m pretty new to ruby and this is my first real program I’m writing.
Currently I face an issue with the GPGME gem that I cannot figure out
how to solve: The GPGME::decrypt method does not seem to work as I
expect it, after reading the documentation.
In fact the program seems to hang somewhere during the decryption. My
guess is that something is wrong with my passphrase callback method, but
I cannot figure out how this needs to be done, as the examples for the
gem does not contain a decryption example, only a signing example from
which I have copied the passphrase callback method, but the method does
not seem to work, as the callback method seems to be called with no
arguments.

I have written a test script to work on this problem, it can be found at
the end of the email.
When it hangs after the passphrase callback, after waiting about 10
seconds I’m pressing ^C to interrupt the script. The output of the test
script is as follows:
$ RUBYOPT=rubygems ruby test.rb
pwd:
xxx
encrypting
dumping to file
decrypting
Passphrase callback
^C/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme.rb:1212:in
decrypt_verify': Interrupt from /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme.rb:134:in decrypt’
from
/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme.rb:943:in new' from /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme.rb:130:in decrypt’
from test.rb:51:in decrypt' from test.rb:43:in run_test’
from test.rb:33:in initialize' from /usr/ruby/1.8/lib/ruby/1.8/singleton.rb:94:in new’
from /usr/ruby/1.8/lib/ruby/1.8/singleton.rb:94:in `instance’
from test.rb:56

$ gpg --decrypt edata

You need a passphrase to unlock the secret key for
user: “xxxx xxxxxxxxxxxx [email protected]
4096-bit RSA key, ID D2BBECEB, created 2010-01-12 (main key ID ADE8309D)

gpg: encrypted with 4096-bit RSA key, ID D2BBECEB, created 2010-01-12
“xxxx xxxxxxxxxxxx [email protected]
Dummy test data
Dummy test data
Dummy test data
Dummy test data
Dummy test data

The fact that gpg is able to decrypt the data shows that the encryption
of the data is working perfectly fine, I just cannot figure out how to
do the decryption in GPGME.
A google search for GPGME::decrypt did not help, I could not find
anything besides the documentation of the module.

Script:
#!/usr/bin/env ruby

require ‘singleton’
require ‘gpgme’

class SMGConfig
include Singleton
attr_accessor :gpg_key
attr_accessor :gpg_password
def initialize()
@gpg_key = ‘ADE8309D’
puts “pwd:”
@gpg_password = gets
end
end

#def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)

config = SMGConfig.instance

puts “Passphrase callback”

io = IO.for_fd(fd, ‘w’)

io.puts(config.gpg_password)

io.flush

#end
def passfunc()
SMGConfig.instance.gpg_password
end

class GPG
include Singleton
def initialize()
@config = SMGConfig.instance
run_test()
end
def run_test()
# Run a test if gpg is able to start and encrypt and
decrypt data reliably with the known password
data = “Dummy test data\n” * 5
puts “encrypting”
edata = encrypt(data)
puts “dumping to file”
File.open(‘edata’, ‘w’) { | f | f.write(edata) }
puts “decrypting”
ddata = decrypt(edata)
puts “GPG failed to initialize” if !(data.eql?(ddata))
puts “done run_test”
end
def encrypt(data)
edata = GPGME::encrypt(@config.gpg_key, data)
end
def decrypt(edata)
GPGME::decrypt(edata, { :passphrase_callback =>
passfunc })
end
end

$stdout.sync = true
x = GPG.instance

Daniel F. [email protected] writes:

I’m pretty new to ruby and this is my first real program I’m writing.
Currently I face an issue with the GPGME gem that I cannot figure out
how to solve: The GPGME::decrypt method does not seem to work as I
expect it, after reading the documentation.

First of all, what version of GnuPG are you using? Since GPGME (C
library) uses the gpg command internally, that information would be
helpful to debug.

Try:

gpg --version

In fact the program seems to hang somewhere during the decryption. My
guess is that something is wrong with my passphrase callback method,
but I cannot figure out how this needs to be done, as the examples for
the gem does not contain a decryption example, only a signing example
from which I have copied the passphrase callback method, but the
method does not seem to work, as the callback method seems to be
called with no arguments.

Could you provide actual input args to passfunc, that can be inspected
with:

def passfunc(*args)
p args
end

Regards,

Am 17.01.2010 13:24, schrieb Daiki U.:

Try:

gpg --version

$ gpg --version
gpg (GnuPG) 1.4.10

with:

def passfunc(*args)
p args
puts “Passphrase callback”
SMGConfig.instance.gpg_password
end

Relevant part of the output:
decrypting
[]
Passphrase callback

If I interpret this right, [] means that there’s an empty array, which
means no arguments?

Regards,
Daniel

Daiki U. [email protected] writes:

Could you try the attached script, which decrypts a file specified as
the first command line argument?

Sorry, I mistakenly posted a wrong script. Please use this one
instead…

Am 17.01.2010 14:19, schrieb Daiki U.:

Daiki U.[email protected] writes:

Could you try the attached script, which decrypts a file specified as
the first command line argument?

Sorry, I mistakenly posted a wrong script. Please use this one instead…

Results in the same problem, I had to interrupt the script and it was
interrupted in the same line as with my script.
$ uname -a
SunOS backupdev 5.11 snv_111b i86pc i386 i86pc Solaris
$ export | grep GPG
$ time RUBYOPT=rubygems ruby decrypt.rb edata
^C/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme.rb:1212:in
decrypt_verify': Interrupt from /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme.rb:134:in decrypt’
from
/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme.rb:943:in new' from /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme.rb:130:in decrypt’
from decrypt.rb:22

real 0m12.420s
user 0m0.079s
sys 0m0.046s

$ gpg --decrypt edata

You need a passphrase to unlock the secret key for
user: “xxxx xxxxxxxxxxx [email protected]
4096-bit RSA key, ID D2BBECEB, created 2010-01-12 (main key ID ADE8309D)

gpg: encrypted with 4096-bit RSA key, ID D2BBECEB, created 2010-01-12
“xxxx xxxxxxxxxxx [email protected]
Dummy test data
Dummy test data
Dummy test data
Dummy test data
Dummy test data
$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-solaris2.11]
$ gem list --local

*** LOCAL GEMS ***

aws-s3 (0.6.2)
builder (2.1.2)
gpgme (1.0.8)
mime-types (1.16)
xml-simple (1.0.12)
$

The line in the gem is
1212 err = GPGME::gpgme_op_decrypt_verify(self, cipher, plain)
The only place I could find a probably definition of the
gpgme_op_decrypt_verify function seems to be the C API to GPGME in
gpgme_n.c in the gpgme-gem dir.
It seems like the installation of the gem did not build a full working
instance of the gem.

I completely uninstalled the gem and reinstalled it:
root@backupdev:~# gem i gpgme
Building native extensions. This could take a while…
ERROR: Error installing gpgme:
ERROR: Failed to build gem native extension.

/usr/ruby/1.8/bin/ruby extconf.rb i gpgme
checking for gpgme-config… yes
checking for gpgme >= 1.1.3… yes
checking for gpgme_op_export_keys()… no
creating Makefile

make
Makefile:143: warning: overriding commands for target
/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib' Makefile:139: warning: ignoring old commands for target /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib’
/usr/sfw/bin/gcc -I. -I. -I/usr/ruby/1.8/lib/ruby/1.8/i386-solaris2.11
-I. -I/usr/sfw/include -fPIC -g -O3 -fPIC -I/usr/local/include
-I/usr/local/include -c gpgme_n.c
/usr/sfw/bin/gcc -G -o gpgme_n.so gpgme_n.o -L. -L/usr/ruby/1.8/lib
-R/usr/ruby/1.8/lib -L/usr/sfw/lib -R/usr/sfw/lib -R
/usr/ruby/1.8/lib -L/usr/ruby/1.8/lib -lruby -L/usr/local/lib -lgpgme
-L/usr/local/lib -lgpg-error -lsocket -lnsl -ldl -lcrypt -lm -lc

make install
Makefile:143: warning: overriding commands for target
/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib' Makefile:139: warning: ignoring old commands for target /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib’
/usr/bin/ginstall -c -m 0755 gpgme_n.so
/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib
/usr/bin/ginstall -c -m 644 ./lib/gpgme/compat.rb
/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme
/usr/bin/ginstall: ./lib/gpgme/compat.rb' and /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme/compat.rb’ are the
same file
make: *** [/var/ruby/1.8/gem_home/gems/gpgme-1.0.8/lib/gpgme/compat.rb]
Error 1

Gem files will remain installed in
/var/ruby/1.8/gem_home/gems/gpgme-1.0.8 for inspection.
Results logged to /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/gem_make.out
root@backupdev:~# gem i gpgme
Building native extensions. This could take a while…
Successfully installed gpgme-1.0.8
1 gem installed
Installing ri documentation for gpgme-1.0.8…
Installing RDoc documentation for gpgme-1.0.8…
Could not find main page README
Could not find main page README
Could not find main page README
Could not find main page README

It looks like the installation is confused when the old data is not
cleaned up, before a second try is done.
On the other side the library seems to be built just fine, or the
important error is not shown:
root@backupdev:~# ldd /var/ruby/1.8/gem_home/gems/gpgme-1.0.8/gpgme_n.so
libruby.so => /usr/ruby/1.8/lib/libruby.so
libgpgme.so.11 => /usr/local/lib/libgpgme.so.11
libgpg-error.so.0 => /usr/local/lib/libgpg-error.so.0
libsocket.so.1 => /lib/libsocket.so.1
libnsl.so.1 => /lib/libnsl.so.1
libdl.so.1 => /lib/libdl.so.1
libcrypt.so.1 => /usr/lib/libcrypt.so.1
libm.so.2 => /lib/libm.so.2
libc.so.1 => /lib/libc.so.1
libcurses.so.1 => /usr/lib/libcurses.so.1
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libmp.so.2 => /lib/libmp.so.2
libmd.so.1 => /lib/libmd.so.1
libscf.so.1 => /lib/libscf.so.1
libgen.so.1 => /lib/libgen.so.1
libuutil.so.1 => /lib/libuutil.so.1

I’m also wondering about the following line during installation of the
gem:
checking for gpgme_op_export_keys()… no
What exactly is the gem doing here? Am I missing a library?

Regards,
Daniel

Daniel F. [email protected] writes:

Results in the same problem, I had to interrupt the script and it was
interrupted in the same line as with my script.

Unfortunately I can’t reproduce your problem since I don’t have any
i386-solaris2.11 env, but you may be able to investigate what happens,
by adding the following lines to ~/.gnupg/gpg.conf:

logger-file /your/home/gpg.log
debug-all

(Please note that the secret information might be leaked to that file,
so I would suggest to prepare a new key for testing).

I’m also wondering about the following line during installation of the gem:
checking for gpgme_op_export_keys()… no
What exactly is the gem doing here? Am I missing a library?

That is harmless since it just indicates that GPGME installed on your
system is slightly old and does not have gpgme_op_export_keys().

Anyway, could you tell me what version of GPGME you are using (with
gpgme-config --version). Also, if you keep the GPGME source code, could
you try “make check” to see if you have working GPGME installation?

Regards,

Am 18.01.2010 08:08, schrieb Daiki U.:

debug-all

(Please note that the secret information might be leaked to that file,
so I would suggest to prepare a new key for testing).

I’m using a real developing system, no real-world data on it :wink:
The logfile is created when running the decrypt ruby script, but is
completely empty (i.e. 0 bytes), so no help from here.

I’m also wondering about the following line during installation of the gem:
checking for gpgme_op_export_keys()… no
What exactly is the gem doing here? Am I missing a library?

That is harmless since it just indicates that GPGME installed on your
system is slightly old and does not have gpgme_op_export_keys().

This actually worries me. I downloaded the version (1.1.8) just
yesterday morning from
http://www.gnupg.org/download/index.en.html
As that seems to be the latest version, I assume it should include the
function?

Anyway, could you tell me what version of GPGME you are using (with
gpgme-config --version). Also, if you keep the GPGME source code, could
you try “make check” to see if you have working GPGME installation?

root@backupdev:~# gpgme-config --version
1.1.8
root@backupdev:~/src/gpgme-1.1.8# make check
Making check in src
make[1]: Entering directory /root/src/gpgme-1.1.8/src' make check-am make[2]: Entering directory /root/src/gpgme-1.1.8/src’
make[2]: Nothing to be done for check-am'. make[2]: Leaving directory /root/src/gpgme-1.1.8/src’
make[1]: Leaving directory /root/src/gpgme-1.1.8/src' Making check in tests make[1]: Entering directory /root/src/gpgme-1.1.8/tests’
Making check in gpg
make[2]: Entering directory /root/src/gpgme-1.1.8/tests/gpg' make check-TESTS make[3]: Entering directory /root/src/gpgme-1.1.8/tests/gpg’
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.10 (SunOS)

hQEOA2rm1+5GqHH4EAQAjvp69T65sXNBLeO1Xk5ZwjM6BgSSPQLLKW+w1Afmx2yy
yCyC/eMyMmJmOQ3siW/gKnos4fDNOm1VtYW4U4j49t5eeKaqymyALGPAEyOxB+Us
8SJky3Kx+qQ1XpH7g1IftupBw5LiDnMk8feJc6OFJK0DVDg+T3csq9fwqyN7ihAD
/0yL6sf8xnLRLiNLcW37fyVDmePt3BrLBKAIqwzbiVg5qULwsDn2kORgpcdIFTIk
BwX8lFSG9bQQtD2repAjpUCipUS0WmriOL3e3DvKgbqHRUWHly8E/r3P4ORrGn45
3QrIO9yCMuBWUcBrY/Iz8TUtABihR0roFekxVeqWwRq1hQEOA1OB6k7im6N/EAQA
ieHgS+3jd08zw8lMYh/GvSsXzB9wbNIpbnND/pkC6+MtsSn4lkNb2vVfHUVOUBg3
9EWLSAAKoNLjwKdeP0eEMC8HY73N91eqhImDqLs9SSeOXIypu6P8h+BKqc9OjSZY
i9h41k2nFDm390+xMASVU69+vghkEbdml1RLQ1RlDtEEAJFNXVcwYodZtEmlisJ9
qgLYqMxlZOmZuC7cZ3+F6dOIS7+wstFL/esWbhX5BT3XKyu5/yrbX/PWwrDtbDoH
NW6zC333mXBBEEy2EEi7qPkfPyAiRPdkBzJcXe69gykVHfysFEqh2TVuuNWYF5/u
o+pT9f8Bzvh7eXFMlSATiUNG0koBrjtwn6eABInBbPhjQz+juuA5+Y87L4o2VEkj
5MhAmSH8fBxbpgm6gZBA9WG9XHBvPNmO4hMpc3wdGux1kl1jBrixYDYyLWvd7Q==
=4DCK
-----END PGP MESSAGE-----
PASS: t-encrypt

At this point it just hangs, which I assume is caused by the same
underlying problem as the decrypt function hanging. So it looks like I’m
hitting a problem with the GPGME library and not them gem.

Regards,
Daniel

Daniel F. [email protected] writes:

decrypting
[]
Passphrase callback

If I interpret this right, [] means that there’s an empty array, which
means no arguments?

You are right, but the result looks strange. Could you try the attached
script, which decrypts a file specified as the first command line
argument? I’ve confirmed it working with gpgme-1.0.8 (gem), ruby-1.8.7,
and gpg 1.4.10, as follows:

$ echo this is a test | gpg --encrypt -r 37ED8A79 > test.gpg
$ ruby1.8 -rubygems decrypt.rb test.gpg
Plaintext:
this is a test

Daniel F. [email protected] writes:

That is harmless since it just indicates that GPGME installed on your
system is slightly old and does not have gpgme_op_export_keys().

This actually worries me. I downloaded the version (1.1.8) just
yesterday morning from
GnuPG - Download
As that seems to be the latest version, I assume it should include the
function?

The web page seems not up to date. I’m currently using GPGME 1.2.0 and
1.3.0 was released a week ago:
http://lists.gnupg.org/pipermail/gnupg-announce/2010q1/000298.html

At this point it just hangs, which I assume is caused by the same
underlying problem as the decrypt function hanging. So it looks like I’m
hitting a problem with the GPGME library and not them gem.

Then you may want to try the new version of GPGME.

Regards,

Hi,

Am 18.01.2010 09:36, schrieb Daiki U.:

The web page seems not up to date. I’m currently using GPGME 1.2.0 and
1.3.0 was released a week ago:
[Announce] GPGME 1.3.0 released

That’s strange then, I’d always expect the webpage to be current.
Anyway, I tried 1.3.0.

At this point it just hangs, which I assume is caused by the same
underlying problem as the decrypt function hanging. So it looks like I’m
hitting a problem with the GPGME library and not them gem.

Then you may want to try the new version of GPGME.

No luck. I didn’t even try them gem with it. “make check” resulted in 20
failed tests out of 21. The one test that was successful was called
something-config and probably just asked gpg for it’s version.
I’ve given up on the gpgme library and have just written a basic wrapper
class around the gpg binary myself. It is not as secure as gpgme, but
the security impact is acceptable for what I’m doing.

Thank you for your help!
Daniel

Daniel F. [email protected] writes:

The web page seems not up to date. I’m currently using GPGME 1.2.0 and
1.3.0 was released a week ago:
[Announce] GPGME 1.3.0 released

That’s strange then, I’d always expect the webpage to be
current. Anyway, I tried 1.3.0.

I’ve reported it to the GnuPG team and asked them which is the current
stable release, and now it is known as 1.2.0. I think that the webpage
will be fixed shortly.

No luck. I didn’t even try them gem with it. “make check” resulted in
20 failed tests out of 21.

Probably filing a bug at http://bugs.g10code.com, along with the output
of “make check”, will help the development :wink:

Regards,