~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_gpg.py

(jelmer) Don't complain about directory already existing in 'mkdir -p'.
 (Martin Packman)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2007, 2009, 2011 Canonical Ltd
 
2
#   Authors: Robert Collins <robert.collins@canonical.com>
 
3
#
 
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.
 
8
#
 
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.
 
13
#
 
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
 
17
 
 
18
"""Tests for signing and verifying blobs of data via gpg."""
 
19
 
 
20
# import system imports here
 
21
import sys
 
22
 
 
23
from bzrlib import (
 
24
    errors,
 
25
    gpg,
 
26
    trace,
 
27
    ui,
 
28
    )
 
29
from bzrlib.tests import (
 
30
    TestCase,
 
31
    features,
 
32
    )
 
33
 
 
34
class FakeConfig(object):
 
35
 
 
36
    def gpg_signing_key(self):
 
37
        return "amy@example.com"
 
38
 
 
39
    def gpg_signing_command(self):
 
40
        return "false"
 
41
 
 
42
    def acceptable_keys(self):
 
43
        return None
 
44
 
 
45
 
 
46
class TestCommandLine(TestCase):
 
47
 
 
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())
 
52
 
 
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')
 
58
 
 
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')
 
71
 
 
72
            self.assertEqual(new_content, my_gpg.sign(content))
 
73
        else:
 
74
            my_gpg._command_line = lambda:['cat', '-']
 
75
            self.assertEqual(content, my_gpg.sign(content))
 
76
 
 
77
    def test_returns_output(self):
 
78
        content = "some content\nwith newlines\n"
 
79
        self.assertProduces(content)
 
80
 
 
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 = []
 
85
        def clear_term():
 
86
            old_clear_term()
 
87
            clear_term_called.append(True)
 
88
        ui.ui_factory.clear_term = clear_term
 
89
        try:
 
90
            self.assertProduces(content)
 
91
        finally:
 
92
            ui.ui_factory.clear_term = old_clear_term
 
93
        self.assertEqual([True], clear_term_called)
 
94
 
 
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')
 
99
 
 
100
class TestVerify(TestCase):
 
101
 
 
102
    def import_keys(self):
 
103
        from StringIO import StringIO
 
104
        import gpgme
 
105
        context = gpgme.Context()
 
106
 
 
107
        key = StringIO("""-----BEGIN PGP PUBLIC KEY BLOCK-----
 
108
Version: GnuPG v1.4.11 (GNU/Linux)
 
109
 
 
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=
 
135
=hUJn
 
136
-----END PGP PUBLIC KEY BLOCK-----
 
137
""")
 
138
 
 
139
        secret_key = StringIO("""-----BEGIN PGP PRIVATE KEY BLOCK-----
 
140
Version: GnuPG v1.4.11 (GNU/Linux)
 
141
 
 
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==
 
194
=LXn0
 
195
-----END PGP PRIVATE KEY BLOCK-----
 
196
""")
 
197
 
 
198
        revoked_key = StringIO("""-----BEGIN PGP PUBLIC KEY BLOCK-----
 
199
Version: GnuPG v1.4.11 (GNU/Linux)
 
200
 
 
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
 
218
7dMv2kKTJPoXUpiXJbg=
 
219
=hLYO
 
220
-----END PGP PUBLIC KEY BLOCK-----
 
221
""")
 
222
 
 
223
        expired_key = StringIO("""-----BEGIN PGP PUBLIC KEY BLOCK-----
 
224
Version: GnuPG v1.4.11 (GNU/Linux)
 
225
 
 
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
 
240
kRk=
 
241
=p0gt
 
242
-----END PGP PUBLIC KEY BLOCK-----
 
243
""")
 
244
        context.import_(key)
 
245
        context.import_(secret_key)
 
246
        context.import_(revoked_key)
 
247
        context.import_(expired_key)
 
248
 
 
249
    def test_verify_untrusted_but_accepted(self):
 
250
        #untrusted by gpg but listed as acceptable_keys by user
 
251
        self.requireFeature(features.gpgme)
 
252
        self.import_keys()
 
253
            
 
254
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
255
Hash: SHA1
 
256
 
 
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)
 
262
 
 
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=
 
269
=iwsn
 
270
-----END PGP SIGNATURE-----
 
271
"""
 
272
        plain = """bazaar-ng testament short form 1
 
273
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
274
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
275
"""
 
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,
 
279
                            plain))
 
280
 
 
281
    def test_verify_unacceptable_key(self):
 
282
        self.requireFeature(features.gpgme)
 
283
        self.import_keys()
 
284
            
 
285
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
286
Hash: SHA1
 
287
 
 
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)
 
293
 
 
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=
 
300
=iwsn
 
301
-----END PGP SIGNATURE-----
 
302
"""
 
303
        plain = """bazaar-ng testament short form 1
 
304
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
305
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
306
"""
 
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))
 
311
 
 
312
    def test_verify_valid_but_untrusted(self):
 
313
        self.requireFeature(features.gpgme)
 
314
        self.import_keys()
 
315
            
 
316
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
317
Hash: SHA1
 
318
 
 
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)
 
324
 
 
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=
 
331
=iwsn
 
332
-----END PGP SIGNATURE-----
 
333
"""
 
334
        plain = """bazaar-ng testament short form 1
 
335
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
336
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
337
"""
 
338
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
339
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
 
340
                            plain))
 
341
 
 
342
    def test_verify_bad_testament(self):
 
343
        self.requireFeature(features.gpgme)
 
344
        self.import_keys()
 
345
            
 
346
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
347
Hash: SHA1
 
348
 
 
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)
 
354
 
 
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=
 
361
=iwsn
 
362
-----END PGP SIGNATURE-----
 
363
"""
 
364
        plain = """bazaar-ng testament short form 1
 
365
revision-id: doctor@example.com-20110527185938-hluafawphszb8dl1
 
366
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
367
"""
 
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,
 
371
                            plain))
 
372
 
 
373
 
 
374
    def test_verify_revoked_signature(self):
 
375
        self.requireFeature(features.gpgme)
 
376
        self.import_keys()
 
377
            
 
378
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
379
Hash: SHA1
 
380
 
 
381
asdf
 
382
-----BEGIN PGP SIGNATURE-----
 
383
Version: GnuPG v1.4.11 (GNU/Linux)
 
384
 
 
385
iJwEAQECAAYFAk45V18ACgkQjs6dvEpb0cSIZQP/eOGTXGPlrNwvDkcX2d8O///I
 
386
ecB4sUIUEpv1XAk1MkNu58lsjjK72lRaLusEGqd7HwrFmpxVeVs0oWLg23PNPCFs
 
387
yJBID9ma+VxFVPtkEFnrc1R72sBJLfBcTxMkwVTC8eeznjdtn+cg+aLkxbPdrGnr
 
388
JFA6kUIJU2w9LU/b88Y=
 
389
=UuRX
 
390
-----END PGP SIGNATURE-----
 
391
"""
 
392
        plain = """asdf\n"""
 
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,
 
396
                            plain))
 
397
 
 
398
    def test_verify_invalid(self):
 
399
        self.requireFeature(features.gpgme)
 
400
        self.import_keys()
 
401
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
402
Hash: SHA1
 
403
 
 
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)
 
409
 
 
410
iEYEARECAAYFAk33gYsACgkQpQbm1N1NUIhiDACglOuQDlnSF4NxfHSkN/zrmFy8
 
411
nswAoNGXAVuR9ONasAKIGBNUE0b+lols
 
412
=SOuC
 
413
-----END PGP SIGNATURE-----
 
414
"""
 
415
        plain = """bazaar-ng testament short form 1
 
416
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
417
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
418
"""
 
419
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
420
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None),
 
421
                            my_gpg.verify(content, plain))
 
422
 
 
423
    def test_verify_expired_but_valid(self):
 
424
        self.requireFeature(features.gpgme)
 
425
        self.import_keys()
 
426
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
427
Hash: SHA1
 
428
 
 
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)
 
434
 
 
435
iJwEAQECAAYFAk42esUACgkQHOJve0+NFRPc5wP7BoZkzBU8JaHMLv/LmqLr0sUz
 
436
zuE51ofZZ19L7KVtQWsOi4jFy0fi4A5TFwO8u9SOfoREGvkw292Uty9subSouK5/
 
437
mFmDOYPQ+O83zWgYZsBmMJWYDZ+X9I6XXZSbPtV/7XyTjaxtl5uRnDVJjg+AzKvD
 
438
dTp8VatVVrwuvzOPDVc=
 
439
=uHen
 
440
-----END PGP SIGNATURE-----
 
441
"""
 
442
        plain = """bazaar-ng testament short form 1
 
443
revision-id: test@example.com-20110801100657-f1dr1nompeex723z
 
444
sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb
 
445
"""
 
446
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
447
        self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513'),
 
448
                            my_gpg.verify(content, plain))
 
449
 
 
450
    def test_verify_unknown_key(self):
 
451
        self.requireFeature(features.gpgme)
 
452
        self.import_keys()
 
453
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
454
Hash: SHA1
 
455
 
 
456
asdf
 
457
-----BEGIN PGP SIGNATURE-----
 
458
Version: GnuPG v1.4.11 (GNU/Linux)
 
459
 
 
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=
 
466
=RNR5
 
467
-----END PGP SIGNATURE-----
 
468
"""
 
469
        plain = "asdf\n"
 
470
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
471
        self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F'),
 
472
                            my_gpg.verify(content, plain))
 
473
 
 
474
    def test_set_acceptable_keys(self):
 
475
        self.requireFeature(features.gpgme)
 
476
        self.import_keys()
 
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'])
 
481
 
 
482
    def test_set_acceptable_keys_unknown(self):
 
483
        self.requireFeature(features.gpgme)
 
484
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
485
        self.notes = []
 
486
        def note(*args):
 
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'])
 
493
 
 
494
 
 
495
class TestDisabled(TestCase):
 
496
 
 
497
    def test_sign(self):
 
498
        self.assertRaises(errors.SigningFailed,
 
499
                          gpg.DisabledGPGStrategy(None).sign, 'content')
 
500
 
 
501
    def test_verify(self):
 
502
        self.assertRaises(errors.SignatureVerificationFailed,
 
503
                          gpg.DisabledGPGStrategy(None).verify, 'content',
 
504
                          'testament')