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