Giter Site home page Giter Site logo

ruby-gpgme's Introduction

GPGME

This README is better viewed through the YARD formatted documentation: www.rubydoc.info/github/ueno/ruby-gpgme for latest github version, or www.rubydoc.info/gems/gpgme for latest gem release.

<img src=“https://github.com/ueno/ruby-gpgme/actions/workflows/test.yml/badge.svg” alt=“Build Status” /> <img src=“https://coveralls.io/repos/ueno/ruby-gpgme/badge.png” alt=“Coverage Status” />

Requirements

  • Ruby 1.8 or later

  • GPGME 1.1.2 or later

  • gpg-agent (optional, but recommended)

Installation

$ gem install gpgme

API

GPGME provides three levels of API. The highest level API is as simple as it gets, the mid level API provides more functionality but might be less user-friendly, and the lowest level API is close to the C interface of GPGME.

The highest level API

For example, to create a cleartext signature of the plaintext from stdin and write the result to stdout can be written as follows.

crypto = GPGME::Crypto.new
crypto.clearsign $stdin, :output => $stdout

The mid level API

The same example can be rewritten in the mid level API as follows.

plain = GPGME::Data.new($stdin)
sig   = GPGME::Data.new($stdout)
GPGME::Ctx.new do |ctx|
  ctx.sign(plain, sig, GPGME::SIG_MODE_CLEAR)
end

The lowest level API

The same example can be rewritten in the lowest level API as follows.

ret = []
GPGME::gpgme_new(ret)
ctx = ret.shift
GPGME::gpgme_data_new_from_fd(ret, 0)
plain = ret.shift
GPGME::gpgme_data_new_from_fd(ret, 1)
sig = ret.shift
GPGME::gpgme_op_sign(ctx, plain, sig, GPGME::SIG_MODE_CLEAR)

As you see, it’s much harder to write a program in this API than the highest level API. However, if you are already familiar with the C interface of GPGME and want to control detailed behavior of GPGME, it might be useful.

Usage

All the high level methods attack the mid level GPGME::Ctx API. It is recommended to read through the GPGME::Ctx.new methods for common options.

Also, most of the input/output is done via GPGME::Data objects that create a common interface for reading/writing to normal strings, or other common objects like files. Read the GPGME::Data documentation to understand how it works. Every time the lib needs a GPGME::Data object, it will be automatically converted to it.

Crypto

The GPGME::Crypto class has the high level convenience methods to encrypt, decrypt, sign and verify signatures. Here are some examples, but it is recommended to read through the GPGME::Crypto class to see all the options.

  • Document encryption via GPGME::Crypto#encrypt:

crypto = GPGME::Crypto.new
crypto.encrypt "Hello world!", :recipients => "[email protected]"
  • Symmetric encryption:

crypto = GPGME::Crypto.new :password => "gpgme"
crypto.encrypt "Hello world!", :symmetric => true
  • Document decryption via GPGME::Crypto#decrypt (including signature verification):

crypto.decrypt File.open("text.gpg")
  • Document signing via GPGME::Crypto#sign. Also the clearsigning and detached signing.

crypto.sign "I hereby proclaim Github the beneficiary of all my money when I die"
  • Sign verification via GPGME::Crypto#verify

sign = crypto.sign "Some text"
data = crypto.verify(sign) { |signature| signature.valid? }

Key

The GPGME::Key object represents a key, and has the high level related methods to work with them and find them, export, import, deletetion and creation.

  • Key listing

GPGME::Key.find(:secret, "[email protected]")
# => Returns an array with all the secret keys available in the keychain.
#    that match "[email protected]"
  • Key exporting

GPGME::Key.export("[email protected]")
# => Returns a GPGME::Data object with the exported key.

key = GPGME::Key.find(:secret, "[email protected]").first
key.export
# => Returns a GPGME::Data object with the exported key.
  • Key importing

GPGME::Key.import(File.open("my.key"))
  • Key validation

GPGME::Key.valid?(public_key)
# => Returns wheter this key is valid or not
  • TODO: Key generation

Engine

Provides three convenience methods to obtain information about the gpg engine one is currently using. For example:

  • Getting current information

GPGME::Engine.info.first
     # => #<GPGME::EngineInfo:0x00000100d4fbd8
            @file_name="/usr/local/bin/gpg",
            @protocol=0,
            @req_version="1.3.0",
            @version="1.4.11">
  • Changing home directory to work with different settings:

GPGME::Engine.home_dir = '/tmp'

Round trip example using keychain keys

Rather than importing the keys it’s possible to specify the recipient when performing crypto functions. Here’s a roundtrip example, and note that as this is for a console, the conf.echo = false line is to stop IRB complaining when echoing binary data

# Stop IRB echoing everything, which errors with binary data.
# Not required for production code
conf.echo = false

class PassphraseCallback
  def initialize(passphrase)
    @passphrase = passphrase
  end

  def call(*args)
    fd = args.last
    io = IO.for_fd(fd, 'w')
    io.puts(@passphrase)
    io.flush
  end
end

# recipients can be found using $ gpg --list-keys --homedir ./keychain_location
# pub   2048R/A1B2C3D4 2014-01-17
# Use that line to substitute your own. 2048R is the key length and type (RSA in this case)

# If you want to substitute a non-default keychain into the engine do this:
# home_dir = Rails.root.join('keychain_location').to_s
# GPGME::Engine.set_info(GPGME::PROTOCOL_OpenPGP, '/usr/local/bin/gpg', home_dir)
# Note GPG executable location will change across platforms

crypto = GPGME::Crypto.new
options = {:recipients => 'A1B2C3D4'}

plaintext = GPGME::Data.new(File.open(Rails.root.join('Gemfile')))

data = crypto.encrypt plaintext, options

f = File.open(Rails.root.join('Gemfile.gpg'), 'wb')
bytes_written = f.write(data)
f.close

puts bytes_written

crypto = GPGME::Crypto.new
options = {:recipients => 'A1B2C3D4', :passphrase_callback => PassphraseCallback.new('my_passphrase')}

cipthertext = GPGME::Data.new(File.open(Rails.root.join('Gemfile.gpg')))

data = crypto.decrypt cipthertext, options
puts data

Contributing

To run the local test suite you need bundler and gpg:

bundle
rake compile   # simple rake task to compile the extension
rake           # runs the test suite

License

The library itself is licensed under LGPLv2.1+. See the file COPYING.LESSER and each file for copyright and warranty information.

ruby-gpgme's People

Contributors

allantokuda-zipnosis avatar anatol avatar ariejan avatar benburkert avatar betelgeuse avatar ccebrecos avatar dansketcher avatar dbussink avatar dctucker avatar duckdalbe avatar duritong avatar erichmachado avatar igor-drozdov avatar jhawthorn avatar jk779 avatar lildude avatar mrsimo avatar nfgrep avatar nicolasleger avatar sathieu avatar sbryant avatar skalee avatar stanhu avatar strathmeyer avatar tamird avatar thukim avatar timothyjb avatar ueno avatar verseth avatar zed-0xff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruby-gpgme's Issues

password vs passphrase

In the example below, I have tried password and passphrase. Neither seem to allow me to run my code without a openpgp box prompting for the passphrase, the following message:

Pinentry Mac
"Please enter the passphrase to unlock the secret key for the OpenPGP certificate"
What do I need to change to allow my code to run without the prompt? I know my password is correct in the code.

I have tried :
ctx = GPGME::Ctx.new :password=> 'password'
and this:
ctx = GPGME::Ctx.new :passphrase_callback => method(:passfunc)

But both do not seem to work. Any advice is appreciated.

  def self.passfunc(obj, uid_hint, passphrase_info, prev_was_bad, fd)
    io = IO.for_fd(fd, 'w')
    io.puts 'password'
    io.flush
  end

  def self.decrypt_file(local_file, decrypted_file = nil)
    # Set decrypted file path if one is not provided
    decrypted_file = local_file.chomp(File.extname(local_file)) + ".csv" if decrypted_file == nil
    encrypted_data = GPGME::Data.new(File.open(local_file))

    # Set the password and GPG Key to decryption
    ctx = GPGME::Ctx.new :password=> 'password'

    # I have tried the passphrase call back
    #ctx = GPGME::Ctx.new :passphrase_callback => method(:passfunc)

    #KEY= GPGME::Data.new(File.open("key.gpg"))
    ctx.import_keys Rebal::Config::KEY

    # Decrypt the data
    decrypted = ctx.decrypt encrypted_data
    decrypted.seek(0)

    #Write the data to a file
    File.write(decrypted_file, decrypted.read)

    #return path
    decrypted_file
  end

Problem with unicode string

An example:

# -*- coding: utf-8 -*-

require 'gpgme'

plain_data = '你好, Ruby'

crypto = GPGME::Crypto.new
encrypted_data = crypto.encrypt(plain_data).read

decrypted_data = crypto.decrypt(encrypted_data, :password => 'xxxx').to_s

puts decrypted_data

The encrypt method will trunk the string if it contains unicode characters.

Do I miss any parameters?

Support for jRuby

I see #5 had something going, but then died, is there any additional work in support for jRuby?

Problem with set_passphrase_cb

I need to be able to implement gpgme from a systems tool and pass the key password as a string. However, using the password attribute to Ctx.new does not accomplish this. This is the code I'm using...


#!/usr/bin/ruby
#
require 'rubygems'
require 'gpgme'

file = "/tmp/encrypted.gpg"
cipher = File.open(file).read
ctx = GPGME::Ctx.new( { :password => 'foobar' } )
raw = GPGME::Data.new(cipher)
txt = GPGME::Data.new
txt = ctx.decrypt(raw)
txt.seek 0
puts txt

I've walked through the Ruby side of things and it looks like set_passphrase_callback is called correctly with passfunc set to #<Method: GPGME::Ctx.pass_function> and hook_value being the value of my password but the pass_function never gets called. GPGME seems to want to use gpg-agent. Without gpg-agent running I get prompted by GPG for a password, which then works. If I run gpg-agent then it works seamlessly no matter what value I put into :password above.

The problem seems to be on the C side rather than the ruby side, but have you seen this behaviour before? This is gnupg2-2.0.14-4, gpgme-1.1.8-3 with the 2.0.1 gpgme gem on CentOS

A few other notes...

  • gpg-agent is not running anywhere
  • I have no GPG_* variables set in my environment

Thanks in advance for any help.

Simple Decryption with Passphrase File - GPGME::Error::BadPassphrase

I have been unable to decrypt a file which requires a passphrase. I have looked at all examples and documentation. I can decrypt fine from the command line with the gpg agent, but not with this library yet.

Just need to decrypt with a passphrase. I keep getting a GPGME::Error::BadPassphrase

Here is what I have:

msg.body = ENCRYPTED_FILE_CONTENTS
GPGME::Key.import(File.open("/usr/local/pwds/.gnupg/.pf"))
crypto = GPGME::Crypto.new
cipher = GPGME::Data.new(msg.body)
json_msg_body = crypto.decrypt(cipher)

Any help would be greatly appreciated.

Cannot install on OS X 10.10(.1)

Install is complaining about "You have to install development tools first.", but development tools is already installed and up to date.

  • xcode 6.1.1 (6A2008a)
  • xquartz 2.7.7 (xorg-server 1.15.2)
  • rvm 1.25.29
  • ruby 1.9.3p547
  • rails 3.2.13
  • gpgme-2.0.7
$ brew doctor
Your system is ready to brew.
$ gem install gpgme
Building native extensions.  This could take a while...
ERROR:  Error installing gpgme:
    ERROR: Failed to build gem native extension.

    /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/bin/ruby extconf.rb
************************************************************************
IMPORTANT!  gpgme gem uses locally built versions of required C libraries,
namely libgpg-error, libassuan, and gpgme.

If this is a concern for you and you want to use the system library
instead, abort this installation process and reinstall gpgme gem as
follows:

    gem install gpgme -- --use-system-libraries

************************************************************************
sh: line 1: 47984 Segmentation fault: 11  /usr/local/opt/gcc46/bin/gcc-4.6 -v 2>&1
Extracting libgpg-error-1.13.tar.bz2 into tmp//ports/libgpg-error/1.13... OK
Running 'configure' for libgpg-error 1.13... OK
Running 'compile' for libgpg-error 1.13... OK
Running 'install' for libgpg-error 1.13... OK
Activating libgpg-error 1.13 (from /Users/zykadelic/.rvm/gems/ruby-1.9.3-p547/gems/gpgme-2.0.7/ports//libgpg-error/1.13)...
sh: line 1: 51364 Segmentation fault: 11  /usr/local/opt/gcc46/bin/gcc-4.6 -v 2>&1
Extracting libassuan-2.1.2.tar.bz2 into tmp//ports/libassuan/2.1.2... OK
Running 'configure' for libassuan 2.1.2... OK
Running 'compile' for libassuan 2.1.2... OK
Running 'install' for libassuan 2.1.2... OK
Activating libassuan 2.1.2 (from /Users/zykadelic/.rvm/gems/ruby-1.9.3-p547/gems/gpgme-2.0.7/ports//libassuan/2.1.2)...
sh: line 1: 54987 Segmentation fault: 11  /usr/local/opt/gcc46/bin/gcc-4.6 -v 2>&1
Extracting gpgme-1.5.1.tar.bz2 into tmp//ports/gpgme/1.5.1... OK
Running 'configure' for gpgme 1.5.1... OK
Running 'compile' for gpgme 1.5.1... OK
Running 'install' for gpgme 1.5.1... OK
Activating gpgme 1.5.1 (from /Users/zykadelic/.rvm/gems/ruby-1.9.3-p547/gems/gpgme-2.0.7/ports//gpgme/1.5.1)...
checking for linker flags for static linking... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/bin/ruby
    --clean
    --use-system-libraries
/Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:381:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:461:in `try_link0'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:476:in `try_link'
    from extconf.rb:159:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /Users/zykadelic/.rvm/gems/ruby-1.9.3-p547/gems/gpgme-2.0.7 for inspection.
Results logged to /Users/zykadelic/.rvm/gems/ruby-1.9.3-p547/extensions/x86_64-darwin-13/1.9.1/gpgme-2.0.7/gem_make.out
$ gem install gpgme -- --use-system-libraries
Building native extensions with: '--use-system-libraries'
This could take a while...
ERROR:  Error installing gpgme:
    ERROR: Failed to build gem native extension.

    /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/bin/ruby extconf.rb --use-system-libraries
checking for gpgme-config... yes
checking for gpgme >= 1.1.3... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/bin/ruby
    --clean
    --use-system-libraries
/Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:381:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:461:in `try_link0'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:712:in `try_run'
    from extconf.rb:185:in `block in <main>'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:790:in `block in checking_for'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:284:in `block (2 levels) in postpone'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:254:in `open'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:284:in `block in postpone'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:254:in `open'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:280:in `postpone'
    from /Users/zykadelic/.rvm/rubies/ruby-1.9.3-p547/lib/ruby/1.9.1/mkmf.rb:789:in `checking_for'
    from extconf.rb:184:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /Users/zykadelic/.rvm/gems/ruby-1.9.3-p547/gems/gpgme-2.0.7 for inspection.
Results logged to /Users/zykadelic/.rvm/gems/ruby-1.9.3-p547/extensions/x86_64-darwin-13/1.9.1/gpgme-2.0.7/gem_make.out

Cannot install on Windows

Sorry if this is completely not supported, but we have a rails project (Ruby 1.8.7, Rails 3.2.8) that uses gpgme for signature verification. The production environment is Linux, but we have some developers working on Windows.

Is this gem even supported on Windows?
If so, what are the installation instructions?

My environment:
Windows 7 Pro 64-bit
ruby 1.8.7 (2012-06-29 patchlevel 370) [i386-mingw32]

C:>gem install gpgme
Temporarily enhancing PATH to include DevKit...
Building native extensions. This could take a while...
ERROR: Error installing gpgme:
ERROR: Failed to build gem native extension.

C:/Ruby187/bin/ruby.exe extconf.rb
-- tar xjvf C:/Ruby187/lib/ruby/gems/1.8/gems/gpgme-2.0.1/ext/gpgme/libgpg-error-1.10.tar.bz2
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=C:/Ruby187/bin/ruby
extconf.rb:11:in sys': tar xjvf C:/Ruby187/lib/ruby/gems/1.8/gems/gpgme-2.0.1/ext/gpgme/libgpg-error-1.10.tar.bz2 failed! (RuntimeError) from extconf.rb:18:inbuild'
from extconf.rb:33

Gem files will remain installed in C:/Ruby187/lib/ruby/gems/1.8/gems/gpgme-2.0.1 for inspection.
Results logged to C:/Ruby187/lib/ruby/gems/1.8/gems/gpgme-2.0.1/ext/gpgme/gem_make.out

Can't install: Incorrect arguments passed to the C compiler

I tried installing gpgme 2.0.10 on my Arch Linux machine and got the error:

configure: error: in `/tmp/test/gem/gems/gpgme-2.0.10/ext/gpgme/tmp/x86_64-unknown-linux-gnu/ports/libgpg-error/1.20/libgpg-error-1.20':
configure: error: C compiler cannot create executables
See `config.log' for more details

Looking in config.log I get:

configure:3699: $? = 0
configure:3688: gcc -v >&5
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/5.2.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/gcc-multilib/src/gcc-5.2.0/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --with-default-libstdcxx-abi=gcc4-compatible
Thread model: posix
gcc version 5.2.0 (GCC) 
configure:3699: $? = 0
configure:3688: gcc -V >&5
gcc: error: unrecognized command line option '-V'
gcc: fatal error: no input files
compilation terminated.
configure:3699: $? = 1
configure:3688: gcc -qversion >&5
gcc: error: unrecognized command line option '-qversion'
gcc: fatal error: no input files
compilation terminated.
configure:3699: $? = 1
configure:3719: checking whether the C compiler works
configure:3741: gcc '-fPIC '   conftest.c  >&5
gcc: error: '-fPIC: No such file or directory
gcc: error: ': No such file or directory
configure:3745: $? = 1
configure:3783: result: no
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "libgpg-error"
| #define PACKAGE_TARNAME "libgpg-error"
| #define PACKAGE_VERSION "1.20"
| #define PACKAGE_STRING "libgpg-error 1.20"
| #define PACKAGE_BUGREPORT "http://bugs.gnupg.org"
| #define PACKAGE_URL ""
| #define PACKAGE "libgpg-error"
| #define VERSION "1.20"
| /* end confdefs.h.  */
| 
| int
| main ()
| {
| 
|   ;
|   return 0;
| }
configure:3788: error: in `/tmp/test/gem/gems/gpgme-2.0.10/ext/gpgme/tmp/x86_64-unknown-linux-gnu/ports/libgpg-error/1.20/libgpg-error-1.20':
configure:3790: error: C compiler cannot create executables
See `config.log' for more details

Running gcc --version I get

gcc (GCC) 5.2.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I think the error is that the single quote ' is prepended to -fPIC in ext/gpgme/extconf.rb. It works when compiling with --use-system-libraries.

The full command that I ran was:

> gem install --ignore-dependencies --no-user-install -i "test/gem" -n "test/usr/bin" gpgme-2.0.10.gem

and I have attached the output and the config.log here: https://gist.github.com/adament/68897817542127fc3c93

Documentation on GPGME::Engine.engine_info is wrong

1.9.3p125 :001 > GPGME::Engine.engine_info
NoMethodError: undefined method `engine_info' for GPGME::Engine:Module

It's actually GPGME::Engine.info. This needs to be fixed in both README and rdocs for GPGME::Engine.info. @betelgeuse initially found this out.

Multi-Signers not working in version 2.0.2

I found that the parameter :signers did not work properly compared to :signer.

Starting from the documentation at http://rubydoc.info/gems/gpgme/2.0.2/frames :signers should "if +:sign+ specified to true, a list of additional possible signers. Must be an array of sign identifiers."

If only given this parameter, gpgme chooses the default-key or the first private key (by gpg --list-secret-keys) as signature key. Is this a bug or is :signers only usable additional to :signer?

Sorry, if this is not actually a bug, but I am very much interested in the opinion of the gpgme maintainers.

Weird filename on decryption: name="-&11"

User prompted to save decrypted file into weird filename.

$ gpg  encrypted.file
You need a passphrase to unlock the secret key for
...
gpg: encrypted with 4096-bit ELG-E key, ID...
gpg: encrypted.file: unknown suffix
Enter new filename [-&11]:
$ gpg --list-packets encrypted.file
...
:compressed packet: algo=2
:literal data packet:
        mode b (62), created 1428044156, name="-&11",
        raw data: unknown length

Data was encrypted with simple GPGME::Crypto.new.encrypt('data', :recipients => 'xxxxxxxx').

My guess, this is related to file descriptor redirection.

Clarify error raised when trying to sign with no private subkey available.

So, there I was, messing with sup (sup-heliotrope/sup#468), while the I found out an error is raised when I try to sign anything.

During further investigation using the following example code:

#!/usr/bin/env ruby
require 'gpgme'

crypto = GPGME::Crypto.new
signature = crypto.clearsign('This is a test message!')

puts signature.read

I got the following error:

/usr/lib64/ruby/gems/2.2.0/gems/gpgme-2.0.10/lib/gpgme/ctx.rb:475:in `sign': General error (GPGME::Error::General)
    from /usr/lib64/ruby/gems/2.2.0/gems/gpgme-2.0.10/lib/gpgme/crypto.rb:249:in `block in sign'
    from /usr/lib64/ruby/gems/2.2.0/gems/gpgme-2.0.10/lib/gpgme/ctx.rb:79:in `new'
    from /usr/lib64/ruby/gems/2.2.0/gems/gpgme-2.0.10/lib/gpgme/crypto.rb:242:in `sign'
    from /usr/lib64/ruby/gems/2.2.0/gems/gpgme-2.0.10/lib/gpgme/crypto.rb:331:in `clearsign'
    from test.rb:5:in `<main>'

Which soon after lead me to discovery that I had no secret subkey to sign with.

I think this kind of error reporting may need improvement because it's unclear what the problem is.

The GPG version is 2.1.7-r1.
The system GPGME version is 1.5.5.
The Ruby GPGME bindings version is 2.0.10.

Thanks in advance!

Misleading error when trying to use :passphrase_callback with GnuPG 2.0.x

Right now I'm attempting to develop an application using ruby-gpgme (at commit fd1d6b0). Here is your example sign, using the passphrase callback:

#!/usr/bin/env ruby
# test_sign.rb
require 'gpgme'

def passfunc(hook, 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

crypto = GPGME::Crypto.new
signature = crypto.clearsign('test test test', {
                               :signer => '0xDEADBEEF',
                               :passphrase_callback => method(:passfunc)
                             })
puts signature.read

However when I'm using GnuPG version 2.0.x:

$ gpg --version
gpg (GnuPG/MacGPG2) 2.0.22
libgcrypt 1.5.3
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: ~/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ?, ?
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

I get this horribly misleading error when trying to set the callback:

$ bundle exec ruby test_sign.rb
/Users/justinbull/.rvm/gems/ruby-2.0.0-p247/bundler/gems/ruby-gpgme-fd1d6b09d1b1/lib/gpgme/ctx.rb:438:in `sign': Bad passphrase (GPGME::Error::BadPassphrase)
    from /Users/justinbull/.rvm/gems/ruby-2.0.0-p247/bundler/gems/ruby-gpgme-fd1d6b09d1b1/lib/gpgme/crypto.rb:249:in `block in sign'
    from /Users/justinbull/.rvm/gems/ruby-2.0.0-p247/bundler/gems/ruby-gpgme-fd1d6b09d1b1/lib/gpgme/ctx.rb:71:in `new'
    from /Users/justinbull/.rvm/gems/ruby-2.0.0-p247/bundler/gems/ruby-gpgme-fd1d6b09d1b1/lib/gpgme/crypto.rb:242:in `sign'
    from /Users/justinbull/.rvm/gems/ruby-2.0.0-p247/bundler/gems/ruby-gpgme-fd1d6b09d1b1/lib/gpgme/crypto.rb:331:in `clearsign'
    from test_sign.rb:28:in `<main>'

I don't know what you can do to alleviate this error, but perhaps detect the version is 2.0.x and say that the :passphrase_callback logic is not supported?

An aside:

Using GnuPG 2.0.x, what's the best method to programatically sign some data? That is, without a human typing in the passphrase of a private key?

problems with verify

Hi.

First, let me say thanks for your time and effort maintaining these Ruby bindings. Great work.

However, I'm having some trouble getting the correct output when verifying signatures. I always end up getting GPGME::Error::NoData. I've double checked the signature, and everything appears to be feeding into libgpgme okay.

I'm developing on OS X and deploying on Linux. I've been able to get a positive verification when running ruby-gpgme with the Mac GnuPG tools, but get this failure when running against the Homebrew gnupg package on OS X or the Ubuntu gnupg package.

Even ruby-gpgme seems to be be failing it's own tests, as well:

  1. Error:
    test_0005_can_also_sign_at_the_same_time(GPGME::Crypto::encrypt):
    GPGME::Error::NoData: No data
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:392:in verify' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:312:inblock in verify'
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:67:in new' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:311:inverify'
    /Users/bryan/www/forks/ruby-gpgme/test/crypto_test.rb:89:in block (3 levels) in <top (required)>' /Users/bryan/.rvm/gems/ruby-1.9.2-p290/gems/mocha-0.9.12/lib/mocha/integration/mini_test/version_201_to_202.rb:27:inrun'

  2. Error:
    test_0006_can_be_signed_by_more_than_one_person(GPGME::Crypto::encrypt):
    GPGME::Error::NoData: No data
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:392:in verify' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:312:inblock in verify'
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:67:in new' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:311:inverify'
    /Users/bryan/www/forks/ruby-gpgme/test/crypto_test.rb:102:in block (3 levels) in <top (required)>' /Users/bryan/.rvm/gems/ruby-1.9.2-p290/gems/mocha-0.9.12/lib/mocha/integration/mini_test/version_201_to_202.rb:27:inrun'

  3. Error:
    test_0002_selects_who_to_sign_for(GPGME::Crypto::sign):
    GPGME::Error::NoData: No data
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:392:in verify' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:312:inblock in verify'
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:67:in new' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:311:inverify'
    /Users/bryan/www/forks/ruby-gpgme/test/crypto_test.rb:232:in block (3 levels) in <top (required)>' /Users/bryan/.rvm/gems/ruby-1.9.2-p290/gems/mocha-0.9.12/lib/mocha/integration/mini_test/version_201_to_202.rb:27:inrun'

  4. Error:
    test_0001_signs_normal_strings(GPGME::Crypto::sign):
    GPGME::Error::NoData: No data
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:392:in verify' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:312:inblock in verify'
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:67:in new' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:311:inverify'
    /Users/bryan/www/forks/ruby-gpgme/test/crypto_test.rb:206:in block (3 levels) in <top (required)>' /Users/bryan/.rvm/gems/ruby-1.9.2-p290/gems/mocha-0.9.12/lib/mocha/integration/mini_test/version_201_to_202.rb:27:inrun'

  5. Error:
    test_0002__expired_key_is_true_when_the_key_has_expired(GPGME::Signature):
    GPGME::Error::NoData: No data
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:392:in verify' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:312:inblock in verify'
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:67:in new' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:311:inverify'
    /Users/bryan/www/forks/ruby-gpgme/test/signature_test.rb:28:in block (3 levels) in <top (required)>' /Users/bryan/www/forks/ruby-gpgme/test/test_helper.rb:61:inwith_key'
    /Users/bryan/www/forks/ruby-gpgme/test/signature_test.rb:25:in block (2 levels) in <top (required)>' /Users/bryan/.rvm/gems/ruby-1.9.2-p290/gems/mocha-0.9.12/lib/mocha/integration/mini_test/version_201_to_202.rb:27:inrun'

  6. Error:
    test_0001__valid_is_true_when_the_signature_is_valid(GPGME::Signature):
    GPGME::Error::NoData: No data
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:392:in verify' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:312:inblock in verify'
    /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/ctx.rb:67:in new' /Users/bryan/www/forks/ruby-gpgme/lib/gpgme/crypto.rb:311:inverify'
    /Users/bryan/www/forks/ruby-gpgme/test/signature_test.rb:10:in block (2 levels) in <top (required)>' /Users/bryan/.rvm/gems/ruby-1.9.2-p290/gems/mocha-0.9.12/lib/mocha/integration/mini_test/version_201_to_202.rb:27:inrun'

105 tests, 176 assertions, 0 failures, 6 errors, 0 skips
rake aborted!

I'm stumped. Any thoughts? Thanks.

ruby 2.0.0 incompatibility on OS X mavericks

@ueno I had to apply the changes from #40 to get the tests to run. Here's the output:

~/Development/ruby-gpgme master bundle exec rake
mkdir tmp
************************************************************************
IMPORTANT!  gpgme gem uses locally built versions of required C libraries,
namely libgpg-error, libassuan, and gpgme.

If this is a concern for you and you want to use the system library
instead, abort this installation process and reinstall gpgme gem as
follows:

    gem install gpgme -- --use-system-libraries

************************************************************************
Extracting libgpg-error-1.12.tar.bz2 into tmp/x86_64-apple-darwin13.2.0/ports/libgpg-error/1.12... OK
Running 'configure' for libgpg-error 1.12... OK
Running 'compile' for libgpg-error 1.12... OK
Running 'install' for libgpg-error 1.12... OK
Activating libgpg-error 1.12 (from /Users/tamird/Development/ruby-gpgme/ports/x86_64-apple-darwin13.2.0/libgpg-error/1.12)...
Extracting libassuan-2.1.1.tar.bz2 into tmp/x86_64-apple-darwin13.2.0/ports/libassuan/2.1.1... OK
Running 'configure' for libassuan 2.1.1... OK
Running 'compile' for libassuan 2.1.1... OK
Running 'install' for libassuan 2.1.1... OK
Activating libassuan 2.1.1 (from /Users/tamird/Development/ruby-gpgme/ports/x86_64-apple-darwin13.2.0/libassuan/2.1.1)...
Extracting gpgme-1.4.3.tar.bz2 into tmp/x86_64-apple-darwin13.2.0/ports/gpgme/1.4.3... OK
Running 'configure' for gpgme 1.4.3... OK
Running 'compile' for gpgme 1.4.3... OK
Running 'install' for gpgme 1.4.3... OK
Activating gpgme 1.4.3 (from /Users/tamird/Development/ruby-gpgme/ports/x86_64-apple-darwin13.2.0/gpgme/1.4.3)...
checking for linker flags for static linking... NONE
checking for gpgme.h... yes
checking for gpgme >= 1.1.3... no
checking for gpgme_op_export_keys()... no
creating Makefile
compiling /Users/tamird/Development/ruby-gpgme/ext/gpgme/gpgme_n.c
/Users/tamird/Development/ruby-gpgme/ext/gpgme/gpgme_n.c:211:34: warning: implicit conversion loses integer precision: 'long' to 'gpgme_error_t' (aka 'unsigned int')
      [-Wshorten-64-to-32]
  return INT2FIX(gpgme_err_code (NUM2LONG(verr)));
         ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/include/ruby-2.0.0/ruby/ruby.h:592:21: note: expanded from macro 'NUM2LONG'
#define NUM2LONG(x) rb_num2long_inline(x)
                    ^
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/include/ruby-2.0.0/ruby/ruby.h:241:45: note: expanded from macro 'INT2FIX'
#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG))
                                            ^
/Users/tamird/Development/ruby-gpgme/ext/gpgme/gpgme_n.c:217:36: warning: implicit conversion loses integer precision: 'long' to 'gpgme_error_t' (aka 'unsigned int')
      [-Wshorten-64-to-32]
  return INT2FIX(gpgme_err_source (NUM2LONG(verr)));
         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/include/ruby-2.0.0/ruby/ruby.h:592:21: note: expanded from macro 'NUM2LONG'
#define NUM2LONG(x) rb_num2long_inline(x)
                    ^
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/include/ruby-2.0.0/ruby/ruby.h:241:45: note: expanded from macro 'INT2FIX'
#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG))
                                            ^
/Users/tamird/Development/ruby-gpgme/ext/gpgme/gpgme_n.c:223:39: warning: implicit conversion loses integer precision: 'long' to 'gpgme_error_t' (aka 'unsigned int')
      [-Wshorten-64-to-32]
  return rb_str_new2 (gpgme_strerror (NUM2LONG(verr)));
                      ~~~~~~~~~~~~~~  ^
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/include/ruby-2.0.0/ruby/ruby.h:592:21: note: expanded from macro 'NUM2LONG'
#define NUM2LONG(x) rb_num2long_inline(x)
                    ^
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/include/ruby-2.0.0/ruby/intern.h:760:27: note: expanded from macro 'rb_str_new_cstr'
    (__builtin_constant_p(str)) ?               \
                          ^
/Users/tamird/Development/ruby-gpgme/ext/gpgme/gpgme_n.c:223:39: warning: implicit conversion loses integer precision: 'long' to 'gpgme_error_t' (aka 'unsigned int')
      [-Wshorten-64-to-32]
  return rb_str_new2 (gpgme_strerror (NUM2LONG(verr)));
                      ~~~~~~~~~~~~~~  ^
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/include/ruby-2.0.0/ruby/ruby.h:592:21: note: expanded from macro 'NUM2LONG'
#define NUM2LONG(x) rb_num2long_inline(x)
                    ^
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/include/ruby-2.0.0/ruby/intern.h:762:18: note: expanded from macro 'rb_str_new_cstr'
        rb_str_new_cstr(str);                   \
                        ^
/Users/tamird/Development/ruby-gpgme/ext/gpgme/gpgme_n.c:246:28: warning: comparison of integers of different signs: 'long' and 'size_t' (aka 'unsigned long') [-Wsign-compare]
  if (RSTRING_LEN(vbuffer) < size)
      ~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
5 warnings generated.
linking shared-object gpgme_n.bundle
/Users/tamird/.rvm/rubies/ruby-2.0.0-p481/bin/ruby -I"lib:test" -I"/Users/tamird/.rvm/gems/ruby-2.0.0-p481/gems/rake-10.3.2/lib" "/Users/tamird/.rvm/gems/ruby-2.0.0-p481/gems/rake-10.3.2/lib/rake/rake_test_loader.rb" "test/**/*_test.rb"
dyld: lazy symbol binding failed: Symbol not found: ___emutls_get_address
  Referenced from: /Users/tamird/Development/ruby-gpgme/tmp/gpgme_n.bundle
  Expected in: flat namespace

dyld: Symbol not found: ___emutls_get_address
  Referenced from: /Users/tamird/Development/ruby-gpgme/tmp/gpgme_n.bundle
  Expected in: flat namespace

rake aborted!
SignalException: SIGTRAP
/Users/tamird/.rvm/gems/ruby-2.0.0-p481/bin/ruby_executable_hooks:15:in `eval'
/Users/tamird/.rvm/gems/ruby-2.0.0-p481/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => default => test
(See full trace by running task with --trace)

Unable to import key

I'm unable to import a key file. I'm using ruby 1.9.3-p448

running:

require "gpgme"

begin
  key = GPGME::Key.import(File.open("private.key"), {:password => "redacted"})

rescue GPGME::Error => g
  puts g.inspect
  puts g.message
  puts g.code
  puts g.source
end

Output

#<GPGME::Error: GPGME::Error>
Inappropriate ioctl for device
32870
7

I have gpg, MacGPGTools and gpg-agent installed on my system. Am I missing something?

Invalid crypto engine (GPGME::Error::InvalidEngine)

I am getting the Invalid crypto engine (GPGME::Error::InvalidEngine) error in my attempts to use the GPGME class.

This is on Mac OS X with gpg, gpgme, and gpg-agent installed. Command-line GPG works fine.

What am I missing?
It installs cleanly:
gem install gpgme

Fetching: gpgme-2.0.5.gem (100%)
Building native extensions.  This could take a while...
Successfully installed gpgme-2.0.5
Parsing documentation for gpgme-2.0.5
Installing ri documentation for gpgme-2.0.5
Done installing documentation for gpgme after 3 seconds
1 gem installed

Then trying to run even one of the example scripts:
ruby keylist.rb

/Users/frank/.rvm/gems/ruby-2.1.1/gems/gpgme-2.0.5/lib/gpgme/ctx.rb:238:in `keylist_start': Invalid crypto engine (GPGME::Error::InvalidEngine)
    from /Users/frank/.rvm/gems/ruby-2.1.1/gems/gpgme-2.0.5/lib/gpgme/ctx.rb:269:in `each_key'
    from keylist.rb:5:in `<main>'

GPGME::Error::InvalidValue: GPGME::Error::InvalidValue

Hello,

I've been trying to encrypt a data and it seem to work well on my local machine, however when I've deployed it on our server, it keeps on raising this error even with the simplest way of encrypting my data. Has anyone encountered this issue?

e.g. crypto = GPGME::Crypto.new
      crypto.encrypt "The quick brown fox", :always_trust => true

This always raises this error "GPGME::Error::InvalidValue: GPGME::Error::InvalidValue".

add sign + encrypt example to README

It might be nice to add an example in the README for encrypting and signing. The API docs are a bit vague on how this works and it's especially confusing since the parameters for GPGME::Crypto.sign() are different than the ones in GPGME::Crypto.encrypt(). Suggested sample code block:

encrypted = crypto.encrypt(
                   "text to be encrypted",
                   :recipients => "[email protected]",
                   :sign => true,
                   :signers => "[email protected]",
                   :password => "sig_key_password")

I'm happy to fork/pull if you prefer!

bump version of mini_portile?

is there a reason "mini_portile" must be <= 0.6.0? 0.6.1 was released recently and my RPM build system has now produced a mini_portile package that is incompatible with my gpgme package :(

I can easily build an older mini_portile by hand, but it's still a workaround.

NameError: uninitialized constant GPGME::PINENTRY_MODE_DEFAULT

I'm seeing this error when using 2.0.5 with puppet enterprise 3.1.3 on RHEL 6.

Puppet::Parser::AST::Resource failed with error NameError: uninitialized constant GPGME::PINENTRY_MODE_DEFAULT

We have had to revert to 2.0.2 to get this to continue to work.

This is with gpgme-1.1.8-3 (default that comes with RHEL6)

R.

GPGME::Crypto options are not documented

http://www.rubydoc.info/gems/gpgme/GPGME/Crypto says

Different, independent methods providing the simplest possible API to execute crypto operations via GPG. All methods accept as options the same common options as GPGME::Ctx.new. Read the documentation for that class to know how to customize things further (like output stuff in ASCII armored format, for example).

Ok, I read http://www.rubydoc.info/gems/gpgme/GPGME/Ctx but there is no description or even list of at least :output, :recipients, :always_trust, :sign, :signer and who knows how much more.

It would be awesomely useful if documentation state full list of options. For example, I hoped there is option to specify encrypted file name (related to #62).

gpgme_n.c fails to compile without -fPIC on x86_64

Installation of the gem fails on a 64bit system:

$ gem install --install-dir ./tmp gpgme
Building native extensions.  This could take a while...
ERROR:  Error installing gpgme:
        ERROR: Failed to build gem native extension.

...
make
compiling gpgme_n.c
linking shared-object gpgme_n.so
/usr/bin/ld: /usr/lib/libgpgme.a(data.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/usr/lib/libgpgme.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [gpgme_n.so] Error 1
$ uname -a
Linux example.com 3.2.0-4-amd64 #1 SMP Debian 3.2.57-3+deb7u2 x86_64 GNU/Linux

It compiles fine on 32 bit. When building the extensions, gpgme-config --cflags is run to determine what flags to add to CFLAGS before compiling. The output of this command is empty, though, so it won't add -fPIC to the list of CFLAGS.

I'm using GCC version 4.7.2 (Debian 4.7.2-5).

add a build option to use system gpgme

Recent gpgme git master has some new features including pinentry mode. To use them, maybe good to add an option to link ruby-gpgme to gpgme, installed outside of the builddir.

GPGME::Crypto#encrypt throws an Errno::EBADF exception

The following code always throws an Errno::EBADF exception after some loop iterations:

require 'gpgme'

puts GPGME::Engine.info.inspect

crypto = GPGME::Crypto.new(armor: false, symmetric: true, password: 'password')

(0..1000000).each do |n|
  puts n
  crypto.encrypt(GPGME::Data.from_str('data'))
end

I tried it with Ruby 2.0.0p353 and Ruby 2.0.0p576 on Ubuntu 12.04.5 LTS and Ubuntu 14.04.1 LTS:

$ rvm use ruby-2.0.0-p576@gpgme --create

$ gem install gpgme
...
Successfully installed mini_portile-0.6.0
...
Successfully installed gpgme-2.0.7
...

$ ruby test.rb
[#<GPGME::EngineInfo:0x000000014bda10 @protocol=0, @file_name="/usr/bin/gpg", @version="1.4.16", @req_version="1.4.0">, #<GPGME::EngineInfo:0x000000014bd970 @protocol=6, @file_name="/nonexistent", @version="1.0", @req_version="1.0">]
0
1
...
403
404
/home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:484:in `flush': Bad file descriptor (Errno::EBADF)
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:484:in `pass_function'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:449:in `call'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:449:in `gpgme_op_encrypt'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:449:in `encrypt'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/crypto.rb:99:in `block in encrypt'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:71:in `new'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/crypto.rb:90:in `encrypt'
        from test.rb:21:in `block in <main>'
        from test.rb:19:in `each'
        from test.rb:19:in `<main>'

Installed packages under Ubuntu 12.04.5 LTS

$ dpkg --list gnupg libgpgme11 libgpgme11-dev
...
ii  gnupg                         1.4.11-3ubuntu2.7             GNU privacy guard - a free PGP replacement
ii  libgpgme11                    1.2.0-1.4ubuntu2.1            GPGME - GnuPG Made Easy
ii  libgpgme11-dev                1.2.0-1.4ubuntu2.1            GPGME - GnuPG Made Easy

Installed packages under Ubuntu 14.04.1 LTS

$ dpkg --list gnupg libgpgme11 libgpgme11-dev
...
ii  gnupg                         1.4.16-1ubuntu2.1   amd64               GNU privacy guard - a free PGP replacement
ii  libgpgme11:amd64              1.4.3-0.1ubuntu5.1  amd64               GPGME - GnuPG Made Easy (library)
ii  libgpgme11-dev                1.4.3-0.1ubuntu5.1  amd64               GPGME - GnuPG Made Easy (development files)

Get list of original recipients after decrypting

Hi,
is there a way how to get list of original recipients, after decrypting data?

When decrypting data wit gpg command line, gpg (GnuPG 1.4.15) will output this info in form gpg: encrypted with... for each recipient.

In gpgme, this info seems to be accessible from gpgme_recipient_t, which is part of gpgme_decrypt_result_t, which is returned by gpgme_op_decrypt_result function. Doesn't seem to be mapped to ruby-gpgme, or at least I can find it.

Any ideas how can I get this information?

Thanks, .st

Unsupported protocol during import_keys

Here is the error that I get:
C:/app/Ruby22-x64/lib/ruby/gems/2.2.0/gems/gpgme-2.0.10/lib/gpgme/ctx.rb:385:in `import_keys': Unsupported protocol (GPGME::Error)
The code I used:

require 'rubygems'
require 'gpgme'
def passfunc(obj, uid_hint, passphrase_info, prev_was_bad, fd)
io = IO.for_fd(fd, 'w')
io.puts "hello"
io.flush
end
encrypted_data = GPGME::Data.new(File.open("C:/app/pgp/src/test/encryptedText.txt"))
key = GPGME::Data.new(File.open("C:/app/pgp/src/test/privateKey.skr"))
ctx = GPGME::Ctx.new :passphrase_callback => method(:passfunc)
ctx.import_keys key
decrypted = ctx.decrypt encrypted_data
decrypted.seek(0)
puts decrypted.read

This code works fine on mac but as mention throwing an error on windows (win7x64 and also Win 10), GnuPg for windows is installed and the %PATH% is configured.

I tried to set this
GPGME::Engine.set_info(GPGME::PROTOCOL_OpenPGP, nil, nil)
But then the error is:
C:/app/Ruby22-x64/lib/ruby/gems/2.2.0/gems/gpgme-2.0.10/lib/gpgme/engine.rb:60:in `set_info': Invalid crypto engine (GPGME::Error::InvalidEngine)
What is the problem?
Thanks!

Problem with keys

I have the following problem, this is my code

def decrypt(encrypted_data)
    buffer = GPGME::Data.new

    GPGME::Crypto.new.decrypt(
      encrypted_data,
      :password => "mypassword",
      :armor => true,
      :recipients => "[email protected]",
      :always_trust => true,
      :output => buffer)

    buffer.read
end

GPGME::Key.import(my_secret_key)
100.times { decrypt(my_encrypted_data) }

At some point, randomly, the key just dissapears from the keyring and I cannot import any key anymore, cannot do nothing until I restart all the app.

I need to decrypt a lot of items and I cannot do it because the key dissapears (GPGME::Key.find(:secret) returns []) and it does not let me continue from that point.

Any help will be appreciated.

Need a more up-to-date release

Hi, I'm currently pulling this gem directly from Github instead of using a released version, because of the UTF truncation fixes on master. Any chance of getting a new gem release published?

Better error message if needed engine if not installed

I installed ruby-gpgme without an installation of gpg. When trying to run existing tests this resulted in the following error message:

Assertion failed: (*lock == MUTEX_UNLOCKED), function _gpgme_ath_mutex_lock, file ath.c, line 108.

I don't think the gem should allow installing itself without any engines being available as it will not be able to provide any useful functionality. @betelgeuse found the root cause.

Crypto.encrypt seems to be truncating data

I have a very simple script:

require 'gpgme'

key     = File.expand_path("~/Documents/gpg_keys/somename.pub")
in_file = File.expand_path(ARGV[0])

if GPGME::Key.find(:public, "somename").empty?
  warn "importing key"
  GPGME::Key.import(File.open(key)) 
end

warn "encrypting file"
crypto = GPGME::Crypto.new(:always_trust => true)
crypto.encrypt(File.read(in_file), :output => $stdout, :recepient => "somename" )

Which I then run with the following command:

ruby gpgme-test.rb rsahae_2013-10-07.tgz > ruby-gpgme-test.tgz.gpg

The script runs fine but when I try to decrypt the data from the command line using 'gpg', then untarring it, I get problems. The last couple files are missing. When I look at a file and the result with I encrypt from the command line, and when I encrypt using ruby-gpgme, you can see that the ruby-gpgme encrypted file is smaller. Somehow it's truncating the data. Why is it doing that?

/tmp » ls -l *tgz*
-rw-r--r--  1 rsahae  wheel  17282451 Oct 10 14:29 gpg-test.tgz
-rw-r--r--  1 rsahae  wheel  17282801 Oct 10 16:15 gpg-test.tgz.gpg
-rw-r--r--  1 rsahae  wheel  16646828 Oct 10 16:25 ruby-gpgme-test.tgz.gpg

GPGME::Error: No such file or directory

[3] pry(main)> crypto = GPGME::Crypto.new
=> #<GPGME::Crypto:0x007fa1e57d2790 @default_options={}>
[4] pry(main)> crypto.encrypt "Hello world!", :recipients => "[email protected]"
GPGME::Error: No such file or directory
from /Users/roykolak/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/gpgme-2.0.2/lib/gpgme/ctx.rb:43:in `new'
[5] pry(main)>

this one is killing me... anyone ever experience this? OSX 10.9, brew installed gpgme 1.4.3

All sorts of build artifacts left behind in gem dir

gpgme seems to leave all sorts of cruft in the ext/ directory after installation.

Here's the size of each of the dirs under gems/gpgme-2.0.2:

$ du -sh gpgme-2.0.2/*
28K examples
73M ext
1.5M    lib
96K test

This is the content of the gpgme-2.0.2/ext/gpgme dir:

drwxrwxr-x.  6 rbowes Linux Admins    4096 Jan  7 14:52 dst
-rw-rw-r--.  1 rbowes Linux Admins    1570 Jan  7 14:52 extconf.rb
drwxrwxr-x.  9 rbowes Linux Admins    4096 Jan  7 14:53 gpgme-1.4.0
-rw-rw-r--.  1 rbowes Linux Admins  958151 Jan  7 14:52 gpgme-1.4.0.tar.bz2
-rw-rw-r--.  1 rbowes Linux Admins   82048 Jan  7 14:52 gpgme_n.c
-rw-rw-r--.  1 rbowes Linux Admins  247624 Jan  7 14:53 gpgme_n.o
-rwxrwxr-x.  1 rbowes Linux Admins 1373575 Jan  7 14:53 gpgme_n.so
drwxrwxr-x.  8 rbowes Linux Admins    4096 Jan  7 14:52 libassuan-2.1.0
-rw-rw-r--.  1 rbowes Linux Admins  537489 Jan  7 14:52 libassuan-2.1.0.tar.bz2
-rw-rw-r--.  1 rbowes Linux Admins  918808 Jan  7 14:53 libassuan_ext.a
drwxrwxr-x. 10 rbowes Linux Admins    4096 Jan  7 14:52 libgpg-error-1.11
-rw-rw-r--.  1 rbowes Linux Admins  489057 Jan  7 14:52 libgpg-error-1.11.tar.bz2
-rw-rw-r--.  1 rbowes Linux Admins  638947 Jan  7 14:52 libgpg-error-1.11.tar.gz
-rw-rw-r--.  1 rbowes Linux Admins  113574 Jan  7 14:53 libgpg-error_ext.a
-rw-rw-r--.  1 rbowes Linux Admins 2864720 Jan  7 14:53 libgpgme_ext.a
-rw-rw-r--.  1 rbowes Linux Admins    6167 Jan  7 14:53 Makefile
-rw-rw-r--.  1 rbowes Linux Admins  190228 Jan  7 14:53 mkmf.log

This includes the gpgme-1.4.0 tarball (and extracted version), the libassuan-2.1.0 tarballs (and extracted version), the libgpg-error-1.11 tarball - both gzipped and bzipped versions (and an extracted version - not sure which tarball?).

I have two problems with this:

  1. I'm really not happy for random rubygems to pull in their own copies of native crypto libraries - you should use the system libraries
  2. Why is all this cruft left behind in the gem dir, post-install? You should at least clean up after yourself.

can't import an RSA key generated via ssh-keygen -t rsa

I generated a pub/priv key pair called testing_rsa testing_rsa.pub.

Then I do the below code, but the results it returns show 0 successfulness:

GPGME::Key.import(File.open('testing_rsa.pub'))  # => 
#<GPGME::ImportResult:0x91ea9d4 @considered=0, @no_user_id=0, @imported=0, @imported_rsa=0, @unchanged=0, @new_user_ids=0, @new_sub_keys=0, @new_signatures=0, @new_revocations=0, @secret_read=0, @secret_imported=0, @secret_unchanged=0, @not_imported=0, @imports=[]>

Am I misusing that method? I'm building a app for encrypting/ decrypting on the command line and want to be able to specify arbitrary files/ strings as encryption/ decryption keys.

GPGME::Error::BadPassphrase when using decrypt without pinentry dialog box

Steps to reproduce:
Run bundle exec rails c
Run the following
crypto = GPGME::Crypto.new :armor=>true
decrypted_object = crypto.decrypt(encrypted_data, :password => my_password)
The Pinentry Mac dialog box appears as expected
Copy my password from my_password and paste into dialog box.
Text is decrypted as expected.
Exit the rails console.
Open up ~/.gnupg/gpg-agent.conf
and add
pinentry-program /usr/bin/pinentry-curses
to avoid having that dialog box come up
Save and close
Run echo RELOADAGENT | gpg-connect-agent to load the change
Run bundle exec rails c
run the following (same as above)
crypto = GPGME::Crypto.new :armor=>true
decrypted_object = crypto.decrypt(encrypted_data, :password => my_password)
Now I get the error:
GPGME::Error::BadPassphrase: GPGME::Error::BadPassphrase
from /Users/USERNAME/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/gpgme-2.0.8/lib/gpgme/ctx.rb:398:in decrypt_verify' from /Users/USERNAME/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/gpgme-2.0.8/lib/gpgme/crypto.rb:172:inblock in decrypt'
from /Users/USERNAME/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/gpgme-2.0.8/lib/gpgme/ctx.rb:71:in new' from /Users/USERNAME/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/gpgme-2.0.8/lib/gpgme/crypto.rb:170:indecrypt'

Research indicates I'm using an incompatible version of gnupg, i.e. 2.0., however:
gpg --version gives:
gpg (GnuPG) 1.4.19
Home: ~/.gnupg
and gpg2 --version gives:
gpg (GnuPG) 2.1.4
libgcrypt 1.6.3
Home: ~/.gnupg

And finally, GPGME::Engine.info gives:

GPGME::EngineInfo:0x007fe4b8e8d2e0 @protocol=0, @file_name="/usr/local/bin/gpg2", @Version="2.1.4", @req_version="1.4.0",

GPGME::EngineInfo:0x007fe4b8e8d218 @protocol=1, @file_name="/usr/local/bin/gpgsm", @Version="2.1.4", @req_version="2.0.4",

GPGME::EngineInfo:0x007fe4b8e8d178 @protocol=2, @file_name="/usr/local/bin/gpgconf", @Version="2.1.4", @req_version="2.0.4",

GPGME::EngineInfo:0x007fe4b8e8d0d8 @protocol=3, @file_name="/Users/jevans/.gnupg/S.gpg-agent", @Version="1.0", @req_version="1.0", @home_dir="!GPG_AGENT",

GPGME::EngineInfo:0x007fe4b8e8d010 @protocol=6, @file_name="/nonexistent", @Version="1.0", @req_version="1.0"

Other info:
Mac 10.10.3
Installed GPG Tools - GPG Suite Beta 6 (gnupg 2.0.27)
Installed gpg2 via make
Installed gpg 1.4 via brew

Soo.....Any guidance on how to use the passphrase via the script rather than via the dialog box?

Decrypt returns empty string

Hello, I'm probably doing something wrong, I can't find any instructions. I have a PGP encrypted XLS file and a PGP key. Here's is my code that returns an empty string:

require 'rubygems'
require 'gpgme'

def passfunc(obj, uid_hint, passphrase_info, prev_was_bad, fd)
  io = IO.for_fd(fd, 'w')
  io.puts "PASSPHRASE"
  io.flush
end

encrypted_data = GPGME::Data.new(File.open("file.xls.pgp"))
key = GPGME::Data.new(File.open("key.txt"))

ctx = GPGME::Ctx.new :passphrase_callback => method(:passfunc)
ctx.import_keys key

decrypted = ctx.decrypt encrypted_data

puts decrypted.read

I'm able to decrypt this file in a program called GNU Privacy Assistant on Windows using the same key. Any help is appreciated.

http://stackoverflow.com/questions/10092184/how-to-decrypt-pgp-encrypted-file-with-ruby-gpgme

Using node GPG on client side

Hello im new to javascript and was trying to use the GPG encryption/decryption functions, I was able to use npm to install and use libraries that do not have dependencies in themselves but GPG does. Would you mind showing me a way i can "require" GPG in a javascript file im using for a browser extension on the client side please?
thank you in advance
-Mujy

Errno::ENOMEM Foked process memory issue?

We are using this on a big site, server has 32 Gb ram. But after a couple of days runing we are receiving this error when trying to encript a binary file:

Errno::ENOMEM (Cannot allocate memory):
  gpgme (2.0.2) lib/gpgme/ctx.rb:219:in `keylist_start'
  gpgme (2.0.2) lib/gpgme/ctx.rb:250:in `each_key'
  gpgme (2.0.2) lib/gpgme/ctx.rb:265:in `keys'
  gpgme (2.0.2) lib/gpgme/key.rb:57:in `find'
  gpgme (2.0.2) lib/gpgme/ctx.rb:67:in `new'
  gpgme (2.0.2) lib/gpgme/key.rb:56:in `find'
  gpgme (2.0.2) lib/gpgme/key.rb:52:in `each'
  gpgme (2.0.2) lib/gpgme/key.rb:52:in `find'
  gpgme (2.0.2) lib/gpgme/crypto.rb:84:in `encrypt'
  lib/attachment_auto_backup.rb:13:in `send_to_s3'
  app/models/zipped_file.rb:19
....
  config/initializers/mongrel.rb:62:in `dispatch_cgi'

this is our code:

crypto = GPGME::Crypto.new
    crypted_content = crypto.encrypt relative_path_tarball, :recipients => "[email protected]", :always_trust => true

My experience suggest me that this is because an attemp to fork a process... but I've searched over the gpgme code and it seems to happend on a loop trying to find the key to encrypt.

crypto.rb
keys        = Key.find(:public, options[:recipients])

If i run on rails console:

GPGME::Key.find :public, "[email protected]"

I got this output almost inmediatly:

[
    [0] #<GPGME::Key pub 1024D/9869EFC4 2007-11-17 trust=nil, owner_trust=:ultimate, capability=[:encrypt, :sign, :certify, :authenticate], subkeys=[#<GPGME::SubKey sub 1024D/XXXXX XXX-11-17 trust=nil, capability=[:encrypt, :sign, :certify, :authenticate]>, #<GPGME::SubKey sub 2048g/XXXXXXXX 2007-11-17 trust=nil, capability=[:encrypt, :sign, :certify, :authenticate]>], uids=[#<GPGME::UserID XXX <[email protected]> validity=ultimate, signatures=[]>]>
]

Make these bindings part of GnuPG?

Werner Koch just said in a talk that the GnuPG-team will start to integrate python-bindings into future releases, and that they would like to be approached about other language bindings to be included.

Their motiviation seems to be to provide those bindings with timely updates and fixes, and make them even more broadly available.

What do you think?

GPGME::Ctx.decrypt returns empty GPGME::Data

I've been pulling my hair out over this. I'm having an empty GPGME::Data object returned every time that I attempt to decrypt a valid GPG message, without an error.

GPGME::Ctx.new(:passphrase_callback => method(:passphrase_callback), :progress_callback => method(:progress_callback)) do |c|
    p last_response.body.force_encoding('utf-8')
    data = GPGME::Data.new '-----BEGIN PGP MESSAGE-----\n...'
    data.seek 0
    p data.read
    data.seek 0
    msg = c.decrypt data
    msg.seek 0
    p msg.read
    msg.seek 0
end

All those .seek 0 and .read lines are to debug, and here's the output from running this code:

"-----BEGIN PGP MESSAGE-----\n..."                           
""17: 1287/0                                                                                                                                                                                                                                                                

.to_s also returns an empty string. 17: 1287/0 is (I think?) a result of the :progress_callback method, which is the same as is used in your example:

def progress_callback(hook, what, type, current, total)
    $stderr.write("#{what}: #{current}/#{total}\r")
    $stderr.flush
end

GPGMe version is GnuPG 1.4.11 on a linux-based machine (string is encrypted using ruby-gpgme on the same machine).

Cannot deploy via Capistrano

See this comment:

*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/usr/local/rvm/rubies/ruby-2.1.1/bin/ruby
    --clean
    --use-system-libraries
extconf.rb:51:in `initialize': No such device or address @ rb_sysopen - /dev/tty (Errno::ENXIO)
    from extconf.rb:51:in `open'
    from extconf.rb:51:in `message!'
    from extconf.rb:57:in `<main>'

extconf failed, exit code 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.