launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #20589
[Merge] lp:~apw/launchpad/signing-record-public-keys-when-used into lp:launchpad
Andy Whitcroft has proposed merging lp:~apw/launchpad/signing-record-public-keys-when-used into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~apw/launchpad/signing-record-public-keys-when-used/+merge/296678
Publish the public components of any keys used when signing elements of a raw-signing upload. These public components are published into control/ within the published upload ensuring they are included in the checksum files allowing verification of these keys.
At the same time move the incoming raw-signing.options options file into control/ so that all control information is kept in one directory reducing namespace pollution in the upload. This is deliberately not backwards compatible as there are no existing users of this functionality.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~apw/launchpad/signing-record-public-keys-when-used into lp:launchpad.
=== modified file 'lib/lp/archivepublisher/signing.py'
--- lib/lp/archivepublisher/signing.py 2016-06-06 16:53:57 +0000
+++ lib/lp/archivepublisher/signing.py 2016-06-07 14:29:40 +0000
@@ -20,6 +20,7 @@
import os
import shutil
+import stat
import subprocess
import tarfile
import tempfile
@@ -104,12 +105,30 @@
dists_signed, "%s-%s" % (self.package, self.arch))
self.archiveroot = pubconf.archiveroot
+ self.public_keys = []
+
+ def publishPublicKey(self, key):
+ """Record this key as having been used in this upload."""
+ if key not in self.public_keys:
+ self.public_keys.append(key)
+
+ def copyPublishedPublicKeys(self):
+ """Copy out published keys into the custom upload."""
+ keydir = os.path.join(self.tmpdir, self.version, "control")
+ if not os.path.exists(keydir):
+ os.makedirs(keydir)
+ for key in self.public_keys:
+ # Ensure we only emit files which are world readable.
+ if stat.S_IMODE(os.stat(key).st_mode) & stat.S_IROTH:
+ shutil.copy(key, os.path.join(keydir, os.path.basename(key)))
+
def setSigningOptions(self):
- """Find and extract raw-signing.options from the tarball."""
+ """Find and extract raw-signing options from the tarball."""
self.signing_options = {}
+ # Look for an options file in the top level control directory.
options_file = os.path.join(self.tmpdir, self.version,
- "raw-signing.options")
+ "control", "options")
if not os.path.exists(options_file):
return
@@ -202,6 +221,7 @@
self.uefi_key, self.uefi_cert)
if not key or not cert:
return
+ self.publishPublicKey(cert)
cmdl = ["sbsign", "--key", key, "--cert", cert, image]
return self.callLog("UEFI signing", cmdl)
@@ -265,6 +285,7 @@
self.kmod_pem, self.kmod_x509)
if not pem or not cert:
return
+ self.publishPublicKey(cert)
cmdl = ["kmodsign", "-D", "sha512", pem, cert, image, image + ".sig"]
return self.callLog("Kmod signing", cmdl)
@@ -303,6 +324,9 @@
'signed-only' in self.signing_options):
os.unlink(filename)
+ # Copy out the public keys where they were used.
+ self.copyPublishedPublicKeys()
+
# If tarball output is requested, tar up the results.
if 'tarball' in self.signing_options:
self.convertToTarball()
=== modified file 'lib/lp/archivepublisher/tests/test_signing.py'
--- lib/lp/archivepublisher/tests/test_signing.py 2016-06-06 14:26:00 +0000
+++ lib/lp/archivepublisher/tests/test_signing.py 2016-06-07 14:29:40 +0000
@@ -235,7 +235,7 @@
# If the configured key/cert are missing, processing succeeds but
# nothing is signed.
self.openArchive("test", "1.0", "amd64")
- self.archive.add_file("1.0/raw-signing.options", "")
+ self.archive.add_file("1.0/control/options", "")
upload = self.process_emulate()
self.assertContentEqual([], upload.signing_options.keys())
@@ -243,7 +243,7 @@
# If the configured key/cert are missing, processing succeeds but
# nothing is signed.
self.openArchive("test", "1.0", "amd64")
- self.archive.add_file("1.0/raw-signing.options", "first\n")
+ self.archive.add_file("1.0/control/options", "first\n")
upload = self.process_emulate()
self.assertContentEqual(['first'], upload.signing_options.keys())
@@ -251,7 +251,7 @@
# If the configured key/cert are missing, processing succeeds but
# nothing is signed.
self.openArchive("test", "1.0", "amd64")
- self.archive.add_file("1.0/raw-signing.options", "first\nsecond\n")
+ self.archive.add_file("1.0/control/options", "first\nsecond\n")
upload = self.process_emulate()
self.assertContentEqual(['first', 'second'],
upload.signing_options.keys())
@@ -279,7 +279,7 @@
self.setUpUefiKeys()
self.setUpKmodKeys()
self.openArchive("test", "1.0", "amd64")
- self.archive.add_file("1.0/raw-signing.options", "tarball")
+ self.archive.add_file("1.0/control/options", "tarball")
self.archive.add_file("1.0/empty.efi", "")
self.archive.add_file("1.0/empty.ko", "")
self.process_emulate()
@@ -292,8 +292,10 @@
self.assertTrue(os.path.exists(tarfilename))
with tarfile.open(tarfilename) as tarball:
self.assertContentEqual([
- '1.0', '1.0/empty.efi', '1.0/empty.efi.signed', '1.0/empty.ko',
- '1.0/empty.ko.sig', '1.0/raw-signing.options',
+ '1.0', '1.0/control', '1.0/control/kmod.x509',
+ '1.0/control/uefi.crt', '1.0/empty.efi',
+ '1.0/empty.efi.signed', '1.0/empty.ko', '1.0/empty.ko.sig',
+ '1.0/control/options',
], tarball.getnames())
def test_options_signed_only(self):
@@ -302,7 +304,7 @@
self.setUpUefiKeys()
self.setUpKmodKeys()
self.openArchive("test", "1.0", "amd64")
- self.archive.add_file("1.0/raw-signing.options", "signed-only")
+ self.archive.add_file("1.0/control/options", "signed-only")
self.archive.add_file("1.0/empty.efi", "")
self.archive.add_file("1.0/empty.ko", "")
self.process_emulate()
@@ -322,7 +324,7 @@
self.setUpUefiKeys()
self.setUpKmodKeys()
self.openArchive("test", "1.0", "amd64")
- self.archive.add_file("1.0/raw-signing.options",
+ self.archive.add_file("1.0/control/options",
"tarball\nsigned-only")
self.archive.add_file("1.0/empty.efi", "")
self.archive.add_file("1.0/empty.ko", "")
@@ -332,8 +334,9 @@
self.assertTrue(os.path.exists(tarfilename))
with tarfile.open(tarfilename) as tarball:
self.assertContentEqual([
- '1.0', '1.0/empty.efi.signed', '1.0/empty.ko.sig',
- '1.0/raw-signing.options',
+ '1.0', '1.0/control', '1.0/control/kmod.x509',
+ '1.0/control/uefi.crt', '1.0/empty.efi.signed',
+ '1.0/empty.ko.sig', '1.0/control/options',
], tarball.getnames())
def test_no_signed_files(self):
Follow ups