Commit Graph

27 Commits

Author SHA1 Message Date
Joachim Vandersmissen
747ae81883 certs: Add ECDSA signature verification self-test
Commit c27b2d2012 ("crypto: testmgr - allow ecdsa-nist-p256 and -p384
in FIPS mode") enabled support for ECDSA in crypto/testmgr.c. The
PKCS#7 signature verification API builds upon the KCAPI primitives to
perform its high-level operations. Therefore, this change in testmgr.c
also allows ECDSA to be used by the PKCS#7 signature verification API
(in FIPS mode).

However, from a FIPS perspective, the PKCS#7 signature verification API
is a distinct "service" from the KCAPI primitives. This is because the
PKCS#7 API performs a "full" signature verification, which consists of
both hashing the data to be verified, and the public key operation.
On the other hand, the KCAPI primitive does not perform this hashing
step - it accepts pre-hashed data from the caller and only performs the
public key operation.

For this reason, the ECDSA self-tests in crypto/testmgr.c are not
sufficient to cover ECDSA signature verification offered by the PKCS#7
API. This is reflected by the self-test already present in this file
for RSA PKCS#1 v1.5 signature verification.

The solution is simply to add a second self-test here for ECDSA. P-256
with SHA-256 hashing was chosen as those parameters should remain
FIPS-approved for the foreseeable future, while keeping the performance
impact to a minimum. The ECDSA certificate and PKCS#7 signed data was
generated using OpenSSL. The input data is identical to the input data
for the existing RSA self-test.

Signed-off-by: Joachim Vandersmissen <git@jvdsn.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2024-05-14 05:01:04 +03:00
Joachim Vandersmissen
8cd9f234f7 certs: Move RSA self-test data to separate file
In preparation of adding new ECDSA self-tests, the existing data for
the RSA self-tests is moved to a separate file. This file is only
compiled if the new CONFIG_FIPS_SIGNATURE_SELFTEST_RSA configuration
option is set, which ensures that the required dependencies (RSA,
SHA-256) are present. Otherwise, the kernel would panic when trying to
execute the self-test.
The introduction of this new option, rather than adding the
dependencies to the existing CONFIG_FIPS_SIGNATURE_SELFTEST option,
allows for additional self-tests to be added for different algorithms.
The kernel can then be configured to only execute the self-tests for
those algorithms that are included.

Signed-off-by: Joachim Vandersmissen <git@jvdsn.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2024-05-14 05:01:03 +03:00
Herbert Xu
04a93202ed 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: 3cde3174eb ("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>
2023-10-27 18:04:24 +08:00
David Howells
3cde3174eb 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/
2022-06-21 16:05:12 +01:00
David Howells
60050ffe3d certs: Move load_certificate_list() to be with the asymmetric keys code
Move load_certificate_list(), which loads a series of binary X.509
certificates from a blob and inserts them as keys into a keyring, to be
with the asymmetric keys code that it drives.

This makes it easier to add FIPS selftest code in which we need to load up
a private keyring for the tests to use.

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/165515742145.1554877.13488098107542537203.stgit@warthog.procyon.org.uk/
2022-06-21 16:05:06 +01:00
Eric Biggers
d3cff4a95e KEYS: remove support for asym_tpm keys
asym_tpm keys are tied to TPM v1.2, which uses outdated crypto and has
been deprecated in favor of TPM v2.0 for over 7 years.  A very quick
look at this code also immediately found some memory safety bugs
(https://lore.kernel.org/r/20220113235440.90439-2-ebiggers@kernel.org).
Note that this code is reachable by unprivileged users.

According to Jarkko (one of the keyrings subsystem maintainers), this
code has no practical use cases, and he isn't willing to maintain it
(https://lore.kernel.org/r/YfFZPbKkgYJGWu1Q@iki.fi).

Therefore, let's remove it.

Note that this feature didn't have any documentation or tests, so we
don't need to worry about removing those.

Cc: David Howells <dhowells@redhat.com>
Cc: Denis Kenzior <denkenz@gmail.com>
Cc: James Morris <jmorris@namei.org>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2022-03-08 13:55:52 +02:00
Denis Kenzior
d5e72745ca KEYS: Add parser for TPM-based keys [ver #2]
For TPM based keys, the only standard seems to be described here:
http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#rfc.section.4.4

Quote from the relevant section:
"Rather, a common form of storage for "wrapped" keys is to encode the
binary TCPA_KEY structure in a single ASN.1 OCTET-STRING, and store the
result in PEM format with the tag "-----BEGIN TSS KEY BLOB-----". "

This patch implements the above behavior.  It is assumed that the PEM
encoding is stripped out by userspace and only the raw DER/BER format is
provided.  This is similar to how PKCS7, PKCS8 and X.509 keys are
handled.

Signed-off-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: James Morris <james.morris@microsoft.com>
2018-10-26 09:30:46 +01:00
Denis Kenzior
903be6bb84 KEYS: asym_tpm: add skeleton for asym_tpm [ver #2]
This patch adds the basic skeleton for the asym_tpm asymmetric key
subtype.

Signed-off-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: James Morris <james.morris@microsoft.com>
2018-10-26 09:30:46 +01:00
David Howells
3c58b2362b KEYS: Implement PKCS#8 RSA Private Key parser [ver #2]
Implement PKCS#8 RSA Private Key format [RFC 5208] parser for the
asymmetric key type.  For the moment, this will only support unencrypted
DER blobs.  PEM and decryption can be added later.

PKCS#8 keys can be loaded like this:

	openssl pkcs8 -in private_key.pem -topk8 -nocrypt -outform DER | \
	  keyctl padd asymmetric foo @s

Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: Denis Kenzior <denkenz@gmail.com>
Tested-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: James Morris <james.morris@microsoft.com>
2018-10-26 09:30:46 +01:00
Masahiro Yamada
4fa8bc949d kbuild: rename *-asn1.[ch] to *.asn1.[ch]
Our convention is to distinguish file types by suffixes with a period
as a separator.

*-asn1.[ch] is a different pattern from other generated sources such
as *.lex.c, *.tab.[ch], *.dtb.S, etc.  More confusing, files with
'-asn1.[ch]' are generated files, but '_asn1.[ch]' are checked-in
files:
  net/netfilter/nf_conntrack_h323_asn1.c
  include/linux/netfilter/nf_conntrack_h323_asn1.h
  include/linux/sunrpc/gss_asn1.h

Rename generated files to *.asn1.[ch] for consistency.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2018-04-07 19:04:02 +09:00
Masahiro Yamada
3ca3273eaa kbuild: clean up *-asn1.[ch] patterns from top-level Makefile
Clean up these patterns from the top Makefile to omit 'clean-files'
in each Makefile.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2018-04-07 19:04:02 +09:00
Greg Kroah-Hartman
b24413180f License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.

By default all files without license information are under the default
license of the kernel, which is GPL version 2.

Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier.  The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.

This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.

How this work was done:

Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
 - file had no licensing information it it.
 - file was a */uapi/* one with no licensing information in it,
 - file was a */uapi/* one with existing licensing information,

Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.

The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne.  Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.

The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed.  Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.

Criteria used to select files for SPDX license identifier tagging was:
 - Files considered eligible had to be source code files.
 - Make and config files were included as candidates if they contained >5
   lines of source
 - File already had some variant of a license header in it (even if <5
   lines).

All documentation files were explicitly excluded.

The following heuristics were used to determine which SPDX license
identifiers to apply.

 - when both scanners couldn't find any license traces, file was
   considered to have no license information in it, and the top level
   COPYING file license applied.

   For non */uapi/* files that summary was:

   SPDX license identifier                            # files
   ---------------------------------------------------|-------
   GPL-2.0                                              11139

   and resulted in the first patch in this series.

   If that file was a */uapi/* path one, it was "GPL-2.0 WITH
   Linux-syscall-note" otherwise it was "GPL-2.0".  Results of that was:

   SPDX license identifier                            # files
   ---------------------------------------------------|-------
   GPL-2.0 WITH Linux-syscall-note                        930

   and resulted in the second patch in this series.

 - if a file had some form of licensing information in it, and was one
   of the */uapi/* ones, it was denoted with the Linux-syscall-note if
   any GPL family license was found in the file or had no licensing in
   it (per prior point).  Results summary:

   SPDX license identifier                            # files
   ---------------------------------------------------|------
   GPL-2.0 WITH Linux-syscall-note                       270
   GPL-2.0+ WITH Linux-syscall-note                      169
   ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause)    21
   ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)    17
   LGPL-2.1+ WITH Linux-syscall-note                      15
   GPL-1.0+ WITH Linux-syscall-note                       14
   ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause)    5
   LGPL-2.0+ WITH Linux-syscall-note                       4
   LGPL-2.1 WITH Linux-syscall-note                        3
   ((GPL-2.0 WITH Linux-syscall-note) OR MIT)              3
   ((GPL-2.0 WITH Linux-syscall-note) AND MIT)             1

   and that resulted in the third patch in this series.

 - when the two scanners agreed on the detected license(s), that became
   the concluded license(s).

 - when there was disagreement between the two scanners (one detected a
   license but the other didn't, or they both detected different
   licenses) a manual inspection of the file occurred.

 - In most cases a manual inspection of the information in the file
   resulted in a clear resolution of the license that should apply (and
   which scanner probably needed to revisit its heuristics).

 - When it was not immediately clear, the license identifier was
   confirmed with lawyers working with the Linux Foundation.

 - If there was any question as to the appropriate license identifier,
   the file was flagged for further research and to be revisited later
   in time.

In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.

Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights.  The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.

Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.

In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.

Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
 - a full scancode scan run, collecting the matched texts, detected
   license ids and scores
 - reviewing anything where there was a license detected (about 500+
   files) to ensure that the applied SPDX license was correct
 - reviewing anything where there was no detection but the patch license
   was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
   SPDX license was correct

This produced a worksheet with 20 files needing minor correction.  This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.

These .csv files were then reviewed by Greg.  Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected.  This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.)  Finally Greg ran the script using the .csv files to
generate the patches.

Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-02 11:10:55 +01:00
David Howells
cfb664ff2b 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>
2016-04-11 22:42:55 +01:00
David Howells
d43de6c780 akcipher: Move the RSA DER encoding check to the crypto layer
Move the RSA EMSA-PKCS1-v1_5 encoding from the asymmetric-key public_key
subtype to the rsa crypto module's pkcs1pad template.  This means that the
public_key subtype no longer has any dependencies on public key type.

To make this work, the following changes have been made:

 (1) The rsa pkcs1pad template is now used for RSA keys.  This strips off the
     padding and returns just the message hash.

 (2) In a previous patch, the pkcs1pad template gained an optional second
     parameter that, if given, specifies the hash used.  We now give this,
     and pkcs1pad checks the encoded message E(M) for the EMSA-PKCS1-v1_5
     encoding and verifies that the correct digest OID is present.

 (3) The crypto driver in crypto/asymmetric_keys/rsa.c is now reduced to
     something that doesn't care about what the encryption actually does
     and and has been merged into public_key.c.

 (4) CONFIG_PUBLIC_KEY_ALGO_RSA is gone.  Module signing must set
     CONFIG_CRYPTO_RSA=y instead.

Thoughts:

 (*) Should the encoding style (eg. raw, EMSA-PKCS1-v1_5) also be passed to
     the padding template?  Should there be multiple padding templates
     registered that share most of the code?

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.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
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
4c0b4b1d1a pefile: Parse the "Microsoft individual code signing" data blob
The PKCS#7 certificate should contain a "Microsoft individual code signing"
data blob as its signed content.  This blob contains a digest of the signed
content of the PE binary and the OID of the digest algorithm used (typically
SHA256).

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
2014-07-09 14:58:37 +01:00
David Howells
26d1164be3 pefile: Parse a PE binary to find a key and a signature contained therein
Parse a PE binary to find a key and a signature contained therein.  Later
patches will check the signature and add the key if the signature checks out.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
2014-07-09 14:58:37 +01:00
David Howells
22d01afb21 PKCS#7: Provide a key type for testing PKCS#7
Provide a key type for testing the PKCS#7 parser.  It is given a non-detached
PKCS#7 message as payload:

	keyctl padd pkcs7_test a @s <stuff.pkcs7

The PKCS#7 wrapper is validated against the trusted certificates available and
then stripped off.  If successful, the key can be read, which will give the
data content of the PKCS#7 message.

A suitable message can be created by running make on the attached Makefile.
This will produce a file called stuff.pkcs7 for test loading.  The key3.x509
file should be put into the kernel source tree before it is built and
converted to DER form:

	openssl x509 -in .../pkcs7/key3.x509 -outform DER -out key3.x509

###############################################################################
#
# Create a pkcs7 message and sign it twice
#
#	openssl x509 -text -inform PEM -noout -in key2.x509
#
###############################################################################
stuff.pkcs7: stuff.txt key2.priv key2.x509 key4.priv key4.x509 certs
	$(RM) $@
	openssl smime -sign \
		-signer key2.x509 \
		-inkey key2.priv \
		-signer key4.x509 \
		-inkey key4.priv \
		-in stuff.txt \
		-certfile certs \
		-out $@ -binary -outform DER -nodetach
	openssl pkcs7 -inform DER -in stuff.pkcs7  -print_certs -noout
	openssl asn1parse -inform DER -in stuff.pkcs7  -i >out

stuff.txt:
	echo "The quick red fox jumped over the lazy brown dog" >stuff.txt

certs: key1.x509 key2.x509 key3.x509 key4.x509
	cat key{1,3}.x509 >$@

###############################################################################
#
# Generate a signed key
#
#	openssl x509 -text -inform PEM -noout -in key2.x509
#
###############################################################################
key2.x509: key2.x509_unsigned key1.priv key1.x509
	openssl x509 \
		-req -in key2.x509_unsigned \
		-out key2.x509 \
		-extfile key2.genkey -extensions myexts \
		-CA key1.x509 \
		-CAkey key1.priv \
		-CAcreateserial

key2.priv key2.x509_unsigned: key2.genkey
	openssl req -new -nodes -utf8 -sha1 -days 36500 \
		-batch -outform PEM \
		-config key2.genkey \
		-keyout key2.priv \
		-out key2.x509_unsigned

key2.genkey:
	@echo Generating X.509 key generation config
	@echo  >$@ "[ req ]"
	@echo >>$@ "default_bits = 4096"
	@echo >>$@ "distinguished_name = req_distinguished_name"
	@echo >>$@ "prompt = no"
	@echo >>$@ "string_mask = utf8only"
	@echo >>$@ "x509_extensions = myexts"
	@echo >>$@
	@echo >>$@ "[ req_distinguished_name ]"
	@echo >>$@ "O = Magrathea"
	@echo >>$@ "CN = PKCS7 key 2"
	@echo >>$@ "emailAddress = slartibartfast@magrathea.h2g2"
	@echo >>$@
	@echo >>$@ "[ myexts ]"
	@echo >>$@ "basicConstraints=critical,CA:FALSE"
	@echo >>$@ "keyUsage=digitalSignature"
	@echo >>$@ "subjectKeyIdentifier=hash"
	@echo >>$@ "authorityKeyIdentifier=keyid"

###############################################################################
#
# Generate a couple of signing keys
#
#	openssl x509 -text -inform PEM -noout -in key1.x509
#
###############################################################################
key1.x509: key1.x509_unsigned key4.priv key4.x509
	openssl x509 \
		-req -in key1.x509_unsigned \
		-out key1.x509 \
		-extfile key1.genkey -extensions myexts \
		-CA key4.x509 \
		-CAkey key4.priv \
		-CAcreateserial

key1.priv key1.x509_unsigned: key1.genkey
	openssl req -new -nodes -utf8 -sha1 -days 36500 \
		-batch -outform PEM \
		-config key1.genkey \
		-keyout key1.priv \
		-out key1.x509_unsigned

key1.genkey:
	@echo Generating X.509 key generation config
	@echo  >$@ "[ req ]"
	@echo >>$@ "default_bits = 4096"
	@echo >>$@ "distinguished_name = req_distinguished_name"
	@echo >>$@ "prompt = no"
	@echo >>$@ "string_mask = utf8only"
	@echo >>$@ "x509_extensions = myexts"
	@echo >>$@
	@echo >>$@ "[ req_distinguished_name ]"
	@echo >>$@ "O = Magrathea"
	@echo >>$@ "CN = PKCS7 key 1"
	@echo >>$@ "emailAddress = slartibartfast@magrathea.h2g2"
	@echo >>$@
	@echo >>$@ "[ myexts ]"
	@echo >>$@ "basicConstraints=critical,CA:TRUE"
	@echo >>$@ "keyUsage=digitalSignature,keyCertSign"
	@echo >>$@ "subjectKeyIdentifier=hash"
	@echo >>$@ "authorityKeyIdentifier=keyid"

###############################################################################
#
# Generate a signed key
#
#	openssl x509 -text -inform PEM -noout -in key4.x509
#
###############################################################################
key4.x509: key4.x509_unsigned key3.priv key3.x509
	openssl x509 \
		-req -in key4.x509_unsigned \
		-out key4.x509 \
		-extfile key4.genkey -extensions myexts \
		-CA key3.x509 \
		-CAkey key3.priv \
		-CAcreateserial

key4.priv key4.x509_unsigned: key4.genkey
	openssl req -new -nodes -utf8 -sha1 -days 36500 \
		-batch -outform PEM \
		-config key4.genkey \
		-keyout key4.priv \
		-out key4.x509_unsigned

key4.genkey:
	@echo Generating X.509 key generation config
	@echo  >$@ "[ req ]"
	@echo >>$@ "default_bits = 4096"
	@echo >>$@ "distinguished_name = req_distinguished_name"
	@echo >>$@ "prompt = no"
	@echo >>$@ "string_mask = utf8only"
	@echo >>$@ "x509_extensions = myexts"
	@echo >>$@
	@echo >>$@ "[ req_distinguished_name ]"
	@echo >>$@ "O = Magrathea"
	@echo >>$@ "CN = PKCS7 key 4"
	@echo >>$@ "emailAddress = slartibartfast@magrathea.h2g2"
	@echo >>$@
	@echo >>$@ "[ myexts ]"
	@echo >>$@ "basicConstraints=critical,CA:TRUE"
	@echo >>$@ "keyUsage=digitalSignature,keyCertSign"
	@echo >>$@ "subjectKeyIdentifier=hash"
	@echo >>$@ "authorityKeyIdentifier=keyid"

###############################################################################
#
# Generate a couple of signing keys
#
#	openssl x509 -text -inform PEM -noout -in key3.x509
#
###############################################################################
key3.priv key3.x509: key3.genkey
	openssl req -new -nodes -utf8 -sha1 -days 36500 \
		-batch -x509 -outform PEM \
		-config key3.genkey \
		-keyout key3.priv \
		-out key3.x509

key3.genkey:
	@echo Generating X.509 key generation config
	@echo  >$@ "[ req ]"
	@echo >>$@ "default_bits = 4096"
	@echo >>$@ "distinguished_name = req_distinguished_name"
	@echo >>$@ "prompt = no"
	@echo >>$@ "string_mask = utf8only"
	@echo >>$@ "x509_extensions = myexts"
	@echo >>$@
	@echo >>$@ "[ req_distinguished_name ]"
	@echo >>$@ "O = Magrathea"
	@echo >>$@ "CN = PKCS7 key 3"
	@echo >>$@ "emailAddress = slartibartfast@magrathea.h2g2"
	@echo >>$@
	@echo >>$@ "[ myexts ]"
	@echo >>$@ "basicConstraints=critical,CA:TRUE"
	@echo >>$@ "keyUsage=digitalSignature,keyCertSign"
	@echo >>$@ "subjectKeyIdentifier=hash"
	@echo >>$@ "authorityKeyIdentifier=keyid"

clean:
	$(RM) *~
	$(RM) key1.* key2.* key3.* key4.* stuff.* out certs

Signed-off-by: David Howells <dhowells@redhat.com>
2014-07-08 13:50:20 +01:00
David Howells
08815b62d7 PKCS#7: Find intersection between PKCS#7 message and known, trusted keys
Find the intersection between the X.509 certificate chain contained in a PKCS#7
message and a set of keys that we already know and trust.

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:15 +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
David Howells
2e3fadbf73 PKCS#7: Implement a parser [RFC 2315]
Implement a parser for a PKCS#7 signed-data message as described in part of
RFC 2315.

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:49:56 +01:00
David Howells
c26fd69fa0 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>
2012-10-08 13:50:22 +10:30
David Howells
612e0fe999 RSA: Implement signature verification algorithm [PKCS#1 / RFC3447]
Implement RSA public key cryptography [PKCS#1 / RFC3447].  At this time, only
the signature verification algorithm is supported.  This uses the asymmetric
public key subtype to hold its key data.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2012-10-08 13:50:16 +10:30
David Howells
4ae71c1dce KEYS: Provide signature verification with an asymmetric key
Provide signature verification using an asymmetric-type key to indicate the
public key to be used.

The API is a single function that can be found in crypto/public_key.h:

	int verify_signature(const struct key *key,
			     const struct public_key_signature *sig)

The first argument is the appropriate key to be used and the second argument
is the parsed signature data:

	struct public_key_signature {
		u8 *digest;
		u16 digest_size;
		enum pkey_hash_algo pkey_hash_algo : 8;
		union {
			MPI mpi[2];
			struct {
				MPI s;		/* m^d mod n */
			} rsa;
			struct {
				MPI r;
				MPI s;
			} dsa;
		};
	};

This should be filled in prior to calling the function.  The hash algorithm
should already have been called and the hash finalised and the output should
be in a buffer pointed to by the 'digest' member.

Any extra data to be added to the hash by the hash format (eg. PGP) should
have been added by the caller prior to finalising the hash.

It is assumed that the signature is made up of a number of MPI values.  If an
algorithm becomes available for which this is not the case, the above structure
will have to change.

It is also assumed that it will have been checked that the signature algorithm
matches the key algorithm.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2012-10-08 13:50:15 +10:30
David Howells
a9681bf3dd KEYS: Asymmetric public-key algorithm crypto key subtype
Add a subtype for supporting asymmetric public-key encryption algorithms such
as DSA (FIPS-186) and RSA (PKCS#1 / RFC1337).

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2012-10-08 13:50:14 +10:30
David Howells
964f3b3bf4 KEYS: Implement asymmetric key type
Create a key type that can be used to represent an asymmetric key type for use
in appropriate cryptographic operations, such as encryption, decryption,
signature generation and signature verification.

The key type is "asymmetric" and can provide access to a variety of
cryptographic algorithms.

Possibly, this would be better as "public_key" - but that has the disadvantage
that "public key" is an overloaded term.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2012-10-08 13:50:12 +10:30