Merge lp:~jelmer/brz/gpg-detached-sign into lp:~brz/brz/base

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merged at revision: 6892
Proposed branch: lp:~jelmer/brz/gpg-detached-sign
Merge into: lp:~brz/brz/base
Diff against target: 442 lines (+72/-109)
8 files modified
breezy/bzr/remote.py (+5/-3)
breezy/gpg.py (+38/-29)
breezy/merge_directive.py (+1/-1)
breezy/repository.py (+6/-5)
breezy/tests/per_repository/test_signatures.py (+1/-1)
breezy/tests/test_commit.py (+2/-1)
breezy/tests/test_gpg.py (+13/-54)
breezy/tests/test_log.py (+6/-15)
To merge this branch: bzr merge lp:~jelmer/brz/gpg-detached-sign
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+341598@code.launchpad.net

Commit message

Add support for passing mode argument to GPGSignature.sign.

Description of the change

Add support for passing mode argument to GPGSignature.sign.

This is necessary for brz-git, which needs to create detached signatures.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'breezy/bzr/remote.py'
--- breezy/bzr/remote.py 2017-11-23 20:02:55 +0000
+++ breezy/bzr/remote.py 2018-03-18 20:19:21 +0000
@@ -2692,7 +2692,7 @@
26922692
2693 def store_revision_signature(self, gpg_strategy, plaintext, revision_id):2693 def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
2694 with self.lock_write():2694 with self.lock_write():
2695 signature = gpg_strategy.sign(plaintext)2695 signature = gpg_strategy.sign(plaintext, gpg.MODE_CLEAR)
2696 self.add_signature_text(revision_id, signature)2696 self.add_signature_text(revision_id, signature)
26972697
2698 def add_signature_text(self, revision_id, signature):2698 def add_signature_text(self, revision_id, signature):
@@ -2737,9 +2737,11 @@
2737 signature = self.get_signature_text(revision_id)2737 signature = self.get_signature_text(revision_id)
27382738
2739 testament = _mod_testament.Testament.from_revision(self, revision_id)2739 testament = _mod_testament.Testament.from_revision(self, revision_id)
2740 plaintext = testament.as_short_text()
27412740
2742 return gpg_strategy.verify(signature, plaintext)2741 (status, key, signed_plaintext) = gpg_strategy.verify(signature)
2742 if testament.as_short_text() != signed_plaintext:
2743 return gpg.SIGNATURE_NOT_VALID, None
2744 return (status, key)
27432745
2744 def item_keys_introduced_by(self, revision_ids, _files_pb=None):2746 def item_keys_introduced_by(self, revision_ids, _files_pb=None):
2745 self._ensure_real()2747 self._ensure_real()
27462748
=== modified file 'breezy/gpg.py'
--- breezy/gpg.py 2018-02-24 15:50:23 +0000
+++ breezy/gpg.py 2018-03-18 20:19:21 +0000
@@ -52,6 +52,10 @@
52SIGNATURE_NOT_SIGNED = 352SIGNATURE_NOT_SIGNED = 3
53SIGNATURE_EXPIRED = 453SIGNATURE_EXPIRED = 4
5454
55MODE_NORMAL = 0
56MODE_DETACH = 1
57MODE_CLEAR = 2
58
5559
56class GpgNotInstalled(errors.DependencyNotPresent):60class GpgNotInstalled(errors.DependencyNotPresent):
5761
@@ -123,10 +127,10 @@
123 def __init__(self, ignored):127 def __init__(self, ignored):
124 """Real strategies take a configuration."""128 """Real strategies take a configuration."""
125129
126 def sign(self, content):130 def sign(self, content, mode):
127 raise SigningFailed('Signing is disabled.')131 raise SigningFailed('Signing is disabled.')
128132
129 def verify(self, content, testament):133 def verify(self, signed_data, signature=None):
130 raise SignatureVerificationFailed('Signature verification is \134 raise SignatureVerificationFailed('Signature verification is \
131disabled.')135disabled.')
132136
@@ -146,12 +150,14 @@
146 def __init__(self, ignored):150 def __init__(self, ignored):
147 """Real strategies take a configuration."""151 """Real strategies take a configuration."""
148152
149 def sign(self, content):153 def sign(self, content, mode):
150 return ("-----BEGIN PSEUDO-SIGNED CONTENT-----\n" + content +154 return ("-----BEGIN PSEUDO-SIGNED CONTENT-----\n" + content +
151 "-----END PSEUDO-SIGNED CONTENT-----\n")155 "-----END PSEUDO-SIGNED CONTENT-----\n")
152156
153 def verify(self, content, testament):157 def verify(self, signed_data, signature=None):
154 return SIGNATURE_VALID, None158 plain_text = signed_data.replace("-----BEGIN PSEUDO-SIGNED CONTENT-----\n", "")
159 plain_text = plain_text.replace("-----END PSEUDO-SIGNED CONTENT-----\n", "")
160 return SIGNATURE_VALID, None, plain_text
155161
156 def set_acceptable_keys(self, command_line_input):162 def set_acceptable_keys(self, command_line_input):
157 if command_line_input is not None:163 if command_line_input is not None:
@@ -187,6 +193,7 @@
187 try:193 try:
188 import gpg194 import gpg
189 self.context = gpg.Context()195 self.context = gpg.Context()
196 self.context.armor = True
190 except ImportError as error:197 except ImportError as error:
191 pass # can't use verify()198 pass # can't use verify()
192199
@@ -224,7 +231,7 @@
224 except ImportError as error:231 except ImportError as error:
225 return False232 return False
226233
227 def sign(self, content):234 def sign(self, content, mode):
228 import gpg235 import gpg
229 if isinstance(content, unicode):236 if isinstance(content, unicode):
230 raise errors.BzrBadParameterUnicode('content')237 raise errors.BzrBadParameterUnicode('content')
@@ -232,29 +239,34 @@
232 plain_text = gpg.Data(content)239 plain_text = gpg.Data(content)
233 try:240 try:
234 output, result = self.context.sign(241 output, result = self.context.sign(
235 plain_text, mode=gpg.constants.sig.mode.CLEAR)242 plain_text, mode={
243 MODE_DETACH: gpg.constants.sig.mode.DETACH,
244 MODE_CLEAR: gpg.constants.sig.mode.CLEAR,
245 MODE_NORMAL: gpg.constants.sig.mode.NORMAL,
246 }[mode])
236 except gpg.errors.GPGMEError as error:247 except gpg.errors.GPGMEError as error:
237 raise SigningFailed(str(error))248 raise SigningFailed(str(error))
238249
239 return output250 return output
240251
241 def verify(self, content, testament):252 def verify(self, signed_data, signature=None):
242 """Check content has a valid signature.253 """Check content has a valid signature.
243254
244 :param content: the commit signature255 :param signed_data; Signed data
245 :param testament: the valid testament string for the commit256 :param signature: optional signature (if detached)
246257
247 :return: SIGNATURE_VALID or a failed SIGNATURE_ value, key uid if valid258 :return: SIGNATURE_VALID or a failed SIGNATURE_ value, key uid if valid, plain text
248 """259 """
249 try:260 try:
250 import gpg261 import gpg
251 except ImportError as error:262 except ImportError as error:
252 raise errors.GpgNotInstalled(error)263 raise errors.GpgNotInstalled(error)
253264
254 signature = gpg.Data(content)265 signed_data = gpg.Data(signed_data)
255 sink = gpg.Data()266 if signature:
267 signature = gpg.Data(signature)
256 try:268 try:
257 plain_output, result = self.context.verify(signature)269 plain_output, result = self.context.verify(signed_data, signature)
258 except gpg.errors.BadSignatures as error:270 except gpg.errors.BadSignatures as error:
259 fingerprint = error.result.signatures[0].fpr271 fingerprint = error.result.signatures[0].fpr
260 if error.result.signatures[0].summary & gpg.constants.SIGSUM_KEY_EXPIRED:272 if error.result.signatures[0].summary & gpg.constants.SIGSUM_KEY_EXPIRED:
@@ -262,35 +274,32 @@
262 if expires > error.result.signatures[0].timestamp:274 if expires > error.result.signatures[0].timestamp:
263 # The expired key was not expired at time of signing.275 # The expired key was not expired at time of signing.
264 # test_verify_expired_but_valid()276 # test_verify_expired_but_valid()
265 return SIGNATURE_EXPIRED, fingerprint[-8:]277 return SIGNATURE_EXPIRED, fingerprint[-8:], None
266 else:278 else:
267 # I can't work out how to create a test where the signature279 # I can't work out how to create a test where the signature
268 # was expired at the time of signing.280 # was expired at the time of signing.
269 return SIGNATURE_NOT_VALID, None281 return SIGNATURE_NOT_VALID, None, None
270282
271 # GPG does not know this key.283 # GPG does not know this key.
272 # test_verify_unknown_key()284 # test_verify_unknown_key()
273 if error.result.signatures[0].summary & gpg.constants.SIGSUM_KEY_MISSING:285 if error.result.signatures[0].summary & gpg.constants.SIGSUM_KEY_MISSING:
274 return SIGNATURE_KEY_MISSING, fingerprint[-8:]286 return SIGNATURE_KEY_MISSING, fingerprint[-8:], None
275287
276 return SIGNATURE_NOT_VALID, None288 return SIGNATURE_NOT_VALID, None, None
277 except gpg.errors.GPGMEError as error:289 except gpg.errors.GPGMEError as error:
278 raise SignatureVerificationFailed(error[2])290 raise SignatureVerificationFailed(error)
279291
280 # No result if input is invalid.292 # No result if input is invalid.
281 # test_verify_invalid()293 # test_verify_invalid()
282 if len(result.signatures) == 0:294 if len(result.signatures) == 0:
283 return SIGNATURE_NOT_VALID, None295 return SIGNATURE_NOT_VALID, None, plain_output
296
284 # User has specified a list of acceptable keys, check our result is in297 # User has specified a list of acceptable keys, check our result is in
285 # it. test_verify_unacceptable_key()298 # it. test_verify_unacceptable_key()
286 fingerprint = result.signatures[0].fpr299 fingerprint = result.signatures[0].fpr
287 if self.acceptable_keys is not None:300 if self.acceptable_keys is not None:
288 if not fingerprint in self.acceptable_keys:301 if not fingerprint in self.acceptable_keys:
289 return SIGNATURE_KEY_MISSING, fingerprint[-8:]302 return SIGNATURE_KEY_MISSING, fingerprint[-8:], plain_output
290 # Check the signature actually matches the testament.
291 # test_verify_bad_testament()
292 if testament != plain_output:
293 return SIGNATURE_NOT_VALID, None
294 # Yay gpg set the valid bit.303 # Yay gpg set the valid bit.
295 # Can't write a test for this one as you can't set a key to be304 # Can't write a test for this one as you can't set a key to be
296 # trusted using gpg.305 # trusted using gpg.
@@ -298,20 +307,20 @@
298 key = self.context.get_key(fingerprint)307 key = self.context.get_key(fingerprint)
299 name = key.uids[0].name308 name = key.uids[0].name
300 email = key.uids[0].email309 email = key.uids[0].email
301 return SIGNATURE_VALID, name + " <" + email + ">"310 return SIGNATURE_VALID, name.decode('utf-8') + u" <" + email.decode('utf-8') + u">", plain_output
302 # Sigsum_red indicates a problem, unfortunatly I have not been able311 # Sigsum_red indicates a problem, unfortunatly I have not been able
303 # to write any tests which actually set this.312 # to write any tests which actually set this.
304 if result.signatures[0].summary & gpg.constants.SIGSUM_RED:313 if result.signatures[0].summary & gpg.constants.SIGSUM_RED:
305 return SIGNATURE_NOT_VALID, None314 return SIGNATURE_NOT_VALID, None, plain_output
306 # Summary isn't set if sig is valid but key is untrusted but if user315 # Summary isn't set if sig is valid but key is untrusted but if user
307 # has explicity set the key as acceptable we can validate it.316 # has explicity set the key as acceptable we can validate it.
308 if result.signatures[0].summary == 0 and self.acceptable_keys is not None:317 if result.signatures[0].summary == 0 and self.acceptable_keys is not None:
309 if fingerprint in self.acceptable_keys:318 if fingerprint in self.acceptable_keys:
310 # test_verify_untrusted_but_accepted()319 # test_verify_untrusted_but_accepted()
311 return SIGNATURE_VALID, None320 return SIGNATURE_VALID, None, plain_output
312 # test_verify_valid_but_untrusted()321 # test_verify_valid_but_untrusted()
313 if result.signatures[0].summary == 0 and self.acceptable_keys is None:322 if result.signatures[0].summary == 0 and self.acceptable_keys is None:
314 return SIGNATURE_NOT_VALID, None323 return SIGNATURE_NOT_VALID, None, plain_output
315 # Other error types such as revoked keys should (I think) be caught by324 # Other error types such as revoked keys should (I think) be caught by
316 # SIGSUM_RED so anything else means something is buggy.325 # SIGSUM_RED so anything else means something is buggy.
317 raise SignatureVerificationFailed(326 raise SignatureVerificationFailed(
318327
=== modified file 'breezy/merge_directive.py'
--- breezy/merge_directive.py 2017-10-27 00:18:42 +0000
+++ breezy/merge_directive.py 2018-03-18 20:19:21 +0000
@@ -251,7 +251,7 @@
251 :return: a string251 :return: a string
252 """252 """
253 my_gpg = gpg.GPGStrategy(branch.get_config_stack())253 my_gpg = gpg.GPGStrategy(branch.get_config_stack())
254 return my_gpg.sign(''.join(self.to_lines()))254 return my_gpg.sign(''.join(self.to_lines()), gpg.MODE_CLEAR)
255255
256 def to_email(self, mail_to, branch, sign=False):256 def to_email(self, mail_to, branch, sign=False):
257 """Serialize as an email message.257 """Serialize as an email message.
258258
=== modified file 'breezy/repository.py'
--- breezy/repository.py 2018-02-24 15:50:23 +0000
+++ breezy/repository.py 2018-03-18 20:19:21 +0000
@@ -887,7 +887,7 @@
887887
888 def store_revision_signature(self, gpg_strategy, plaintext, revision_id):888 def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
889 with self.lock_write():889 with self.lock_write():
890 signature = gpg_strategy.sign(plaintext)890 signature = gpg_strategy.sign(plaintext, gpg.MODE_CLEAR)
891 self.add_signature_text(revision_id, signature)891 self.add_signature_text(revision_id, signature)
892892
893 def add_signature_text(self, revision_id, signature):893 def add_signature_text(self, revision_id, signature):
@@ -1104,11 +1104,12 @@
1104 return gpg.SIGNATURE_NOT_SIGNED, None1104 return gpg.SIGNATURE_NOT_SIGNED, None
1105 signature = self.get_signature_text(revision_id)1105 signature = self.get_signature_text(revision_id)
11061106
1107 testament = _mod_testament.Testament.from_revision(1107 testament = _mod_testament.Testament.from_revision(self, revision_id)
1108 self, revision_id)
1109 plaintext = testament.as_short_text()
11101108
1111 return gpg_strategy.verify(signature, plaintext)1109 (status, key, signed_plaintext) = gpg_strategy.verify(signature)
1110 if testament.as_short_text() != signed_plaintext:
1111 return gpg.SIGNATURE_NOT_VALID, None
1112 return (status, key)
11121113
1113 def verify_revision_signatures(self, revision_ids, gpg_strategy):1114 def verify_revision_signatures(self, revision_ids, gpg_strategy):
1114 """Verify revision signatures for a number of revisions.1115 """Verify revision signatures for a number of revisions.
11151116
=== modified file 'breezy/tests/per_repository/test_signatures.py'
--- breezy/tests/per_repository/test_signatures.py 2017-08-07 19:09:47 +0000
+++ breezy/tests/per_repository/test_signatures.py 2018-03-18 20:19:21 +0000
@@ -123,7 +123,7 @@
123 '-----END PSEUDO-SIGNED CONTENT-----\n',123 '-----END PSEUDO-SIGNED CONTENT-----\n',
124 repo.get_signature_text(a))124 repo.get_signature_text(a))
125 self.assertEqual(125 self.assertEqual(
126 (gpg.SIGNATURE_VALID, None, ),126 (gpg.SIGNATURE_VALID, None),
127 repo.verify_revision_signature(a, strategy))127 repo.verify_revision_signature(a, strategy))
128128
129 def test_verify_revision_signatures(self):129 def test_verify_revision_signatures(self):
130130
=== modified file 'breezy/tests/test_commit.py'
--- breezy/tests/test_commit.py 2018-02-15 19:38:33 +0000
+++ breezy/tests/test_commit.py 2018-03-18 20:19:21 +0000
@@ -435,7 +435,8 @@
435 message="base", allow_pointless=True, rev_id='B',435 message="base", allow_pointless=True, rev_id='B',
436 working_tree=wt)436 working_tree=wt)
437 def sign(text):437 def sign(text):
438 return breezy.gpg.LoopbackGPGStrategy(None).sign(text)438 return breezy.gpg.LoopbackGPGStrategy(None).sign(
439 text, breezy.gpg.MODE_CLEAR)
439 self.assertEqual(sign(Testament.from_revision(branch.repository,440 self.assertEqual(sign(Testament.from_revision(branch.repository,
440 'B').as_short_text()),441 'B').as_short_text()),
441 branch.repository.get_signature_text('B'))442 branch.repository.get_signature_text('B'))
442443
=== modified file 'breezy/tests/test_gpg.py'
--- breezy/tests/test_gpg.py 2017-07-04 20:03:11 +0000
+++ breezy/tests/test_gpg.py 2018-03-18 20:19:21 +0000
@@ -224,8 +224,7 @@
224"""224"""
225 my_gpg = gpg.GPGStrategy(FakeConfig())225 my_gpg = gpg.GPGStrategy(FakeConfig())
226 my_gpg.set_acceptable_keys("bazaar@example.com")226 my_gpg.set_acceptable_keys("bazaar@example.com")
227 self.assertEqual((gpg.SIGNATURE_VALID, None), my_gpg.verify(content,227 self.assertEqual((gpg.SIGNATURE_VALID, None, plain), my_gpg.verify(content))
228 plain))
229228
230 def test_verify_unacceptable_key(self):229 def test_verify_unacceptable_key(self):
231 self.requireFeature(features.gpg)230 self.requireFeature(features.gpg)
@@ -255,8 +254,8 @@
255"""254"""
256 my_gpg = gpg.GPGStrategy(FakeConfig())255 my_gpg = gpg.GPGStrategy(FakeConfig())
257 my_gpg.set_acceptable_keys("foo@example.com")256 my_gpg.set_acceptable_keys("foo@example.com")
258 self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'E3080E45'),257 self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'E3080E45', plain),
259 my_gpg.verify(content, plain))258 my_gpg.verify(content))
260259
261 def test_verify_valid_but_untrusted(self):260 def test_verify_valid_but_untrusted(self):
262 self.requireFeature(features.gpg)261 self.requireFeature(features.gpg)
@@ -285,40 +284,7 @@
285sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4284sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
286"""285"""
287 my_gpg = gpg.GPGStrategy(FakeConfig())286 my_gpg = gpg.GPGStrategy(FakeConfig())
288 self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,287 self.assertEqual((gpg.SIGNATURE_NOT_VALID, None, plain), my_gpg.verify(content))
289 plain))
290
291 def test_verify_bad_testament(self):
292 self.requireFeature(features.gpg)
293 self.import_keys()
294
295 content = """-----BEGIN PGP SIGNED MESSAGE-----
296Hash: SHA1
297
298bazaar-ng testament short form 1
299revision-id: amy@example.com-20110527185938-hluafawphszb8dl1
300sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
301-----BEGIN PGP SIGNATURE-----
302Version: GnuPG v1.4.11 (GNU/Linux)
303
304iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk
305FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+
3066g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx
3077UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG
308rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6
309NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8=
310=iwsn
311-----END PGP SIGNATURE-----
312"""
313 plain = """bazaar-ng testament short form 1
314revision-id: doctor@example.com-20110527185938-hluafawphszb8dl1
315sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
316"""
317 my_gpg = gpg.GPGStrategy(FakeConfig())
318 my_gpg.set_acceptable_keys("bazaar@example.com")
319 self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,
320 plain))
321
322288
323 def test_verify_revoked_signature(self):289 def test_verify_revoked_signature(self):
324 self.requireFeature(features.gpg)290 self.requireFeature(features.gpg)
@@ -341,8 +307,7 @@
341 plain = """asdf\n"""307 plain = """asdf\n"""
342 my_gpg = gpg.GPGStrategy(FakeConfig())308 my_gpg = gpg.GPGStrategy(FakeConfig())
343 my_gpg.set_acceptable_keys("test@example.com")309 my_gpg.set_acceptable_keys("test@example.com")
344 self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content,310 self.assertEqual((gpg.SIGNATURE_NOT_VALID, None, None), my_gpg.verify(content))
345 plain))
346311
347 def test_verify_invalid(self):312 def test_verify_invalid(self):
348 self.requireFeature(features.gpg)313 self.requireFeature(features.gpg)
@@ -366,8 +331,8 @@
366sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4331sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4
367"""332"""
368 my_gpg = gpg.GPGStrategy(FakeConfig())333 my_gpg = gpg.GPGStrategy(FakeConfig())
369 self.assertEqual((gpg.SIGNATURE_NOT_VALID, None),334 self.assertEqual((gpg.SIGNATURE_NOT_VALID, None, plain),
370 my_gpg.verify(content, plain))335 my_gpg.verify(content))
371336
372 def test_verify_expired_but_valid(self):337 def test_verify_expired_but_valid(self):
373 self.requireFeature(features.gpg)338 self.requireFeature(features.gpg)
@@ -388,13 +353,9 @@
388=uHen353=uHen
389-----END PGP SIGNATURE-----354-----END PGP SIGNATURE-----
390"""355"""
391 plain = """bazaar-ng testament short form 1
392revision-id: test@example.com-20110801100657-f1dr1nompeex723z
393sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb
394"""
395 my_gpg = gpg.GPGStrategy(FakeConfig())356 my_gpg = gpg.GPGStrategy(FakeConfig())
396 self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513'),357 self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513', None),
397 my_gpg.verify(content, plain))358 my_gpg.verify(content))
398359
399 def test_verify_unknown_key(self):360 def test_verify_unknown_key(self):
400 self.requireFeature(features.gpg)361 self.requireFeature(features.gpg)
@@ -415,10 +376,9 @@
415=RNR5376=RNR5
416-----END PGP SIGNATURE-----377-----END PGP SIGNATURE-----
417"""378"""
418 plain = "asdf\n"
419 my_gpg = gpg.GPGStrategy(FakeConfig())379 my_gpg = gpg.GPGStrategy(FakeConfig())
420 self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F'),380 self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F', None),
421 my_gpg.verify(content, plain))381 my_gpg.verify(content))
422382
423 def test_set_acceptable_keys(self):383 def test_set_acceptable_keys(self):
424 self.requireFeature(features.gpg)384 self.requireFeature(features.gpg)
@@ -454,9 +414,8 @@
454414
455 def test_sign(self):415 def test_sign(self):
456 self.assertRaises(gpg.SigningFailed,416 self.assertRaises(gpg.SigningFailed,
457 gpg.DisabledGPGStrategy(None).sign, 'content')417 gpg.DisabledGPGStrategy(None).sign, 'content', gpg.MODE_CLEAR)
458418
459 def test_verify(self):419 def test_verify(self):
460 self.assertRaises(gpg.SignatureVerificationFailed,420 self.assertRaises(gpg.SignatureVerificationFailed,
461 gpg.DisabledGPGStrategy(None).verify, 'content',421 gpg.DisabledGPGStrategy(None).verify, 'content')
462 'testament')
463422
=== modified file 'breezy/tests/test_log.py'
--- breezy/tests/test_log.py 2017-12-04 00:25:02 +0000
+++ breezy/tests/test_log.py 2018-03-18 20:19:21 +0000
@@ -317,31 +317,22 @@
317317
318318
319class TestFormatSignatureValidity(tests.TestCaseWithTransport):319class TestFormatSignatureValidity(tests.TestCaseWithTransport):
320 class UTFLoopbackGPGStrategy(gpg.LoopbackGPGStrategy):320
321 def verify(self, content, testament):321 def verify_revision_signature(self, revid, gpg_strategy):
322 return (gpg.SIGNATURE_VALID,322 return (gpg.SIGNATURE_VALID,
323 u'UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>')323 u'UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>')
324
325 def has_signature_for_revision_id(self, revision_id):
326 return True
327
328 def get_signature_text(self, revision_id):
329 return ''
330324
331 def test_format_signature_validity_utf(self):325 def test_format_signature_validity_utf(self):
332 """Check that GPG signatures containing UTF-8 names are formatted326 """Check that GPG signatures containing UTF-8 names are formatted
333 correctly."""327 correctly."""
334 # Monkey patch to use our UTF-8 generating GPGStrategy
335 self.overrideAttr(gpg, 'GPGStrategy', self.UTFLoopbackGPGStrategy)
336 wt = self.make_branch_and_tree('.')328 wt = self.make_branch_and_tree('.')
337 revid = wt.commit('empty commit')329 revid = wt.commit('empty commit')
338 repo = wt.branch.repository330 repo = wt.branch.repository
339 # Monkey patch out checking if this rev is actually signed, since we331 # Monkey patch out checking if this rev is actually signed, since we
340 # can't sign it without a heavier TestCase and LoopbackGPGStrategy332 # can't sign it without a heavier TestCase and LoopbackGPGStrategy
341 # doesn't care anyways.333 # doesn't care anyways.
342 self.overrideAttr(repo, 'has_signature_for_revision_id',334 self.overrideAttr(repo, 'verify_revision_signature',
343 self.has_signature_for_revision_id)335 self.verify_revision_signature)
344 self.overrideAttr(repo, 'get_signature_text', self.get_signature_text)
345 out = log.format_signature_validity(revid, wt.branch)336 out = log.format_signature_validity(revid, wt.branch)
346 self.assertEqual(337 self.assertEqual(
347u'valid signature from UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>',338u'valid signature from UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>',

Subscribers

People subscribed via source and target branches