~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_gpg.py

  • Committer: Martin Packman
  • Date: 2012-01-05 10:37:58 UTC
  • mto: This revision was merged to the branch mainline in revision 6427.
  • Revision ID: martin.packman@canonical.com-20120105103758-wzftnmsip5iv9n2g
Revert addition of get_message_encoding function

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
# import system imports here
21
21
import sys
22
22
 
23
 
from bzrlib import errors, ui
24
 
import bzrlib.gpg as gpg
25
 
from bzrlib.tests import TestCase
26
 
from bzrlib.tests import features
27
 
 
28
 
class FakeConfig(object):
29
 
 
30
 
    def gpg_signing_command(self):
31
 
        return "false"
32
 
 
33
 
    def acceptable_keys(self):
34
 
        return None
35
 
 
36
 
 
37
 
class TestCommandLine(TestCase):
 
23
from bzrlib import (
 
24
    config,
 
25
    errors,
 
26
    gpg,
 
27
    tests,
 
28
    trace,
 
29
    ui,
 
30
    )
 
31
from bzrlib.tests import (
 
32
    TestCase,
 
33
    features,
 
34
    )
 
35
 
 
36
 
 
37
class FakeConfig(config.Stack):
 
38
 
 
39
    def __init__(self, content=None):
 
40
        store = config.IniFileStore()
 
41
        if content is None:
 
42
            content = '''
 
43
gpg_signing_key=amy@example.com
 
44
gpg_signing_command=false'''
 
45
        store._load_from_string(content)
 
46
        super(FakeConfig, self).__init__([store.get_sections])
 
47
 
 
48
 
 
49
class TestCommandLine(tests.TestCase):
 
50
 
 
51
    def setUp(self):
 
52
        super(TestCommandLine, self).setUp()
 
53
        self.my_gpg = gpg.GPGStrategy(FakeConfig())
38
54
 
39
55
    def test_signing_command_line(self):
40
 
        my_gpg = gpg.GPGStrategy(FakeConfig())
41
 
        self.assertEqual(['false',  '--clearsign'],
 
56
        self.assertEqual(['false',  '--clearsign', '-u', 'amy@example.com'],
 
57
                         self.my_gpg._command_line())
 
58
 
 
59
    def test_signing_command_line_from_default(self):
 
60
        # Using 'default' for gpg_signing_key will use the mail part of 'email'
 
61
        my_gpg = gpg.GPGStrategy(FakeConfig('''
 
62
email=Amy <amy@example.com>
 
63
gpg_signing_key=default
 
64
gpg_signing_command=false'''))
 
65
        self.assertEqual(['false',  '--clearsign', '-u', 'amy@example.com'],
 
66
                         my_gpg._command_line())
 
67
 
 
68
    def test_signing_command_line_from_email(self):
 
69
        # Not setting gpg_signing_key will use the mail part of 'email'
 
70
        my_gpg = gpg.GPGStrategy(FakeConfig('''
 
71
email=Amy <amy@example.com>
 
72
gpg_signing_command=false'''))
 
73
        self.assertEqual(['false',  '--clearsign', '-u', 'amy@example.com'],
42
74
                         my_gpg._command_line())
43
75
 
44
76
    def test_checks_return_code(self):
45
77
        # This test needs a unix like platform - one with 'false' to run.
46
78
        # if you have one, please make this work :)
47
 
        my_gpg = gpg.GPGStrategy(FakeConfig())
48
 
        self.assertRaises(errors.SigningFailed, my_gpg.sign, 'content')
 
79
        self.assertRaises(errors.SigningFailed, self.my_gpg.sign, 'content')
49
80
 
50
81
    def assertProduces(self, content):
51
82
        # This needs a 'cat' command or similar to work.
52
 
        my_gpg = gpg.GPGStrategy(FakeConfig())
53
83
        if sys.platform == 'win32':
54
84
            # Windows doesn't come with cat, and we don't require it
55
85
            # so lets try using python instead.
56
86
            # But stupid windows and line-ending conversions.
57
87
            # It is too much work to make sys.stdout be in binary mode.
58
88
            # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443
59
 
            my_gpg._command_line = lambda:[sys.executable, '-c',
 
89
            self.my_gpg._command_line = lambda:[sys.executable, '-c',
60
90
                    'import sys; sys.stdout.write(sys.stdin.read())']
61
91
            new_content = content.replace('\n', '\r\n')
62
92
 
63
 
            self.assertEqual(new_content, my_gpg.sign(content))
 
93
            self.assertEqual(new_content, self.my_gpg.sign(content))
64
94
        else:
65
 
            my_gpg._command_line = lambda:['cat', '-']
66
 
            self.assertEqual(content, my_gpg.sign(content))
 
95
            self.my_gpg._command_line = lambda:['cat', '-']
 
96
            self.assertEqual(content, self.my_gpg.sign(content))
67
97
 
68
98
    def test_returns_output(self):
69
99
        content = "some content\nwith newlines\n"
88
118
        self.assertRaises(errors.BzrBadParameterUnicode,
89
119
                          self.assertProduces, u'foo')
90
120
 
 
121
class TestVerify(TestCase):
 
122
 
91
123
    def import_keys(self):
92
124
        from StringIO import StringIO
93
125
        import gpgme
184
216
-----END PGP PRIVATE KEY BLOCK-----
185
217
""")
186
218
 
 
219
        revoked_key = StringIO("""-----BEGIN PGP PUBLIC KEY BLOCK-----
 
220
Version: GnuPG v1.4.11 (GNU/Linux)
 
221
 
 
222
mI0ETjlW5gEEAOb/6P+TVM59E897wRtatxys2BhsHCXM4T7xjIiANfDwejDdifqh
 
223
tluTfSJLLxPembtrrEjux1C0AJgc+f0MIfsc3Pr3eFJzKB2ot/1IVG1/1KnA0zt3
 
224
W2xPT3lRib27WJ9Fag+dMtQaIzgJ7/n2DFxsFZ33FD2kxrEXB2exGg6FABEBAAGI
 
225
pgQgAQIAEAUCTjlXkAkdAHJldm9rZWQACgkQjs6dvEpb0cQPHAP/Wi9rbx0e+1Sf
 
226
ziGgyVdr3m3A6uvze5oXKVgFRbGRUYSH4/I8GW0W9x4TcRg9h+YaQ8NUdADr9kNE
 
227
tKAljLqYA5qdqSfYuaij1M++Xj+KUZ359R74sHuQqwnRy1XXQNfRs/QpXA7vLdds
 
228
rjg+pbWuXO92TZJUdnqtWW+VEyZBsPy0G3Rlc3Qga2V5IDx0ZXN0QGV4YW1wbGUu
 
229
Y29tPoi4BBMBAgAiBQJOOVbmAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
 
230
CRCOzp28SlvRxNWzA/42WVmI0b+6mF/imEOlY1TiyvrcpK250rkSDsCtL4lOwy7G
 
231
antZhpgNfnXRd/ySfsS3EB6dpOWgOSxGRvWQhA+vxBT9BYNk49qd3JIrSaSWpR12
 
232
rET8qO1rEQQFWsw03CxTGujxGlmEO+a1yguRXp2UWaY7FngcQmD+8q7BUIVm7riN
 
233
BE45VuYBBADTEH2jHTjNCc5CMOhea6EJTrkx3upcEqB2oyhWeSWJiBGOxlcddsjo
 
234
3J3/EmBB8kK1hM9TidD3SG64x1N287lg8ELJBlKv+pQVyxohGJ1u/THgpTDMMQcL
 
235
luG5rAHQGSfyzKTiOnaTyBYg3M/nzgUOU9dKEFB0EA3tjUXFOT+r3wARAQABiJ8E
 
236
GAECAAkFAk45VuYCGwwACgkQjs6dvEpb0cRSLQP/fzCWX2lXwlwWiVF8BOPF7o9z
 
237
icHErc7/X17RGb4qj1kVf+UkRdUWJrbEVh4h6MncBIuA70WsYogiw+Kz/0LCtQAR
 
238
YUJsPy/EL++OKPH1aFasOdTxwkTka85+RdYqhP1+z/aYLFMWq6mRFI+o6x2k5mGi
 
239
7dMv2kKTJPoXUpiXJbg=
 
240
=hLYO
 
241
-----END PGP PUBLIC KEY BLOCK-----
 
242
""")
 
243
 
 
244
        expired_key = StringIO("""-----BEGIN PGP PUBLIC KEY BLOCK-----
 
245
Version: GnuPG v1.4.11 (GNU/Linux)
 
246
 
 
247
mI0ETjZ6PAEEALkR4GcFQidCCxV7pgQwQd5MZua0YO2l92fVqHX+PhnZ6egCLKdD
 
248
2bWlMUd6MLPF3FlRL7BBAxvW/DazkBOp7ljsnpMpptEzY49Uem1irYLYiVb9zK96
 
249
0sQZzFxFkfEYetQEXC68mIck8tbySOX5NAOw++3jFm3J7dsU1R3XtYzRABEBAAG0
 
250
G3Rlc3Qga2V5IDx0ZXN0QGV4YW1wbGUuY29tPoi+BBMBAgAoBQJONno8AhsDBQkA
 
251
AVGABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRAc4m97T40VEz+DA/9PBphG
 
252
Yp9cHVaHSfTUKGTGgIbvRe60sFNpDCYZeAGDrygOMuI8MNzbVpwefRBFHVPx7jWd
 
253
rrYMsLkcsNUS9D0baU+0D/qp7JVg7ZSQtG0O6IG4eTZhibteY1fu0+unlXmg9NHx
 
254
5VvhwzBiJDYji00M2p/CZEMiYFUuy76CsxUpN7iNBE42ejwBBACkv2/mX7IPQg0C
 
255
A3KSrJsJv+sdvKm4b4xuI4OwagwTIVz4KlTqV4IBrVjSBfwyMXucXz0bTW85qjgA
 
256
+n67td8vyjYYZUEz1uY9lSquQQDnAN0txL3cLHZXWiWOkmzZVddQtlflK2a/J9o0
 
257
QkHPVUm+hc4l64dIzStrNl2S66fAvQARAQABiKUEGAECAA8FAk42ejwCGwwFCQAB
 
258
UYAACgkQHOJve0+NFROEYQP/epg+o8iBs31hkSERyZjrRR66LpywezWj30Rn/3mX
 
259
Fzi9HkF4xLemWOzdNt9C5PYrOep85PQg8haEjknxVjZFS0ikT1h3OWk/TF1ZrLVm
 
260
WzyX8DaHQEjKpLJJjXcAbTiZBNMk0QaVC9RvIeHpCf3n3DC49DdjsPJRMKOn8KDi
 
261
kRk=
 
262
=p0gt
 
263
-----END PGP PUBLIC KEY BLOCK-----
 
264
""")
187
265
        context.import_(key)
188
266
        context.import_(secret_key)
 
267
        context.import_(revoked_key)
 
268
        context.import_(expired_key)
189
269
 
190
 
    def test_verify_valid(self):
 
270
    def test_verify_untrusted_but_accepted(self):
 
271
        #untrusted by gpg but listed as acceptable_keys by user
191
272
        self.requireFeature(features.gpgme)
192
273
        self.import_keys()
193
 
            
 
274
 
194
275
        content = """-----BEGIN PGP SIGNED MESSAGE-----
195
276
Hash: SHA1
196
277
 
218
299
        self.assertEqual((gpg.SIGNATURE_VALID, None), my_gpg.verify(content,
219
300
                            plain))
220
301
 
 
302
    def test_verify_unacceptable_key(self):
 
303
        self.requireFeature(features.gpgme)
 
304
        self.import_keys()
 
305
 
 
306
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
307
Hash: SHA1
 
308
 
 
309
bazaar-ng testament short form 1
 
310
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
311
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
312
-----BEGIN PGP SIGNATURE-----
 
313
Version: GnuPG v1.4.11 (GNU/Linux)
 
314
 
 
315
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
 
316
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
 
317
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
 
318
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
 
319
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
 
320
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
 
321
=iwsn
 
322
-----END PGP SIGNATURE-----
 
323
"""
 
324
        plain = """bazaar-ng testament short form 1
 
325
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
326
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
327
"""
 
328
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
329
        my_gpg.set_acceptable_keys("foo@example.com")
 
330
        self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'E3080E45'),
 
331
                         my_gpg.verify(content, plain))
 
332
 
 
333
    def test_verify_valid_but_untrusted(self):
 
334
        self.requireFeature(features.gpgme)
 
335
        self.import_keys()
 
336
 
 
337
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
338
Hash: SHA1
 
339
 
 
340
bazaar-ng testament short form 1
 
341
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
342
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
343
-----BEGIN PGP SIGNATURE-----
 
344
Version: GnuPG v1.4.11 (GNU/Linux)
 
345
 
 
346
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
 
347
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
 
348
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
 
349
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
 
350
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
 
351
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
 
352
=iwsn
 
353
-----END PGP SIGNATURE-----
 
354
"""
 
355
        plain = """bazaar-ng testament short form 1
 
356
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
357
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
358
"""
 
359
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
360
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
 
361
                            plain))
 
362
 
221
363
    def test_verify_bad_testament(self):
222
364
        self.requireFeature(features.gpgme)
223
365
        self.import_keys()
224
 
            
 
366
 
225
367
        content = """-----BEGIN PGP SIGNED MESSAGE-----
226
368
Hash: SHA1
227
369
 
249
391
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
250
392
                            plain))
251
393
 
 
394
 
 
395
    def test_verify_revoked_signature(self):
 
396
        self.requireFeature(features.gpgme)
 
397
        self.import_keys()
 
398
 
 
399
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
400
Hash: SHA1
 
401
 
 
402
asdf
 
403
-----BEGIN PGP SIGNATURE-----
 
404
Version: GnuPG v1.4.11 (GNU/Linux)
 
405
 
 
406
iJwEAQECAAYFAk45V18ACgkQjs6dvEpb0cSIZQP/eOGTXGPlrNwvDkcX2d8O///I
 
407
ecB4sUIUEpv1XAk1MkNu58lsjjK72lRaLusEGqd7HwrFmpxVeVs0oWLg23PNPCFs
 
408
yJBID9ma+VxFVPtkEFnrc1R72sBJLfBcTxMkwVTC8eeznjdtn+cg+aLkxbPdrGnr
 
409
JFA6kUIJU2w9LU/b88Y=
 
410
=UuRX
 
411
-----END PGP SIGNATURE-----
 
412
"""
 
413
        plain = """asdf\n"""
 
414
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
415
        my_gpg.set_acceptable_keys("test@example.com")
 
416
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
 
417
                            plain))
 
418
 
252
419
    def test_verify_invalid(self):
253
420
        self.requireFeature(features.gpgme)
 
421
        self.import_keys()
254
422
        content = """-----BEGIN PGP SIGNED MESSAGE-----
255
423
Hash: SHA1
256
424
 
273
441
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None),
274
442
                            my_gpg.verify(content, plain))
275
443
 
 
444
    def test_verify_expired_but_valid(self):
 
445
        self.requireFeature(features.gpgme)
 
446
        self.import_keys()
 
447
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
448
Hash: SHA1
 
449
 
 
450
bazaar-ng testament short form 1
 
451
revision-id: test@example.com-20110801100657-f1dr1nompeex723z
 
452
sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb
 
453
-----BEGIN PGP SIGNATURE-----
 
454
Version: GnuPG v1.4.10 (GNU/Linux)
 
455
 
 
456
iJwEAQECAAYFAk42esUACgkQHOJve0+NFRPc5wP7BoZkzBU8JaHMLv/LmqLr0sUz
 
457
zuE51ofZZ19L7KVtQWsOi4jFy0fi4A5TFwO8u9SOfoREGvkw292Uty9subSouK5/
 
458
mFmDOYPQ+O83zWgYZsBmMJWYDZ+X9I6XXZSbPtV/7XyTjaxtl5uRnDVJjg+AzKvD
 
459
dTp8VatVVrwuvzOPDVc=
 
460
=uHen
 
461
-----END PGP SIGNATURE-----
 
462
"""
 
463
        plain = """bazaar-ng testament short form 1
 
464
revision-id: test@example.com-20110801100657-f1dr1nompeex723z
 
465
sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb
 
466
"""
 
467
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
468
        self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513'),
 
469
                            my_gpg.verify(content, plain))
 
470
 
 
471
    def test_verify_unknown_key(self):
 
472
        self.requireFeature(features.gpgme)
 
473
        self.import_keys()
 
474
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
475
Hash: SHA1
 
476
 
 
477
asdf
 
478
-----BEGIN PGP SIGNATURE-----
 
479
Version: GnuPG v1.4.11 (GNU/Linux)
 
480
 
 
481
iQEcBAEBAgAGBQJOORKwAAoJENf6AkFdUeVvJDYH/1Cz+AJn1Jvy5n64o+0fZ5Ow
 
482
Y7UQb4QQTIOV7jI7n4hv/yBzuHrtImFzYvQl/o2Ezzi8B8L5gZtQy+xCUF+Q8iWs
 
483
gytZ5JUtSze7hDZo1NUl4etjoRGYqRfrUcvE2LkVH2dFbDGyyQfVmoeSHa5akuuP
 
484
QZmyg2F983rACVIpGvsqTH6RcBdvE9vx68lugeKQA8ArDn39/74FBFipFzrXSPij
 
485
eKFpl+yZmIb3g6HkPIC8o4j/tMvc37xF1OG5sBu8FT0+FC+VgY7vAblneDftAbyP
 
486
sIODx4WcfJtjLG/qkRYqJ4gDHo0eMpTJSk2CWebajdm4b+JBrM1F9mgKuZFLruE=
 
487
=RNR5
 
488
-----END PGP SIGNATURE-----
 
489
"""
 
490
        plain = "asdf\n"
 
491
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
492
        self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F'),
 
493
                            my_gpg.verify(content, plain))
 
494
 
276
495
    def test_set_acceptable_keys(self):
277
496
        self.requireFeature(features.gpgme)
278
497
        self.import_keys()
284
503
    def test_set_acceptable_keys_unknown(self):
285
504
        self.requireFeature(features.gpgme)
286
505
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
506
        self.notes = []
 
507
        def note(*args):
 
508
            self.notes.append(args[0] % args[1:])
 
509
        self.overrideAttr(trace, 'note', note)
287
510
        my_gpg.set_acceptable_keys("unknown")
288
511
        self.assertEqual(my_gpg.acceptable_keys, [])
 
512
        self.assertEqual(self.notes,
 
513
            ['No GnuPG key results for pattern: unknown'])
289
514
 
290
515
 
291
516
class TestDisabled(TestCase):