Commit 73314774 authored by David Woodhouse's avatar David Woodhouse Committed by David Howells

modsign: Add explicit CONFIG_SYSTEM_TRUSTED_KEYS option

Let the user explicitly provide a file containing trusted keys, instead of
just automatically finding files matching *.x509 in the build tree and
trusting whatever we find. This really ought to be an *explicit*
configuration, and the build rules for dealing with the files were
fairly painful too.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent fb117949
...@@ -88,6 +88,7 @@ This has a number of options available: ...@@ -88,6 +88,7 @@ This has a number of options available:
than being a module) so that modules signed with that algorithm can have than being a module) so that modules signed with that algorithm can have
their signatures checked without causing a dependency loop. their signatures checked without causing a dependency loop.
(4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY) (4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY)
Setting this option to something other than its default of Setting this option to something other than its default of
...@@ -104,6 +105,13 @@ This has a number of options available: ...@@ -104,6 +105,13 @@ This has a number of options available:
means of the KBUILD_SIGN_PIN variable. means of the KBUILD_SIGN_PIN variable.
(5) "Additional X.509 keys for default system keyring" (CONFIG_SYSTEM_TRUSTED_KEYS)
This option can be set to the filename of a PEM-encoded file containing
additional certificates which will be included in the system keyring by
default.
======================= =======================
GENERATING SIGNING KEYS GENERATING SIGNING KEYS
======================= =======================
...@@ -171,10 +179,9 @@ in a keyring called ".system_keyring" that can be seen by: ...@@ -171,10 +179,9 @@ in a keyring called ".system_keyring" that can be seen by:
302d2d52 I------ 1 perm 1f010000 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 [] 302d2d52 I------ 1 perm 1f010000 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
... ...
Beyond the public key generated specifically for module signing, any file Beyond the public key generated specifically for module signing, additional
placed in the kernel source root directory or the kernel build root directory trusted certificates can be provided in a PEM-encoded file referenced by the
whose name is suffixed with ".x509" will be assumed to be an X.509 public key CONFIG_SYSTEM_TRUSTED_KEYS configuration option.
and will be added to the keyring.
Further, the architecture code may take public keys from a hardware store and Further, the architecture code may take public keys from a hardware store and
add those in also (e.g. from the UEFI key database). add those in also (e.g. from the UEFI key database).
......
...@@ -1752,6 +1752,19 @@ config SYSTEM_TRUSTED_KEYRING ...@@ -1752,6 +1752,19 @@ config SYSTEM_TRUSTED_KEYRING
Keys in this keyring are used by module signature checking. Keys in this keyring are used by module signature checking.
config SYSTEM_TRUSTED_KEYS
string "Additional X.509 keys for default system keyring"
depends on SYSTEM_TRUSTED_KEYRING
help
If set, this option should be the filename of a PEM-formatted file
containing trusted X.509 certificates to be included in the default
system keyring. Any certificate used for module signing is implicitly
also trusted.
NOTE: If you previously provided keys for the system keyring in the
form of DER-encoded *.x509 files in the top-level build directory,
those are no longer used. You will need to set this option instead.
config SYSTEM_DATA_VERIFICATION config SYSTEM_DATA_VERIFICATION
def_bool n def_bool n
select SYSTEM_TRUSTED_KEYRING select SYSTEM_TRUSTED_KEYRING
......
...@@ -114,46 +114,75 @@ $(obj)/config_data.h: $(obj)/config_data.gz FORCE ...@@ -114,46 +114,75 @@ $(obj)/config_data.h: $(obj)/config_data.gz FORCE
############################################################################### ###############################################################################
# #
# Roll all the X.509 certificates that we can find together and pull them into # When a Kconfig string contains a filename, it is suitable for
# the kernel so that they get loaded into the system trusted keyring during # passing to shell commands. It is surrounded by double-quotes, and
# boot. # any double-quotes or backslashes within it are escaped by
# backslashes.
# #
# We look in the source root and the build root for all files whose name ends # This is no use for dependencies or $(wildcard). We need to strip the
# in ".x509". Unfortunately, this will generate duplicate filenames, so we # surrounding quotes and the escaping from quotes and backslashes, and
# have make canonicalise the pathnames and then sort them to discard the # we *do* need to escape any spaces in the string. So, for example:
# duplicates. #
# Usage: $(eval $(call config_filename,FOO))
#
# Defines FOO_FILENAME based on the contents of the CONFIG_FOO option,
# transformed as described above to be suitable for use within the
# makefile.
#
# Also, if the filename is a relative filename and exists in the source
# tree but not the build tree, define FOO_SRCPREFIX as $(srctree)/ to
# be prefixed to *both* command invocation and dependencies.
#
# Note: We also print the filenames in the quiet_cmd_foo text, and
# perhaps ought to have a version specially escaped for that purpose.
# But it's only cosmetic, and $(patsubst "%",%,$(CONFIG_FOO)) is good
# enough. It'll strip the quotes in the common case where there's no
# space and it's a simple filename, and it'll retain the quotes when
# there's a space. There are some esoteric cases in which it'll print
# the wrong thing, but we don't really care. The actual dependencies
# and commands *do* get it right, with various combinations of single
# and double quotes, backslashes and spaces in the filenames.
# #
############################################################################### ###############################################################################
ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) #
X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509) quote := $(firstword " ")
X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += $(objtree)/signing_key.x509 space :=
X509_CERTIFICATES-raw := $(sort $(foreach CERT,$(X509_CERTIFICATES-y), \ space +=
$(or $(realpath $(CERT)),$(CERT)))) space_escape := %%%SPACE%%%
X509_CERTIFICATES := $(subst $(realpath $(objtree))/,,$(X509_CERTIFICATES-raw)) #
define config_filename =
ifeq ($(X509_CERTIFICATES),) ifneq ($$(CONFIG_$(1)),"")
$(warning *** No X.509 certificates found ***) $(1)_FILENAME := $$(subst \\,\,$$(subst \$$(quote),$$(quote),$$(subst $$(space_escape),\$$(space),$$(patsubst "%",%,$$(subst $$(space),$$(space_escape),$$(CONFIG_$(1)))))))
ifneq ($$(patsubst /%,%,$$(firstword $$($(1)_FILENAME))),$$(firstword $$($(1)_FILENAME)))
else
ifeq ($$(wildcard $$($(1)_FILENAME)),)
ifneq ($$(wildcard $$(srctree)/$$($(1)_FILENAME)),)
$(1)_SRCPREFIX := $(srctree)/
endif
endif endif
ifneq ($(wildcard $(obj)/.x509.list),)
ifneq ($(shell cat $(obj)/.x509.list),$(X509_CERTIFICATES))
$(warning X.509 certificate list changed to "$(X509_CERTIFICATES)" from "$(shell cat $(obj)/.x509.list)")
$(shell rm $(obj)/.x509.list)
endif endif
endif endif
endef
#
###############################################################################
ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
$(eval $(call config_filename,SYSTEM_TRUSTED_KEYS))
SIGNING_X509-$(CONFIG_MODULE_SIG) += signing_key.x509
kernel/system_certificates.o: $(obj)/x509_certificate_list kernel/system_certificates.o: $(obj)/x509_certificate_list
quiet_cmd_x509certs = CERTS $@ quiet_cmd_x509certs = CERTS $(SIGNING_X509-y) $(patsubst "%",%,$(2))
cmd_x509certs = cat $(X509_CERTIFICATES) /dev/null >$@ $(foreach X509,$(X509_CERTIFICATES),; $(kecho) " - Including cert $(X509)") cmd_x509certs = ( cat $(SIGNING_X509-y) /dev/null; \
awk '/-----BEGIN CERTIFICATE-----/{flag=1;next}/-----END CERTIFICATE-----/{flag=0}flag' $(2) /dev/null | base64 -d ) > $@ || ( rm $@; exit 1)
targets += $(obj)/x509_certificate_list targets += $(obj)/x509_certificate_list
$(obj)/x509_certificate_list: $(X509_CERTIFICATES) $(obj)/.x509.list $(obj)/x509_certificate_list: $(SIGNING_X509-y) include/config/system/trusted/keys.h $(wildcard include/config/module/sig.h) $(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(SYSTEM_TRUSTED_KEYS_FILENAME)
$(call if_changed,x509certs) $(call if_changed,x509certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS))
targets += $(obj)/.x509.list
$(obj)/.x509.list:
@echo $(X509_CERTIFICATES) >$@
endif endif
clean-files := x509_certificate_list .x509.list clean-files := x509_certificate_list .x509.list
...@@ -212,40 +241,16 @@ x509.genkey: ...@@ -212,40 +241,16 @@ x509.genkey:
@echo >>x509.genkey "authorityKeyIdentifier=keyid" @echo >>x509.genkey "authorityKeyIdentifier=keyid"
endif endif
# We need to obtain the certificate from CONFIG_MODULE_SIG_KEY. $(eval $(call config_filename,MODULE_SIG_KEY))
quiet_cmd_extract_der = CERT_DER $(2)
cmd_extract_der = scripts/extract-cert "$(2)" signing_key.x509
# CONFIG_MODULE_SIG_KEY is either a PKCS#11 URI or a filename. It is # If CONFIG_MODULE_SIG_KEY isn't a PKCS#11 URI, depend on it
# surrounded by quotes, and may contain spaces. To strip the quotes ifeq ($(patsubst pkcs11:%,%,$(firstword $(MODULE_SIG_KEY_FILENAME))),$(firstword $(MODULE_SIG_KEY_FILENAME)))
# with $(patsubst) we need to turn the spaces into something else. X509_DEP := $(MODULE_SIG_KEY_SRCPREFIX)$(MODULE_SIG_KEY_FILENAME)
# And if it's a filename, those spaces need to be escaped as '\ ' in
# order to use it in dependencies or $(wildcard).
space :=
space +=
space_escape := %%%SPACE%%%
X509_SOURCE_temp := $(subst $(space),$(space_escape),$(CONFIG_MODULE_SIG_KEY))
# We need this to check for absolute paths or PKCS#11 URIs.
X509_SOURCE_ONEWORD := $(patsubst "%",%,$(X509_SOURCE_temp))
# This is the actual source filename/URI without the quotes
X509_SOURCE := $(subst $(space_escape),$(space),$(X509_SOURCE_ONEWORD))
# This\ version\ with\ spaces\ escaped\ for\ $(wildcard)\ and\ dependencies
X509_SOURCE_ESCAPED := $(subst $(space_escape),\$(space),$(X509_SOURCE_ONEWORD))
ifeq ($(patsubst pkcs11:%,%,$(X509_SOURCE_ONEWORD)),$(X509_SOURCE_ONEWORD))
# If it's a filename, depend on it.
X509_DEP := $(X509_SOURCE_ESCAPED)
ifeq ($(patsubst /%,%,$(X509_SOURCE_ONEWORD)),$(X509_SOURCE_ONEWORD))
ifeq ($(wildcard $(X509_SOURCE_ESCAPED)),)
ifneq ($(wildcard $(srctree)/$(X509_SOURCE_ESCAPED)),)
# Non-absolute filename, found in source tree and not build tree
X509_SOURCE := $(srctree)/$(X509_SOURCE)
X509_DEP := $(srctree)/$(X509_SOURCE_ESCAPED)
endif
endif
endif
endif endif
quiet_cmd_extract_der = SIGNING_CERT $(patsubst "%",%,$(2))
cmd_extract_der = scripts/extract-cert $(2) signing_key.x509
signing_key.x509: scripts/extract-cert include/config/module/sig/key.h $(X509_DEP) signing_key.x509: scripts/extract-cert include/config/module/sig/key.h $(X509_DEP)
$(call cmd,extract_der,$(X509_SOURCE)) $(call cmd,extract_der,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY))
endif endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment