sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/

test/test_crypto.rb (8384B) - raw

      1 # tests for sup's crypto libs
      2 #
      3 # Copyright Clint Byrum <clint@ubuntu.com> 2011. All Rights Reserved.
      4 # Copyright Sup Developers                 2013.
      5 #
      6 # This program is free software; you can redistribute it and/or
      7 # modify it under the terms of the GNU General Public License
      8 # as published by the Free Software Foundation; either version 2
      9 # of the License, or (at your option) any later version.
     10 #
     11 # This program is distributed in the hope that it will be useful,
     12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 # GNU General Public License for more details.
     15 #
     16 # You should have received a copy of the GNU General Public License
     17 # along with this program; if not, write to the Free Software
     18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     19 # 02110-1301, USA.
     20 
     21 require 'test_helper'
     22 require 'sup'
     23 require 'stringio'
     24 require 'tmpdir'
     25 
     26 module Redwood
     27 
     28 class TestCryptoManager < Minitest::Test
     29 
     30     def setup
     31         @from_email = 'sup-test-1@foo.bar'
     32         @from_email_ecc = 'sup-fake-ecc@fake.fake'
     33         @to_email   = 'sup-test-2@foo.bar'
     34         # Use test gnupg setup
     35         @orig_gnupghome = ENV['GNUPGHOME']
     36         ENV['GNUPGHOME'] = File.join(File.dirname(__FILE__), 'gnupg_test_home')
     37 
     38         @path = Dir.mktmpdir
     39         Redwood::HookManager.init File.join(@path, 'hooks')
     40 
     41         account = {
     42           :name => +"test",
     43           :email => @from_email.dup,
     44           :alternates => [@from_email_ecc.dup],
     45           :sendmail => "/bin/false",
     46         }
     47         Redwood::AccountManager.init :default => account
     48 
     49         Redwood::CryptoManager.init
     50     end
     51 
     52     def teardown
     53       CryptoManager.deinstantiate!
     54       AccountManager.deinstantiate!
     55       HookManager.deinstantiate!
     56       FileUtils.rm_r @path
     57 
     58       ENV['GNUPGHOME'] = @orig_gnupghome
     59     end
     60 
     61     def test_sign
     62       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
     63 
     64       signed = CryptoManager.sign @from_email,@to_email,"ABCDEFG"
     65       assert_instance_of RMail::Message, signed
     66       assert_equal("multipart/signed; protocol=application/pgp-signature; micalg=pgp-sha256",
     67                    signed.header["Content-Type"])
     68       assert_equal "ABCDEFG", signed.body[0]
     69       assert signed.body[1].body.length > 0 , "signature length must be > 0"
     70       assert (signed.body[1].body.include? "-----BEGIN PGP SIGNATURE-----") , "Expecting PGP armored data"
     71     end
     72 
     73     def test_sign_nested_parts
     74       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
     75 
     76       body = RMail::Message.new
     77       body.header["Content-Disposition"] = +"inline"
     78       body.body = "ABCDEFG"
     79       payload = RMail::Message.new
     80       payload.header["MIME-Version"] = +"1.0"
     81       payload.add_part body
     82       payload.add_part RMail::Message.make_attachment "attachment", "text/plain", nil, "attachment.txt"
     83       signed = CryptoManager.sign @from_email, @to_email, payload
     84       ## The result is a multipart/signed containing a multipart/mixed.
     85       ## There should be a MIME-Version header on the top-level
     86       ## multipart/signed message, but *not* on the enclosed
     87       ## multipart/mixed part.
     88       assert_equal 1, signed.to_s.scan(/MIME-Version:/).size
     89     end
     90 
     91     def test_encrypt
     92       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
     93 
     94       encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
     95       assert_instance_of RMail::Message, encrypted
     96       assert (encrypted.body[1].body.include? "-----BEGIN PGP MESSAGE-----") , "Expecting PGP armored data"
     97     end
     98 
     99     def test_sign_and_encrypt
    100       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
    101 
    102       encrypted = CryptoManager.sign_and_encrypt @from_email, [@to_email], "ABCDEFG"
    103       assert_instance_of RMail::Message, encrypted
    104       assert (encrypted.body[1].body.include? "-----BEGIN PGP MESSAGE-----") , "Expecting PGP armored data"
    105     end
    106 
    107     def test_decrypt
    108       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
    109 
    110       encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
    111       assert_instance_of RMail::Message, encrypted
    112       assert_instance_of String, (encrypted.body[1].body)
    113       decrypted = CryptoManager.decrypt encrypted.body[1], true
    114       assert_instance_of Array, decrypted
    115       assert_instance_of Chunk::CryptoNotice, decrypted[0]
    116       assert_instance_of Chunk::CryptoNotice, decrypted[1]
    117       assert_instance_of RMail::Message, decrypted[2]
    118       assert_equal "ABCDEFG" , decrypted[2].body
    119     end
    120 
    121     def test_decrypt_and_verify
    122       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
    123 
    124       encrypted = CryptoManager.sign_and_encrypt @from_email, [@to_email], "ABCDEFG"
    125       assert_instance_of RMail::Message, encrypted
    126       assert_instance_of String, (encrypted.body[1].body)
    127       decrypted = CryptoManager.decrypt encrypted.body[1], true
    128       assert_instance_of Array, decrypted
    129       assert_instance_of Chunk::CryptoNotice, decrypted[0]
    130       assert_instance_of Chunk::CryptoNotice, decrypted[1]
    131       assert_instance_of RMail::Message, decrypted[2]
    132       assert_match(/^Signature made .* using RSA key ID 072B50BE/,
    133                    decrypted[1].lines[0])
    134       assert_equal "Good signature from \"#{@from_email}\"", decrypted[1].lines[1]
    135       assert_equal "ABCDEFG" , decrypted[2].body
    136     end
    137 
    138     def test_decrypt_and_verify_nondefault_key
    139       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
    140 
    141       encrypted = CryptoManager.sign_and_encrypt @from_email_ecc, [@to_email], "ABCDEFG"
    142       assert_instance_of RMail::Message, encrypted
    143       assert_instance_of String, (encrypted.body[1].body)
    144       decrypted = CryptoManager.decrypt encrypted.body[1], true
    145       assert_instance_of Array, decrypted
    146       assert_instance_of Chunk::CryptoNotice, decrypted[0]
    147       assert_instance_of Chunk::CryptoNotice, decrypted[1]
    148       assert_instance_of RMail::Message, decrypted[2]
    149       assert_match(/^Signature made .* key ID AC34B83C/, decrypted[1].lines[0])
    150       assert_equal "Good signature from \"#{@from_email_ecc}\"", decrypted[1].lines[1]
    151       assert_equal "ABCDEFG" , decrypted[2].body
    152     end
    153 
    154     def test_verify
    155       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
    156 
    157       signed = CryptoManager.sign @from_email, @to_email, "ABCDEFG"
    158       assert_instance_of RMail::Message, signed
    159       assert_instance_of String, (signed.body[1].body)
    160       chunk = CryptoManager.verify signed.body[0], signed.body[1], true
    161       assert_instance_of Redwood::Chunk::CryptoNotice, chunk
    162       assert_match(/^Signature made .* using RSA key ID 072B50BE/,
    163                    chunk.lines[0])
    164       assert_equal "Good signature from \"#{@from_email}\"", chunk.lines[1]
    165     end
    166 
    167     def test_verify_unknown_keytype
    168       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
    169 
    170       signed = CryptoManager.sign @from_email_ecc, @to_email, "ABCDEFG"
    171       assert_instance_of RMail::Message, signed
    172       assert_instance_of String, (signed.body[1].body)
    173       chunk = CryptoManager.verify signed.body[0], signed.body[1], true
    174       assert_instance_of Redwood::Chunk::CryptoNotice, chunk
    175       assert_match(/^Signature made .* using unknown key type \(303\) key ID AC34B83C/,
    176                    chunk.lines[0])
    177       assert_equal "Good signature from \"#{@from_email_ecc}\"", chunk.lines[1]
    178     end
    179 
    180     def test_verify_nested_parts
    181       skip CryptoManager.not_working_reason if not CryptoManager.have_crypto?
    182 
    183       ## Generate a multipart/signed containing a multipart/mixed.
    184       ## We will test verifying the generated signature below.
    185       ## Importantly, the inner multipart/mixed does *not* have a
    186       ## MIME-Version header because it is not a top-level message.
    187       payload = RMail::Parser.read <<EOS
    188 Content-Type: multipart/mixed; boundary="=-1652088224-7794-561531-1825-1-="
    189 
    190 
    191 --=-1652088224-7794-561531-1825-1-=
    192 Content-Disposition: inline
    193 
    194 ABCDEFG
    195 --=-1652088224-7794-561531-1825-1-=
    196 Content-Disposition: attachment; filename="attachment.txt"
    197 Content-Type: text/plain; name="attachment.txt"
    198 
    199 attachment
    200 --=-1652088224-7794-561531-1825-1-=--
    201 EOS
    202       signed = CryptoManager.sign @from_email_ecc, @to_email, payload
    203       CryptoManager.verify payload, signed.body[1], true
    204     end
    205 end
    206 
    207 end