Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull security subsystem updates from James Morris:
 "Highlights:

   - PKCS#7 support added to support signed kexec, also utilized for
     module signing.  See comments in 3f1e1bea.

     ** NOTE: this requires linking against the OpenSSL library, which
        must be installed, e.g.  the openssl-devel on Fedora **

   - Smack
      - add IPv6 host labeling; ignore labels on kernel threads
      - support smack labeling mounts which use binary mount data

   - SELinux:
      - add ioctl whitelisting (see
        http://kernsec.org/files/lss2015/vanderstoep.pdf)
      - fix mprotect PROT_EXEC regression caused by mm change

   - Seccomp:
      - add ptrace options for suspend/resume"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (57 commits)
  PKCS#7: Add OIDs for sha224, sha284 and sha512 hash algos and use them
  Documentation/Changes: Now need OpenSSL devel packages for module signing
  scripts: add extract-cert and sign-file to .gitignore
  modsign: Handle signing key in source tree
  modsign: Use if_changed rule for extracting cert from module signing key
  Move certificate handling to its own directory
  sign-file: Fix warning about BIO_reset() return value
  PKCS#7: Add MODULE_LICENSE() to test module
  Smack - Fix build error with bringup unconfigured
  sign-file: Document dependency on OpenSSL devel libraries
  PKCS#7: Appropriately restrict authenticated attributes and content type
  KEYS: Add a name for PKEY_ID_PKCS7
  PKCS#7: Improve and export the X.509 ASN.1 time object decoder
  modsign: Use extract-cert to process CONFIG_SYSTEM_TRUSTED_KEYS
  extract-cert: Cope with multiple X.509 certificates in a single file
  sign-file: Generate CMS message as signature instead of PKCS#7
  PKCS#7: Support CMS messages also [RFC5652]
  X.509: Change recorded SKID & AKID to not include Subject or Issuer
  PKCS#7: Check content type and versions
  MAINTAINERS: The keyrings mailing list has moved
  ...
This commit is contained in:
Linus Torvalds 2015-09-08 12:41:25 -07:00
commit b793c005ce
76 changed files with 3588 additions and 1407 deletions

1
.gitignore vendored
View file

@ -97,6 +97,7 @@ GTAGS
# Leavings from module signing
#
extra_certificates
signing_key.pem
signing_key.priv
signing_key.x509
x509.genkey

View file

@ -43,6 +43,7 @@ o udev 081 # udevd --version
o grub 0.93 # grub --version || grub-install --version
o mcelog 0.6 # mcelog --version
o iptables 1.4.2 # iptables -V
o openssl & libcrypto 1.0.1k # openssl version
Kernel compilation
@ -79,6 +80,17 @@ BC
You will need bc to build kernels 3.10 and higher
OpenSSL
-------
Module signing and external certificate handling use the OpenSSL program and
crypto library to do key creation and signature generation.
You will need openssl to build kernels 3.7 and higher if module signing is
enabled. You will also need openssl development packages to build kernels 4.3
and higher.
System utilities
================
@ -295,6 +307,10 @@ Binutils
--------
o <ftp://ftp.kernel.org/pub/linux/devel/binutils/>
OpenSSL
-------
o <https://www.openssl.org/>
System utilities
****************
@ -392,4 +408,3 @@ o <http://oprofile.sf.net/download/>
NFS-Utils
---------
o <http://nfs.sourceforge.net/>

View file

@ -174,6 +174,11 @@ The output directory is often set using "O=..." on the commandline.
The value can be overridden in which case the default value is ignored.
KBUILD_SIGN_PIN
--------------------------------------------------
This variable allows a passphrase or PIN to be passed to the sign-file
utility when signing kernel modules, if the private key requires such.
KBUILD_MODPOST_WARN
--------------------------------------------------
KBUILD_MODPOST_WARN can be set to avoid errors in case of undefined

View file

@ -89,6 +89,32 @@ This has a number of options available:
their signatures checked without causing a dependency loop.
(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
"certs/signing_key.pem" will disable the autogeneration of signing keys
and allow the kernel modules to be signed with a key of your choosing.
The string provided should identify a file containing both a private key
and its corresponding X.509 certificate in PEM form, or — on systems where
the OpenSSL ENGINE_pkcs11 is functional — a PKCS#11 URI as defined by
RFC7512. In the latter case, the PKCS#11 URI should reference both a
certificate and a private key.
If the PEM file containing the private key is encrypted, or if the
PKCS#11 token requries a PIN, this can be provided at build time by
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.
Note that enabling module signing adds a dependency on the OpenSSL devel
packages to the kernel build processes for the tool that does the signing.
=======================
GENERATING SIGNING KEYS
=======================
@ -100,16 +126,16 @@ it can be deleted or stored securely. The public key gets built into the
kernel so that it can be used to check the signatures as the modules are
loaded.
Under normal conditions, the kernel build will automatically generate a new
keypair using openssl if one does not exist in the files:
Under normal conditions, when CONFIG_MODULE_SIG_KEY is unchanged from its
default, the kernel build will automatically generate a new keypair using
openssl if one does not exist in the file:
signing_key.priv
signing_key.x509
certs/signing_key.pem
during the building of vmlinux (the public part of the key needs to be built
into vmlinux) using parameters in the:
x509.genkey
certs/x509.genkey
file (which is also generated if it does not already exist).
@ -135,8 +161,12 @@ kernel sources tree and the openssl command. The following is an example to
generate the public/private key files:
openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
-config x509.genkey -outform DER -out signing_key.x509 \
-keyout signing_key.priv
-config x509.genkey -outform PEM -out kernel_key.pem \
-keyout kernel_key.pem
The full pathname for the resulting kernel_key.pem file can then be specified
in the CONFIG_MODULE_SIG_KEY option, and the certificate and key therein will
be used instead of an autogenerated keypair.
=========================
@ -152,10 +182,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 []
...
Beyond the public key generated specifically for module signing, any file
placed in the kernel source root directory or the kernel build root directory
whose name is suffixed with ".x509" will be assumed to be an X.509 public key
and will be added to the keyring.
Beyond the public key generated specifically for module signing, additional
trusted certificates can be provided in a PEM-encoded file referenced by the
CONFIG_SYSTEM_TRUSTED_KEYS configuration option.
Further, the architecture code may take public keys from a hardware store and
add those in also (e.g. from the UEFI key database).
@ -181,7 +210,7 @@ To manually sign a module, use the scripts/sign-file tool available in
the Linux kernel source tree. The script requires 4 arguments:
1. The hash algorithm (e.g., sha256)
2. The private key filename
2. The private key filename or PKCS#11 URI
3. The public key filename
4. The kernel module to be signed
@ -194,6 +223,9 @@ The hash algorithm used does not have to match the one configured, but if it
doesn't, you should make sure that hash algorithm is either built into the
kernel or can be loaded without requiring itself.
If the private key requires a passphrase or PIN, it can be provided in the
$KBUILD_SIGN_PIN environment variable.
============================
SIGNED MODULES AND STRIPPING

View file

@ -28,6 +28,10 @@ Smack kernels use the CIPSO IP option. Some network
configurations are intolerant of IP options and can impede
access to systems that use them as Smack does.
Smack is used in the Tizen operating system. Please
go to http://wiki.tizen.org for information about how
Smack is used in Tizen.
The current git repository for Smack user space is:
git://github.com/smack-team/smack.git
@ -108,6 +112,8 @@ in the smackfs filesystem. This pseudo-filesystem is mounted
on /sys/fs/smackfs.
access
Provided for backward compatibility. The access2 interface
is preferred and should be used instead.
This interface reports whether a subject with the specified
Smack label has a particular access to an object with a
specified Smack label. Write a fixed format access rule to
@ -136,6 +142,8 @@ change-rule
those in the fourth string. If there is no such rule it will be
created using the access specified in the third and the fourth strings.
cipso
Provided for backward compatibility. The cipso2 interface
is preferred and should be used instead.
This interface allows a specific CIPSO header to be assigned
to a Smack label. The format accepted on write is:
"%24s%4d%4d"["%4d"]...
@ -157,7 +165,19 @@ direct
doi
This contains the CIPSO domain of interpretation used in
network packets.
ipv6host
This interface allows specific IPv6 internet addresses to be
treated as single label hosts. Packets are sent to single
label hosts only from processes that have Smack write access
to the host label. All packets received from single label hosts
are given the specified label. The format accepted on write is:
"%h:%h:%h:%h:%h:%h:%h:%h label" or
"%h:%h:%h:%h:%h:%h:%h:%h/%d label".
The "::" address shortcut is not supported.
If label is "-DELETE" a matched entry will be deleted.
load
Provided for backward compatibility. The load2 interface
is preferred and should be used instead.
This interface allows access control rules in addition to
the system defined rules to be specified. The format accepted
on write is:
@ -181,6 +201,8 @@ load2
permissions that are not allowed. The string "r-x--" would
specify read and execute access.
load-self
Provided for backward compatibility. The load-self2 interface
is preferred and should be used instead.
This interface allows process specific access rules to be
defined. These rules are only consulted if access would
otherwise be permitted, and are intended to provide additional
@ -205,6 +227,8 @@ netlabel
received from single label hosts are given the specified
label. The format accepted on write is:
"%d.%d.%d.%d label" or "%d.%d.%d.%d/%d label".
If the label specified is "-CIPSO" the address is treated
as a host that supports CIPSO headers.
onlycap
This contains labels processes must have for CAP_MAC_ADMIN
and CAP_MAC_OVERRIDE to be effective. If this file is empty
@ -232,7 +256,8 @@ unconfined
is dangerous and can ruin the proper labeling of your system.
It should never be used in production.
You can add access rules in /etc/smack/accesses. They take the form:
If you are using the smackload utility
you can add access rules in /etc/smack/accesses. They take the form:
subjectlabel objectlabel access

View file

@ -1,9 +1,7 @@
Yama is a Linux Security Module that collects a number of system-wide DAC
security protections that are not handled by the core kernel itself. To
select it at boot time, specify "security=yama" (though this will disable
any other LSM).
Yama is controlled through sysctl in /proc/sys/kernel/yama:
Yama is a Linux Security Module that collects system-wide DAC security
protections that are not handled by the core kernel itself. This is
selectable at build-time with CONFIG_SECURITY_YAMA, and can be controlled
at run-time through sysctls in /proc/sys/kernel/yama:
- ptrace_scope

View file

@ -2621,6 +2621,15 @@ S: Supported
F: Documentation/filesystems/ceph.txt
F: fs/ceph/
CERTIFICATE HANDLING:
M: David Howells <dhowells@redhat.com>
M: David Woodhouse <dwmw2@infradead.org>
L: keyrings@linux-nfs.org
S: Maintained
F: Documentation/module-signing.txt
F: certs/
F: scripts/extract-cert.c
CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM:
L: linux-usb@vger.kernel.org
S: Orphan
@ -5994,7 +6003,7 @@ F: kernel/kexec.c
KEYS/KEYRINGS:
M: David Howells <dhowells@redhat.com>
L: keyrings@linux-nfs.org
L: keyrings@vger.kernel.org
S: Maintained
F: Documentation/security/keys.txt
F: include/linux/key.h
@ -6006,7 +6015,7 @@ KEYS-TRUSTED
M: David Safford <safford@us.ibm.com>
M: Mimi Zohar <zohar@linux.vnet.ibm.com>
L: linux-security-module@vger.kernel.org
L: keyrings@linux-nfs.org
L: keyrings@vger.kernel.org
S: Supported
F: Documentation/security/keys-trusted-encrypted.txt
F: include/keys/trusted-type.h
@ -6017,7 +6026,7 @@ KEYS-ENCRYPTED
M: Mimi Zohar <zohar@linux.vnet.ibm.com>
M: David Safford <safford@us.ibm.com>
L: linux-security-module@vger.kernel.org
L: keyrings@linux-nfs.org
L: keyrings@vger.kernel.org
S: Supported
F: Documentation/security/keys-trusted-encrypted.txt
F: include/keys/encrypted-type.h
@ -9264,6 +9273,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
S: Supported
F: security/apparmor/
YAMA SECURITY MODULE
M: Kees Cook <keescook@chromium.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
S: Supported
F: security/yama/
SENSABLE PHANTOM
M: Jiri Slaby <jirislaby@gmail.com>
S: Maintained

View file

@ -875,10 +875,9 @@ INITRD_COMPRESS-$(CONFIG_RD_LZ4) := lz4
# export INITRD_COMPRESS := $(INITRD_COMPRESS-y)
ifdef CONFIG_MODULE_SIG_ALL
MODSECKEY = ./signing_key.priv
MODPUBKEY = ./signing_key.x509
export MODPUBKEY
mod_sign_cmd = perl $(srctree)/scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY)
$(eval $(call config_filename,MODULE_SIG_KEY))
mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY) certs/signing_key.x509
else
mod_sign_cmd = true
endif
@ -886,7 +885,7 @@ export mod_sign_cmd
ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
@ -1178,8 +1177,8 @@ MRPROPER_DIRS += include/config usr/include include/generated \
arch/*/include/generated .tmp_objdiff
MRPROPER_FILES += .config .config.old .version .old_version \
Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
signing_key.priv signing_key.x509 x509.genkey \
extra_certificates signing_key.x509.keyid \
signing_key.pem signing_key.priv signing_key.x509 \
x509.genkey extra_certificates signing_key.x509.keyid \
signing_key.x509.signer vmlinux-gdb.py
# clean - Delete most, but leave enough to build external modules

View file

@ -320,7 +320,6 @@ CONFIG_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_YAMA=y
CONFIG_SECURITY_YAMA_STACKED=y
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_HMAC=y

View file

@ -533,7 +533,9 @@ static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
int ret;
ret = verify_pefile_signature(kernel, kernel_len,
system_trusted_keyring, &trusted);
system_trusted_keyring,
VERIFYING_KEXEC_PE_SIGNATURE,
&trusted);
if (ret < 0)
return ret;
if (!trusted)

42
certs/Kconfig Normal file
View file

@ -0,0 +1,42 @@
menu "Certificates for signature checking"
config MODULE_SIG_KEY
string "File name or PKCS#11 URI of module signing key"
default "certs/signing_key.pem"
depends on MODULE_SIG
help
Provide the file name of a private key/certificate in PEM format,
or a PKCS#11 URI according to RFC7512. The file should contain, or
the URI should identify, both the certificate and its corresponding
private key.
If this option is unchanged from its default "certs/signing_key.pem",
then the kernel will automatically generate the private key and
certificate as described in Documentation/module-signing.txt
config SYSTEM_TRUSTED_KEYRING
bool "Provide system-wide ring of trusted keys"
depends on KEYS
help
Provide a system keyring to which trusted keys can be added. Keys in
the keyring are considered to be trusted. Keys may be added at will
by the kernel from compiled-in data and from hardware key stores, but
userspace may only add extra keys if those keys can be verified by
keys already in the keyring.
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.
endmenu

94
certs/Makefile Normal file
View file

@ -0,0 +1,94 @@
#
# Makefile for the linux kernel signature checking certificates.
#
obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o
ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
$(eval $(call config_filename,SYSTEM_TRUSTED_KEYS))
# GCC doesn't include .incbin files in -MD generated dependencies (PR#66871)
$(obj)/system_certificates.o: $(obj)/x509_certificate_list
# Cope with signing_key.x509 existing in $(srctree) not $(objtree)
AFLAGS_system_certificates.o := -I$(srctree)
quiet_cmd_extract_certs = EXTRACT_CERTS $(patsubst "%",%,$(2))
cmd_extract_certs = scripts/extract-cert $(2) $@ || ( rm $@; exit 1)
targets += x509_certificate_list
$(obj)/x509_certificate_list: scripts/extract-cert $(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(SYSTEM_TRUSTED_KEYS_FILENAME) FORCE
$(call if_changed,extract_certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS))
endif
clean-files := x509_certificate_list .x509.list
ifeq ($(CONFIG_MODULE_SIG),y)
###############################################################################
#
# If module signing is requested, say by allyesconfig, but a key has not been
# supplied, then one will need to be generated to make sure the build does not
# fail and that the kernel may be used afterwards.
#
###############################################################################
ifndef CONFIG_MODULE_SIG_HASH
$(error Could not determine digest type to use from kernel config)
endif
# We do it this way rather than having a boolean option for enabling an
# external private key, because 'make randconfig' might enable such a
# boolean option and we unfortunately can't make it depend on !RANDCONFIG.
ifeq ($(CONFIG_MODULE_SIG_KEY),"certs/signing_key.pem")
$(obj)/signing_key.pem: $(obj)/x509.genkey
@echo "###"
@echo "### Now generating an X.509 key pair to be used for signing modules."
@echo "###"
@echo "### If this takes a long time, you might wish to run rngd in the"
@echo "### background to keep the supply of entropy topped up. It"
@echo "### needs to be run as root, and uses a hardware random"
@echo "### number generator if one is available."
@echo "###"
openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \
-batch -x509 -config $(obj)/x509.genkey \
-outform PEM -out $(obj)/signing_key.pem \
-keyout $(obj)/signing_key.pem 2>&1
@echo "###"
@echo "### Key pair generated."
@echo "###"
$(obj)/x509.genkey:
@echo Generating X.509 key generation config
@echo >$@ "[ req ]"
@echo >>$@ "default_bits = 4096"
@echo >>$@ "distinguished_name = req_distinguished_name"
@echo >>$@ "prompt = no"
@echo >>$@ "string_mask = utf8only"
@echo >>$@ "x509_extensions = myexts"
@echo >>$@
@echo >>$@ "[ req_distinguished_name ]"
@echo >>$@ "#O = Unspecified company"
@echo >>$@ "CN = Build time autogenerated kernel key"
@echo >>$@ "#emailAddress = unspecified.user@unspecified.company"
@echo >>$@
@echo >>$@ "[ myexts ]"
@echo >>$@ "basicConstraints=critical,CA:FALSE"
@echo >>$@ "keyUsage=digitalSignature"
@echo >>$@ "subjectKeyIdentifier=hash"
@echo >>$@ "authorityKeyIdentifier=keyid"
endif
$(eval $(call config_filename,MODULE_SIG_KEY))
# If CONFIG_MODULE_SIG_KEY isn't a PKCS#11 URI, depend on it
ifeq ($(patsubst pkcs11:%,%,$(firstword $(MODULE_SIG_KEY_FILENAME))),$(firstword $(MODULE_SIG_KEY_FILENAME)))
X509_DEP := $(MODULE_SIG_KEY_SRCPREFIX)$(MODULE_SIG_KEY_FILENAME)
endif
# GCC PR#66871 again.
$(obj)/system_certificates.o: $(obj)/signing_key.x509
targets += signing_key.x509
$(obj)/signing_key.x509: scripts/extract-cert $(X509_DEP) FORCE
$(call if_changed,extract_certs,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY))
endif

View file

@ -0,0 +1,23 @@
#include <linux/export.h>
#include <linux/init.h>
__INITRODATA
.align 8
.globl VMLINUX_SYMBOL(system_certificate_list)
VMLINUX_SYMBOL(system_certificate_list):
__cert_list_start:
#ifdef CONFIG_MODULE_SIG
.incbin "certs/signing_key.x509"
#endif
.incbin "certs/x509_certificate_list"
__cert_list_end:
.align 8
.globl VMLINUX_SYMBOL(system_certificate_list_size)
VMLINUX_SYMBOL(system_certificate_list_size):
#ifdef CONFIG_64BIT
.quad __cert_list_end - __cert_list_start
#else
.long __cert_list_end - __cert_list_start
#endif

157
certs/system_keyring.c Normal file
View file

@ -0,0 +1,157 @@
/* System trusted keyring for trusted public keys
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/cred.h>
#include <linux/err.h>
#include <keys/asymmetric-type.h>
#include <keys/system_keyring.h>
#include <crypto/pkcs7.h>
struct key *system_trusted_keyring;
EXPORT_SYMBOL_GPL(system_trusted_keyring);
extern __initconst const u8 system_certificate_list[];
extern __initconst const unsigned long system_certificate_list_size;
/*
* Load the compiled-in keys
*/
static __init int system_trusted_keyring_init(void)
{
pr_notice("Initialise system trusted keyring\n");
system_trusted_keyring =
keyring_alloc(".system_keyring",
KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
KEY_ALLOC_NOT_IN_QUOTA, NULL);
if (IS_ERR(system_trusted_keyring))
panic("Can't allocate system trusted keyring\n");
set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
return 0;
}
/*
* Must be initialised before we try and load the keys into the keyring.
*/
device_initcall(system_trusted_keyring_init);
/*
* Load the compiled-in list of X.509 certificates.
*/
static __init int load_system_certificate_list(void)
{
key_ref_t key;
const u8 *p, *end;
size_t plen;
pr_notice("Loading compiled-in X.509 certificates\n");
p = system_certificate_list;
end = p + system_certificate_list_size;
while (p < end) {
/* Each cert begins with an ASN.1 SEQUENCE tag and must be more
* than 256 bytes in size.
*/
if (end - p < 4)
goto dodgy_cert;
if (p[0] != 0x30 &&
p[1] != 0x82)
goto dodgy_cert;
plen = (p[2] << 8) | p[3];
plen += 4;
if (plen > end - p)
goto dodgy_cert;
key = key_create_or_update(make_key_ref(system_trusted_keyring, 1),
"asymmetric",
NULL,
p,
plen,
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ),
KEY_ALLOC_NOT_IN_QUOTA |
KEY_ALLOC_TRUSTED);
if (IS_ERR(key)) {
pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
PTR_ERR(key));
} else {
set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags);
pr_notice("Loaded X.509 cert '%s'\n",
key_ref_to_ptr(key)->description);
key_ref_put(key);
}
p += plen;
}
return 0;
dodgy_cert:
pr_err("Problem parsing in-kernel X.509 certificate list\n");
return 0;
}
late_initcall(load_system_certificate_list);
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
/**
* Verify a PKCS#7-based signature on system data.
* @data: The data to be verified.
* @len: Size of @data.
* @raw_pkcs7: The PKCS#7 message that is the signature.
* @pkcs7_len: The size of @raw_pkcs7.
* @usage: The use to which the key is being put.
*/
int system_verify_data(const void *data, unsigned long len,
const void *raw_pkcs7, size_t pkcs7_len,
enum key_being_used_for usage)
{
struct pkcs7_message *pkcs7;
bool trusted;
int ret;
pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
if (IS_ERR(pkcs7))
return PTR_ERR(pkcs7);
/* The data should be detached - so we need to supply it. */
if (pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
pr_err("PKCS#7 signature with non-detached data\n");
ret = -EBADMSG;
goto error;
}
ret = pkcs7_verify(pkcs7, usage);
if (ret < 0)
goto error;
ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
if (ret < 0)
goto error;
if (!trusted) {
pr_err("PKCS#7 signature not signed with a trusted key\n");
ret = -ENOKEY;
}
error:
pkcs7_free_message(pkcs7);
pr_devel("<==%s() = %d\n", __func__, ret);
return ret;
}
EXPORT_SYMBOL_GPL(system_verify_data);
#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */

View file

@ -1635,5 +1635,6 @@ config CRYPTO_HASH_INFO
source "drivers/crypto/Kconfig"
source crypto/asymmetric_keys/Kconfig
source certs/Kconfig
endif # if CRYPTO

View file

@ -15,15 +15,21 @@ obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
x509_key_parser-y := \
x509-asn1.o \
x509_akid-asn1.o \
x509_rsakey-asn1.o \
x509_cert_parser.o \
x509_public_key.o
$(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h $(obj)/x509_rsakey-asn1.h
$(obj)/x509_cert_parser.o: \
$(obj)/x509-asn1.h \
$(obj)/x509_akid-asn1.h \
$(obj)/x509_rsakey-asn1.h
$(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h
$(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h
$(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h
clean-files += x509-asn1.c x509-asn1.h
clean-files += x509_akid-asn1.c x509_akid-asn1.h
clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h
#

View file

@ -12,6 +12,7 @@
*/
#include <keys/asymmetric-subtype.h>
#include <keys/asymmetric-parser.h>
#include <crypto/public_key.h>
#include <linux/seq_file.h>
#include <linux/module.h>
#include <linux/slab.h>
@ -20,6 +21,16 @@
MODULE_LICENSE("GPL");
const char *const key_being_used_for[NR__KEY_BEING_USED_FOR] = {
[VERIFYING_MODULE_SIGNATURE] = "mod sig",
[VERIFYING_FIRMWARE_SIGNATURE] = "firmware sig",
[VERIFYING_KEXEC_PE_SIGNATURE] = "kexec PE sig",
[VERIFYING_KEY_SIGNATURE] = "key sig",
[VERIFYING_KEY_SELF_SIGNATURE] = "key self sig",
[VERIFYING_UNSPECIFIED_SIGNATURE] = "unspec sig",
};
EXPORT_SYMBOL_GPL(key_being_used_for);
static LIST_HEAD(asymmetric_key_parsers);
static DECLARE_RWSEM(asymmetric_key_parsers_sem);

View file

@ -97,6 +97,15 @@ int mscode_note_digest_algo(void *context, size_t hdrlen,
case OID_sha256:
ctx->digest_algo = HASH_ALGO_SHA256;
break;
case OID_sha384:
ctx->digest_algo = HASH_ALGO_SHA384;
break;
case OID_sha512:
ctx->digest_algo = HASH_ALGO_SHA512;
break;
case OID_sha224:
ctx->digest_algo = HASH_ALGO_SHA224;
break;
case OID__NR:
sprint_oid(value, vlen, buffer, sizeof(buffer));

View file

@ -1,14 +1,14 @@
PKCS7ContentInfo ::= SEQUENCE {
contentType ContentType,
contentType ContentType ({ pkcs7_check_content_type }),
content [0] EXPLICIT SignedData OPTIONAL
}
ContentType ::= OBJECT IDENTIFIER ({ pkcs7_note_OID })
SignedData ::= SEQUENCE {
version INTEGER,
version INTEGER ({ pkcs7_note_signeddata_version }),
digestAlgorithms DigestAlgorithmIdentifiers,
contentInfo ContentInfo,
contentInfo ContentInfo ({ pkcs7_note_content }),
certificates CHOICE {
certSet [0] IMPLICIT ExtendedCertificatesAndCertificates,
certSequence [2] IMPLICIT Certificates
@ -21,7 +21,7 @@ SignedData ::= SEQUENCE {
}
ContentInfo ::= SEQUENCE {
contentType ContentType,
contentType ContentType ({ pkcs7_note_OID }),
content [0] EXPLICIT Data OPTIONAL
}
@ -68,8 +68,8 @@ SignerInfos ::= CHOICE {
}
SignerInfo ::= SEQUENCE {
version INTEGER,
issuerAndSerialNumber IssuerAndSerialNumber,
version INTEGER ({ pkcs7_note_signerinfo_version }),
sid SignerIdentifier, -- CMS variant, not PKCS#7
digestAlgorithm DigestAlgorithmIdentifier ({ pkcs7_sig_note_digest_algo }),
authenticatedAttributes CHOICE {
aaSet [0] IMPLICIT SetOfAuthenticatedAttribute
@ -88,6 +88,12 @@ SignerInfo ::= SEQUENCE {
} OPTIONAL
} ({ pkcs7_note_signed_info })
SignerIdentifier ::= CHOICE {
-- RFC5652 sec 5.3
issuerAndSerialNumber IssuerAndSerialNumber,
subjectKeyIdentifier [0] IMPLICIT SubjectKeyIdentifier
}
IssuerAndSerialNumber ::= SEQUENCE {
issuer Name ({ pkcs7_sig_note_issuer }),
serialNumber CertificateSerialNumber ({ pkcs7_sig_note_serial })
@ -95,6 +101,8 @@ IssuerAndSerialNumber ::= SEQUENCE {
CertificateSerialNumber ::= INTEGER
SubjectKeyIdentifier ::= OCTET STRING ({ pkcs7_sig_note_skid })
SetOfAuthenticatedAttribute ::= SET OF AuthenticatedAttribute
AuthenticatedAttribute ::= SEQUENCE {
@ -103,7 +111,7 @@ AuthenticatedAttribute ::= SEQUENCE {
}
UnauthenticatedAttribute ::= SEQUENCE {
type OBJECT IDENTIFIER ({ pkcs7_note_OID }),
type OBJECT IDENTIFIER,
values SET OF ANY
}

View file

@ -14,16 +14,26 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/key-type.h>
#include <keys/asymmetric-type.h>
#include <crypto/pkcs7.h>
#include <keys/user-type.h>
#include <keys/system_keyring.h>
#include "pkcs7_parser.h"
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PKCS#7 testing key type");
static unsigned pkcs7_usage;
module_param_named(usage, pkcs7_usage, uint, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(pkcs7_usage,
"Usage to specify when verifying the PKCS#7 message");
/*
* Preparse a PKCS#7 wrapped and validated data blob.
*/
static int pkcs7_preparse(struct key_preparsed_payload *prep)
{
enum key_being_used_for usage = pkcs7_usage;
struct pkcs7_message *pkcs7;
const void *data, *saved_prep_data;
size_t datalen, saved_prep_datalen;
@ -32,6 +42,11 @@ static int pkcs7_preparse(struct key_preparsed_payload *prep)
kenter("");
if (usage >= NR__KEY_BEING_USED_FOR) {
pr_err("Invalid usage type %d\n", usage);
return -EINVAL;
}
saved_prep_data = prep->data;
saved_prep_datalen = prep->datalen;
pkcs7 = pkcs7_parse_message(saved_prep_data, saved_prep_datalen);
@ -40,7 +55,7 @@ static int pkcs7_preparse(struct key_preparsed_payload *prep)
goto error;
}
ret = pkcs7_verify(pkcs7);
ret = pkcs7_verify(pkcs7, usage);
if (ret < 0)
goto error_free;

Some files were not shown because too many files have changed in this diff Show more