Merge lp:~cjwatson/launchpad/inline-release into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 17758
Proposed branch: lp:~cjwatson/launchpad/inline-release
Merge into: lp:launchpad
Diff against target: 133 lines (+52/-7)
3 files modified
lib/lp/archivepublisher/archivesigningkey.py (+9/-0)
lib/lp/archivepublisher/tests/archive-signing.txt (+23/-4)
lib/lp/archivepublisher/tests/test_publisher.py (+20/-3)
To merge this branch: bzr merge lp:~cjwatson/launchpad/inline-release
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+272132@code.launchpad.net

Commit message

Add clearsigned InRelease files for archives.

Description of the change

Add clearsigned InRelease files for archives.

This only applies to PPAs. The primary archive will be handled by a separate change to ubuntu-archive-publishing once one remaining bit of Canonical's infrastructure has been upgraded to cope with that.

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

This will also affect partner, and I don't think we've checked its mirror scripts.

review: Approve (code)
Revision history for this message
Colin Watson (cjwatson) wrote :

The partner mirror scripts were part of the puppet work I landed a little while back. I've just rechecked puppet with specific attention to archive.canonical.com and it looks fine to me.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/archivepublisher/archivesigningkey.py'
--- lib/lp/archivepublisher/archivesigningkey.py 2015-07-08 16:05:11 +0000
+++ lib/lp/archivepublisher/archivesigningkey.py 2015-09-25 11:13:31 +0000
@@ -135,3 +135,12 @@
135 os.path.join(suite_path, 'Release.gpg'), 'w')135 os.path.join(suite_path, 'Release.gpg'), 'w')
136 release_signature_file.write(signature)136 release_signature_file.write(signature)
137 release_signature_file.close()137 release_signature_file.close()
138
139 inline_release = gpghandler.signContent(
140 release_file_content, secret_key.fingerprint,
141 mode=gpgme.SIG_MODE_CLEAR)
142
143 inline_release_file = open(
144 os.path.join(suite_path, 'InRelease'), 'w')
145 inline_release_file.write(inline_release)
146 inline_release_file.close()
138147
=== modified file 'lib/lp/archivepublisher/tests/archive-signing.txt'
--- lib/lp/archivepublisher/tests/archive-signing.txt 2012-09-20 12:00:22 +0000
+++ lib/lp/archivepublisher/tests/archive-signing.txt 2015-09-25 11:13:31 +0000
@@ -15,9 +15,11 @@
15Once the signing key is available, the subsequent publications will15Once the signing key is available, the subsequent publications will
16result in a signed repository.16result in a signed repository.
1717
18The signed repository will contained a detached signature of the18The signed repository will contain a detached signature of the
19top-level 'Release' file, named 'Release.gpg' and a ASCII-armoded19top-level 'Release' file, named 'Release.gpg' and a ASCII-armored
20export of the public GPG key (name 'key.gpg')20export of the public GPG key (name 'key.gpg'). A clearsigned
21'InRelease' file is also created, reducing the risk of clients
22acquiring skewed copies of the content and its signature.
2123
22We will set up and use the test-keyserver.24We will set up and use the test-keyserver.
2325
@@ -377,7 +379,7 @@
377 /var/tmp/ppa.test/cprov/ppa/ubuntutest/dists/hoary/Release379 /var/tmp/ppa.test/cprov/ppa/ubuntutest/dists/hoary/Release
378380
379It produces a detached signature for the repository Release current381It produces a detached signature for the repository Release current
380file contents.382file contents, and a clearsigned InRelease file.
381383
382 >>> from lp.archivepublisher.config import getPubConfig384 >>> from lp.archivepublisher.config import getPubConfig
383 >>> archive_root = getPubConfig(cprov.archive).archiveroot385 >>> archive_root = getPubConfig(cprov.archive).archiveroot
@@ -398,6 +400,15 @@
398 -----END PGP SIGNATURE-----400 -----END PGP SIGNATURE-----
399 <BLANKLINE>401 <BLANKLINE>
400402
403 >>> inline_release_path = os.path.join(suite_path, 'InRelease')
404 >>> print open(inline_release_path).read()
405 -----BEGIN PGP SIGNED MESSAGE-----
406 ...
407 -----BEGIN PGP SIGNATURE-----
408 ...
409 -----END PGP SIGNATURE-----
410 <BLANKLINE>
411
401The signature can be verified by retrieving the public key from the412The signature can be verified by retrieving the public key from the
402keyserver.413keyserver.
403414
@@ -415,6 +426,14 @@
415 >>> signature.fingerprint == expected_fingerprint426 >>> signature.fingerprint == expected_fingerprint
416 True427 True
417428
429 >>> inline_signature = gpghandler.getVerifiedSignature(
430 ... content=open(inline_release_path).read())
431 >>> inline_signature.fingerprint == expected_fingerprint
432 True
433 >>> print inline_signature.plain_data
434 This is a fake release file.
435 <BLANKLINE>
436
418Finally, if we try to sign a repository for which the archive doesn't437Finally, if we try to sign a repository for which the archive doesn't
419have a 'signing_key' set, it raises an error.438have a 'signing_key' set, it raises an error.
420439
421440
=== modified file 'lib/lp/archivepublisher/tests/test_publisher.py'
--- lib/lp/archivepublisher/tests/test_publisher.py 2015-04-09 05:16:37 +0000
+++ lib/lp/archivepublisher/tests/test_publisher.py 2015-09-25 11:13:31 +0000
@@ -2183,6 +2183,10 @@
2183 return os.path.join(self.suite_path, 'Release.gpg')2183 return os.path.join(self.suite_path, 'Release.gpg')
21842184
2185 @property2185 @property
2186 def inline_release_file_path(self):
2187 return os.path.join(self.suite_path, 'InRelease')
2188
2189 @property
2186 def public_key_path(self):2190 def public_key_path(self):
2187 return os.path.join(2191 return os.path.join(
2188 self.archive_publisher._config.distsroot, 'key.gpg')2192 self.archive_publisher._config.distsroot, 'key.gpg')
@@ -2206,7 +2210,8 @@
2206 """Check publisher behaviour when signing repositories.2210 """Check publisher behaviour when signing repositories.
22072211
2208 When the 'signing_key' is available every modified suite Release2212 When the 'signing_key' is available every modified suite Release
2209 file gets signed with a detached signature name 'Release.gpg'.2213 file gets signed with a detached signature name 'Release.gpg' and
2214 a clearsigned file name 'InRelease'.
2210 """2215 """
2211 cprov = getUtility(IPersonSet).getByName('cprov')2216 cprov = getUtility(IPersonSet).getByName('cprov')
2212 self.assertTrue(cprov.archive.signing_key is None)2217 self.assertTrue(cprov.archive.signing_key is None)
@@ -2222,19 +2227,31 @@
22222227
2223 self._publishArchive(cprov.archive)2228 self._publishArchive(cprov.archive)
22242229
2225 # Both, Release and Release.gpg exist.2230 # All of Release, Release.gpg, and InRelease exist.
2226 self.assertTrue(os.path.exists(self.release_file_path))2231 self.assertTrue(os.path.exists(self.release_file_path))
2227 self.assertTrue(os.path.exists(self.release_file_signature_path))2232 self.assertTrue(os.path.exists(self.release_file_signature_path))
2233 self.assertTrue(os.path.exists(self.inline_release_file_path))
22282234
2229 # Release file signature is correct and was done by Celso's PPA2235 # Release file signature is correct and was done by Celso's PPA
2230 # signing_key.2236 # signing_key.
2231 with open(self.release_file_path) as release_file:2237 with open(self.release_file_path) as release_file:
2238 release_content = release_file.read()
2232 with open(self.release_file_signature_path) as release_file_sig:2239 with open(self.release_file_signature_path) as release_file_sig:
2233 signature = getUtility(IGPGHandler).getVerifiedSignature(2240 signature = getUtility(IGPGHandler).getVerifiedSignature(
2234 release_file.read(), release_file_sig.read())2241 release_content, release_file_sig.read())
2235 self.assertEqual(2242 self.assertEqual(
2236 cprov.archive.signing_key.fingerprint, signature.fingerprint)2243 cprov.archive.signing_key.fingerprint, signature.fingerprint)
22372244
2245 # InRelease file signature and content are correct, and the
2246 # signature was done by Celso's PPA signing_key.
2247 with open(self.inline_release_file_path) as inline_release_file:
2248 inline_signature = getUtility(IGPGHandler).getVerifiedSignature(
2249 inline_release_file.read())
2250 self.assertEqual(
2251 inline_signature.fingerprint,
2252 cprov.archive.signing_key.fingerprint)
2253 self.assertEqual(release_content, inline_signature.plain_data)
2254
2238 # All done, turn test-keyserver off.2255 # All done, turn test-keyserver off.
2239 tac.tearDown()2256 tac.tearDown()
22402257