[linux-signed] 02/05: Add skeleton of signing script and makefile rule
debian-kernel at lists.debian.org
debian-kernel at lists.debian.org
Mon Apr 4 18:39:11 UTC 2016
This is an automated email from the git hooks/post-receive script.
benh pushed a commit to branch master
in repository linux-signed.
commit d8162b29533038e4e5b779682f653370519a76a3
Author: Ben Hutchings <ben at decadent.org.uk>
Date: Sun Apr 3 20:38:03 2016 +0100
Add skeleton of signing script and makefile rule
---
debian/.gitignore | 1 +
debian/README.source | 46 ++++++++++++++++++++++
debian/bin/sign.py | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++
debian/rules | 8 +++-
debian/rules.defs | 7 ++++
debian/rules.real | 2 +
6 files changed, 167 insertions(+), 2 deletions(-)
diff --git a/debian/.gitignore b/debian/.gitignore
index 08f76f2..5eeee81 100644
--- a/debian/.gitignore
+++ b/debian/.gitignore
@@ -6,6 +6,7 @@
/control*
/files
/linux-image-*
+/localpackages/
/rules.gen
/source.lintian-overrides
/stamps/
diff --git a/debian/README.source b/debian/README.source
new file mode 100644
index 0000000..c8a9a31
--- /dev/null
+++ b/debian/README.source
@@ -0,0 +1,46 @@
+NOTE: This package can only be updated by the holder of a signing key
+trusted by the linux-image packages. This is currently Ben Hutchings,
+but in future will be the FTP masters.
+
+All signatures are made at source preparation time, not during a
+build. This avoids the need to expose signing keys to buildds and
+allows reproducible builds.
+
+When preparing a source package, you will need sbsigntool and the
+appropriate versions of the linux-kbuild and linux-support packages
+installed. All the linux-image package must have already been built
+(but not installed).
+
+To generate a key pair and *self-signed* certificate: for testing,
+run:
+
+ openssl genrsa -out foo.key.priv.pem 2048
+ openssl req -key foo.key.priv.pem -out foo.req.pem -new
+ openssl x509 -in foo.req.pem -req -signkey foo.key.priv.pem -out foo.cer.pem
+
+For module signing you need a DER fomat certificate, so add
+'-outform der' to the last comand.
+
+To generate the signatures:
+
+1. Uupdate debian/rules.defs:
+ - KERNEL_ABINAME: The kernel ABI name as included in all
+ linux-image package names, e.g. 4.5.0-trunk.
+ - KERNEL_IMAGE_VERSION: Version of the linux-image packages to be
+ signed.
+ - KERNEL_MODULES_PRIVKEY: Name of the private key file (RSA PEM
+ format) for module signing.
+ - KERNEL_MODULES_CERT: Name of the certificate file (X.509 PEM
+ format) for module signing. This file must also be included in
+ src:linux and listed in CONFIG_SYSTEM_TRUSTED_KEYS.
+ - KERNEL_IMAGE_PRIVKEY: Name of the private key file (RSA PEM
+ format) for image signing.
+ - KERNEL_IMAGE_CERT: Name of the certificate file (X.509 PEM
+ format) for image signing. This certificate must be trusted by
+ the boot loader for Secure Boot to work.
+2. If the packages are not yet publicly available (e.g. for a security
+ update), create debian/localpackages/ and copy or link them into
+ there.
+3. Run 'debian/rules sign'
+
+ -- Ben Hutchings <ben at decadent.org.uk>, Mon, 4 Apr 2016 16:48:16 +0100
diff --git a/debian/bin/sign.py b/debian/bin/sign.py
new file mode 100755
index 0000000..a2d3878
--- /dev/null
+++ b/debian/bin/sign.py
@@ -0,0 +1,105 @@
+#!/usr/bin/python3
+
+import sys
+sys.path.append(sys.argv[1] + "/lib/python")
+
+import os, os.path, shutil, tempfile
+
+from debian_linux.config import ConfigCoreDump
+from debian_linux.debian import VersionLinux
+
+def get_package(name, version, arch):
+ packages_dir = 'debian/localpackages/'
+ package_file = '%s/%s_%s_%s.deb' % (packages_dir, name, version, arch)
+ unpack_dir = '%s/%s_%s_%s' % (packages_dir, name, version, arch)
+
+ # FIXME Need a way to download for any architecture with signature
+ # verification
+ os.makedirs(packages_dir, exist_ok=True)
+ if not os.path.isfile(package_file):
+ if os.system('debsnap -d %s -f --binary -a %s %s %s' %
+ (packages_dir, arch, name, version)):
+ raise Exception('debsnap failed')
+
+ if not os.path.isdir(unpack_dir):
+ # Unpack to a temporary directory before moving into place, so we
+ # don't cache a half-unpacked package
+ unpack_temp_dir = unpack_dir + '.temp'
+ if os.path.isdir(unpack_temp_dir):
+ shutil.rmtree(unpack_temp_dir)
+ os.makedirs(unpack_temp_dir)
+ if os.system('dpkg-deb -x %s %s' % (package_file, unpack_temp_dir)):
+ raise Exception('dpkg-deb failed')
+ os.rename(unpack_temp_dir, unpack_dir)
+
+ return unpack_dir
+
+def sign_module(module_name, signature_name, privkey_name, cert_name):
+ print('Should sign module %s with %s/%s and detach signature as %s' %
+ (module_name, privkey_name, cert_name, signature_name))
+
+def sign_modules(modules_dir, signature_dir, privkey_name, cert_name):
+ for walk_dir, subdir_names, file_names in os.walk(modules_dir):
+ rel_dir = os.path.relpath(walk_dir, modules_dir)
+ for rel_name in file_names:
+ if rel_name.endswith('.ko'):
+ sign_module(os.path.join(walk_dir, rel_name),
+ os.path.join(signature_dir, rel_dir, rel_name) + '.sig',
+ privkey_name, cert_name)
+
+def sign_image_efi(image_name, signature_name, privkey_name, cert_name):
+ print('Should sign image %s with %s/%s and detach signature as %s' %
+ (image_name, privkey_name, cert_name, signature_name))
+
+def sign(config_name, imageversion_str, modules_privkey_name, modules_cert_name,
+ image_privkey_name, image_cert_name):
+ config = ConfigCoreDump(fp=open(config_name, 'rb'))
+ assert config['version',]['source'] == imageversion_str
+ abiname = config['version',]['abiname']
+ imageversion = VersionLinux(imageversion_str)
+
+ signature_dir = 'debian/signatures'
+ if os.path.isdir(signature_dir):
+ shutil.rmtree(signature_dir)
+
+ for arch in iter(config['base', ]['arches']):
+ for featureset in config['base', arch].get('featuresets', ()):
+ if not config.merge('base', None, featureset).get('enabled', True):
+ continue
+
+ for flavour in config['base', arch, featureset]['flavours']:
+ if not (config.merge('build', arch, featureset, flavour)
+ .get('signed-modules', False)):
+ continue
+
+ kernelversion = '%s%s-%s' % \
+ (abiname,
+ '' if featureset == 'none' else '-' + featureset,
+ flavour)
+ package_name = 'linux-image-' + kernelversion
+
+ package_dir = get_package(package_name, imageversion, arch)
+
+ signature_dir = os.path.join('debian/signatures', package_name)
+ os.makedirs(signature_dir)
+ sign_modules('%s/lib/modules/%s' % (package_dir, kernelversion),
+ '%s/lib/modules/%s' % (signature_dir, kernelversion),
+ modules_privkey_name, modules_cert_name)
+
+ # Currently we can only sign kernel images built with an
+ # EFI stub, which has space for an embedded signature.
+ with open(os.path.join(package_dir,
+ 'boot/config-%s' % kernelversion)) \
+ as kconfig:
+ if 'CONFIG_EFI_STUB=y\n' in kconfig:
+ sign_image_efi('%s/boot/vmlinuz-%s' %
+ (package_dir, kernelversion),
+ '%s/boot/vmlinuz-%s.sig' %
+ (signature_dir, kernelversion),
+ image_privkey_name,
+ image_cert_name)
+
+ print('Signatures should be committed: git add debian/signatures && git commit')
+
+if __name__ == '__main__':
+ sign(sys.argv[1] + "/config.defines.dump", *sys.argv[2:])
diff --git a/debian/rules b/debian/rules
index b2439ed..683359e 100755
--- a/debian/rules
+++ b/debian/rules
@@ -4,6 +4,7 @@ SHELL := sh -e
include debian/rules.defs
GENCONTROL = debian/bin/gencontrol.py
+SIGN = debian/bin/sign.py
DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
DEB_BUILD_ARCH := $(shell dpkg-architecture -qDEB_BUILD_ARCH)
@@ -60,9 +61,12 @@ binary-arch-all: debian/control $(BUILD_DIR)
$(MAKE) -f debian/rules.gen binary-arch
maintainerclean: clean
- rm -f debian/control debian/control.md5sum debian/rules.gen debian/*.bug-presubj
+ rm -rf debian/control debian/control.md5sum debian/rules.gen debian/*.bug-presubj debian/localpackages
# dh_clean won't deal with binary packages that no longer exist after
# removal of a flavour.
rm -rf $(filter-out %.config %.postinst %.templates %.NEWS, $(wildcard debian/linux-*))
-.PHONY: build build-arch build-indep clean binary binary-arch binary-indep binary-arch-all maintainerclean
+sign:
+ $(SIGN) /usr/src/linux-support-$(KERNEL_ABINAME) "$(KERNEL_IMAGE_VERSION)" "$(KERNEL_MODULES_PRIVKEY)" "$(KERNEL_MODULES_CERT)" "$(KERNEL_IMAGE_PRIVKEY)" "$(KERNEL_IMAGE_CERT)"
+
+.PHONY: build build-arch build-indep clean binary binary-arch binary-indep binary-arch-all maintainerclean sign
diff --git a/debian/rules.defs b/debian/rules.defs
index 2239bcc..4c20a16 100644
--- a/debian/rules.defs
+++ b/debian/rules.defs
@@ -3,3 +3,10 @@ STAMPS_DIR = debian/stamps
TEMPLATES_DIR = debian/templates
KERNEL_ABINAME := 4.5.0-trunk
KERNEL_IMAGE_VERSION := 4.5-1~exp2
+
+# For initial testing - to be replaced with HSM
+KERNEL_SIGNER := benh at debian.org
+KERNEL_MODULES_PRIVKEY := $(HOME)/.linux-modules-$(KERNEL_SIGNER).key.priv.pem
+KERNEL_MODULES_CERT = debian/certs/linux-modules-$(KERNEL_SIGNER).cert.pem
+KERNEL_IMAGE_PRIVKEY := $(HOME)/.linux-image-$(KERNEL_SIGNER).key.priv.pem
+KERNEL_IMAGE_CERT := debian/certs/linux-image-$(KERNEL_SIGNER).cert.pem
diff --git a/debian/rules.real b/debian/rules.real
index 339bd00..963912c 100644
--- a/debian/rules.real
+++ b/debian/rules.real
@@ -1,5 +1,7 @@
SHELL := bash -e
+include debian/rules.defs
+
build-indep:
install-signed: DH_OPTIONS = -p$(PACKAGE_NAME)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux-signed.git
More information about the Kernel-svn-changes
mailing list