1
# Copyright (C) 2005, 2006, 2007, 2009, 2011 Canonical Ltd
2
# Authors: Robert Collins <robert.collins@canonical.com>
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
"""Tests for signing and verifying blobs of data via gpg."""
20
# import system imports here
29
from bzrlib.tests import (
34
class FakeConfig(object):
36
def gpg_signing_key(self):
37
return "amy@example.com"
39
def gpg_signing_command(self):
42
def acceptable_keys(self):
46
class TestCommandLine(TestCase):
48
def test_signing_command_line(self):
49
my_gpg = gpg.GPGStrategy(FakeConfig())
50
self.assertEqual(['false', '--clearsign', '-u', 'amy@example.com'],
51
my_gpg._command_line())
53
def test_checks_return_code(self):
54
# This test needs a unix like platform - one with 'false' to run.
55
# if you have one, please make this work :)
56
my_gpg = gpg.GPGStrategy(FakeConfig())
57
self.assertRaises(errors.SigningFailed, my_gpg.sign, 'content')
59
def assertProduces(self, content):
60
# This needs a 'cat' command or similar to work.
61
my_gpg = gpg.GPGStrategy(FakeConfig())
62
if sys.platform == 'win32':
63
# Windows doesn't come with cat, and we don't require it
64
# so lets try using python instead.
65
# But stupid windows and line-ending conversions.
66
# It is too much work to make sys.stdout be in binary mode.
67
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443
68
my_gpg._command_line = lambda:[sys.executable, '-c',
69
'import sys; sys.stdout.write(sys.stdin.read())']
70
new_content = content.replace('\n', '\r\n')
72
self.assertEqual(new_content, my_gpg.sign(content))
74
my_gpg._command_line = lambda:['cat', '-']
75
self.assertEqual(content, my_gpg.sign(content))
77
def test_returns_output(self):
78
content = "some content\nwith newlines\n"
79
self.assertProduces(content)
81
def test_clears_progress(self):
82
content = "some content\nwith newlines\n"
83
old_clear_term = ui.ui_factory.clear_term
84
clear_term_called = []
87
clear_term_called.append(True)
88
ui.ui_factory.clear_term = clear_term
90
self.assertProduces(content)
92
ui.ui_factory.clear_term = old_clear_term
93
self.assertEqual([True], clear_term_called)
95
def test_aborts_on_unicode(self):
96
"""You can't sign Unicode text; it must be encoded first."""
97
self.assertRaises(errors.BzrBadParameterUnicode,
98
self.assertProduces, u'foo')
100
class TestVerify(TestCase):
102
def import_keys(self):
103
from StringIO import StringIO
105
context = gpgme.Context()
107
key = StringIO("""-----BEGIN PGP PUBLIC KEY BLOCK-----
108
Version: GnuPG v1.4.11 (GNU/Linux)
110
mQENBE343IgBCADwzPW7kmKb2bjB+UU+1ER/ABMZspvtoZMPusUw7bk6coXHF/0W
111
u1K/hSYeX9xaGOfOQw41r/g13MoR9dsL6L84RLiisf38rRoBZt+d5bCbZA5Xo801
112
2PeoBoGo6u5oOYKAFLMvrUitPiiE0IT/oQTfC4YUrLN4A+9W0QZruPGIpIXwmZXr
113
L0zsqYfNqIN0ompeJenVpKpvm3loJ/zfK7R3EJ3hsv6nkUmWCFsP1Pw3UV1YuCmw
114
Mkdn1U7DaOql1WjXgj9ABQDJrun2TGsqrSRzBODtHKA/uOX0K3VfKBU8VZo3dXUm
115
1Q4ZeZC39L9qJGTH8TQYlwBLe1yAOp+vx7QJABEBAAG0JEJhemFhciBUZXN0IEtl
116
eSA8YmF6YWFyQGV4YW1wbGUuY29tPokBOAQTAQIAIgUCTfjciAIbAwYLCQgHAwIG
117
FQgCCQoLBBYCAwECHgECF4AACgkQh2gbHuMIDkWJUggAwj537fH6WW+GGLA5onys
118
2hZmXUq/tU+L92bjQoRY4fmsQpk/FUVPUf+NQ0v1gkxx4BTfyYewaj5G6L8cvqW2
119
jj7UiJd8z9gTRxWTnYwfR/w5PGmxfJsBfEUKWsccrPQdOXAhwu0fjYIVk4nqgswa
120
IOAZIwe5Vsfs36uSS7p8RQHAZXLXtTOn3KcXHaxu83w6nc4zkWRovGJ9isBN3haO
121
2qEa0mYiAfDpz40CGtb8N/TQHF3Xcw8rJcxpg6RF3jMtWQnzbVJFp13it00R3LqW
122
o/r3RII3Ii3z2yARlg6D+5hVOrFBV8jFLkff1R2ZnVu+7WOrnbpmt3OiMkSeZrtB
123
OrkBDQRN+NyIAQgArRZ2YGzUj5dXOVIWgZ1/QFpyfx/cG/293WjRE4Wt2e4SxMf2
124
V0dcVCqWwT0+a79Wbausv4bStD4SkwDmu0Jf3z5ERzrr7oZwP0PMsIlM5zT6XSsr
125
6UUneB3UXX7MrEqVogVhRM0ORIaK/oRwMXr7K6xVT+bCBP3/p66kHtY1ZpfEzTEX
126
imBsN3GqoewBHYIneJKBtHE7uzdzw3O5p5dXqoj5foxGi9R1J15vAmt5pI68HJeX
127
P6ktvXbX2Iu7VDNoCvRXM9+ntyJtsXCjNXg4pTGHS/XO4nm2db4FUZOBcVMb1vCc
128
VtFjLTcbCqJqpoJWUtsLcNqDqMHOQDpe6KTNTQARAQABiQEfBBgBAgAJBQJN+NyI
129
AhsMAAoJEIdoGx7jCA5FrR8IANnOF3PUj1TbRcwV6RoWmHsFQHrPmM8ogXia1Lsv
130
jE1iEWoC+muvKh6Oydf90k6ZslS7rdDnp2qzYY8W/TiDkxP+fvsZ4mMi1Y0F+3ty
131
1jzWhcsnB2VrJSiavxEXk0tKPrNv4EUGWG6wHsC9TBj37If+nrMyim94VHvI0eHm
132
X8yMlN4O3HfmgD9CbJdUxueP3e31OIYuwh/6F7GII8TNEVHU/8vh/mQcCxppNbc+
133
boff+kIsoa/TAMLwtJoSrX1nXm0K3vZePRLnIgmwVzdkOIkaRJUG2tSQFvkfhvtE
134
LhnkL5l4MO0wrUds0UWRwa3d7j/P2ExrqXdlLmEzrifWyEQ=
136
-----END PGP PUBLIC KEY BLOCK-----
139
secret_key = StringIO("""-----BEGIN PGP PRIVATE KEY BLOCK-----
140
Version: GnuPG v1.4.11 (GNU/Linux)
142
lQOYBE343IgBCADwzPW7kmKb2bjB+UU+1ER/ABMZspvtoZMPusUw7bk6coXHF/0W
143
u1K/hSYeX9xaGOfOQw41r/g13MoR9dsL6L84RLiisf38rRoBZt+d5bCbZA5Xo801
144
2PeoBoGo6u5oOYKAFLMvrUitPiiE0IT/oQTfC4YUrLN4A+9W0QZruPGIpIXwmZXr
145
L0zsqYfNqIN0ompeJenVpKpvm3loJ/zfK7R3EJ3hsv6nkUmWCFsP1Pw3UV1YuCmw
146
Mkdn1U7DaOql1WjXgj9ABQDJrun2TGsqrSRzBODtHKA/uOX0K3VfKBU8VZo3dXUm
147
1Q4ZeZC39L9qJGTH8TQYlwBLe1yAOp+vx7QJABEBAAEAB/0RJTbV991SOtVfPQVu
148
LM+tD0SiOXJwIBIINlngsFHWVIiBSDb6uF8dneMR70IRnuEFHFyAUXA7PZDxvcSu
149
phAqIdKCWxQPkAULAS0o4U2K3ZFGh4uOqvfZ8eSnh1rETFv7Yf3u23K89cZiy99n
150
EtWgSqzC/2z5PaZ7/alsYCBqhHuyd4Phaud7qv7FTz8mFrCf+CCY+D08wbnZBu4g
151
N9tBwoxT/UKRfv3nghIh9v+3qWfBEFGhrYbt92XKFbHOQeATZz8AGIv1eqN/+ZQY
152
oYmvVfO3GkrWaRoPeJNLqSDEn/45O1Uh9MJ4mQclXqB0QzMShle8uusHxIeJSQsR
153
z//VBAD11WS7qSgCeiHR+4jDzrrlb2snnA2bfDToEomDxd/n8xm7nJWdkNfJ2BCw
154
KvnxYVxjFNAwkKJGRajzALBLzRVO+K9NtSLiddv5zv+UNdgsKuE8tD7Jqxd/IbWw
155
AimCtL8osnJ+r9dvL+NyjkAT6l/NdEbLXGrBaMeTfSgl2cBOOwQA+sJIh1R5PiCK
156
nLIs9pm3PSy3w92Peelq/x/+0aebTZaJUk2ou3oCvB3druDqrUeaopuuCc0drV7C
157
Ldoey8x/T2ZGzmT2af9qNaD6ScTimDodXcJdwlpobhZTKpsE4EyywpLXtlWte1x0
158
1Mq3llQsIdRdf3GLS+L207hWgKDiDosD/0SyOBO/IBDteeEzeN2hNE3A8oeVbvRS
159
XrS/3uj6oKmlWUBORYP8ptUrXPoVPmNz2y4GO+OysFtfct3Yqb+Sb/52SXMOHTox
160
2oLW08tkzfkDArU5aauMEPmyutGyJ+hGo7fsuLXzXR8OPw4yZJdzG1tRlP2TTKmq
161
Fx8G/Ik6bN4zTYK0JEJhemFhciBUZXN0IEtleSA8YmF6YWFyQGV4YW1wbGUuY29t
162
PokBOAQTAQIAIgUCTfjciAIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQ
163
h2gbHuMIDkWJUggAwj537fH6WW+GGLA5onys2hZmXUq/tU+L92bjQoRY4fmsQpk/
164
FUVPUf+NQ0v1gkxx4BTfyYewaj5G6L8cvqW2jj7UiJd8z9gTRxWTnYwfR/w5PGmx
165
fJsBfEUKWsccrPQdOXAhwu0fjYIVk4nqgswaIOAZIwe5Vsfs36uSS7p8RQHAZXLX
166
tTOn3KcXHaxu83w6nc4zkWRovGJ9isBN3haO2qEa0mYiAfDpz40CGtb8N/TQHF3X
167
cw8rJcxpg6RF3jMtWQnzbVJFp13it00R3LqWo/r3RII3Ii3z2yARlg6D+5hVOrFB
168
V8jFLkff1R2ZnVu+7WOrnbpmt3OiMkSeZrtBOp0DlwRN+NyIAQgArRZ2YGzUj5dX
169
OVIWgZ1/QFpyfx/cG/293WjRE4Wt2e4SxMf2V0dcVCqWwT0+a79Wbausv4bStD4S
170
kwDmu0Jf3z5ERzrr7oZwP0PMsIlM5zT6XSsr6UUneB3UXX7MrEqVogVhRM0ORIaK
171
/oRwMXr7K6xVT+bCBP3/p66kHtY1ZpfEzTEXimBsN3GqoewBHYIneJKBtHE7uzdz
172
w3O5p5dXqoj5foxGi9R1J15vAmt5pI68HJeXP6ktvXbX2Iu7VDNoCvRXM9+ntyJt
173
sXCjNXg4pTGHS/XO4nm2db4FUZOBcVMb1vCcVtFjLTcbCqJqpoJWUtsLcNqDqMHO
174
QDpe6KTNTQARAQABAAf1EfceUlGLvoA/+yDTNTMjuPfzfKwbB/FOVfX44g3Za1eT
175
v7RvSuj4rFYIdE9UvZEei/pqPOSc+hhSsKZCulGXD5TUpf3AyG7ipWU/kID46Csp
176
0V08DPpFHnuw/N6+qNo5iSnhN9U1XMLjYT5d1HvKur26r2vWbmUTSJ1qIluHL2fT
177
R1pKYYLuoff4MIjZ01Hawq72jjor+dLBmMWveHpq4XNp+vQ4x8aFnY9ozufon0nM
178
uRSJRlQjDNB274tvUbmDFP+nzNbqF1nBTZ6FTdH/iKVNbytiYF7Hbat8GWVZqY1u
179
CZr7BklpIVWlk62ll0psMIPVyANi7YT332LLqYmBBADJKTx2dariG/kWU2W/9VEO
180
2VZpqsqazAxOoFEIOpcOlByhhyw5g0IKu0UyzHkhoCje0cWxpdSBFG432b8zL0AT
181
Z0RycfUG7Sgp9CpY1h8Cc/HbBa8xo1fSM7zplPQrHBqUzlVVBq6HOkUq+7qsPFWc
182
RRie95VsDmIMKQKPJHeYHQQA3EYGit+QHV0dccAInghEsf/mq8Gfnvo6HPYhWcDC
183
DTM39NhNlnl1WkTFCd2TWc+TWQ4KlRsh6bMjUpNa2qjrUl90fLekbogcxxMhcwa6
184
xgzEANZfwqdY0u3aB/CyZ6odfThwcAoeqoMpw34CfeKEroubpi2n8wKByrN2MQXJ
185
4vEEAJbXZOqgAcFAFBUVb5mVT0s2lJMagZFPdhRJz2bttz01s/B8aca6CrDpFRjT
186
03zRFUZjwDYqZDWBC181dCE9yla4OkWd5QyRKSS2EE02KEYqRzT0RngQn7s4AW2r
187
326up3Jhleln3hgD4Kk3V3KHmyK8zqZA0qWzry4Vl2jjkbnAPB2JAR8EGAECAAkF
188
Ak343IgCGwwACgkQh2gbHuMIDkWtHwgA2c4Xc9SPVNtFzBXpGhaYewVAes+YzyiB
189
eJrUuy+MTWIRagL6a68qHo7J1/3STpmyVLut0OenarNhjxb9OIOTE/5++xniYyLV
190
jQX7e3LWPNaFyycHZWslKJq/EReTS0o+s2/gRQZYbrAewL1MGPfsh/6eszKKb3hU
191
e8jR4eZfzIyU3g7cd+aAP0Jsl1TG54/d7fU4hi7CH/oXsYgjxM0RUdT/y+H+ZBwL
192
Gmk1tz5uh9/6Qiyhr9MAwvC0mhKtfWdebQre9l49EuciCbBXN2Q4iRpElQba1JAW
193
+R+G+0QuGeQvmXgw7TCtR2zRRZHBrd3uP8/YTGupd2UuYTOuJ9bIRA==
195
-----END PGP PRIVATE KEY BLOCK-----
198
revoked_key = StringIO("""-----BEGIN PGP PUBLIC KEY BLOCK-----
199
Version: GnuPG v1.4.11 (GNU/Linux)
201
mI0ETjlW5gEEAOb/6P+TVM59E897wRtatxys2BhsHCXM4T7xjIiANfDwejDdifqh
202
tluTfSJLLxPembtrrEjux1C0AJgc+f0MIfsc3Pr3eFJzKB2ot/1IVG1/1KnA0zt3
203
W2xPT3lRib27WJ9Fag+dMtQaIzgJ7/n2DFxsFZ33FD2kxrEXB2exGg6FABEBAAGI
204
pgQgAQIAEAUCTjlXkAkdAHJldm9rZWQACgkQjs6dvEpb0cQPHAP/Wi9rbx0e+1Sf
205
ziGgyVdr3m3A6uvze5oXKVgFRbGRUYSH4/I8GW0W9x4TcRg9h+YaQ8NUdADr9kNE
206
tKAljLqYA5qdqSfYuaij1M++Xj+KUZ359R74sHuQqwnRy1XXQNfRs/QpXA7vLdds
207
rjg+pbWuXO92TZJUdnqtWW+VEyZBsPy0G3Rlc3Qga2V5IDx0ZXN0QGV4YW1wbGUu
208
Y29tPoi4BBMBAgAiBQJOOVbmAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
209
CRCOzp28SlvRxNWzA/42WVmI0b+6mF/imEOlY1TiyvrcpK250rkSDsCtL4lOwy7G
210
antZhpgNfnXRd/ySfsS3EB6dpOWgOSxGRvWQhA+vxBT9BYNk49qd3JIrSaSWpR12
211
rET8qO1rEQQFWsw03CxTGujxGlmEO+a1yguRXp2UWaY7FngcQmD+8q7BUIVm7riN
212
BE45VuYBBADTEH2jHTjNCc5CMOhea6EJTrkx3upcEqB2oyhWeSWJiBGOxlcddsjo
213
3J3/EmBB8kK1hM9TidD3SG64x1N287lg8ELJBlKv+pQVyxohGJ1u/THgpTDMMQcL
214
luG5rAHQGSfyzKTiOnaTyBYg3M/nzgUOU9dKEFB0EA3tjUXFOT+r3wARAQABiJ8E
215
GAECAAkFAk45VuYCGwwACgkQjs6dvEpb0cRSLQP/fzCWX2lXwlwWiVF8BOPF7o9z
216
icHErc7/X17RGb4qj1kVf+UkRdUWJrbEVh4h6MncBIuA70WsYogiw+Kz/0LCtQAR
217
YUJsPy/EL++OKPH1aFasOdTxwkTka85+RdYqhP1+z/aYLFMWq6mRFI+o6x2k5mGi
220
-----END PGP PUBLIC KEY BLOCK-----
223
expired_key = StringIO("""-----BEGIN PGP PUBLIC KEY BLOCK-----
224
Version: GnuPG v1.4.11 (GNU/Linux)
226
mI0ETjZ6PAEEALkR4GcFQidCCxV7pgQwQd5MZua0YO2l92fVqHX+PhnZ6egCLKdD
227
2bWlMUd6MLPF3FlRL7BBAxvW/DazkBOp7ljsnpMpptEzY49Uem1irYLYiVb9zK96
228
0sQZzFxFkfEYetQEXC68mIck8tbySOX5NAOw++3jFm3J7dsU1R3XtYzRABEBAAG0
229
G3Rlc3Qga2V5IDx0ZXN0QGV4YW1wbGUuY29tPoi+BBMBAgAoBQJONno8AhsDBQkA
230
AVGABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRAc4m97T40VEz+DA/9PBphG
231
Yp9cHVaHSfTUKGTGgIbvRe60sFNpDCYZeAGDrygOMuI8MNzbVpwefRBFHVPx7jWd
232
rrYMsLkcsNUS9D0baU+0D/qp7JVg7ZSQtG0O6IG4eTZhibteY1fu0+unlXmg9NHx
233
5VvhwzBiJDYji00M2p/CZEMiYFUuy76CsxUpN7iNBE42ejwBBACkv2/mX7IPQg0C
234
A3KSrJsJv+sdvKm4b4xuI4OwagwTIVz4KlTqV4IBrVjSBfwyMXucXz0bTW85qjgA
235
+n67td8vyjYYZUEz1uY9lSquQQDnAN0txL3cLHZXWiWOkmzZVddQtlflK2a/J9o0
236
QkHPVUm+hc4l64dIzStrNl2S66fAvQARAQABiKUEGAECAA8FAk42ejwCGwwFCQAB
237
UYAACgkQHOJve0+NFROEYQP/epg+o8iBs31hkSERyZjrRR66LpywezWj30Rn/3mX
238
Fzi9HkF4xLemWOzdNt9C5PYrOep85PQg8haEjknxVjZFS0ikT1h3OWk/TF1ZrLVm
239
WzyX8DaHQEjKpLJJjXcAbTiZBNMk0QaVC9RvIeHpCf3n3DC49DdjsPJRMKOn8KDi
242
-----END PGP PUBLIC KEY BLOCK-----
245
context.import_(secret_key)
246
context.import_(revoked_key)
247
context.import_(expired_key)
249
def test_verify_untrusted_but_accepted(self):
250
#untrusted by gpg but listed as acceptable_keys by user
251
self.requireFeature(features.gpgme)
254
content = """-----BEGIN PGP SIGNED MESSAGE-----
257
bazaar-ng testament short form 1
258
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
259
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
260
-----BEGIN PGP SIGNATURE-----
261
Version: GnuPG v1.4.11 (GNU/Linux)
263
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
264
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
265
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
266
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
267
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
268
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
270
-----END PGP SIGNATURE-----
272
plain = """bazaar-ng testament short form 1
273
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
274
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
276
my_gpg = gpg.GPGStrategy(FakeConfig())
277
my_gpg.set_acceptable_keys("bazaar@example.com")
278
self.assertEqual((gpg.SIGNATURE_VALID, None), my_gpg.verify(content,
281
def test_verify_unacceptable_key(self):
282
self.requireFeature(features.gpgme)
285
content = """-----BEGIN PGP SIGNED MESSAGE-----
288
bazaar-ng testament short form 1
289
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
290
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
291
-----BEGIN PGP SIGNATURE-----
292
Version: GnuPG v1.4.11 (GNU/Linux)
294
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
295
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
296
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
297
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
298
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
299
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
301
-----END PGP SIGNATURE-----
303
plain = """bazaar-ng testament short form 1
304
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
305
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
307
my_gpg = gpg.GPGStrategy(FakeConfig())
308
my_gpg.set_acceptable_keys("foo@example.com")
309
self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'E3080E45'),
310
my_gpg.verify(content, plain))
312
def test_verify_valid_but_untrusted(self):
313
self.requireFeature(features.gpgme)
316
content = """-----BEGIN PGP SIGNED MESSAGE-----
319
bazaar-ng testament short form 1
320
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
321
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
322
-----BEGIN PGP SIGNATURE-----
323
Version: GnuPG v1.4.11 (GNU/Linux)
325
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
326
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
327
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
328
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
329
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
330
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
332
-----END PGP SIGNATURE-----
334
plain = """bazaar-ng testament short form 1
335
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
336
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
338
my_gpg = gpg.GPGStrategy(FakeConfig())
339
self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
342
def test_verify_bad_testament(self):
343
self.requireFeature(features.gpgme)
346
content = """-----BEGIN PGP SIGNED MESSAGE-----
349
bazaar-ng testament short form 1
350
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
351
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
352
-----BEGIN PGP SIGNATURE-----
353
Version: GnuPG v1.4.11 (GNU/Linux)
355
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
356
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
357
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
358
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
359
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
360
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
362
-----END PGP SIGNATURE-----
364
plain = """bazaar-ng testament short form 1
365
revision-id: doctor@example.com-20110527185938-hluafawphszb8dl1
366
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
368
my_gpg = gpg.GPGStrategy(FakeConfig())
369
my_gpg.set_acceptable_keys("bazaar@example.com")
370
self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
374
def test_verify_revoked_signature(self):
375
self.requireFeature(features.gpgme)
378
content = """-----BEGIN PGP SIGNED MESSAGE-----
382
-----BEGIN PGP SIGNATURE-----
383
Version: GnuPG v1.4.11 (GNU/Linux)
385
iJwEAQECAAYFAk45V18ACgkQjs6dvEpb0cSIZQP/eOGTXGPlrNwvDkcX2d8O///I
386
ecB4sUIUEpv1XAk1MkNu58lsjjK72lRaLusEGqd7HwrFmpxVeVs0oWLg23PNPCFs
387
yJBID9ma+VxFVPtkEFnrc1R72sBJLfBcTxMkwVTC8eeznjdtn+cg+aLkxbPdrGnr
390
-----END PGP SIGNATURE-----
393
my_gpg = gpg.GPGStrategy(FakeConfig())
394
my_gpg.set_acceptable_keys("test@example.com")
395
self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
398
def test_verify_invalid(self):
399
self.requireFeature(features.gpgme)
401
content = """-----BEGIN PGP SIGNED MESSAGE-----
404
bazaar-ng testament short form 1
405
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
406
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
407
-----BEGIN PGP SIGNATURE-----
408
Version: GnuPG v1.4.11 (GNU/Linux)
410
iEYEARECAAYFAk33gYsACgkQpQbm1N1NUIhiDACglOuQDlnSF4NxfHSkN/zrmFy8
411
nswAoNGXAVuR9ONasAKIGBNUE0b+lols
413
-----END PGP SIGNATURE-----
415
plain = """bazaar-ng testament short form 1
416
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
417
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
419
my_gpg = gpg.GPGStrategy(FakeConfig())
420
self.assertEqual((gpg.SIGNATURE_NOT_VALID, None),
421
my_gpg.verify(content, plain))
423
def test_verify_expired_but_valid(self):
424
self.requireFeature(features.gpgme)
426
content = """-----BEGIN PGP SIGNED MESSAGE-----
429
bazaar-ng testament short form 1
430
revision-id: test@example.com-20110801100657-f1dr1nompeex723z
431
sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb
432
-----BEGIN PGP SIGNATURE-----
433
Version: GnuPG v1.4.10 (GNU/Linux)
435
iJwEAQECAAYFAk42esUACgkQHOJve0+NFRPc5wP7BoZkzBU8JaHMLv/LmqLr0sUz
436
zuE51ofZZ19L7KVtQWsOi4jFy0fi4A5TFwO8u9SOfoREGvkw292Uty9subSouK5/
437
mFmDOYPQ+O83zWgYZsBmMJWYDZ+X9I6XXZSbPtV/7XyTjaxtl5uRnDVJjg+AzKvD
440
-----END PGP SIGNATURE-----
442
plain = """bazaar-ng testament short form 1
443
revision-id: test@example.com-20110801100657-f1dr1nompeex723z
444
sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb
446
my_gpg = gpg.GPGStrategy(FakeConfig())
447
self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513'),
448
my_gpg.verify(content, plain))
450
def test_verify_unknown_key(self):
451
self.requireFeature(features.gpgme)
453
content = """-----BEGIN PGP SIGNED MESSAGE-----
457
-----BEGIN PGP SIGNATURE-----
458
Version: GnuPG v1.4.11 (GNU/Linux)
460
iQEcBAEBAgAGBQJOORKwAAoJENf6AkFdUeVvJDYH/1Cz+AJn1Jvy5n64o+0fZ5Ow
461
Y7UQb4QQTIOV7jI7n4hv/yBzuHrtImFzYvQl/o2Ezzi8B8L5gZtQy+xCUF+Q8iWs
462
gytZ5JUtSze7hDZo1NUl4etjoRGYqRfrUcvE2LkVH2dFbDGyyQfVmoeSHa5akuuP
463
QZmyg2F983rACVIpGvsqTH6RcBdvE9vx68lugeKQA8ArDn39/74FBFipFzrXSPij
464
eKFpl+yZmIb3g6HkPIC8o4j/tMvc37xF1OG5sBu8FT0+FC+VgY7vAblneDftAbyP
465
sIODx4WcfJtjLG/qkRYqJ4gDHo0eMpTJSk2CWebajdm4b+JBrM1F9mgKuZFLruE=
467
-----END PGP SIGNATURE-----
470
my_gpg = gpg.GPGStrategy(FakeConfig())
471
self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F'),
472
my_gpg.verify(content, plain))
474
def test_set_acceptable_keys(self):
475
self.requireFeature(features.gpgme)
477
my_gpg = gpg.GPGStrategy(FakeConfig())
478
my_gpg.set_acceptable_keys("bazaar@example.com")
479
self.assertEqual(my_gpg.acceptable_keys,
480
[u'B5DEED5FCB15DAE6ECEF919587681B1EE3080E45'])
482
def test_set_acceptable_keys_unknown(self):
483
self.requireFeature(features.gpgme)
484
my_gpg = gpg.GPGStrategy(FakeConfig())
487
self.notes.append(args[0] % args[1:])
488
self.overrideAttr(trace, 'note', note)
489
my_gpg.set_acceptable_keys("unknown")
490
self.assertEqual(my_gpg.acceptable_keys, [])
491
self.assertEqual(self.notes,
492
['No GnuPG key results for pattern: unknown'])
495
class TestDisabled(TestCase):
498
self.assertRaises(errors.SigningFailed,
499
gpg.DisabledGPGStrategy(None).sign, 'content')
501
def test_verify(self):
502
self.assertRaises(errors.SignatureVerificationFailed,
503
gpg.DisabledGPGStrategy(None).verify, 'content',