History log of /linux-master/crypto/asymmetric_keys/x509_public_key.c
Revision Date Author Comments
# 04a93202 15-Oct-2023 Herbert Xu <herbert@gondor.apana.org.au>

certs: Break circular dependency when selftest is modular

The modular build fails because the self-test code depends on pkcs7
which in turn depends on x509 which contains the self-test.

Split the self-test out into its own module to break the cycle.

Fixes: 3cde3174eb91 ("certs: Add FIPS selftests")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


# ef5b52a6 15-Aug-2023 Thore Sommer <public@thson.de>

X.509: if signature is unsupported skip validation

When the hash algorithm for the signature is not available the digest size
is 0 and the signature in the certificate is marked as unsupported.

When validating a self-signed certificate, this needs to be checked,
because otherwise trying to validate the signature will fail with an
warning:

Loading compiled-in X.509 certificates
WARNING: CPU: 0 PID: 1 at crypto/rsa-pkcs1pad.c:537 \
pkcs1pad_verify+0x46/0x12c
...
Problem loading in-kernel X.509 certificate (-22)

Signed-off-by: Thore Sommer <public@thson.de>
Cc: stable@vger.kernel.org # v4.7+
Fixes: 6c2dc5ae4ab7 ("X.509: Extract signature digest and make self-signed cert checks earlier")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


# e5221fa6 15-Jun-2023 Herbert Xu <herbert@gondor.apana.org.au>

KEYS: asymmetric: Move sm2 code into x509_public_key

The sm2 certificate requires a modified digest. Move the code
for the hashing from the signature verification path into the
code where we generate the digest.

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


# 3cde3174 18-May-2022 David Howells <dhowells@redhat.com>

certs: Add FIPS selftests

Add some selftests for signature checking when FIPS mode is enabled. These
need to be done before we start actually using the signature checking for
things and must panic the kernel upon failure.

Note that the tests must not check the blacklist lest this provide a way to
prevent a kernel from booting by installing a hash of a test key in the
appropriate UEFI table.

Reported-by: Simo Sorce <simo@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
Link: https://lore.kernel.org/r/165515742832.1554877.2073456606206090838.stgit@warthog.procyon.org.uk/


# 141e5239 12-Jul-2021 Mickaël Salaün <mic@linux.microsoft.com>

certs: Factor out the blacklist hash creation

Factor out the blacklist hash creation with the get_raw_hash() helper.
This also centralize the "tbs" and "bin" prefixes and make them private,
which help to manage them consistently.

Cc: David Howells <dhowells@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Eric Snowberg <eric.snowberg@oracle.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Link: https://lore.kernel.org/r/20210712170313.884724-5-mic@digikod.net
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>


# 8bdc3e05 18-Jan-2022 Eric Biggers <ebiggers@google.com>

KEYS: x509: remove dead code that set ->unsupported_sig

The X.509 parser always sets cert->sig->pkey_algo and
cert->sig->hash_algo on success, since x509_note_sig_algo() is a
mandatory action in the X.509 ASN.1 grammar, and it returns an error if
the signature's algorithm is unknown. Thus, remove the dead code which
handled these fields being NULL.

Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@google.com>
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>


# 7d30198e 09-Nov-2021 Andrew Zaborowski <andrew.zaborowski@intel.com>

keys: X.509 public key issuer lookup without AKID

There are non-root X.509 v3 certificates in use out there that contain
no Authority Key Identifier extension (RFC5280 section 4.2.1.1). For
trust verification purposes the kernel asymmetric key type keeps two
struct asymmetric_key_id instances that the key can be looked up by,
and another two to look up the key's issuer. The x509 public key type
and the PKCS7 type generate them from the SKID and AKID extensions in
the certificate. In effect current code has no way to look up the
issuer certificate for verification without the AKID.

To remedy this, add a third asymmetric_key_id blob to the arrays in
both asymmetric_key_id's (for certficate subject) and in the
public_keys_signature's auth_ids (for issuer lookup), using just raw
subject and issuer DNs from the certificate. Adapt
asymmetric_key_ids() and its callers to use the third ID for lookups
when none of the other two are available. Attempt to keep the logic
intact when they are, to minimise behaviour changes. Adapt the
restrict functions' NULL-checks to include that ID too. Do not modify
the lookup logic in pkcs7_verify.c, the AKID extensions are still
required there.

Internally use a new "dn:" prefix to the search specifier string
generated for the key lookup in find_asymmetric_key(). This tells
asymmetric_key_match_preparse to only match the data against the raw
DN in the third ID and shouldn't conflict with search specifiers
already in use.

In effect implement what (2) in the struct asymmetric_key_id comment
(include/keys/asymmetric-type.h) is probably talking about already, so
do not modify that comment. It is also how "openssl verify" looks up
issuer certificates without the AKID available. Lookups by the raw
DN are unambiguous only provided that the CAs respect the condition in
RFC5280 4.2.1.1 that the AKID may only be omitted if the CA uses
a single signing key.

The following is an example of two things that this change enables.
A self-signed ceritficate is generated following the example from
https://letsencrypt.org/docs/certificates-for-localhost/, and can be
looked up by an identifier and verified against itself by linking to a
restricted keyring -- both things not possible before due to the missing
AKID extension:

$ openssl req -x509 -out localhost.crt -outform DER -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
echo -e "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\n" \
"subjectAltName=DNS:localhost\nkeyUsage=digitalSignature\n" \
"extendedKeyUsage=serverAuth")
$ keyring=`keyctl newring test @u`
$ trusted=`keyctl padd asymmetric trusted $keyring < localhost.crt`; \
echo $trusted
39726322
$ keyctl search $keyring asymmetric dn:3112301006035504030c096c6f63616c686f7374
39726322
$ keyctl restrict_keyring $keyring asymmetric key_or_keyring:$trusted
$ keyctl padd asymmetric verified $keyring < localhost.crt

Signed-off-by: Andrew Zaborowski <andrew.zaborowski@intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>


# 299f561a 16-Mar-2021 Stefan Berger <stefanb@linux.ibm.com>

x509: Add support for parsing x509 certs with ECDSA keys

Add support for parsing of x509 certificates that contain ECDSA keys,
such as NIST P256, that have been signed by a CA using any of the
current SHA hash algorithms.

Cc: David Howells <dhowells@redhat.com>
Cc: keyrings@vger.kernel.org
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


# 21552563 20-Sep-2020 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>

X.509: support OSCCA SM2-with-SM3 certificate verification

The digital certificate format based on SM2 crypto algorithm as
specified in GM/T 0015-2012. It was published by State Encryption
Management Bureau, China.

The method of generating Other User Information is defined as
ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA), it also
specified in https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02.

The x509 certificate supports SM2-with-SM3 type certificate
verification. Because certificate verification requires ZA
in addition to tbs data, ZA also depends on elliptic curve
parameters and public key data, so you need to access tbs in sig
and calculate ZA. Finally calculate the digest of the
signature and complete the verification work. The calculation
process of ZA is declared in specifications GM/T 0009-2012
and GM/T 0003.2-2012.

Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Tested-by: Xufeng Zhang <yunbo.xufeng@linux.alibaba.com>
Reviewed-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


# 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>


# 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>


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

X.509: 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>


# 1e684d38 15-Nov-2017 David Howells <dhowells@redhat.com>

pkcs7: Set the module licence to prevent tainting

Set the module licence to prevent the kernel from being tainted if loaded
as a module.

Reported-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: David Howells <dhowells@redhat.com>


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

X.509: Allow X.509 certs to be blacklisted

Allow X.509 certs to be blacklisted based on their TBSCertificate hash.
This is convenient since we have to determine this anyway to be able to
check the signature on an X.509 certificate. This is also what UEFI uses
in its blacklist.

If a certificate built into the kernel is blacklisted, something like the
following might then be seen during boot:

X.509: Cert 123412341234c55c1dcc601ab8e172917706aa32fb5eaf826813547fdf02dd46 is blacklisted
Problem loading in-kernel X.509 certificate (-129)

where the hex string shown is the blacklisted hash.

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


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

KEYS: Move the point of trust determination to __key_link()

Move the point at which a key is determined to be trustworthy to
__key_link() so that we use the contents of the keyring being linked in to
to determine whether the key being linked in is trusted or not.

What is 'trusted' then becomes a matter of what's in the keyring.

Currently, the test is done when the key is parsed, but given that at that
point we can only sensibly refer to the contents of the system trusted
keyring, we can only use that as the basis for working out the
trustworthiness of a new key.

With this change, a trusted keyring is a set of keys that once the
trusted-only flag is set cannot be added to except by verification through
one of the contained keys.

Further, adding a key into a trusted keyring, whilst it might grant
trustworthiness in the context of that keyring, does not automatically
grant trustworthiness in the context of a second keyring to which it could
be secondarily linked.

To accomplish this, the authentication data associated with the key source
must now be retained. For an X.509 cert, this means the contents of the
AuthorityKeyIdentifier and the signature data.


If system keyrings are disabled then restrict_link_by_builtin_trusted()
resolves to restrict_link_reject(). The integrity digital signature code
still works correctly with this as it was previously using
KEY_FLAG_TRUSTED_ONLY, which doesn't permit anything to be added if there
is no system keyring against which trust can be determined.

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


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

X.509: Move the trust validation code out to its own file

Move the X.509 trust validation code out to its own file so that it can be
generalised.

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


# 5f7f5c81 06-Apr-2016 David Howells <dhowells@redhat.com>

X.509: Use verify_signature() if we have a struct key * to use

We should call verify_signature() rather than directly calling
public_key_verify_signature() if we have a struct key to use as we
shouldn't be poking around in the private data of the key struct as that's
subtype dependent.

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


# 9eb02989 06-Apr-2016 David Howells <dhowells@redhat.com>

KEYS: Generalise x509_request_asymmetric_key()

Generalise x509_request_asymmetric_key(). It doesn't really have any
dependencies on X.509 features as it uses generalised IDs and the
public_key structs that contain data extracted from X.509.

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


# 983023f2 06-Apr-2016 David Howells <dhowells@redhat.com>

KEYS: Move x509_request_asymmetric_key() to asymmetric_type.c

Move x509_request_asymmetric_key() to asymmetric_type.c so that it can be
generalised.

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


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

X.509: Fix self-signed determination

There's a bug in the code determining whether a certificate is self-signed
or not: if they have neither AKID nor SKID then we just assume that the
cert is self-signed, which may not be true.

Fix this by checking that the raw subject name matches the raw issuer name
and that the public key algorithm for the key and signature are both the
same in addition to requiring that the AKID bits match.

Signed-off-by: David Howells <dhowells@redhat.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>


# 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>


# 864e7a81 06-Apr-2016 David Howells <dhowells@redhat.com>

X.509: Whitespace cleanup

Clean up some whitespace.

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>


# 41c89b64 02-Dec-2015 Petko Manolov <petkan@mip-labs.com>

IMA: create machine owner and blacklist keyrings

This option creates IMA MOK and blacklist keyrings. IMA MOK is an
intermediate keyring that sits between .system and .ima keyrings,
effectively forming a simple CA hierarchy. To successfully import a key
into .ima_mok it must be signed by a key which CA is in .system keyring.
On turn any key that needs to go in .ima keyring must be signed by CA in
either .system or .ima_mok keyrings. IMA MOK is empty at kernel boot.

IMA blacklist keyring contains all revoked IMA keys. It is consulted
before any other keyring. If the search is successful the requested
operation is rejected and error is returned to the caller.

Signed-off-by: Petko Manolov <petkan@mip-labs.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>


# 146aa8b1 21-Oct-2015 David Howells <dhowells@redhat.com>

KEYS: Merge the type-specific data with the payload data

Merge the type-specific data with the payload data into one four-word chunk
as it seems pointless to keep them separate.

Use user_key_payload() for accessing the payloads of overloaded
user-defined keys.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: linux-cifs@vger.kernel.org
cc: ecryptfs@vger.kernel.org
cc: linux-ext4@vger.kernel.org
cc: linux-f2fs-devel@lists.sourceforge.net
cc: linux-nfs@vger.kernel.org
cc: ceph-devel@vger.kernel.org
cc: linux-ima-devel@lists.sourceforge.net


# 271817a3 19-Oct-2015 Sowmini Varadhan <sowmini.varadhan@oracle.com>

crypto: asymmetric_keys - Fix unaligned access in x509_get_sig_params()

x509_get_sig_params() has the same code pattern as the one in
pkcs7_verify() that is fixed by commit 62f57d05e287 ("crypto: pkcs7 - Fix
unaligned access in pkcs7_verify()") so apply a similar fix here: make
sure that desc is pointing at an algined value past the digest_size,
and take alignment values into consideration when doing kzalloc()

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


# e7c87bef 25-Sep-2015 David Howells <dhowells@redhat.com>

X.509: Don't strip leading 00's from key ID when constructing key description

Don't strip leading zeros from the crypto key ID when using it to construct
the struct key description as the signature in kernels up to and including
4.2 matched this aspect of the key. This means that 1 in 256 keys won't
actually match if their key ID begins with 00.

The key ID is stored in the module signature as binary and so must be
converted to text in order to invoke request_key() - but it isn't stripped
at this point.

Something like this is likely to be observed in dmesg when the key is loaded:

[ 1.572423] Loaded X.509 cert 'Build time autogenerated kernel
key: 62a7c3d2da278be024da4af8652c071f3fea33'

followed by this when we try and use it:

[ 1.646153] Request for unknown module key 'Build time autogenerated
kernel key: 0062a7c3d2da278be024da4af8652c071f3fea33' err -11

The 'Loaded' line should show an extra '00' on the front of the hex string.

This problem should not affect 4.3-rc1 and onwards because there the key
should be matched on one of its auxiliary identities rather than the key
struct's description string.

Reported-by: Arjan van de Ven <arjan@linux.intel.com>
Reported-by: Andy Whitcroft <apw@canonical.com>
Signed-off-by: David Howells <dhowells@redhat.com>


# fd19a3d1 29-Jul-2015 David Howells <dhowells@redhat.com>

PKCS#7: Improve and export the X.509 ASN.1 time object decoder

Make the X.509 ASN.1 time object decoder fill in a time64_t rather than a
struct tm to make comparison easier (unfortunately, this makes readable
display less easy) and export it so that it can be used by the PKCS#7 code
too.

Further, tighten up its parsing to reject invalid dates (eg. weird
characters, non-existent hour numbers) and unsupported dates (eg. timezones
other than 'Z' or dates earlier than 1970).

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: David Woodhouse <David.Woodhouse@intel.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>


# f2b3dee4 11-Feb-2015 Mimi Zohar <zohar@linux.vnet.ibm.com>

KEYS: fix "ca_keys=" partial key matching

The call to asymmetric_key_hex_to_key_id() from ca_keys_setup()
silently fails with -ENOMEM. Instead of dynamically allocating
memory from a __setup function, this patch defines a variable
and calls __asymmetric_key_hex_to_key_id(), a new helper function,
directly.

This bug was introduced by 'commit 46963b774d44 ("KEYS: Overhaul
key identification when searching for asymmetric keys")'.

Changelog:
- for clarification, rename hexlen to asciihexlen in
asymmetric_key_hex_to_key_id()
- add size argument to __asymmetric_key_hex_to_key_id() - David Howells
- inline __asymmetric_key_hex_to_key_id() - David Howells
- remove duplicate strlen() calls

Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Cc: stable@vger.kernel.org # 3.18


# 7a224e78 06-Oct-2014 Dmitry Kasatkin <d.kasatkin@samsung.com>

KEYS: strip 'id:' from ca_keyid

The 'id:' prefix must be stripped for asymmetric_key_hex_to_key_id() to be
able to process ca_keyid.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: David Howells <dhowells@redhat.com>


# f1b731db 06-Oct-2014 Dmitry Kasatkin <d.kasatkin@samsung.com>

KEYS: Restore partial ID matching functionality for asymmetric keys

Bring back the functionality whereby an asymmetric key can be matched with a
partial match on one of its IDs.

Whilst we're at it, allow for the possibility of having an increased number of
IDs.

Reported-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: David Howells <dhowells@redhat.com>


# dd2f6c44 03-Oct-2014 David Howells <dhowells@redhat.com>

X.509: If available, use the raw subjKeyId to form the key description

Module signing matches keys by comparing against the key description exactly.
However, the way the key description gets constructed got changed to be
composed of the subject name plus the certificate serial number instead of the
subject name and the subjectKeyId. I changed this to avoid problems with
certificates that don't *have* a subjectKeyId.

Instead, if available, use the raw subjectKeyId to form the key description
and only use the serial number if the subjectKeyId doesn't exist.

Reported-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: David Howells <dhowells@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>


# cf5b50fd 02-Aug-2014 David Howells <dhowells@redhat.com>

X.509: Need to export x509_request_asymmetric_key()

Need to export x509_request_asymmetric_key() so that PKCS#7 can use it if
compiled as a module.

Reported-by: James Morris <jmorris@namei.org>
Signed-off-by: David Howells <dhowells@redhat.com>


# 5ce43ad2 28-Jul-2014 David Howells <dhowells@redhat.com>

PKCS#7: Use x509_request_asymmetric_key()

pkcs7_request_asymmetric_key() and x509_request_asymmetric_key() do the same
thing, the latter being a copy of the former created by the IMA folks, so drop
the PKCS#7 version as the X.509 location is more general.

Whilst we're at it, rename the arguments of x509_request_asymmetric_key() to
better reflect what the values being passed in are intended to match on an
X.509 cert.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>


# 185de09c 09-Jul-2014 David Howells <dhowells@redhat.com>

X.509: x509_request_asymmetric_keys() doesn't need string length arguments

x509_request_asymmetric_keys() doesn't need the lengths of the NUL-terminated
strings passing in as it can work that out for itself.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>


# fc7c70e0 18-Jul-2014 David Howells <dhowells@redhat.com>

KEYS: struct key_preparsed_payload should have two payload pointers

struct key_preparsed_payload should have two payload pointers to correspond
with those in struct key.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Steve Dickson <steved@redhat.com>
Acked-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Sage Weil <sage@redhat.com>


# 32c4741c 17-Jun-2014 Dmitry Kasatkin <d.kasatkin@samsung.com>

KEYS: validate certificate trust only with builtin keys

Instead of allowing public keys, with certificates signed by any
key on the system trusted keyring, to be added to a trusted keyring,
this patch further restricts the certificates to those signed only by
builtin keys on the system keyring.

This patch defines a new option 'builtin' for the kernel parameter
'keys_ownerid' to allow trust validation using builtin keys.

Simplified Mimi's "KEYS: define an owner trusted keyring" patch

Changelog v7:
- rename builtin_keys to use_builtin_keys

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>


# ffb70f61 17-Jun-2014 Dmitry Kasatkin <d.kasatkin@samsung.com>

KEYS: validate certificate trust only with selected key

Instead of allowing public keys, with certificates signed by any
key on the system trusted keyring, to be added to a trusted keyring,
this patch further restricts the certificates to those signed by a
particular key on the system keyring.

This patch defines a new kernel parameter 'ca_keys' to identify the
specific key which must be used for trust validation of certificates.

Simplified Mimi's "KEYS: define an owner trusted keyring" patch.

Changelog:
- support for builtin x509 public keys only
- export "asymmetric_keyid_match"
- remove ifndefs MODULE
- rename kernel boot parameter from keys_ownerid to ca_keys

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>


# 3be4beaf 20-Aug-2013 Mimi Zohar <zohar@linux.vnet.ibm.com>

KEYS: verify a certificate is signed by a 'trusted' key

Only public keys, with certificates signed by an existing
'trusted' key on the system trusted keyring, should be added
to a trusted keyring. This patch adds support for verifying
a certificate's signature.

This is derived from David Howells pkcs7_request_asymmetric_key() patch.

Changelog v6:
- on error free key - Dmitry
- validate trust only for not already trusted keys - Dmitry
- formatting cleanup

Changelog:
- define get_system_trusted_keyring() to fix kbuild issues

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>


# 4c1cc40a 23-Nov-2013 Linus Torvalds <torvalds@linux-foundation.org>

Revert "KEYS: verify a certificate is signed by a 'trusted' key"

This reverts commit 09fbc47373826d67531380662b516de2da120545, which
caused the following build errors:

crypto/asymmetric_keys/x509_public_key.c: In function ‘x509_key_preparse’:
crypto/asymmetric_keys/x509_public_key.c:237:35: error: ‘system_trusted_keyring’ undeclared (first use in this function)
ret = x509_validate_trust(cert, system_trusted_keyring);
^
crypto/asymmetric_keys/x509_public_key.c:237:35: note: each undeclared identifier is reported only once for each function it appears in

reported by Jim Davis. Mimi says:

"I made the classic mistake of requesting this patch to be upstreamed
at the last second, rather than waiting until the next open window.

At this point, the best course would probably be to revert the two
commits and fix them for the next open window"

Reported-by: Jim Davis <jim.epost@gmail.com>
Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>


# c7c8bb23 25-Apr-2013 Dmitry Kasatkin <d.kasatkin@samsung.com>

ima: provide support for arbitrary hash algorithms

In preparation of supporting more hash algorithms with larger hash sizes
needed for signature verification, this patch replaces the 20 byte sized
digest, with a more flexible structure. The new structure includes the
hash algorithm, digest size, and digest.

Changelog:
- recalculate filedata hash for the measurement list, if the signature
hash digest size is greater than 20 bytes.
- use generic HASH_ALGO_
- make ima_calc_file_hash static
- scripts lindent and checkpatch fixes

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>


# 3fe78ca2 06-May-2013 Dmitry Kasatkin <d.kasatkin@samsung.com>

keys: change asymmetric keys to use common hash definitions

This patch makes use of the newly defined common hash algorithm info,
replacing, for example, PKEY_HASH with HASH_ALGO.

Changelog:
- Lindent fixes - Mimi

CC: David Howells <dhowells@redhat.com>
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>


# e19aaa7d 17-Sep-2013 Konstantin Khlebnikov <khlebnikov@openvz.org>

X.509: add module description and license

This patch fixes lack of license, otherwise x509_key_parser.ko taints kernel.

Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Signed-off-by: David Howells <dhowells@redhat.com>


# 09fbc473 20-Aug-2013 Mimi Zohar <zohar@linux.vnet.ibm.com>

KEYS: verify a certificate is signed by a 'trusted' key

Only public keys, with certificates signed by an existing
'trusted' key on the system trusted keyring, should be added
to a trusted keyring. This patch adds support for verifying
a certificate's signature.

This is derived from David Howells pkcs7_request_asymmetric_key() patch.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>


# 124df926 18-Jun-2013 David Howells <dhowells@redhat.com>

X.509: Remove certificate date checks

Remove the certificate date checks that are performed when a certificate is
parsed. There are two checks: a valid from and a valid to. The first check is
causing a lot of problems with system clocks that don't keep good time and the
second places an implicit expiry date upon the kernel when used for module
signing, so do we really need them?

Signed-off-by: David Howells <dhowells@redhat.com>
cc: David Woodhouse <dwmw2@infradead.org>
cc: Rusty Russell <rusty@rustcorp.com.au>
cc: Josh Boyer <jwboyer@redhat.com>
cc: Alexander Holler <holler@ahsoftware.de>
cc: stable@vger.kernel.org


# 17334cab 30-Aug-2013 David Howells <dhowells@redhat.com>

X.509: Handle certificates that lack an authorityKeyIdentifier field

Handle certificates that lack an authorityKeyIdentifier field by assuming
they're self-signed and checking their signatures against themselves.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Josh Boyer <jwboyer@redhat.com>


# 2ecdb23b 30-Aug-2013 David Howells <dhowells@redhat.com>

X.509: Check the algorithm IDs obtained from parsing an X.509 certificate

Check that the algorithm IDs obtained from the ASN.1 parse by OID lookup
corresponds to algorithms that are available to us.

Reported-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Howells <dhowells@redhat.com>


# b426beb6 30-Aug-2013 David Howells <dhowells@redhat.com>

X.509: Embed public_key_signature struct and create filler function

Embed a public_key_signature struct in struct x509_certificate, eliminating
now unnecessary fields, and split x509_check_signature() to create a filler
function for it that attaches a digest of the signed data and an MPI that
represents the signature data. x509_free_certificate() is then modified to
deal with these.

Whilst we're at it, export both x509_check_signature() and the new
x509_get_sig_params().

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Josh Boyer <jwboyer@redhat.com>


# 3d167d68 30-Aug-2013 David Howells <dhowells@redhat.com>

KEYS: Split public_key_verify_signature() and make available

Modify public_key_verify_signature() so that it now takes a public_key struct
rather than a key struct and supply a wrapper that takes a key struct. The
wrapper is then used by the asymmetric key subtype and the modified function is
used by X.509 self-signature checking and can be used by other things also.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Josh Boyer <jwboyer@redhat.com>


# 67f7d60b 30-Aug-2013 David Howells <dhowells@redhat.com>

KEYS: Store public key algo ID in public_key struct

Store public key algo ID in public_key struct for reference purposes. This
allows it to be removed from the x509_certificate struct and used to find a
default in public_key_verify_signature().

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Josh Boyer <jwboyer@redhat.com>


# 206ce59a 30-Aug-2013 David Howells <dhowells@redhat.com>

KEYS: Move the algorithm pointer array from x509 to public_key.c

Move the public-key algorithm pointer array from x509_public_key.c to
public_key.c as it isn't X.509 specific.

Note that to make this configure correctly, the public key part must be
dependent on the RSA module rather than the other way round. This needs a
further patch to make use of the crypto module loading stuff rather than using
a fixed table.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Josh Boyer <jwboyer@redhat.com>


# 9abc4e66 30-Aug-2013 David Howells <dhowells@redhat.com>

KEYS: Rename public key parameter name arrays

Rename the arrays of public key parameters (public key algorithm names, hash
algorithm names and ID type names) so that the array name ends in "_name".

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Josh Boyer <jwboyer@redhat.com>


# 2f1c4fef 04-Oct-2012 David Howells <dhowells@redhat.com>

X.509: Convert some printk calls to pr_devel

Some debugging printk() calls should've been converted to pr_devel() calls.
Do that now.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>


# a5752d11 02-Oct-2012 David Howells <dhowells@redhat.com>

MODSIGN: Fix 32-bit overflow in X.509 certificate validity date checking

The current choice of lifetime for the autogenerated X.509 of 100 years,
putting the validTo date in 2112, causes problems on 32-bit systems where a
32-bit time_t wraps in 2106. 64-bit x86_64 systems seem to be unaffected.

This can result in something like:

Loading module verification certificates
X.509: Cert 6e03943da0f3b015ba6ed7f5e0cac4fe48680994 has expired
MODSIGN: Problem loading in-kernel X.509 certificate (-127)

Or:

X.509: Cert 6e03943da0f3b015ba6ed7f5e0cac4fe48680994 is not yet valid
MODSIGN: Problem loading in-kernel X.509 certificate (-129)

Instead of turning the dates into time_t values and comparing, turn the system
clock and the ASN.1 dates into tm structs and compare those piecemeal instead.

Reported-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Josh Boyer <jwboyer@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>


# c26fd69f 24-Sep-2012 David Howells <dhowells@redhat.com>

X.509: Add a crypto key parser for binary (DER) X.509 certificates

Add a crypto key parser for binary (DER) encoded X.509 certificates. The
certificate is parsed and, if possible, the signature is verified.

An X.509 key can be added like this:

# keyctl padd crypto bar @s </tmp/x509.cert
15768135

and displayed like this:

# cat /proc/keys
00f09a47 I--Q--- 1 perm 39390000 0 0 asymmetri bar: X509.RSA e9fd6d08 []

Note that this only works with binary certificates. PEM encoded certificates
are ignored by the parser.

Note also that the X.509 key ID is not congruent with the PGP key ID, but for
the moment, they will match.

If a NULL or "" name is given to add_key(), then the parser will generate a key
description from the CertificateSerialNumber and Name fields of the
TBSCertificate:

00aefc4e I--Q--- 1 perm 39390000 0 0 asymmetri bfbc0cd76d050ea4:/C=GB/L=Cambridge/O=Red Hat/CN=kernel key: X509.RSA 0c688c7b []

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>