GPGME

What's this?

Ruby-GPGME is a Ruby language binding of GPGME (GnuPG Made Easy).

Requirements

Installation

$ gem install ruby-gpgme

or

$ ruby extconf.rb
$ make
$ make install

Examples

examples/genkey.rb

Generate a key pair in your keyring.

examples/keylist.rb

List your keyring like gpg --list-keys.

examples/roundtrip.rb

Encrypt and decrypt a plain text.

examples/sign.rb

Create a clear text signature.

examples/verify.rb

Verify a clear text signature given from stdin.

API

Ruby-GPGME provides three levels of API. The highest level API is close to the command line interface of GnuPG. The mid level API looks object-oriented (or rubyish). The lowest level API is close to the C interface of GPGME.

The highest level API

It can be written in the highest level API to create a cleartext signature of the plaintext from stdin as follows.

$ ruby -rgpgme -e 'GPGME.clearsign($stdin, $stdout)'

The mid level API

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

$ ruby -rgpgme -e <<End  
ctx = GPGME::Ctx.new
plain = GPGME::Data.from_io($stdin)
sig = GPGME::Data.from_io($stdout)
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.

$ ruby -rgpgme -e <<End  
ret = Array.new
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)
End

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

License

Copyright (C) 2003,2006,2007,2008,2009 Daiki Ueno

This file is a part of Ruby-GPGME.

Ruby-GPGME is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

Ruby-GPGME is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

Constants

ATTR_ALGO
ATTR_CAN_CERTIFY
ATTR_CAN_ENCRYPT
ATTR_CAN_SIGN
ATTR_CHAINID
ATTR_COMMENT
ATTR_CREATED
ATTR_EMAIL
ATTR_ERRTOK
ATTR_EXPIRE
ATTR_FPR
ATTR_ISSUER
ATTR_IS_SECRET
ATTR_KEYID
ATTR_KEY_CAPS
ATTR_KEY_DISABLED
ATTR_KEY_EXPIRED
ATTR_KEY_INVALID
ATTR_KEY_REVOKED
ATTR_LEN
ATTR_LEVEL
ATTR_NAME
ATTR_OTRUST
ATTR_SERIAL
ATTR_SIG_STATUS
ATTR_SIG_SUMMARY
ATTR_TYPE
ATTR_UID_INVALID
ATTR_UID_REVOKED
ATTR_USERID
ATTR_VALIDITY
DATA_ENCODING_ARMOR
DATA_ENCODING_BASE64
DATA_ENCODING_BINARY
DATA_ENCODING_NONE
ENCRYPT_ALWAYS_TRUST
GpgmeCtx
GpgmeData
GpgmeDecryptResult
GpgmeEncryptResult
GpgmeEngineInfo
GpgmeError
GpgmeImportResult
GpgmeImportStatus
GpgmeInvalidKey
GpgmeKey
GpgmeKeySig
GpgmeNewSignature
GpgmeSignResult
GpgmeSignature
GpgmeSubKey
GpgmeUserID
GpgmeVerifyResult
IMPORT_NEW
IMPORT_SECRET
IMPORT_SIG
IMPORT_SUBKEY
IMPORT_UID
KEYLIST_MODE_EXTERN
KEYLIST_MODE_LOCAL
KEYLIST_MODE_SIGS
KEYLIST_MODE_VALIDATE
MD_CRC24_RFC2440
MD_CRC32
MD_CRC32_RFC1510
MD_HAVAL
MD_MD2
MD_MD4
MD_MD5
MD_RMD160
MD_SHA1
MD_SHA256
MD_SHA384
MD_SHA512
MD_TIGER
PK_DSA
PK_ELG
PK_ELG_E
PK_RSA
PROTOCOL_CMS
PROTOCOL_OpenPGP
SIGSUM_BAD_POLICY
SIGSUM_CRL_MISSING
SIGSUM_CRL_TOO_OLD
SIGSUM_GREEN
SIGSUM_KEY_EXPIRED
SIGSUM_KEY_MISSING
SIGSUM_KEY_REVOKED
SIGSUM_RED
SIGSUM_SIG_EXPIRED
SIGSUM_SYS_ERROR
SIGSUM_VALID
SIG_MODE_CLEAR
SIG_MODE_DETACH
SIG_MODE_NORMAL
SIG_STAT_BAD
SIG_STAT_DIFF
SIG_STAT_ERROR
SIG_STAT_GOOD
SIG_STAT_GOOD_EXP
SIG_STAT_GOOD_EXPKEY
SIG_STAT_NOKEY
SIG_STAT_NONE
SIG_STAT_NOSIG
STATUS_ABORT
STATUS_ALREADY_SIGNED
STATUS_BADARMOR
STATUS_BADMDC
STATUS_BADSIG
STATUS_BAD_PASSPHRASE
STATUS_BEGIN_DECRYPTION
STATUS_BEGIN_ENCRYPTION
STATUS_BEGIN_STREAM
STATUS_DECRYPTION_FAILED
STATUS_DECRYPTION_OKAY
STATUS_DELETE_PROBLEM
STATUS_ENC_TO
STATUS_END_DECRYPTION
STATUS_END_ENCRYPTION
STATUS_END_STREAM
STATUS_ENTER
STATUS_EOF
STATUS_ERRMDC
STATUS_ERROR
STATUS_ERRSIG
STATUS_EXPKEYSIG
STATUS_EXPSIG
STATUS_FILE_DONE
STATUS_FILE_ERROR
STATUS_FILE_START
STATUS_GET_BOOL
STATUS_GET_HIDDEN
STATUS_GET_LINE
STATUS_GOODMDC
STATUS_GOODSIG
STATUS_GOOD_PASSPHRASE
STATUS_GOT_IT
STATUS_IMPORTED
STATUS_IMPORT_RES
STATUS_INV_RECP
STATUS_KEYEXPIRED
STATUS_KEYREVOKED
STATUS_KEY_CREATED
STATUS_LEAVE
STATUS_MISSING_PASSPHRASE
STATUS_NEED_PASSPHRASE
STATUS_NEED_PASSPHRASE_SYM
STATUS_NODATA
STATUS_NOTATION_DATA
STATUS_NOTATION_NAME
STATUS_NO_PUBKEY
STATUS_NO_RECP
STATUS_NO_SECKEY
STATUS_POLICY_URL
STATUS_PROGRESS
STATUS_RSA_OR_IDEA
STATUS_SESSION_KEY
STATUS_SHM_GET
STATUS_SHM_GET_BOOL
STATUS_SHM_GET_HIDDEN
STATUS_SHM_INFO
STATUS_SIGEXPIRED
STATUS_SIG_CREATED
STATUS_SIG_ID
STATUS_TRUNCATED
STATUS_TRUST_FULLY
STATUS_TRUST_MARGINAL
STATUS_TRUST_NEVER
STATUS_TRUST_ULTIMATE
STATUS_TRUST_UNDEFINED
STATUS_UNEXPECTED
STATUS_USERID_HINT
STATUS_VALIDSIG
VALIDITY_FULL
VALIDITY_MARGINAL
VALIDITY_NEVER
VALIDITY_ULTIMATE
VALIDITY_UNDEFINED
VALIDITY_UNKNOWN
VERSION

Public Class Methods

clearsign(plain, sig=nil, options=Hash.new) click to toggle source

GPGME.clearsign creates a cleartext signature of the plaintext.

The arguments should be specified as follows.

All arguments except plain are optional. plain is input and sig is output. If the last argument is a Hash, options will be read from it.

An input argument is specified by an IO like object (which responds to read), a string, or a GPGME::Data object.

An output argument is specified by an IO like object (which responds to write) or a GPGME::Data object.

options are same as GPGME::Ctx.new() except for

  • :signers Signing keys. If specified, it is an array whose elements are a GPGME::Key object or a string.

# File lib/gpgme.rb, line 289
def GPGME.clearsign(plain, *args_options)
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
  args, options = split_args(args_options)
  args.push(options.merge({:mode => GPGME::SIG_MODE_CLEAR}))
  GPGME.sign(plain, *args)
end
decrypt(cipher, plain=nil, options=Hash.new){|signature| ...} click to toggle source

GPGME.decrypt performs decryption.

The arguments should be specified as follows.

All arguments except cipher are optional. cipher is input, and plain is output. If the last argument is a Hash, options will be read from it.

An input argument is specified by an IO like object (which responds to read), a string, or a GPGME::Data object.

An output argument is specified by an IO like object (which responds to write) or a GPGME::Data object.

options are same as GPGME::Ctx.new().

# File lib/gpgme.rb, line 124
def GPGME.decrypt(cipher, *args_options)
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
  args, options = split_args(args_options)
  plain = args[0]

  check_version(options)
  GPGME::Ctx.new(options) do |ctx|
    cipher_data = input_data(cipher)
    plain_data = output_data(plain)
    begin
      ctx.decrypt_verify(cipher_data, plain_data)
    rescue GPGME::Error::UnsupportedAlgorithm => exc
      exc.algorithm = ctx.decrypt_result.unsupported_algorithm
      raise exc
    rescue GPGME::Error::WrongKeyUsage => exc
      exc.key_usage = ctx.decrypt_result.wrong_key_usage
      raise exc
    end

    verify_result = ctx.verify_result
    if verify_result && block_given?
      verify_result.signatures.each do |signature|
        yield signature
      end
    end

    unless plain
      plain_data.seek(0, IO::SEEK_SET)
      plain_data.read
    end
  end
end
detach_sign(plain, sig=nil, options=Hash.new) click to toggle source

GPGME.detach_sign creates a detached signature of the plaintext.

The arguments should be specified as follows.

All arguments except plain are optional. plain is input and sig is output. If the last argument is a Hash, options will be read from it.

An input argument is specified by an IO like object (which responds to read), a string, or a GPGME::Data object.

An output argument is specified by an IO like object (which responds to write) or a GPGME::Data object.

options are same as GPGME::Ctx.new() except for

  • :signers Signing keys. If specified, it is an array whose elements are a GPGME::Key object or a string.

# File lib/gpgme.rb, line 321
def GPGME.detach_sign(plain, *args_options)
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
  args, options = split_args(args_options)
  args.push(options.merge({:mode => GPGME::SIG_MODE_DETACH}))
  GPGME.sign(plain, *args)
end
encrypt(recipients, plain, cipher=nil, options=Hash.new) click to toggle source

GPGME.encrypt performs encryption.

The arguments should be specified as follows.

All arguments except recipients and plain are optional. plain is input and cipher is output. If the last argument is a Hash, options will be read from it.

The recipients are specified by an array whose elements are a string or a GPGME::Key object. If recipients is nil, it performs symmetric encryption.

An input argument is specified by an IO like object (which responds to read), a string, or a GPGME::Data object.

An output argument is specified by an IO like object (which responds to write) or a GPGME::Data object.

options are same as GPGME::Ctx.new() except for

  • :sign If true, it performs a combined sign and encrypt operation.

  • :signers Signing keys. If specified, it is an array whose elements are a GPGME::Key object or a string.

  • :always_trust Setting this to true specifies all the recipients should be trusted.

# File lib/gpgme.rb, line 361
def GPGME.encrypt(recipients, plain, *args_options)
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 3
  args, options = split_args(args_options)
  cipher = args[0]
  recipient_keys = recipients ? resolve_keys(recipients, false, [:encrypt]) : nil

  check_version(options)
  GPGME::Ctx.new(options) do |ctx|
    plain_data = input_data(plain)
    cipher_data = output_data(cipher)
    begin
      flags = 0
      if options[:always_trust]
        flags |= GPGME::ENCRYPT_ALWAYS_TRUST
      end
      if options[:sign]
        if options[:signers]
          ctx.add_signer(*resolve_keys(options[:signers], true, [:sign]))
        end
        ctx.encrypt_sign(recipient_keys, plain_data, cipher_data, flags)
      else
        ctx.encrypt(recipient_keys, plain_data, cipher_data, flags)
      end
    rescue GPGME::Error::UnusablePublicKey => exc
      exc.keys = ctx.encrypt_result.invalid_recipients
      raise exc
    rescue GPGME::Error::UnusableSecretKey => exc
      exc.keys = ctx.sign_result.invalid_signers
      raise exc
    end

    unless cipher
      cipher_data.seek(0, IO::SEEK_SET)
      cipher_data.read
    end
  end
end
engine_check_version(proto) click to toggle source

Verify that the engine implementing the protocol proto is installed in the system.

# File lib/gpgme.rb, line 753
def engine_check_version(proto)
  err = GPGME::gpgme_engine_check_version(proto)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end
engine_info() click to toggle source

Return a list of info structures of enabled engines.

# File lib/gpgme.rb, line 761
def engine_info
  rinfo = Array.new
  GPGME::gpgme_get_engine_info(rinfo)
  rinfo
end
export(pattern) click to toggle source

GPGME.export extracts public keys from the key ring.

The arguments should be specified as follows.

All arguments are optional. If the last argument is a Hash, options will be read from it.

pattern is a string or nil. If pattern is nil, all available public keys are returned. keydata is output.

An output argument is specified by an IO like object (which responds to write) or a GPGME::Data object.

options are same as GPGME::Ctx.new().

# File lib/gpgme.rb, line 456
def GPGME.export(*args_options)
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
  args, options = split_args(args_options)
  pattern, key = args[0]
  key_data = output_data(key)
  check_version(options)
  GPGME::Ctx.new(options) do |ctx|
    ctx.export_keys(pattern, key_data)

    unless key
      key_data.seek(0, IO::SEEK_SET)
      key_data.read
    end
  end
end
gpgme_data_rewind(dh) click to toggle source
# File lib/gpgme/compat.rb, line 29
def gpgme_data_rewind(dh)
  begin
    GPGME::gpgme_data_seek(dh, 0, IO::SEEK_SET)
  rescue SystemCallError => e
    return e.errno
  end
end
gpgme_op_import_ext(ctx, keydata, nr) click to toggle source
# File lib/gpgme/compat.rb, line 38
def gpgme_op_import_ext(ctx, keydata, nr)
  err = GPGME::gpgme_op_import(ctx, keydata)
  if GPGME::gpgme_err_code(err) == GPGME::GPG_ERR_NO_ERROR
    result = GPGME::gpgme_op_import_result(ctx)
    nr.push(result.considered)
  end
end
import(keydata) click to toggle source

GPGME.import adds the keys to the key ring.

The arguments should be specified as follows.

All arguments are optional. If the last argument is a Hash, options will be read from it.

keydata is input.

An input argument is specified by an IO like object (which responds to read), a string, or a GPGME::Data object.

options are same as GPGME::Ctx.new().

# File lib/gpgme.rb, line 491
def GPGME.import(*args_options)
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
  args, options = split_args(args_options)
  key = args[0]
  key_data = input_data(key)
  check_version(options)
  GPGME::Ctx.new(options) do |ctx|
    ctx.import_keys(key_data)
    ctx.import_result
  end
end
list_keys(pattern=nil, secret_only=false, options=Hash.new){|key| ...} click to toggle source

GPGME.list_keys iterates over the key ring.

The arguments should be specified as follows.

All arguments are optional. If the last argument is a Hash, options will be read from it.

pattern is a string or nil. If pattern is nil, all available keys are returned. If secret_only is true, the only secret keys are returned.

options are same as GPGME::Ctx.new().

# File lib/gpgme.rb, line 418
def GPGME.list_keys(*args_options) # :yields: key
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 3
  args, options = split_args(args_options)
  pattern, secret_only = args
  check_version(options)
  GPGME::Ctx.new do |ctx|
    if block_given?  
      ctx.each_key(pattern, secret_only || false) do |key|
        yield key
      end
    else
      ctx.keys(pattern, secret_only || false)
    end
  end
end
set_engine_info(proto, file_name, home_dir) click to toggle source

Change the default configuration of the crypto engine implementing protocol proto.

file_name is the file name of the executable program implementing the protocol. home_dir is the directory name of the configuration directory.

# File lib/gpgme.rb, line 774
def set_engine_info(proto, file_name, home_dir)
  err = GPGME::gpgme_set_engine_info(proto, file_name, home_dir)
  exc = GPGME::error_to_exception(err)
  raise exc if exc
end
sign(plain, sig=nil, options=Hash.new) click to toggle source

GPGME.sign creates a signature of the plaintext.

The arguments should be specified as follows.

All arguments except plain are optional. plain is input and sig is output. If the last argument is a Hash, options will be read from it.

An input argument is specified by an IO like object (which responds to read), a string, or a GPGME::Data object.

An output argument is specified by an IO like object (which responds to write) or a GPGME::Data object.

options are same as GPGME::Ctx.new() except for

  • :signers Signing keys. If specified, it is an array whose elements are a GPGME::Key object or a string.

  • :mode Desired type of a signature. Either GPGME::SIG_MODE_NORMAL for a normal signature, GPGME::SIG_MODE_DETACH for a detached signature, or GPGME::SIG_MODE_CLEAR for a cleartext signature.

# File lib/gpgme.rb, line 239
def GPGME.sign(plain, *args_options)
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
  args, options = split_args(args_options)
  sig = args[0]

  check_version(options)
  GPGME::Ctx.new(options) do |ctx|
    ctx.add_signer(*resolve_keys(options[:signers], true, [:sign])) if options[:signers]
    mode = options[:mode] || GPGME::SIG_MODE_NORMAL
    plain_data = input_data(plain)
    sig_data = output_data(sig)
    begin
      ctx.sign(plain_data, sig_data, mode)
    rescue GPGME::Error::UnusableSecretKey => exc
      exc.keys = ctx.sign_result.invalid_signers
      raise exc
    end

    unless sig
      sig_data.seek(0, IO::SEEK_SET)
      sig_data.read
    end
  end
end
verify(sig, signed_text=nil, plain=nil, options=Hash.new){|signature| ...} click to toggle source

GPGME.verify verifies a signature.

The arguments should be specified as follows.

All arguments except sig are optional. sig and signed_text are input. plain is output. If the last argument is a Hash, options will be read from it.

An input argument is specified by an IO like object (which responds to read), a string, or a GPGME::Data object.

An output argument is specified by an IO like object (which responds to write) or a GPGME::Data object.

If sig is a detached signature, then the signed text should be provided in signed_text and plain should be nil. Otherwise, if sig is a normal (or cleartext) signature, signed_text should be nil.

options are same as GPGME::Ctx.new().

# File lib/gpgme.rb, line 184
def GPGME.verify(sig, *args_options) # :yields: signature
  raise ArgumentError, 'wrong number of arguments' if args_options.length > 3
  args, options = split_args(args_options)
  signed_text, plain = args

  check_version(options)
  GPGME::Ctx.new(options) do |ctx|
    sig_data = input_data(sig)
    if signed_text
      signed_text_data = input_data(signed_text)
      plain_data = nil
    else
      signed_text_data = nil
      plain_data = output_data(plain)
    end
    ctx.verify(sig_data, signed_text_data, plain_data)
    ctx.verify_result.signatures.each do |signature|
      yield signature
    end
    if !signed_text && !plain
      plain_data.seek(0, IO::SEEK_SET)
      plain_data.read
    end
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.