Merge lp:~cjwatson/launchpad/gpg-fix-verify-retrieve-key into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18905
Proposed branch: lp:~cjwatson/launchpad/gpg-fix-verify-retrieve-key
Merge into: lp:launchpad
Diff against target: 76 lines (+49/-2)
2 files modified
lib/lp/services/gpg/handler.py (+6/-1)
lib/lp/services/gpg/tests/test_gpghandler.py (+43/-1)
To merge this branch: bzr merge lp:~cjwatson/launchpad/gpg-fix-verify-retrieve-key
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+364386@code.launchpad.net

Commit message

Temporarily allow 64-bit key IDs in GPGHandler.retrieveKey, since getVerifiedSignature may need them.

Description of the change

An awkward consequence of https://code.launchpad.net/~cjwatson/launchpad/no-auto-key-retrieve/+merge/364100. I still think this is probably the best approach for now given the keyserver weirdness, but happy to discuss it.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/services/gpg/handler.py'
2--- lib/lp/services/gpg/handler.py 2019-03-12 12:57:14 +0000
3+++ lib/lp/services/gpg/handler.py 2019-03-13 17:42:56 +0000
4@@ -457,7 +457,12 @@
5 if not key.exists_in_local_keyring:
6 pubkey = self._getPubKey(fingerprint)
7 key = self.importPublicKey(pubkey)
8- if fingerprint != key.fingerprint:
9+ # XXX cjwatson 2019-03-13: Remove affordance for 64-bit key IDs
10+ # once we're on GnuPG 2.2.7 and GPGME 1.11.0. See comment in
11+ # getVerifiedSignature.
12+ if (fingerprint != key.fingerprint and
13+ not (len(fingerprint) == 16 and
14+ key.fingerprint.endswith(fingerprint))):
15 ctx = self._getContext()
16 with gpgme_timeline("delete", key.fingerprint):
17 ctx.delete(key.key)
18
19=== modified file 'lib/lp/services/gpg/tests/test_gpghandler.py'
20--- lib/lp/services/gpg/tests/test_gpghandler.py 2018-06-25 11:31:00 +0000
21+++ lib/lp/services/gpg/tests/test_gpghandler.py 2019-03-13 17:42:56 +0000
22@@ -1,4 +1,4 @@
23-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
24+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
25 # GNU Affero General Public License version 3 (see the file LICENSE).
26
27 import base64
28@@ -193,6 +193,48 @@
29 GPGKeyMismatchOnServer, gpghandler.retrieveKey, fingerprint)
30 self.assertEqual([], list(gpghandler.localKeys()))
31
32+ def test_retrieveKey_allows_64bit_key_id(self):
33+ # In order to support retrieving keys during signature verification,
34+ # retrieveKey temporarily allows 64-bit key IDs.
35+ keyserver = self.useFixture(KeyServerTac())
36+ fingerprint = "340CA3BB270E2716C9EE0B768E7EB7086C64A8C5"
37+ key_id = fingerprint[-16:]
38+ shutil.copy2(
39+ test_pubkey_file_from_email("foo.bar@canonical.com"),
40+ os.path.join(keyserver.root, "0x%s.get" % key_id))
41+ gpghandler = getUtility(IGPGHandler)
42+ self.assertEqual(
43+ fingerprint, gpghandler.retrieveKey(key_id).fingerprint)
44+ fingerprints = set(key.fingerprint for key in gpghandler.localKeys())
45+ self.assertIn(fingerprint, fingerprints)
46+
47+ def test_retrieveKey_checks_64bit_key_id(self):
48+ # If retrieveKey is given a 64-bit key ID, it checks that it's a
49+ # suffix of the fingerprint (which is the best it can do).
50+ keyserver = self.useFixture(KeyServerTac())
51+ key_id = "0000000000000000"
52+ shutil.copy2(
53+ test_pubkey_file_from_email("foo.bar@canonical.com"),
54+ os.path.join(keyserver.root, "0x%s.get" % key_id))
55+ gpghandler = getUtility(IGPGHandler)
56+ self.assertRaises(
57+ GPGKeyMismatchOnServer, gpghandler.retrieveKey, key_id)
58+ self.assertEqual([], list(gpghandler.localKeys()))
59+
60+ def test_retrieveKey_forbids_32bit_key_id(self):
61+ # 32-bit key IDs are just too terrible, and retrieveKey doesn't
62+ # support those.
63+ keyserver = self.useFixture(KeyServerTac())
64+ fingerprint = "340CA3BB270E2716C9EE0B768E7EB7086C64A8C5"
65+ key_id = fingerprint[-8:]
66+ shutil.copy2(
67+ test_pubkey_file_from_email("foo.bar@canonical.com"),
68+ os.path.join(keyserver.root, "0x%s.get" % key_id))
69+ gpghandler = getUtility(IGPGHandler)
70+ self.assertRaises(
71+ GPGKeyMismatchOnServer, gpghandler.retrieveKey, key_id)
72+ self.assertEqual([], list(gpghandler.localKeys()))
73+
74 def test_uploadPublicKey_suppress_in_config(self):
75 self.useFixture(KeyServerTac())
76 logger = BufferLogger()