Граф коммитов

29 Коммитов

Автор SHA1 Сообщение Дата
Robbie Harwood 0efd9ed929 asymmetric_keys: log on fatal failures in PE/pkcs7
[ Upstream commit 3584c1dbff ]

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
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-04-20 12:13:54 +02:00
Eric Biggers 255921f63a KEYS: asymmetric: enforce that sig algo matches key algo
commit 2abc9c246e upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-08 14:22:51 +02:00
YueHaibing 3c0940c4ff 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>
2021-01-21 16:16:09 +00:00
Thiago Jung Bauermann e201af16d1 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>
2019-08-05 18:40:19 -04:00
Thomas Gleixner b4d0d230cc 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>
2019-05-24 17:27:11 +02:00
Eric Biggers 877b5691f2 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>
2019-04-25 15:38:12 +08:00
Eric Biggers 29f4a67c17 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: 03bb79315d ("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>
2018-02-22 14:38:33 +00:00
Eric Biggers 971b42c038 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: 6c2dc5ae4a ("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>
2018-02-22 14:38:33 +00:00
Eric Biggers 54c1fb39fe X.509: fix comparisons of ->pkey_algo
->pkey_algo used to be an enum, but was changed to a string by commit
4e8ae72a75 ("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: 4e8ae72a75 ("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>
2017-12-08 15:13:29 +00:00
Eric Biggers a80745a6de 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>
2017-12-08 15:13:28 +00:00
David Howells 03bb79315d 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>
2017-04-03 16:07:25 +01:00
Lans Zhang a46e667887 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>
2016-07-18 12:19:44 +10:00
David Howells 6c2dc5ae4a 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>
2016-04-06 16:13:34 +01:00
David Howells 566a117a8b 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>
2016-04-06 16:13:33 +01:00
David Howells 77d0910d15 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>
2016-04-06 16:13:33 +01:00
David Howells 4e8ae72a75 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>
2016-03-03 21:49:27 +00:00
Tadeusz Struk db6c43bd21 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>
2016-02-10 10:13:27 +00:00
Sowmini Varadhan 62f57d05e2 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>
2015-10-14 22:23:38 +08:00
David Howells 99db443506 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>
2015-08-12 17:01:01 +01:00
David Howells 4ebdb76f7d 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>
2015-08-07 16:26:13 +01:00
David Howells 4573b64a31 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>
2015-08-07 16:26:13 +01:00
David Howells b92e6570a9 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>
2015-08-07 16:26:13 +01:00
David Howells 757932e6da 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>
2014-09-16 17:36:17 +01:00
David Howells 4155942000 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>
2014-09-16 17:36:15 +01:00
David Howells 46963b774d 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>
2014-09-16 17:36:13 +01:00
David Howells 412eccbadf 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>
2014-07-31 14:46:44 +01:00
David Howells 8c76d79393 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>
2014-07-08 13:50:11 +01:00
David Howells a4730357ee 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>
2014-07-08 13:50:08 +01:00
David Howells 9f0d33146e 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>
2014-07-08 13:50:03 +01:00