class EnMail::Adapters::RNP

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

This adapter uses RNP library via ruby-rnp gem.

NOTE: `Rnp` instances are not thread-safe, and neither this adapter is. Any adapter instance should be accessed by at most one thread at a time.

Attributes

rnp[R]

Public Class Methods

new(*args) click to toggle source
Calls superclass method EnMail::Adapters::Base::new
# File lib/enmail/adapters/rnp.rb, line 21
def initialize(*args)
  require_relative "rnp_requirements"
  super
  @rnp = build_rnp_and_load_keys
end

Private Instance Methods

build_input(text) click to toggle source
# File lib/enmail/adapters/rnp.rb, line 80
def build_input(text)
  ::Rnp::Input.from_string(text)
end
build_rnp_and_load_keys() click to toggle source
# File lib/enmail/adapters/rnp.rb, line 84
def build_rnp_and_load_keys
  public_info, secret_info = homedir_info.values_at(:public, :secret)

  rnp = Rnp.new(public_info[:format], secret_info[:format])

  [public_info, secret_info].each do |keyring_info|
    input = ::Rnp::Input.from_path(keyring_info[:path])
    rnp.load_keys(format: keyring_info[:format], input: input)
  end

  rnp.password_provider = options[:key_password]

  rnp
end
compute_signature(text, signer) click to toggle source
# File lib/enmail/adapters/rnp.rb, line 29
def compute_signature(text, signer)
  signer_key = find_key_for(signer, need_secret: true)

  signature = rnp.detached_sign(
    signers: [signer_key],
    input: build_input(text),
    armored: true,
    hash: hash_algorithm,
  )

  ["pgp-#{hash_algorithm.downcase}", signature]
end
encrypt_string(text, recipients) click to toggle source
# File lib/enmail/adapters/rnp.rb, line 42
def encrypt_string(text, recipients)
  recipient_keys =
    recipients.map { |r| find_key_for(r, need_public: true) }

  rnp.encrypt(
    recipients: recipient_keys,
    input: build_input(text),
    armored: true,
  )
end
find_key_for(email, need_public: false, need_secret: false) click to toggle source
# File lib/enmail/adapters/rnp.rb, line 67
def find_key_for(email, need_public: false, need_secret: false)
  rnp.each_keyid do |keyid|
    key = rnp.find_key(keyid: keyid)
    next if need_public && !key.public_key_present?
    next if need_secret && !key.secret_key_present?

    key.each_userid do |userid|
      return key if userid.include?(email)
    end
  end
  nil
end
hash_algorithm() click to toggle source
# File lib/enmail/adapters/rnp.rb, line 104
def hash_algorithm
  "SHA512"
end
homedir_info() click to toggle source
# File lib/enmail/adapters/rnp.rb, line 99
def homedir_info
  @homedir_info ||=
    ::Rnp.homedir_info(options[:homedir] || Rnp.default_homedir)
end
sign_and_encrypt_string(text, signer, recipients) click to toggle source
# File lib/enmail/adapters/rnp.rb, line 53
def sign_and_encrypt_string(text, signer, recipients)
  signer_key = find_key_for(signer, need_secret: true)
  recipient_keys =
    recipients.map { |r| find_key_for(r, need_public: true) }

  rnp.encrypt_and_sign(
    recipients: recipient_keys,
    signers: signer_key,
    input: build_input(text),
    armored: true,
    hash: hash_algorithm,
  )
end