class EnMail::Adapters::GPGME

Secures e-mails according to RFC 3156 “MIME Security with OpenPGP”.

This adapter uses GnuPG Made Easy (GPGME) library via interface provided by gpgme gem.

Public Class Methods

new(*args) click to toggle source
Calls superclass method EnMail::Adapters::Base::new
# File lib/enmail/adapters/gpgme.rb, line 17
def initialize(*args)
  require_relative "gpgme_requirements"
  super
end

Private Instance Methods

build_crypto() click to toggle source
# File lib/enmail/adapters/gpgme.rb, line 64
def build_crypto
  ::GPGME::Crypto.new(default_gpgme_options)
end
compute_signature(text, signer) click to toggle source
# File lib/enmail/adapters/gpgme.rb, line 24
def compute_signature(text, signer)
  plain = ::GPGME::Data.new(text)
  output = ::GPGME::Data.new
  mode = ::GPGME::SIG_MODE_DETACH
  hash_algorithm = nil

  with_ctx(password: options[:key_password]) do |ctx|
    signer_keys = ::GPGME::Key.find(:secret, signer, :sign)
    ctx.add_signer(*signer_keys)

    begin
      ctx.sign(plain, output, mode)
      hash_algorithm_num = ctx.sign_result.signatures[0].hash_algo
      hash_algorithm = ::GPGME.hash_algo_name(hash_algorithm_num)
    rescue ::GPGME::Error::UnusableSecretKey => e
      # TODO Copy-pasted from GPGME gem.  Needs any test coverage.
      e.keys = ctx.sign_result.invalid_signers
      raise e
    end
  end

  output.seek(0)

  ["pgp-#{hash_algorithm.downcase}", output.to_s]
end
default_gpgme_options() click to toggle source
# File lib/enmail/adapters/gpgme.rb, line 73
def default_gpgme_options
  {
    armor: true,
    pinentry_mode: ::GPGME::PINENTRY_MODE_LOOPBACK,
  }
end
encrypt_string(text, recipients) click to toggle source
# File lib/enmail/adapters/gpgme.rb, line 50
def encrypt_string(text, recipients)
  build_crypto.encrypt(text, recipients: recipients)
end
sign_and_encrypt_string(text, signer, recipients) click to toggle source
# File lib/enmail/adapters/gpgme.rb, line 54
def sign_and_encrypt_string(text, signer, recipients)
  build_crypto.encrypt(
    text,
    sign: true,
    signers: [signer],
    recipients: recipients,
    password: options[:key_password],
  )
end
with_ctx(options, &block) click to toggle source
# File lib/enmail/adapters/gpgme.rb, line 68
def with_ctx(options, &block)
  ctx_options = default_gpgme_options.merge(options)
  ::GPGME::Ctx.new(ctx_options, &block)
end