Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clint Fewbar: use gpgme 2 0 #55

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ sup-exception-log.txt
# bundler stuff
Gemfile.lock
.bundle

# generated file for gnupg test
test/gnupg_test_home/random_seed

2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ rvm:

before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq uuid-dev uuid libncursesw5-dev libncursesw5
- sudo apt-get install -qq uuid-dev uuid libncursesw5-dev libncursesw5 gnupg2

script: bundle exec rake travis

Expand Down
2 changes: 0 additions & 2 deletions bin/sup
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ require 'ncursesw'

no_gpgme = false
begin
# gpgme broke its API in 2.0, so make sure we have the old version for now.
gem 'gpgme', '=1.0.8'
require 'gpgme'
rescue LoadError
no_gpgme = true
Expand Down
42 changes: 34 additions & 8 deletions lib/sup/crypto.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
begin
# gpgme broke its API in 2.0, so make sure we have the old version for now.
gem 'gpgme', '=1.0.8'
require 'gpgme'
rescue LoadError
end
Expand Down Expand Up @@ -64,10 +62,17 @@ def initialize
@gpgme_present =
begin
begin
GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
begin
GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
rescue TypeError
GPGME.check_version(nil)
end
true
rescue GPGME::Error
false
rescue ArgumentError
# gpgme 2.0.0 raises this due to the hash->string conversion
false
end
rescue NameError
false
Expand All @@ -81,7 +86,11 @@ def initialize

# if gpg2 is available, it will start gpg-agent if required
if (bin = `which gpg2`.chomp) =~ /\S/
GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
if GPGME.respond_to?('set_engine_info')
GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
else
GPGME.gpgme_set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
end
else
# check if the gpg-options hook uses the passphrase_callback
# if it doesn't then check if gpg agent is present
Expand Down Expand Up @@ -110,6 +119,7 @@ def initialize
end

def have_crypto?; @not_working_reason.nil? end
def not_working_reason; @not_working_reason end

def sign from, to, payload
return unknown_status(@not_working_reason) unless @not_working_reason.nil?
Expand All @@ -120,7 +130,13 @@ def sign from, to, payload
{:operation => "sign", :options => gpg_opts}) || gpg_opts

begin
sig = GPGME.detach_sign(format_payload(payload), gpg_opts)
if GPGME.respond_to?('detach_sign')
sig = GPGME.detach_sign(format_payload(payload), gpg_opts)
else
crypto = GPGME::Crypto.new
gpg_opts[:mode] = GPGME::SIG_MODE_DETACH
sig = crypto.sign(format_payload(payload), gpg_opts).read
end
rescue GPGME::Error => exc
raise Error, gpgme_exc_msg(exc.message)
end
Expand Down Expand Up @@ -153,7 +169,13 @@ def encrypt from, to, payload, sign=false
recipients = to + [from]
recipients = HookManager.run("gpg-expand-keys", { :recipients => recipients }) || recipients
begin
cipher = GPGME.encrypt(recipients, format_payload(payload), gpg_opts)
if GPGME.respond_to?('encrypt')
cipher = GPGME.encrypt(recipients, format_payload(payload), gpg_opts)
else
crypto = GPGME::Crypto.new
gpg_opts[:recipients] = recipients
cipher = crypto.encrypt(format_payload(payload), gpg_opts).read
end
rescue GPGME::Error => exc
raise Error, gpgme_exc_msg(exc.message)
end
Expand Down Expand Up @@ -262,7 +284,11 @@ def decrypt payload, armor=false # a RubyMail::Message object
{:operation => "decrypt", :options => gpg_opts}) || gpg_opts
ctx = GPGME::Ctx.new(gpg_opts)
cipher_data = GPGME::Data.from_str(format_payload(payload))
plain_data = GPGME::Data.empty
if GPGME::Data.respond_to?('empty')
plain_data = GPGME::Data.empty
else
plain_data = GPGME::Data.empty!
end
begin
ctx.decrypt_verify(cipher_data, plain_data)
rescue GPGME::Error => exc
Expand Down Expand Up @@ -330,7 +356,7 @@ def unknown_status lines=[]

def gpgme_exc_msg msg
err_msg = "Exception in GPGME call: #{msg}"
info err_msg
#info err_msg
err_msg
end

Expand Down
1 change: 1 addition & 0 deletions sup.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ SUP: Please run `sup-psych-ify-config-files` to migrate from 0.13 to 0.14
s.add_development_dependency "rake"
s.add_development_dependency "minitest", "~> 4.7"
s.add_development_dependency "rr", "~> 1.0.5"
s.add_development_dependency "gpgme", ">= 2.0.2"
end
end
1 change: 1 addition & 0 deletions test/gnupg_test_home/gpg.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default-key 789E7011
Binary file added test/gnupg_test_home/pubring.gpg
Binary file not shown.
Binary file added test/gnupg_test_home/receiver_pubring.gpg
Binary file not shown.
Binary file added test/gnupg_test_home/receiver_secring.gpg
Binary file not shown.
Binary file added test/gnupg_test_home/receiver_trustdb.gpg
Binary file not shown.
Binary file added test/gnupg_test_home/secring.gpg
Binary file not shown.
20 changes: 20 additions & 0 deletions test/gnupg_test_home/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.20 (GNU/Linux)

mI0EUgi0fAEEAOLAcQW96NEUSB7YE/la8X56jGW5BMX3aAixOF8LvOwMBbUK1T+U
0H2PGIrXVcYyHcPqWRpRahbsIAldBqzffPlzMa+aqJaB1xKkNruxSoIzwPdidZMe
l0Dxz2FDsoXD0KPyWnAYhGmQyz2MFpZxu2tlYqvwWVW//XGnk/KHvIXbABEBAAG0
PlN1cCBUZXN0IFJlY2VpdmVyIChUZXN0IHJlY2VpdmVyIGZvciBTdXApIDxzdXAt
dGVzdC0yQGZvby5iYXI+iL8EEwECACkFAlIItHwCGwMFCQHhM4AHCwkIBwMCAQYV
CAIJCgsEFgIDAQIeAQIXgAAKCRAsABl+cWpykMMVBADHkQPgTz0CqKKp3k+z3dbm
ocmI4tYNn1dOkDQqyfoBTfs6L3g4j5OE2UrguntRYyg5oon+uO5d18CQ5dY0sCw/
o5IwyzTrxI8IocbtZvBdSb+XjLndynGuIQoqaJq9i6n1V4klFHVOna8Q9JstLfRX
H1d4xPhnvKcaDDx/NV3X/biNBFIItHwBBADBpb43MpkrUWlg7HWJ1ZfOlxnOxrJ3
Gz9WFNV06UbcZEuFKA/vHRjM6gWzUn5903FLuCWu3eBrq5xQfWipbp187PmocpoG
skJ6gosLs1fMYRBjv2VbG9xJVKdKJMjqZw5FUpXKAaHr8P9jN6g2STQrbeQ8CVUK
h7zOWRXAXSKUgwARAQABiKUEGAECAA8FAlIItHwCGwwFCQHhM4AACgkQLAAZfnFq
cpDV1QQAzcxFXznEX92DjWxWRC7gRHgIsQk9WJnDzjtnDjSWCp3H85qeTZGZrn9W
NoneV/S5Y7K3Mkceh4rFaANQ3zx4b05y1LFt5N/lPwIe5VB0vcPumtZum2fSGfpK
nTXvzelcWcm2aGyUSaWvOkntWKEEt1kB5Oq6EtZoRZLMzAxLd7s=
=aKsV
-----END PGP PUBLIC KEY BLOCK-----
Binary file added test/gnupg_test_home/trustdb.gpg
Binary file not shown.
109 changes: 109 additions & 0 deletions test/test_crypto.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# tests for sup's crypto libs
#
# Copyright Clint Byrum <[email protected]> 2011. All Rights Reserved.
# Copyright Sup Developers 2013.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

require 'test_helper'
require 'sup'
require 'stringio'
require 'tmpdir'

module Redwood

class TestCryptoManager < ::Minitest::Unit::TestCase

def setup
@from_email = '[email protected]'
@to_email = '[email protected]'
# Use test gnupg setup
@orig_gnupghome = ENV['GNUPGHOME']
ENV['GNUPGHOME'] = File.join(File.dirname(__FILE__), 'gnupg_test_home')

@path = Dir.mktmpdir
Redwood::HookManager.init File.join(@path, 'hooks')

am = {:default=> {:name => "test", :email=> '[email protected]'}}
Redwood::AccountManager.init am

Redwood::CryptoManager.init

if not CryptoManager.have_crypto?
warn "No crypto set up, crypto will not be tested. Reason: #{CryptoManager.not_working_reason}"
end
end

def teardown
CryptoManager.deinstantiate!
AccountManager.deinstantiate!
HookManager.deinstantiate!
FileUtils.rm_r @path

ENV['GNUPGHOME'] = @orig_gnupghome
end

def test_sign
if CryptoManager.have_crypto? then
signed = CryptoManager.sign @from_email,@to_email,"ABCDEFG"
assert_instance_of RMail::Message, signed
assert_equal "ABCDEFG", signed.body[0]
assert signed.body[1].body.length > 0 , "signature length must be > 0"
assert (signed.body[1].body.include? "-----BEGIN PGP SIGNATURE-----") , "Expecting PGP armored data"
end
end

def test_encrypt
if CryptoManager.have_crypto? then
encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
assert_instance_of RMail::Message, encrypted
assert (encrypted.body[1].body.include? "-----BEGIN PGP MESSAGE-----") , "Expecting PGP armored data"
end
end

def test_sign_and_encrypt
if CryptoManager.have_crypto? then
encrypted = CryptoManager.sign_and_encrypt @from_email, [@to_email], "ABCDEFG"
assert_instance_of RMail::Message, encrypted
assert (encrypted.body[1].body.include? "-----BEGIN PGP MESSAGE-----") , "Expecting PGP armored data"
end
end

def test_decrypt
if CryptoManager.have_crypto? then
encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
assert_instance_of RMail::Message, encrypted
assert_instance_of String, (encrypted.body[1].body)
decrypted = CryptoManager.decrypt encrypted.body[1], true
assert_instance_of Array, decrypted
assert_instance_of Chunk::CryptoNotice, decrypted[0]
assert_instance_of Chunk::CryptoNotice, decrypted[1]
assert_instance_of RMail::Message, decrypted[2]
assert_equal "ABCDEFG" , decrypted[2].body
end
end

def test_verify
if CryptoManager.have_crypto?
signed = CryptoManager.sign @from_email, @to_email, "ABCDEFG"
assert_instance_of RMail::Message, signed
assert_instance_of String, (signed.body[1].body)
CryptoManager.verify signed.body[0], signed.body[1], true
end
end
end

end