Added '0install config' sub-command
[zeroinstall.git] / tests / testgpg.py
blob1b399d790cf851a1999986403adea5e4452ec3f2
1 #!/usr/bin/env python
2 from basetest import BaseTest
3 import sys, tempfile
4 import unittest
5 import warnings
7 sys.path.insert(0, '..')
8 from zeroinstall.injector import gpg, model, trust
10 err_sig = """-----BEGIN PGP MESSAGE-----
11 Version: GnuPG v1.4.0 (GNU/Linux)
13 owGbwMvMwCTYk9R5Infvsj7G01xJDE513j1OiSlcHfbMrCDOBJisINP6XQwLGjzn
14 tMxedXc3y75I7r1hQZFTb/ewMcx3yefZ8zb/vZd10I7LEYdDj4fnKsYAAA==
15 =kMeU
16 -----END PGP MESSAGE-----
17 """
19 bad_sig = """-----BEGIN PGP SIGNED MESSAGE-----
20 Hash: SHA1
22 Hell0
23 -----BEGIN PGP SIGNATURE-----
24 Version: GnuPG v1.4.0 (GNU/Linux)
26 iD8DBQFCfk3grgeCgFmlPMERAhl8AKC0aktrLzz646zTY0TRzdnxPdbLBgCeJWbk
27 GRVbJusevCKvtoSn7RAW2mg=
28 =xQJ5
29 -----END PGP SIGNATURE-----
30 """
32 good_sig = """-----BEGIN PGP SIGNED MESSAGE-----
33 Hash: SHA1
35 Hello
36 -----BEGIN PGP SIGNATURE-----
37 Version: GnuPG v1.4.0 (GNU/Linux)
39 iD8DBQFCfk3grgeCgFmlPMERAhl8AKC0aktrLzz646zTY0TRzdnxPdbLBgCeJWbk
40 GRVbJusevCKvtoSn7RAW2mg=
41 =xQJ5
42 -----END PGP SIGNATURE-----
43 """
45 bad_xml_main = """<?xml version='1.0'?>
46 <root/>"""
48 invalid_xmls_sigs = [
49 ('last line is not end-of-comment',
50 """<!-- Base64 Signature
51 """),
52 ('No signature block in XML',
53 """<!-- Base64 Sig
54 iD8DBQBDtpK9rgeCgFmlPMERAg0gAKCaJhXFnk
55 -->
56 """),
57 ('extra data on comment line',
58 """<!-- Base64 Signature data
59 iD8DBQBDtpK9rgeCgFmlPMERAg0gAKCaJhXFnk
60 -->
61 """),
62 ('last line is not end-of-comment',
63 """<!-- Base64 Signature
64 iD8DBQBDtpK9rgeCgFmlPMERAg0gAKCaJhXFnk
65 WZRBLT0an56WYaBODukSsf4=
66 --> More
67 """),
68 ('Invalid base 64 encoded signature:',
69 """<!-- Base64 Signature
70 iD8DBQBDtpK9rgeCgFmlPMERAg0gAKCaJhXFnk
71 WZRBLT0an56WYaBODukSsf4=
72 =zMc+
73 -->
74 """),
75 ('Invalid characters found',
76 """<!-- Base64 Signature
77 iD8DBQBDtpK9rge<CgFmlPMERAg0gAKCaJhXFnk
78 WZRBLT0an56WYaBODukSsf4=
79 -->
80 """)]
82 good_xml_sig = """<?xml version='1.0'?>
83 <root/>
84 <!-- Base64 Signature
85 iD8DBQBDuChIrgeCgFmlPMERAnGEAJ0ZS1PeyWonx6xS/mgpYTKNgSXa5QCeMSYPHhNcvxu3f84y
86 Uk7hxHFeQPo=
87 -->
88 """
90 bad_xml_sig = """<?xml version='1.0'?>
91 <ro0t/>
92 <!-- Base64 Signature
93 iD8DBQBDuChIrgeCgFmlPMERAnGEAJ0ZS1PeyWonx6xS/mgpYTKNgSXa5QCeMSYPHhNcvxu3f84y
94 Uk7hxHFeQPo=
95 -->
96 """
98 from data import thomas_key
100 THOMAS_FINGERPRINT = '92429807C9853C0744A68B9AAE07828059A53CC1'
102 class TestGPG(BaseTest):
103 def setUp(self):
104 BaseTest.setUp(self)
106 stream = tempfile.TemporaryFile()
107 stream.write(thomas_key)
108 stream.seek(0)
109 gpg.import_key(stream)
110 trust.trust_db.trust_key(THOMAS_FINGERPRINT)
111 warnings.filterwarnings("ignore", category = DeprecationWarning)
113 def testImportBad(self):
114 stream = tempfile.TemporaryFile()
115 stream.write("Bad key")
116 stream.seek(0)
117 try:
118 gpg.import_key(stream)
119 assert False
120 except model.SafeException:
121 pass # OK
123 def testErrSig(self):
124 stream = tempfile.TemporaryFile()
125 stream.write(err_sig)
126 stream.seek(0)
127 data, sigs = gpg.check_stream(stream)
128 self.assertEquals("Bad\n", data.read())
129 assert len(sigs) == 1
130 assert isinstance(sigs[0], gpg.ErrSig)
131 assert sigs[0].need_key() == "8C6289C86DBDA68E"
132 self.assertEquals("17", sigs[0].status[gpg.ErrSig.ALG])
133 assert sigs[0].is_trusted() is False
134 assert str(sigs[0]).startswith('ERROR')
136 def testBadSig(self):
137 self.assertEquals("Hell0\n", self.check_bad(bad_sig))
139 def testBadXMLSig(self):
140 self.assertEquals(bad_xml_sig, self.check_bad(bad_xml_sig))
142 def testInvalidXMLSig(self):
143 for error, sig in invalid_xmls_sigs:
144 try:
145 self.check_bad(bad_xml_main + '\n' + sig)
146 except model.SafeException, ex:
147 if error not in str(ex):
148 raise model.SafeException(str(ex) + '\nSig:\n' + sig)
150 def check_bad(self, sig):
151 stream = tempfile.TemporaryFile()
152 stream.write(sig)
153 stream.seek(0)
154 data, sigs = gpg.check_stream(stream)
155 assert len(sigs) == 1
156 assert isinstance(sigs[0], gpg.BadSig)
157 self.assertEquals("AE07828059A53CC1",
158 sigs[0].status[gpg.BadSig.KEYID])
159 assert sigs[0].is_trusted() is False
160 assert sigs[0].need_key() is None
161 assert str(sigs[0]).startswith('BAD')
162 return data.read()
164 def testGoodSig(self):
165 self.assertEquals("Hello\n", self.check_good(good_sig))
167 def testGoodXMLSig(self):
168 self.assertEquals(good_xml_sig, self.check_good(good_xml_sig))
170 def check_good(self, sig):
171 stream = tempfile.TemporaryFile()
172 stream.write(sig)
173 stream.seek(0)
174 data, sigs = gpg.check_stream(stream)
175 assert len(sigs) == 1
176 assert isinstance(sigs[0], gpg.ValidSig)
177 self.assertEquals("92429807C9853C0744A68B9AAE07828059A53CC1",
178 sigs[0].fingerprint)
179 assert sigs[0].is_trusted() is True
180 assert sigs[0].need_key() is None
181 assert str(sigs[0]).startswith('Valid')
182 for item in sigs[0].get_details():
183 if item[0] == 'uid' and len(item) > 9:
184 assert item[9] in ["Thomas Leonard <tal197@users.sourceforge.net>"], str(item)
185 break
186 else:
187 self.fail("Missing name")
188 return data.read()
190 def testNoSig(self):
191 stream = tempfile.TemporaryFile()
192 stream.write("Hello")
193 stream.seek(0)
194 try:
195 gpg.check_stream(stream)
196 assert False
197 except model.SafeException:
198 pass # OK
200 def testLoadKeys(self):
202 self.assertEquals({}, gpg.load_keys([]))
203 keys = gpg.load_keys([THOMAS_FINGERPRINT])
204 self.assertEquals(1, len(keys))
205 key = keys[THOMAS_FINGERPRINT]
206 self.assertEquals(THOMAS_FINGERPRINT, key.fingerprint)
207 self.assertEquals('Thomas Leonard <tal197@users.sourceforge.net>',
208 key.name)
210 if __name__ == '__main__':
211 unittest.main()