diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2015-07-20 16:16:31 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2015-08-07 11:26:14 -0400 |
commit | 99d27b1b52bd5cdf9bd9f7661ca8641e9a1b55e6 (patch) | |
tree | 8525b8bd99f20016d7e893fa4218951a0b249364 | |
parent | fb1179499134bc718dc7557c7a6a95dc72f224cb (diff) |
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.
Fix applied from James Morris that removes an '=' from a macro definition
in kernel/Makefile as this is a feature that only exists from GNU make 3.82
onwards.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | Documentation/module-signing.txt | 15 | ||||
-rw-r--r-- | init/Kconfig | 13 | ||||
-rw-r--r-- | kernel/Makefile | 125 |
3 files changed, 89 insertions, 64 deletions
diff --git a/Documentation/module-signing.txt b/Documentation/module-signing.txt index 5d5e4e32dc26..4e62bc29666e 100644 --- a/Documentation/module-signing.txt +++ b/Documentation/module-signing.txt | |||
@@ -88,6 +88,7 @@ This has a number of options available: | |||
88 | than being a module) so that modules signed with that algorithm can have | 88 | than being a module) so that modules signed with that algorithm can have |
89 | their signatures checked without causing a dependency loop. | 89 | their signatures checked without causing a dependency loop. |
90 | 90 | ||
91 | |||
91 | (4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY) | 92 | (4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY) |
92 | 93 | ||
93 | Setting this option to something other than its default of | 94 | Setting this option to something other than its default of |
@@ -104,6 +105,13 @@ This has a number of options available: | |||
104 | means of the KBUILD_SIGN_PIN variable. | 105 | means of the KBUILD_SIGN_PIN variable. |
105 | 106 | ||
106 | 107 | ||
108 | (5) "Additional X.509 keys for default system keyring" (CONFIG_SYSTEM_TRUSTED_KEYS) | ||
109 | |||
110 | This option can be set to the filename of a PEM-encoded file containing | ||
111 | additional certificates which will be included in the system keyring by | ||
112 | default. | ||
113 | |||
114 | |||
107 | ======================= | 115 | ======================= |
108 | GENERATING SIGNING KEYS | 116 | GENERATING SIGNING KEYS |
109 | ======================= | 117 | ======================= |
@@ -171,10 +179,9 @@ in a keyring called ".system_keyring" that can be seen by: | |||
171 | 302d2d52 I------ 1 perm 1f010000 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 [] | 179 | 302d2d52 I------ 1 perm 1f010000 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 [] |
172 | ... | 180 | ... |
173 | 181 | ||
174 | Beyond the public key generated specifically for module signing, any file | 182 | Beyond the public key generated specifically for module signing, additional |
175 | placed in the kernel source root directory or the kernel build root directory | 183 | trusted certificates can be provided in a PEM-encoded file referenced by the |
176 | whose name is suffixed with ".x509" will be assumed to be an X.509 public key | 184 | CONFIG_SYSTEM_TRUSTED_KEYS configuration option. |
177 | and will be added to the keyring. | ||
178 | 185 | ||
179 | Further, the architecture code may take public keys from a hardware store and | 186 | Further, the architecture code may take public keys from a hardware store and |
180 | add those in also (e.g. from the UEFI key database). | 187 | add those in also (e.g. from the UEFI key database). |
diff --git a/init/Kconfig b/init/Kconfig index 2b119850784b..62b725653c36 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1752,6 +1752,19 @@ config SYSTEM_TRUSTED_KEYRING | |||
1752 | 1752 | ||
1753 | Keys in this keyring are used by module signature checking. | 1753 | Keys in this keyring are used by module signature checking. |
1754 | 1754 | ||
1755 | config SYSTEM_TRUSTED_KEYS | ||
1756 | string "Additional X.509 keys for default system keyring" | ||
1757 | depends on SYSTEM_TRUSTED_KEYRING | ||
1758 | help | ||
1759 | If set, this option should be the filename of a PEM-formatted file | ||
1760 | containing trusted X.509 certificates to be included in the default | ||
1761 | system keyring. Any certificate used for module signing is implicitly | ||
1762 | also trusted. | ||
1763 | |||
1764 | NOTE: If you previously provided keys for the system keyring in the | ||
1765 | form of DER-encoded *.x509 files in the top-level build directory, | ||
1766 | those are no longer used. You will need to set this option instead. | ||
1767 | |||
1755 | config SYSTEM_DATA_VERIFICATION | 1768 | config SYSTEM_DATA_VERIFICATION |
1756 | def_bool n | 1769 | def_bool n |
1757 | select SYSTEM_TRUSTED_KEYRING | 1770 | select SYSTEM_TRUSTED_KEYRING |
diff --git a/kernel/Makefile b/kernel/Makefile index 7453283981ca..575329777d9e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -114,46 +114,75 @@ $(obj)/config_data.h: $(obj)/config_data.gz FORCE | |||
114 | 114 | ||
115 | ############################################################################### | 115 | ############################################################################### |
116 | # | 116 | # |
117 | # Roll all the X.509 certificates that we can find together and pull them into | 117 | # When a Kconfig string contains a filename, it is suitable for |
118 | # the kernel so that they get loaded into the system trusted keyring during | 118 | # passing to shell commands. It is surrounded by double-quotes, and |
119 | # boot. | 119 | # any double-quotes or backslashes within it are escaped by |
120 | # backslashes. | ||
120 | # | 121 | # |
121 | # We look in the source root and the build root for all files whose name ends | 122 | # This is no use for dependencies or $(wildcard). We need to strip the |
122 | # in ".x509". Unfortunately, this will generate duplicate filenames, so we | 123 | # surrounding quotes and the escaping from quotes and backslashes, and |
123 | # have make canonicalise the pathnames and then sort them to discard the | 124 | # we *do* need to escape any spaces in the string. So, for example: |
124 | # duplicates. | 125 | # |
126 | # Usage: $(eval $(call config_filename,FOO)) | ||
127 | # | ||
128 | # Defines FOO_FILENAME based on the contents of the CONFIG_FOO option, | ||
129 | # transformed as described above to be suitable for use within the | ||
130 | # makefile. | ||
131 | # | ||
132 | # Also, if the filename is a relative filename and exists in the source | ||
133 | # tree but not the build tree, define FOO_SRCPREFIX as $(srctree)/ to | ||
134 | # be prefixed to *both* command invocation and dependencies. | ||
135 | # | ||
136 | # Note: We also print the filenames in the quiet_cmd_foo text, and | ||
137 | # perhaps ought to have a version specially escaped for that purpose. | ||
138 | # But it's only cosmetic, and $(patsubst "%",%,$(CONFIG_FOO)) is good | ||
139 | # enough. It'll strip the quotes in the common case where there's no | ||
140 | # space and it's a simple filename, and it'll retain the quotes when | ||
141 | # there's a space. There are some esoteric cases in which it'll print | ||
142 | # the wrong thing, but we don't really care. The actual dependencies | ||
143 | # and commands *do* get it right, with various combinations of single | ||
144 | # and double quotes, backslashes and spaces in the filenames. | ||
125 | # | 145 | # |
126 | ############################################################################### | 146 | ############################################################################### |
127 | ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) | 147 | # |
128 | X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509) | 148 | quote := $(firstword " ") |
129 | X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += $(objtree)/signing_key.x509 | 149 | space := |
130 | X509_CERTIFICATES-raw := $(sort $(foreach CERT,$(X509_CERTIFICATES-y), \ | 150 | space += |
131 | $(or $(realpath $(CERT)),$(CERT)))) | 151 | space_escape := %%%SPACE%%% |
132 | X509_CERTIFICATES := $(subst $(realpath $(objtree))/,,$(X509_CERTIFICATES-raw)) | 152 | # |
133 | 153 | define config_filename | |
134 | ifeq ($(X509_CERTIFICATES),) | 154 | ifneq ($$(CONFIG_$(1)),"") |
135 | $(warning *** No X.509 certificates found ***) | 155 | $(1)_FILENAME := $$(subst \\,\,$$(subst \$$(quote),$$(quote),$$(subst $$(space_escape),\$$(space),$$(patsubst "%",%,$$(subst $$(space),$$(space_escape),$$(CONFIG_$(1))))))) |
156 | ifneq ($$(patsubst /%,%,$$(firstword $$($(1)_FILENAME))),$$(firstword $$($(1)_FILENAME))) | ||
157 | else | ||
158 | ifeq ($$(wildcard $$($(1)_FILENAME)),) | ||
159 | ifneq ($$(wildcard $$(srctree)/$$($(1)_FILENAME)),) | ||
160 | $(1)_SRCPREFIX := $(srctree)/ | ||
161 | endif | ||
136 | endif | 162 | endif |
137 | |||
138 | ifneq ($(wildcard $(obj)/.x509.list),) | ||
139 | ifneq ($(shell cat $(obj)/.x509.list),$(X509_CERTIFICATES)) | ||
140 | $(warning X.509 certificate list changed to "$(X509_CERTIFICATES)" from "$(shell cat $(obj)/.x509.list)") | ||
141 | $(shell rm $(obj)/.x509.list) | ||
142 | endif | 163 | endif |
143 | endif | 164 | endif |
165 | endef | ||
166 | # | ||
167 | ############################################################################### | ||
168 | |||
169 | |||
170 | ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) | ||
171 | |||
172 | $(eval $(call config_filename,SYSTEM_TRUSTED_KEYS)) | ||
173 | |||
174 | SIGNING_X509-$(CONFIG_MODULE_SIG) += signing_key.x509 | ||
144 | 175 | ||
145 | kernel/system_certificates.o: $(obj)/x509_certificate_list | 176 | kernel/system_certificates.o: $(obj)/x509_certificate_list |
146 | 177 | ||
147 | quiet_cmd_x509certs = CERTS $@ | 178 | quiet_cmd_x509certs = CERTS $(SIGNING_X509-y) $(patsubst "%",%,$(2)) |
148 | cmd_x509certs = cat $(X509_CERTIFICATES) /dev/null >$@ $(foreach X509,$(X509_CERTIFICATES),; $(kecho) " - Including cert $(X509)") | 179 | cmd_x509certs = ( cat $(SIGNING_X509-y) /dev/null; \ |
180 | awk '/-----BEGIN CERTIFICATE-----/{flag=1;next}/-----END CERTIFICATE-----/{flag=0}flag' $(2) /dev/null | base64 -d ) > $@ || ( rm $@; exit 1) | ||
149 | 181 | ||
150 | targets += $(obj)/x509_certificate_list | 182 | targets += $(obj)/x509_certificate_list |
151 | $(obj)/x509_certificate_list: $(X509_CERTIFICATES) $(obj)/.x509.list | 183 | $(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) |
152 | $(call if_changed,x509certs) | 184 | $(call if_changed,x509certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS)) |
153 | 185 | ||
154 | targets += $(obj)/.x509.list | ||
155 | $(obj)/.x509.list: | ||
156 | @echo $(X509_CERTIFICATES) >$@ | ||
157 | endif | 186 | endif |
158 | 187 | ||
159 | clean-files := x509_certificate_list .x509.list | 188 | clean-files := x509_certificate_list .x509.list |
@@ -212,40 +241,16 @@ x509.genkey: | |||
212 | @echo >>x509.genkey "authorityKeyIdentifier=keyid" | 241 | @echo >>x509.genkey "authorityKeyIdentifier=keyid" |
213 | endif | 242 | endif |
214 | 243 | ||
215 | # We need to obtain the certificate from CONFIG_MODULE_SIG_KEY. | 244 | $(eval $(call config_filename,MODULE_SIG_KEY)) |
216 | quiet_cmd_extract_der = CERT_DER $(2) | ||
217 | cmd_extract_der = scripts/extract-cert "$(2)" signing_key.x509 | ||
218 | 245 | ||
219 | # CONFIG_MODULE_SIG_KEY is either a PKCS#11 URI or a filename. It is | 246 | # If CONFIG_MODULE_SIG_KEY isn't a PKCS#11 URI, depend on it |
220 | # surrounded by quotes, and may contain spaces. To strip the quotes | 247 | ifeq ($(patsubst pkcs11:%,%,$(firstword $(MODULE_SIG_KEY_FILENAME))),$(firstword $(MODULE_SIG_KEY_FILENAME))) |
221 | # with $(patsubst) we need to turn the spaces into something else. | 248 | X509_DEP := $(MODULE_SIG_KEY_SRCPREFIX)$(MODULE_SIG_KEY_FILENAME) |
222 | # And if it's a filename, those spaces need to be escaped as '\ ' in | ||
223 | # order to use it in dependencies or $(wildcard). | ||
224 | space := | ||
225 | space += | ||
226 | space_escape := %%%SPACE%%% | ||
227 | X509_SOURCE_temp := $(subst $(space),$(space_escape),$(CONFIG_MODULE_SIG_KEY)) | ||
228 | # We need this to check for absolute paths or PKCS#11 URIs. | ||
229 | X509_SOURCE_ONEWORD := $(patsubst "%",%,$(X509_SOURCE_temp)) | ||
230 | # This is the actual source filename/URI without the quotes | ||
231 | X509_SOURCE := $(subst $(space_escape),$(space),$(X509_SOURCE_ONEWORD)) | ||
232 | # This\ version\ with\ spaces\ escaped\ for\ $(wildcard)\ and\ dependencies | ||
233 | X509_SOURCE_ESCAPED := $(subst $(space_escape),\$(space),$(X509_SOURCE_ONEWORD)) | ||
234 | |||
235 | ifeq ($(patsubst pkcs11:%,%,$(X509_SOURCE_ONEWORD)),$(X509_SOURCE_ONEWORD)) | ||
236 | # If it's a filename, depend on it. | ||
237 | X509_DEP := $(X509_SOURCE_ESCAPED) | ||
238 | ifeq ($(patsubst /%,%,$(X509_SOURCE_ONEWORD)),$(X509_SOURCE_ONEWORD)) | ||
239 | ifeq ($(wildcard $(X509_SOURCE_ESCAPED)),) | ||
240 | ifneq ($(wildcard $(srctree)/$(X509_SOURCE_ESCAPED)),) | ||
241 | # Non-absolute filename, found in source tree and not build tree | ||
242 | X509_SOURCE := $(srctree)/$(X509_SOURCE) | ||
243 | X509_DEP := $(srctree)/$(X509_SOURCE_ESCAPED) | ||
244 | endif | ||
245 | endif | ||
246 | endif | ||
247 | endif | 249 | endif |
248 | 250 | ||
251 | quiet_cmd_extract_der = SIGNING_CERT $(patsubst "%",%,$(2)) | ||
252 | cmd_extract_der = scripts/extract-cert $(2) signing_key.x509 | ||
253 | |||
249 | signing_key.x509: scripts/extract-cert include/config/module/sig/key.h $(X509_DEP) | 254 | signing_key.x509: scripts/extract-cert include/config/module/sig/key.h $(X509_DEP) |
250 | $(call cmd,extract_der,$(X509_SOURCE)) | 255 | $(call cmd,extract_der,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY)) |
251 | endif | 256 | endif |