/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_gpg.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-08 23:30:31 UTC
  • mto: This revision was merged to the branch mainline in revision 6690.
  • Revision ID: jelmer@jelmer.uk-20170608233031-3qavls2o7a1pqllj
Update imports.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
"""Tests for signing and verifying blobs of data via gpg."""
19
19
 
20
 
from io import BytesIO
21
 
 
22
20
# import system imports here
23
21
import sys
24
22
 
30
28
    trace,
31
29
    ui,
32
30
    )
 
31
from ..sixish import (
 
32
    BytesIO,
 
33
    )
33
34
from . import (
34
35
    TestCase,
35
36
    features,
40
41
 
41
42
    def __init__(self, content=None):
42
43
        if content is None:
43
 
            content = b'''
 
44
            content = '''
44
45
gpg_signing_key=amy@example.com
45
 
'''
 
46
gpg_signing_command=false'''
46
47
        super(FakeConfig, self).__init__(content)
47
48
 
48
49
 
 
50
class TestCommandLine(tests.TestCase):
 
51
 
 
52
    def setUp(self):
 
53
        super(TestCommandLine, self).setUp()
 
54
        self.my_gpg = gpg.GPGStrategy(FakeConfig())
 
55
 
 
56
    def test_signing_command_line(self):
 
57
        self.assertEqual(['false',  '--clearsign', '-u', 'amy@example.com'],
 
58
                         self.my_gpg._command_line())
 
59
 
 
60
    def test_signing_command_line_from_default(self):
 
61
        # Using 'default' for gpg_signing_key will use the mail part of 'email'
 
62
        my_gpg = gpg.GPGStrategy(FakeConfig('''
 
63
email=Amy <amy@example.com>
 
64
gpg_signing_key=default
 
65
gpg_signing_command=false'''))
 
66
        self.assertEqual(['false',  '--clearsign', '-u', 'amy@example.com'],
 
67
                         my_gpg._command_line())
 
68
 
 
69
    def test_signing_command_line_from_email(self):
 
70
        # Not setting gpg_signing_key will use the mail part of 'email'
 
71
        my_gpg = gpg.GPGStrategy(FakeConfig('''
 
72
email=Amy <amy@example.com>
 
73
gpg_signing_command=false'''))
 
74
        self.assertEqual(['false',  '--clearsign', '-u', 'amy@example.com'],
 
75
                         my_gpg._command_line())
 
76
 
 
77
    def test_checks_return_code(self):
 
78
        # This test needs a unix like platform - one with 'false' to run.
 
79
        # if you have one, please make this work :)
 
80
        self.assertRaises(errors.SigningFailed, self.my_gpg.sign, 'content')
 
81
 
 
82
    def assertProduces(self, content):
 
83
        # This needs a 'cat' command or similar to work.
 
84
        if sys.platform == 'win32':
 
85
            # Windows doesn't come with cat, and we don't require it
 
86
            # so lets try using python instead.
 
87
            # But stupid windows and line-ending conversions.
 
88
            # It is too much work to make sys.stdout be in binary mode.
 
89
            # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443
 
90
            self.my_gpg._command_line = lambda:[sys.executable, '-c',
 
91
                    'import sys; sys.stdout.write(sys.stdin.read())']
 
92
            new_content = content.replace('\n', '\r\n')
 
93
 
 
94
            self.assertEqual(new_content, self.my_gpg.sign(content))
 
95
        else:
 
96
            self.my_gpg._command_line = lambda:['cat', '-']
 
97
            self.assertEqual(content, self.my_gpg.sign(content))
 
98
 
 
99
    def test_returns_output(self):
 
100
        content = "some content\nwith newlines\n"
 
101
        self.assertProduces(content)
 
102
 
 
103
    def test_clears_progress(self):
 
104
        content = "some content\nwith newlines\n"
 
105
        old_clear_term = ui.ui_factory.clear_term
 
106
        clear_term_called = []
 
107
        def clear_term():
 
108
            old_clear_term()
 
109
            clear_term_called.append(True)
 
110
        ui.ui_factory.clear_term = clear_term
 
111
        try:
 
112
            self.assertProduces(content)
 
113
        finally:
 
114
            ui.ui_factory.clear_term = old_clear_term
 
115
        self.assertEqual([True], clear_term_called)
 
116
 
 
117
    def test_aborts_on_unicode(self):
 
118
        """You can't sign Unicode text; it must be encoded first."""
 
119
        self.assertRaises(errors.BzrBadParameterUnicode,
 
120
                          self.assertProduces, u'foo')
 
121
 
 
122
 
49
123
class TestVerify(TestCase):
50
124
 
51
125
    def import_keys(self):
52
 
        import gpg
53
 
        context = gpg.Context()
 
126
        import gpgme
 
127
        context = gpgme.Context()
54
128
 
55
 
        key = gpg.Data(b"""-----BEGIN PGP PUBLIC KEY BLOCK-----
 
129
        key = BytesIO(b"""-----BEGIN PGP PUBLIC KEY BLOCK-----
56
130
Version: GnuPG v1.4.11 (GNU/Linux)
57
131
 
58
132
mQENBE343IgBCADwzPW7kmKb2bjB+UU+1ER/ABMZspvtoZMPusUw7bk6coXHF/0W
84
158
-----END PGP PUBLIC KEY BLOCK-----
85
159
""")
86
160
 
87
 
        secret_key = gpg.Data(b"""-----BEGIN PGP PRIVATE KEY BLOCK-----
 
161
        secret_key = BytesIO(b"""-----BEGIN PGP PRIVATE KEY BLOCK-----
88
162
Version: GnuPG v1.4.11 (GNU/Linux)
89
163
 
90
164
lQOYBE343IgBCADwzPW7kmKb2bjB+UU+1ER/ABMZspvtoZMPusUw7bk6coXHF/0W
143
217
-----END PGP PRIVATE KEY BLOCK-----
144
218
""")
145
219
 
146
 
        revoked_key = gpg.Data(b"""-----BEGIN PGP PUBLIC KEY BLOCK-----
 
220
        revoked_key = BytesIO(b"""-----BEGIN PGP PUBLIC KEY BLOCK-----
147
221
Version: GnuPG v1.4.11 (GNU/Linux)
148
222
 
149
223
mI0ETjlW5gEEAOb/6P+TVM59E897wRtatxys2BhsHCXM4T7xjIiANfDwejDdifqh
168
242
-----END PGP PUBLIC KEY BLOCK-----
169
243
""")
170
244
 
171
 
        expired_key = gpg.Data(b"""-----BEGIN PGP PUBLIC KEY BLOCK-----
 
245
        expired_key = BytesIO(b"""-----BEGIN PGP PUBLIC KEY BLOCK-----
172
246
Version: GnuPG v1.4.11 (GNU/Linux)
173
247
 
174
248
mI0ETjZ6PAEEALkR4GcFQidCCxV7pgQwQd5MZua0YO2l92fVqHX+PhnZ6egCLKdD
189
263
=p0gt
190
264
-----END PGP PUBLIC KEY BLOCK-----
191
265
""")
192
 
        context.op_import(key)
193
 
        context.op_import(secret_key)
194
 
        context.op_import(revoked_key)
195
 
        context.op_import(expired_key)
 
266
        context.import_(key)
 
267
        context.import_(secret_key)
 
268
        context.import_(revoked_key)
 
269
        context.import_(expired_key)
196
270
 
197
271
    def test_verify_untrusted_but_accepted(self):
198
 
        # untrusted by gpg but listed as acceptable_keys by user
199
 
        self.requireFeature(features.gpg)
 
272
        #untrusted by gpg but listed as acceptable_keys by user
 
273
        self.requireFeature(features.gpgme)
200
274
        self.import_keys()
201
275
 
202
 
        content = b"""-----BEGIN PGP SIGNED MESSAGE-----
 
276
        content = """-----BEGIN PGP SIGNED MESSAGE-----
203
277
Hash: SHA1
204
278
 
205
279
bazaar-ng testament short form 1
217
291
=iwsn
218
292
-----END PGP SIGNATURE-----
219
293
"""
220
 
        plain = b"""bazaar-ng testament short form 1
 
294
        plain = """bazaar-ng testament short form 1
221
295
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
222
296
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
223
297
"""
224
298
        my_gpg = gpg.GPGStrategy(FakeConfig())
225
299
        my_gpg.set_acceptable_keys("bazaar@example.com")
226
 
        self.assertEqual((gpg.SIGNATURE_VALID, None, plain),
227
 
                         my_gpg.verify(content))
 
300
        self.assertEqual((gpg.SIGNATURE_VALID, None), my_gpg.verify(content,
 
301
                            plain))
228
302
 
229
303
    def test_verify_unacceptable_key(self):
230
 
        self.requireFeature(features.gpg)
 
304
        self.requireFeature(features.gpgme)
231
305
        self.import_keys()
232
306
 
233
 
        content = b"""-----BEGIN PGP SIGNED MESSAGE-----
 
307
        content = """-----BEGIN PGP SIGNED MESSAGE-----
234
308
Hash: SHA1
235
309
 
236
310
bazaar-ng testament short form 1
248
322
=iwsn
249
323
-----END PGP SIGNATURE-----
250
324
"""
251
 
        plain = b"""bazaar-ng testament short form 1
 
325
        plain = """bazaar-ng testament short form 1
252
326
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
253
327
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
254
328
"""
255
329
        my_gpg = gpg.GPGStrategy(FakeConfig())
256
330
        my_gpg.set_acceptable_keys("foo@example.com")
257
 
        self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'E3080E45', plain),
258
 
                         my_gpg.verify(content))
 
331
        self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'E3080E45'),
 
332
                         my_gpg.verify(content, plain))
259
333
 
260
334
    def test_verify_valid_but_untrusted(self):
261
 
        self.requireFeature(features.gpg)
262
 
        self.import_keys()
263
 
 
264
 
        content = b"""-----BEGIN PGP SIGNED MESSAGE-----
265
 
Hash: SHA1
266
 
 
267
 
bazaar-ng testament short form 1
268
 
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
269
 
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
270
 
-----BEGIN PGP SIGNATURE-----
271
 
Version: GnuPG v1.4.11 (GNU/Linux)
272
 
 
273
 
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
274
 
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
275
 
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
276
 
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
277
 
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
278
 
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
279
 
=iwsn
280
 
-----END PGP SIGNATURE-----
281
 
"""
282
 
        plain = b"""bazaar-ng testament short form 1
283
 
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
284
 
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
285
 
"""
286
 
        my_gpg = gpg.GPGStrategy(FakeConfig())
287
 
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None,
288
 
                          plain), my_gpg.verify(content))
 
335
        self.requireFeature(features.gpgme)
 
336
        self.import_keys()
 
337
 
 
338
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
339
Hash: SHA1
 
340
 
 
341
bazaar-ng testament short form 1
 
342
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
343
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
344
-----BEGIN PGP SIGNATURE-----
 
345
Version: GnuPG v1.4.11 (GNU/Linux)
 
346
 
 
347
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
 
348
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
 
349
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
 
350
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
 
351
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
 
352
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
 
353
=iwsn
 
354
-----END PGP SIGNATURE-----
 
355
"""
 
356
        plain = """bazaar-ng testament short form 1
 
357
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
358
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
359
"""
 
360
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
361
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
 
362
                            plain))
 
363
 
 
364
    def test_verify_bad_testament(self):
 
365
        self.requireFeature(features.gpgme)
 
366
        self.import_keys()
 
367
 
 
368
        content = """-----BEGIN PGP SIGNED MESSAGE-----
 
369
Hash: SHA1
 
370
 
 
371
bazaar-ng testament short form 1
 
372
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
 
373
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
374
-----BEGIN PGP SIGNATURE-----
 
375
Version: GnuPG v1.4.11 (GNU/Linux)
 
376
 
 
377
iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
 
378
FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
 
379
6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
 
380
7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
 
381
rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
 
382
NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
 
383
=iwsn
 
384
-----END PGP SIGNATURE-----
 
385
"""
 
386
        plain = """bazaar-ng testament short form 1
 
387
revision-id: doctor@example.com-20110527185938-hluafawphszb8dl1
 
388
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
 
389
"""
 
390
        my_gpg = gpg.GPGStrategy(FakeConfig())
 
391
        my_gpg.set_acceptable_keys("bazaar@example.com")
 
392
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
 
393
                            plain))
 
394
 
289
395
 
290
396
    def test_verify_revoked_signature(self):
291
 
        self.requireFeature(features.gpg)
 
397
        self.requireFeature(features.gpgme)
292
398
        self.import_keys()
293
399
 
294
 
        content = b"""-----BEGIN PGP SIGNED MESSAGE-----
 
400
        content = """-----BEGIN PGP SIGNED MESSAGE-----
295
401
Hash: SHA1
296
402
 
297
403
asdf
305
411
=UuRX
306
412
-----END PGP SIGNATURE-----
307
413
"""
308
 
        plain = b"""asdf\n"""
 
414
        plain = """asdf\n"""
309
415
        my_gpg = gpg.GPGStrategy(FakeConfig())
310
416
        my_gpg.set_acceptable_keys("test@example.com")
311
 
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None, None),
312
 
                         my_gpg.verify(content))
 
417
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
 
418
                            plain))
313
419
 
314
420
    def test_verify_invalid(self):
315
 
        self.requireFeature(features.gpg)
 
421
        self.requireFeature(features.gpgme)
316
422
        self.import_keys()
317
 
        content = b"""-----BEGIN PGP SIGNED MESSAGE-----
 
423
        content = """-----BEGIN PGP SIGNED MESSAGE-----
318
424
Hash: SHA1
319
425
 
320
426
bazaar-ng testament short form 1
328
434
=SOuC
329
435
-----END PGP SIGNATURE-----
330
436
"""
331
 
        plain = b"""bazaar-ng testament short form 1
 
437
        plain = """bazaar-ng testament short form 1
332
438
revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
333
439
sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
334
440
"""
335
441
        my_gpg = gpg.GPGStrategy(FakeConfig())
336
 
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None, plain),
337
 
                         my_gpg.verify(content))
 
442
        self.assertEqual((gpg.SIGNATURE_NOT_VALID, None),
 
443
                            my_gpg.verify(content, plain))
338
444
 
339
445
    def test_verify_expired_but_valid(self):
340
 
        self.requireFeature(features.gpg)
 
446
        self.requireFeature(features.gpgme)
341
447
        self.import_keys()
342
 
        content = b"""-----BEGIN PGP SIGNED MESSAGE-----
 
448
        content = """-----BEGIN PGP SIGNED MESSAGE-----
343
449
Hash: SHA1
344
 
 
 
450
 
345
451
bazaar-ng testament short form 1
346
452
revision-id: test@example.com-20110801100657-f1dr1nompeex723z
347
453
sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb
348
454
-----BEGIN PGP SIGNATURE-----
349
455
Version: GnuPG v1.4.10 (GNU/Linux)
350
 
 
 
456
 
351
457
iJwEAQECAAYFAk42esUACgkQHOJve0+NFRPc5wP7BoZkzBU8JaHMLv/LmqLr0sUz
352
458
zuE51ofZZ19L7KVtQWsOi4jFy0fi4A5TFwO8u9SOfoREGvkw292Uty9subSouK5/
353
459
mFmDOYPQ+O83zWgYZsBmMJWYDZ+X9I6XXZSbPtV/7XyTjaxtl5uRnDVJjg+AzKvD
355
461
=uHen
356
462
-----END PGP SIGNATURE-----
357
463
"""
 
464
        plain = """bazaar-ng testament short form 1
 
465
revision-id: test@example.com-20110801100657-f1dr1nompeex723z
 
466
sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb
 
467
"""
358
468
        my_gpg = gpg.GPGStrategy(FakeConfig())
359
 
        self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513', None),
360
 
                         my_gpg.verify(content))
 
469
        self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513'),
 
470
                            my_gpg.verify(content, plain))
361
471
 
362
472
    def test_verify_unknown_key(self):
363
 
        self.requireFeature(features.gpg)
 
473
        self.requireFeature(features.gpgme)
364
474
        self.import_keys()
365
 
        content = b"""-----BEGIN PGP SIGNED MESSAGE-----
 
475
        content = """-----BEGIN PGP SIGNED MESSAGE-----
366
476
Hash: SHA1
367
477
 
368
478
asdf
378
488
=RNR5
379
489
-----END PGP SIGNATURE-----
380
490
"""
 
491
        plain = "asdf\n"
381
492
        my_gpg = gpg.GPGStrategy(FakeConfig())
382
 
        self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F', None),
383
 
                         my_gpg.verify(content))
 
493
        self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F'),
 
494
                            my_gpg.verify(content, plain))
384
495
 
385
496
    def test_set_acceptable_keys(self):
386
 
        self.requireFeature(features.gpg)
 
497
        self.requireFeature(features.gpgme)
387
498
        self.import_keys()
388
499
        my_gpg = gpg.GPGStrategy(FakeConfig())
389
500
        my_gpg.set_acceptable_keys("bazaar@example.com")
391
502
                         [u'B5DEED5FCB15DAE6ECEF919587681B1EE3080E45'])
392
503
 
393
504
    def test_set_acceptable_keys_from_config(self):
394
 
        self.requireFeature(features.gpg)
 
505
        self.requireFeature(features.gpgme)
395
506
        self.import_keys()
396
507
        my_gpg = gpg.GPGStrategy(FakeConfig(
397
 
            b'acceptable_keys=bazaar@example.com'))
 
508
                'acceptable_keys=bazaar@example.com'))
398
509
        my_gpg.set_acceptable_keys(None)
399
510
        self.assertEqual(my_gpg.acceptable_keys,
400
511
                         [u'B5DEED5FCB15DAE6ECEF919587681B1EE3080E45'])
401
512
 
402
513
    def test_set_acceptable_keys_unknown(self):
403
 
        self.requireFeature(features.gpg)
 
514
        self.requireFeature(features.gpgme)
404
515
        my_gpg = gpg.GPGStrategy(FakeConfig())
405
516
        self.notes = []
406
 
 
407
517
        def note(*args):
408
518
            self.notes.append(args[0] % args[1:])
409
519
        self.overrideAttr(trace, 'note', note)
410
520
        my_gpg.set_acceptable_keys("unknown")
411
521
        self.assertEqual(my_gpg.acceptable_keys, [])
412
522
        self.assertEqual(self.notes,
413
 
                         ['No GnuPG key results for pattern: unknown'])
 
523
            ['No GnuPG key results for pattern: unknown'])
414
524
 
415
525
 
416
526
class TestDisabled(TestCase):
417
527
 
418
528
    def test_sign(self):
419
 
        self.assertRaises(gpg.SigningFailed,
420
 
                          gpg.DisabledGPGStrategy(None).sign, b'content', gpg.MODE_CLEAR)
 
529
        self.assertRaises(errors.SigningFailed,
 
530
                          gpg.DisabledGPGStrategy(None).sign, 'content')
421
531
 
422
532
    def test_verify(self):
423
 
        self.assertRaises(gpg.SignatureVerificationFailed,
424
 
                          gpg.DisabledGPGStrategy(None).verify, b'content')
 
533
        self.assertRaises(errors.SignatureVerificationFailed,
 
534
                          gpg.DisabledGPGStrategy(None).verify, 'content',
 
535
                          'testament')