History log of /linux-master/crypto/asymmetric_keys/pkcs7_verify.c
Revision Date Author Comments
# 3584c1db 19-Feb-2023 Robbie Harwood <rharwood@redhat.com>

asymmetric_keys: log on fatal failures in PE/pkcs7

These particular errors can be encountered while trying to kexec when
secureboot lockdown is in place. Without this change, even with a
signed debug build, one still needs to reboot the machine to add the
appropriate dyndbg parameters (since lockdown blocks debugfs).

Accordingly, upgrade all pr_debug() before fatal error into pr_warn().

Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Jarkko Sakkinen <jarkko@kernel.org>
cc: Eric Biederman <ebiederm@xmission.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
cc: kexec@lists.infradead.org
Link: https://lore.kernel.org/r/20230220171254.592347-3-rharwood@redhat.com/ # v2


# 0f5d4a0b 15-Dec-2022 Arnd Bergmann <arnd@arndb.de>

crypto: certs: fix FIPS selftest dependency

The selftest code is built into the x509_key_parser module, and depends
on the pkcs7_message_parser module, which in turn has a dependency on
the key parser, creating a dependency loop and a resulting link
failure when the pkcs7 code is a loadable module:

ld: crypto/asymmetric_keys/selftest.o: in function `fips_signature_selftest':
crypto/asymmetric_keys/selftest.c:205: undefined reference to `pkcs7_parse_message'
ld: crypto/asymmetric_keys/selftest.c:209: undefined reference to `pkcs7_supply_detached_data'
ld: crypto/asymmetric_keys/selftest.c:211: undefined reference to `pkcs7_verify'
ld: crypto/asymmetric_keys/selftest.c:215: undefined reference to `pkcs7_validate_trust'
ld: crypto/asymmetric_keys/selftest.c:219: undefined reference to `pkcs7_free_message'

Avoid this by only allowing the selftest to be enabled when either
both parts are loadable modules, or both are built-in.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>


# 2abc9c24 07-Feb-2022 Eric Biggers <ebiggers@google.com>

KEYS: asymmetric: enforce that sig algo matches key algo

Most callers of public_key_verify_signature(), including most indirect
callers via verify_signature() as well as pkcs7_verify_sig_chain(),
don't check that public_key_signature::pkey_algo matches
public_key::pkey_algo. These should always match. However, a malicious
signature could intentionally declare an unintended algorithm. It is
essential that such signatures be rejected outright, or that the
algorithm of the *key* be used -- not the algorithm of the signature as
that would allow attackers to choose the algorithm used.

Currently, public_key_verify_signature() correctly uses the key's
algorithm when deciding which akcipher to allocate. That's good.
However, it uses the signature's algorithm when deciding whether to do
the first step of SM2, which is incorrect. Also, v4.19 and older
kernels used the signature's algorithm for the entire process.

Prevent such errors by making public_key_verify_signature() enforce that
the signature's algorithm (if given) matches the key's algorithm.

Also remove two checks of this done by callers, which are now redundant.

Cc: stable@vger.kernel.org
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Tested-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Vitaly Chikunov <vt@altlinux.org>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>


# 9f8b3f32 18-Jan-2022 Eric Biggers <ebiggers@google.com>

KEYS: x509: remove never-set ->unsupported_key flag

The X.509 parser always sets cert->pub->pkey_algo on success, since
x509_extract_key_data() is a mandatory action in the X.509 ASN.1
grammar, and it returns an error if the algorithm is unknown. Thus,
remove the dead code which handled this field being NULL. This results
in the ->unsupported_key flag never being set, so remove that too.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>


# 3c0940c4 02-Sep-2020 YueHaibing <yuehaibing@huawei.com>

crypto: pkcs7: Use match_string() helper to simplify the code

match_string() returns the array index of a matching string.
Use it instead of the open-coded implementation.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ben Boeckel <mathstuf@gmail.com>


# e201af16 27-Jun-2019 Thiago Jung Bauermann <bauerman@linux.ibm.com>

PKCS#7: Introduce pkcs7_get_digest()

IMA will need to access the digest of the PKCS7 message (as calculated by
the kernel) before the signature is verified, so introduce
pkcs7_get_digest() for that purpose.

Also, modify pkcs7_digest() to detect when the digest was already
calculated so that it doesn't have to do redundant work. Verifying that
sinfo->sig->digest isn't NULL is sufficient because both places which
allocate sinfo->sig (pkcs7_parse_message() and pkcs7_note_signed_info())
use kzalloc() so sig->digest is always initialized to zero.

Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>


# b4d0d230 20-May-2019 Thomas Gleixner <tglx@linutronix.de>

treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36

Based on 1 normalized pattern(s):

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

extracted by the scancode license scanner the SPDX license identifier

GPL-2.0-or-later

has been chosen to replace the boilerplate/reference in 114 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190520170857.552531963@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


# 877b5691 14-Apr-2019 Eric Biggers <ebiggers@google.com>

crypto: shash - remove shash_desc::flags

The flags field in 'struct shash_desc' never actually does anything.
The only ostensibly supported flag is CRYPTO_TFM_REQ_MAY_SLEEP.
However, no shash algorithm ever sleeps, making this flag a no-op.

With this being the case, inevitably some users who can't sleep wrongly
pass MAY_SLEEP. These would all need to be fixed if any shash algorithm
actually started sleeping. For example, the shash_ahash_*() functions,
which wrap a shash algorithm with the ahash API, pass through MAY_SLEEP
from the ahash API to the shash API. However, the shash functions are
called under kmap_atomic(), so actually they're assumed to never sleep.

Even if it turns out that some users do need preemption points while
hashing large buffers, we could easily provide a helper function
crypto_shash_update_large() which divides the data into smaller chunks
and calls crypto_shash_update() and cond_resched() for each chunk. It's
not necessary to have a flag in 'struct shash_desc', nor is it necessary
to make individual shash algorithms aware of this at all.

Therefore, remove shash_desc::flags, and document that the
crypto_shash_*() functions can be called from any context.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


# 29f4a67c 22-Feb-2018 Eric Biggers <ebiggers@google.com>

PKCS#7: fix certificate blacklisting

If there is a blacklisted certificate in a SignerInfo's certificate
chain, then pkcs7_verify_sig_chain() sets sinfo->blacklisted and returns
0. But, pkcs7_verify() fails to handle this case appropriately, as it
actually continues on to the line 'actual_ret = 0;', indicating that the
SignerInfo has passed verification. Consequently, PKCS#7 signature
verification ignores the certificate blacklist.

Fix this by not considering blacklisted SignerInfos to have passed
verification.

Also fix the function comment with regards to when 0 is returned.

Fixes: 03bb79315ddc ("PKCS#7: Handle blacklisted certificates")
Cc: <stable@vger.kernel.org> # v4.12+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>


# 971b42c0 22-Feb-2018 Eric Biggers <ebiggers@google.com>

PKCS#7: fix certificate chain verification

When pkcs7_verify_sig_chain() is building the certificate chain for a
SignerInfo using the certificates in the PKCS#7 message, it is passing
the wrong arguments to public_key_verify_signature(). Consequently,
when the next certificate is supposed to be used to verify the previous
certificate, the next certificate is actually used to verify itself.

An attacker can use this bug to create a bogus certificate chain that
has no cryptographic relationship between the beginning and end.

Fortunately I couldn't quite find a way to use this to bypass the
overall signature verification, though it comes very close. Here's the
reasoning: due to the bug, every certificate in the chain beyond the
first actually has to be self-signed (where "self-signed" here refers to
the actual key and signature; an attacker might still manipulate the
certificate fields such that the self_signed flag doesn't actually get
set, and thus the chain doesn't end immediately). But to pass trust
validation (pkcs7_validate_trust()), either the SignerInfo or one of the
certificates has to actually be signed by a trusted key. Since only
self-signed certificates can be added to the chain, the only way for an
attacker to introduce a trusted signature is to include a self-signed
trusted certificate.

But, when pkcs7_validate_trust_one() reaches that certificate, instead
of trying to verify the signature on that certificate, it will actually
look up the corresponding trusted key, which will succeed, and then try
to verify the *previous* certificate, which will fail. Thus, disaster
is narrowly averted (as far as I could tell).

Fixes: 6c2dc5ae4ab7 ("X.509: Extract signature digest and make self-signed cert checks earlier")
Cc: <stable@vger.kernel.org> # v4.7+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>


# 54c1fb39 08-Dec-2017 Eric Biggers <ebiggers@google.com>

X.509: fix comparisons of ->pkey_algo

->pkey_algo used to be an enum, but was changed to a string by commit
4e8ae72a75aa ("X.509: Make algo identifiers text instead of enum"). But
two comparisons were not updated. Fix them to use strcmp().

This bug broke signature verification in certain configurations,
depending on whether the string constants were deduplicated or not.

Fixes: 4e8ae72a75aa ("X.509: Make algo identifiers text instead of enum")
Cc: <stable@vger.kernel.org> # v4.6+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>


# a80745a6 08-Dec-2017 Eric Biggers <ebiggers@google.com>

pkcs7: use crypto_shash_digest()

Use crypto_shash_digest() instead of crypto_shash_init() followed by
crypto_shash_finup(). (For simplicity only; they are equivalent.)

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>


# 03bb7931 03-Apr-2017 David Howells <dhowells@redhat.com>

PKCS#7: Handle blacklisted certificates

PKCS#7: Handle certificates that are blacklisted when verifying the chain
of trust on the signatures on a PKCS#7 message.

Signed-off-by: David Howells <dhowells@redhat.com>


# a46e6678 17-Jul-2016 Lans Zhang <jia.zhang@windriver.com>

PKCS#7: Fix panic when referring to the empty AKID when DEBUG defined

This fix resolves the following kernel panic if an empty or missing
AuthorityKeyIdentifier is encountered and DEBUG is defined in
pkcs7_verify.c.

[ 459.041989] PKEY: <==public_key_verify_signature() = 0
[ 459.041993] PKCS7: Verified signature 1
[ 459.041995] PKCS7: ==> pkcs7_verify_sig_chain()
[ 459.041999] PKCS7: verify Sample DB Certificate for SCP: 01
[ 459.042002] PKCS7: - issuer Sample KEK Certificate for SCP
[ 459.042014] BUG: unable to handle kernel NULL pointer dereference at (null)
[ 459.042135] IP: [<ffffffff813e7b4c>] pkcs7_verify+0x72c/0x7f0
[ 459.042217] PGD 739e6067 PUD 77719067 PMD 0
[ 459.042286] Oops: 0000 [#1] PREEMPT SMP
[ 459.042328] Modules linked in:
[ 459.042368] CPU: 0 PID: 474 Comm: kexec Not tainted 4.7.0-rc7-WR8.0.0.0_standard+ #18
[ 459.042462] Hardware name: To be filled by O.E.M. To be filled by O.E.M./Aptio CRB, BIOS 5.6.5 10/09/2014
[ 459.042586] task: ffff880073a50000 ti: ffff8800738e8000 task.ti: ffff8800738e8000
[ 459.042675] RIP: 0010:[<ffffffff813e7b4c>] [<ffffffff813e7b4c>] pkcs7_verify+0x72c/0x7f0
[ 459.042784] RSP: 0018:ffff8800738ebd58 EFLAGS: 00010246
[ 459.042845] RAX: 0000000000000000 RBX: ffff880076b7da80 RCX: 0000000000000006
[ 459.042929] RDX: 0000000000000001 RSI: ffffffff81c85001 RDI: ffffffff81ca00a9
[ 459.043014] RBP: ffff8800738ebd98 R08: 0000000000000400 R09: ffff8800788a304c
[ 459.043098] R10: 0000000000000000 R11: 00000000000060ca R12: ffff8800769a2bc0
[ 459.043182] R13: ffff880077358300 R14: 0000000000000000 R15: ffff8800769a2dc0
[ 459.043268] FS: 00007f24cc741700(0000) GS:ffff880074e00000(0000) knlGS:0000000000000000
[ 459.043365] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 459.043431] CR2: 0000000000000000 CR3: 0000000073a36000 CR4: 00000000001006f0
[ 459.043514] Stack:
[ 459.043530] 0000000000000000 ffffffbf00000020 31ffffff813e68b0 0000000000000002
[ 459.043644] ffff8800769a2bc0 0000000000000000 00000000007197b8 0000000000000002
[ 459.043756] ffff8800738ebdd8 ffffffff81153fb1 0000000000000000 0000000000000000
[ 459.043869] Call Trace:
[ 459.043898] [<ffffffff81153fb1>] verify_pkcs7_signature+0x61/0x140
[ 459.043974] [<ffffffff813e7f0b>] verify_pefile_signature+0x2cb/0x830
[ 459.044052] [<ffffffff813e8470>] ? verify_pefile_signature+0x830/0x830
[ 459.044134] [<ffffffff81048e25>] bzImage64_verify_sig+0x15/0x20
[ 459.046332] [<ffffffff81046e09>] arch_kexec_kernel_verify_sig+0x29/0x40
[ 459.048552] [<ffffffff810f10e4>] SyS_kexec_file_load+0x1f4/0x6c0
[ 459.050768] [<ffffffff81050e36>] ? __do_page_fault+0x1b6/0x550
[ 459.052996] [<ffffffff8199241f>] entry_SYSCALL_64_fastpath+0x17/0x93
[ 459.055242] Code: e8 0a d6 ff ff 85 c0 0f 88 7a fb ff ff 4d 39 fd 4d 89 7d 08 74 45 4d 89 fd e9 14 fe ff ff 4d 8b 76 08 31 c0 48 c7 c7 a9 00 ca 81 <41> 0f b7 36 49 8d 56 02 e8 d0 91 d6 ff 4d 8b 3c 24 4d 85 ff 0f
[ 459.060535] RIP [<ffffffff813e7b4c>] pkcs7_verify+0x72c/0x7f0
[ 459.063040] RSP <ffff8800738ebd58>
[ 459.065456] CR2: 0000000000000000
[ 459.075998] ---[ end trace c15f0e897cda28dc ]---

Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
cc: linux-crypto@vger.kernel.org
cc: kexec@lists.infradead.org
Signed-off-by: James Morris <james.l.morris@oracle.com>


# 6c2dc5ae 06-Apr-2016 David Howells <dhowells@redhat.com>

X.509: Extract signature digest and make self-signed cert checks earlier

Extract the signature digest for an X.509 certificate earlier, at the end
of x509_cert_parse() rather than leaving it to the callers thereof since it
has to be called anyway.

Further, immediately after that, check the signature on self-signed
certificates, also rather in the callers of x509_cert_parse().

We note in the x509_certificate struct the following bits of information:

(1) Whether the signature is self-signed (even if we can't check the
signature due to missing crypto).

(2) Whether the key held in the certificate needs unsupported crypto to be
used. We may get a PKCS#7 message with X.509 certs that we can't make
use of - we just ignore them and give ENOPKG at the end it we couldn't
verify anything if at least one of these unusable certs are in the
chain of trust.

(3) Whether the signature held in the certificate needs unsupported crypto
to be checked. We can still use the key held in this certificate,
even if we can't check the signature on it - if it is held in the
system trusted keyring, for instance. We just can't add it to a ring
of trusted keys or follow it further up the chain of trust.

Making these checks earlier allows x509_check_signature() to be removed and
replaced with direct calls to public_key_verify_signature().

Signed-off-by: David Howells <dhowells@redhat.com>


# 566a117a 06-Apr-2016 David Howells <dhowells@redhat.com>

PKCS#7: Make the signature a pointer rather than embedding it

Point to the public_key_signature struct from the pkcs7_signed_info struct
rather than embedding it. This makes the code consistent with the X.509
signature handling and makes it possible to have a common cleanup function.

We also save a copy of the digest in the signature without sharing the
memory with the crypto layer metadata.

Signed-off-by: David Howells <dhowells@redhat.com>


# 77d0910d 06-Apr-2016 David Howells <dhowells@redhat.com>

X.509: Retain the key verification data

Retain the key verification data (ie. the struct public_key_signature)
including the digest and the key identifiers.

Note that this means that we need to take a separate copy of the digest in
x509_get_sig_params() rather than lumping it in with the crypto layer data.

Signed-off-by: David Howells <dhowells@redhat.com>


# 4e8ae72a 03-Mar-2016 David Howells <dhowells@redhat.com>

X.509: Make algo identifiers text instead of enum

Make the identifier public key and digest algorithm fields text instead of
enum.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>


# db6c43bd 02-Feb-2016 Tadeusz Struk <tadeusz.struk@intel.com>

crypto: KEYS: convert public key and digsig asym to the akcipher api

This patch converts the module verification code to the new akcipher API.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David Howells <dhowells@redhat.com>


# f75516a8 09-Feb-2016 Herbert Xu <herbert@gondor.apana.org.au>

crypto: keys - Revert "convert public key to akcipher api"

This needs to go through the security tree so I'm reverting the
patches for now.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


# 57f96bba 02-Feb-2016 Tadeusz Struk <tadeusz.struk@intel.com>

crypto: asymmetric_keys - convert public key and digsig asym to the akcipher api

This patch converts the module verification code to the new akcipher API.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


# 62f57d05 13-Oct-2015 Sowmini Varadhan <sowmini.varadhan@oracle.com>

crypto: pkcs7 - Fix unaligned access in pkcs7_verify()

On sparc, we see unaligned access messages on each modprobe[-r]:

Kernel unaligned access at TPC[6ad9b4] pkcs7_verify [..]
Kernel unaligned access at TPC[6a5484] crypto_shash_finup [..]
Kernel unaligned access at TPC[6a5390] crypto_shash_update [..]
Kernel unaligned access at TPC[10150308] sha1_sparc64_update [..]
Kernel unaligned access at TPC[101501ac] __sha1_sparc64_update [..]

These ware triggered by mod_verify_sig() invocations of pkcs_verify(), and
are are being caused by an unaligned desc at (sha1, digest_size is 0x14)
desc = digest + digest_size;

To fix this, pkcs7_verify needs to make sure that desc is pointing
at an aligned value past the digest_size, and kzalloc appropriately,
taking alignment values into consideration.

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


# 99db4435 05-Aug-2015 David Howells <dhowells@redhat.com>

PKCS#7: Appropriately restrict authenticated attributes and content type

A PKCS#7 or CMS message can have per-signature authenticated attributes
that are digested as a lump and signed by the authorising key for that
signature. If such attributes exist, the content digest isn't itself
signed, but rather it is included in a special authattr which then
contributes to the signature.

Further, we already require the master message content type to be
pkcs7_signedData - but there's also a separate content type for the data
itself within the SignedData object and this must be repeated inside the
authattrs for each signer [RFC2315 9.2, RFC5652 11.1].

We should really validate the authattrs if they exist or forbid them
entirely as appropriate. To this end:

(1) Alter the PKCS#7 parser to reject any message that has more than one
signature where at least one signature has authattrs and at least one
that does not.

(2) Validate authattrs if they are present and strongly restrict them.
Only the following authattrs are permitted and all others are
rejected:

(a) contentType. This is checked to be an OID that matches the
content type in the SignedData object.

(b) messageDigest. This must match the crypto digest of the data.

(c) signingTime. If present, we check that this is a valid, parseable
UTCTime or GeneralTime and that the date it encodes fits within
the validity window of the matching X.509 cert.

(d) S/MIME capabilities. We don't check the contents.

(e) Authenticode SP Opus Info. We don't check the contents.

(f) Authenticode Statement Type. We don't check the contents.

The message is rejected if (a) or (b) are missing. If the message is
an Authenticode type, the message is rejected if (e) is missing; if
not Authenticode, the message is rejected if (d) - (f) are present.

The S/MIME capabilities authattr (d) unfortunately has to be allowed
to support kernels already signed by the pesign program. This only
affects kexec. sign-file suppresses them (CMS_NOSMIMECAP).

The message is also rejected if an authattr is given more than once or
if it contains more than one element in its set of values.

(3) Add a parameter to pkcs7_verify() to select one of the following
restrictions and pass in the appropriate option from the callers:

(*) VERIFYING_MODULE_SIGNATURE

This requires that the SignedData content type be pkcs7-data and
forbids authattrs. sign-file sets CMS_NOATTR. We could be more
flexible and permit authattrs optionally, but only permit minimal
content.

(*) VERIFYING_FIRMWARE_SIGNATURE

This requires that the SignedData content type be pkcs7-data and
requires authattrs. In future, this will require an attribute
holding the target firmware name in addition to the minimal set.

(*) VERIFYING_UNSPECIFIED_SIGNATURE

This requires that the SignedData content type be pkcs7-data but
allows either no authattrs or only permits the minimal set.

(*) VERIFYING_KEXEC_PE_SIGNATURE

This only supports the Authenticode SPC_INDIRECT_DATA content type
and requires at least an SpcSpOpusInfo authattr in addition to the
minimal set. It also permits an SPC_STATEMENT_TYPE authattr (and
an S/MIME capabilities authattr because the pesign program doesn't
remove these).

(*) VERIFYING_KEY_SIGNATURE
(*) VERIFYING_KEY_SELF_SIGNATURE

These are invalid in this context but are included for later use
when limiting the use of X.509 certs.

(4) The pkcs7_test key type is given a module parameter to select between
the above options for testing purposes. For example:

echo 1 >/sys/module/pkcs7_test_key/parameters/usage
keyctl padd pkcs7_test foo @s </tmp/stuff.pkcs7

will attempt to check the signature on stuff.pkcs7 as if it contains a
firmware blob (1 being VERIFYING_FIRMWARE_SIGNATURE).

Suggested-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: David Woodhouse <David.Woodhouse@intel.com>


# 4ebdb76f 20-Jul-2015 David Howells <dhowells@redhat.com>

PKCS#7: Allow detached data to be supplied for signature checking purposes

It is possible for a PKCS#7 message to have detached data. However, to verify
the signatures on a PKCS#7 message, we have to be able to digest the data.
Provide a function to supply that data. An error is given if the PKCS#7
message included embedded data.

This is used in a subsequent patch to supply the data to module signing where
the signature is in the form of a PKCS#7 message with detached data, whereby
the detached data is the module content that is signed.

Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Vivek Goyal <vgoyal@redhat.com>


# 4573b64a 20-Jul-2015 David Howells <dhowells@redhat.com>

X.509: Support X.509 lookup by Issuer+Serial form AuthorityKeyIdentifier

If an X.509 certificate has an AuthorityKeyIdentifier extension that provides
an issuer and serialNumber, then make it so that these are used in preference
to the keyIdentifier field also held therein for searching for the signing
certificate.

If both the issuer+serialNumber and the keyIdentifier are supplied, then the
certificate is looked up by the former but the latter is checked as well. If
the latter doesn't match the subjectKeyIdentifier of the parent certificate,
EKEYREJECTED is returned.

This makes it possible to chain X.509 certificates based on the issuer and
serialNumber fields rather than on subjectKeyIdentifier. This is necessary as
we are having to deal with keys that are represented by X.509 certificates
that lack a subjectKeyIdentifier.

Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Vivek Goyal <vgoyal@redhat.com>


# b92e6570 20-Jul-2015 David Howells <dhowells@redhat.com>

X.509: Extract both parts of the AuthorityKeyIdentifier

Extract both parts of the AuthorityKeyIdentifier, not just the keyIdentifier,
as the second part can be used to match X.509 certificates by issuer and
serialNumber.

Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Vivek Goyal <vgoyal@redhat.com>


# 757932e6 16-Sep-2014 David Howells <dhowells@redhat.com>

PKCS#7: Handle PKCS#7 messages that contain no X.509 certs

The X.509 certificate list in a PKCS#7 message is optional. To save space, we
can omit the inclusion of any X.509 certificates if we are sure that we can
look the relevant public key up by the serial number and issuer given in a
signed info block.

This also supports use of a signed info block for which we can't find a
matching X.509 cert in the certificate list, though it be populated.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>


# 41559420 16-Sep-2014 David Howells <dhowells@redhat.com>

PKCS#7: Better handling of unsupported crypto

Provide better handling of unsupported crypto when verifying a PKCS#7 message.
If we can't bridge the gap between a pair of X.509 certs or between a signed
info block and an X.509 cert because it involves some crypto we don't support,
that's not necessarily the end of the world as there may be other ways points
at which we can intersect with a ring of trusted keys.

Instead, only produce ENOPKG immediately if all the signed info blocks in a
PKCS#7 message require unsupported crypto to bridge to the first X.509 cert.
Otherwise, we defer the generation of ENOPKG until we get ENOKEY during trust
validation.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>


# 46963b77 16-Sep-2014 David Howells <dhowells@redhat.com>

KEYS: Overhaul key identification when searching for asymmetric keys

Make use of the new match string preparsing to overhaul key identification
when searching for asymmetric keys. The following changes are made:

(1) Use the previously created asymmetric_key_id struct to hold the following
key IDs derived from the X.509 certificate or PKCS#7 message:

id: serial number + issuer
skid: subjKeyId + subject
authority: authKeyId + issuer

(2) Replace the hex fingerprint attached to key->type_data[1] with an
asymmetric_key_ids struct containing the id and the skid (if present).

(3) Make the asymmetric_type match data preparse select one of two searches:

(a) An iterative search for the key ID given if prefixed with "id:". The
prefix is expected to be followed by a hex string giving the ID to
search for. The criterion key ID is checked against all key IDs
recorded on the key.

(b) A direct search if the key ID is not prefixed with "id:". This will
look for an exact match on the key description.

(4) Make x509_request_asymmetric_key() take a key ID. This is then converted
into "id:<hex>" and passed into keyring_search() where match preparsing
will turn it back into a binary ID.

(5) X.509 certificate verification then takes the authority key ID and looks
up a key that matches it to find the public key for the certificate
signature.

(6) PKCS#7 certificate verification then takes the id key ID and looks up a
key that matches it to find the public key for the signed information
block signature.

Additional changes:

(1) Multiple subjKeyId and authKeyId values on an X.509 certificate cause the
cert to be rejected with -EBADMSG.

(2) The 'fingerprint' ID is gone. This was primarily intended to convey PGP
public key fingerprints. If PGP is supported in future, this should
generate a key ID that carries the fingerprint.

(3) Th ca_keyid= kernel command line option is now converted to a key ID and
used to match the authority key ID. Possibly this should only match the
actual authKeyId part and not the issuer as well.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>


# 412eccba 31-Jul-2014 David Howells <dhowells@redhat.com>

PKCS#7: X.509 certificate issuer and subject are mandatory fields in the ASN.1

X.509 certificate issuer and subject fields are mandatory fields in the ASN.1
and so their existence needn't be tested for. They are guaranteed to end up
with an empty string if the name material has nothing we can use (see
x509_fabricate_name()).

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>


# 8c76d793 01-Jul-2014 David Howells <dhowells@redhat.com>

PKCS#7: Verify internal certificate chain

Verify certificate chain in the X.509 certificates contained within the PKCS#7
message as far as possible. If any signature that we should be able to verify
fails, we reject the whole lot.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>


# a4730357 01-Jul-2014 David Howells <dhowells@redhat.com>

PKCS#7: Find the right key in the PKCS#7 key list and verify the signature

Find the appropriate key in the PKCS#7 key list and verify the signature with
it. There may be several keys in there forming a chain. Any link in that
chain or the root of that chain may be in our keyrings.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>


# 9f0d3314 01-Jul-2014 David Howells <dhowells@redhat.com>

PKCS#7: Digest the data in a signed-data message

Digest the data in a PKCS#7 signed-data message and attach to the
public_key_signature struct contained in the pkcs7_message struct.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>