From 652bfcb76fe689f4d85b6f3688025a87fb94f9a1 Mon Sep 17 00:00:00 2001 From: Yue Haibing Date: Wed, 31 Jul 2024 15:43:13 +0800 Subject: [PATCH 1/5] KEYS: Remove unused declarations These declarations are never implemented, remove it. Signed-off-by: Yue Haibing Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- include/keys/dns_resolver-type.h | 4 ---- include/linux/key.h | 3 --- 2 files changed, 7 deletions(-) diff --git a/include/keys/dns_resolver-type.h b/include/keys/dns_resolver-type.h index 218ca22fb056..1b89088a2837 100644 --- a/include/keys/dns_resolver-type.h +++ b/include/keys/dns_resolver-type.h @@ -12,8 +12,4 @@ extern struct key_type key_type_dns_resolver; -extern int request_dns_resolver_key(const char *description, - const char *callout_info, - char **data); - #endif /* _KEYS_DNS_RESOLVER_TYPE_H */ diff --git a/include/linux/key.h b/include/linux/key.h index 943a432da3ae..074dca3222b9 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -436,9 +436,6 @@ extern key_ref_t keyring_search(key_ref_t keyring, const char *description, bool recurse); -extern int keyring_add_key(struct key *keyring, - struct key *key); - extern int keyring_restrict(key_ref_t keyring, const char *type, const char *restriction); From 70fd1966c93bf3bfe3fe6d753eb3d83a76597eef Mon Sep 17 00:00:00 2001 From: Roman Smirnov Date: Tue, 17 Sep 2024 18:54:53 +0300 Subject: [PATCH 2/5] KEYS: prevent NULL pointer dereference in find_asymmetric_key() In find_asymmetric_key(), if all NULLs are passed in the id_{0,1,2} arguments, the kernel will first emit WARN but then have an oops because id_2 gets dereferenced anyway. Add the missing id_2 check and move WARN_ON() to the final else branch to avoid duplicate NULL checks. Found by Linux Verification Center (linuxtesting.org) with Svace static analysis tool. Cc: stable@vger.kernel.org # v5.17+ Fixes: 7d30198ee24f ("keys: X.509 public key issuer lookup without AKID") Suggested-by: Sergey Shtylyov Signed-off-by: Roman Smirnov Reviewed-by: Sergey Shtylyov Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- crypto/asymmetric_keys/asymmetric_type.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index a5da8ccd353e..43af5fa510c0 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -60,17 +60,18 @@ struct key *find_asymmetric_key(struct key *keyring, char *req, *p; int len; - WARN_ON(!id_0 && !id_1 && !id_2); - if (id_0) { lookup = id_0->data; len = id_0->len; } else if (id_1) { lookup = id_1->data; len = id_1->len; - } else { + } else if (id_2) { lookup = id_2->data; len = id_2->len; + } else { + WARN_ON(1); + return ERR_PTR(-EINVAL); } /* Construct an identifier "id:". */ From 300e6d4116f956b035281ec94297dc4dc8d4e1d3 Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Fri, 12 Jul 2024 09:11:14 +0200 Subject: [PATCH 3/5] sign-file,extract-cert: move common SSL helper functions to a header Couple error handling helpers are repeated in both tools, so move them to a common header. Signed-off-by: Jan Stancek Reviewed-by: Jarkko Sakkinen Tested-by: R Nageswara Sastry Reviewed-by: Neal Gompa Signed-off-by: Jarkko Sakkinen --- MAINTAINERS | 1 + certs/Makefile | 2 +- certs/extract-cert.c | 37 ++----------------------------------- scripts/sign-file.c | 37 ++----------------------------------- scripts/ssl-common.h | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 71 deletions(-) create mode 100644 scripts/ssl-common.h diff --git a/MAINTAINERS b/MAINTAINERS index 9278c30ef1d5..23f902884855 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5204,6 +5204,7 @@ S: Maintained F: Documentation/admin-guide/module-signing.rst F: certs/ F: scripts/sign-file.c +F: scripts/ssl-common.h F: tools/certs/ CFAG12864B LCD DRIVER diff --git a/certs/Makefile b/certs/Makefile index 1094e3860c2a..f6fa4d8d75e0 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -84,5 +84,5 @@ targets += x509_revocation_list hostprogs := extract-cert -HOSTCFLAGS_extract-cert.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) +HOSTCFLAGS_extract-cert.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) -I$(srctree)/scripts HOSTLDLIBS_extract-cert = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) diff --git a/certs/extract-cert.c b/certs/extract-cert.c index 70e9ec89d87d..8e7ba9974a1f 100644 --- a/certs/extract-cert.c +++ b/certs/extract-cert.c @@ -23,6 +23,8 @@ #include #include +#include "ssl-common.h" + /* * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. * @@ -40,41 +42,6 @@ void format(void) exit(2); } -static void display_openssl_errors(int l) -{ - const char *file; - char buf[120]; - int e, line; - - if (ERR_peek_error() == 0) - return; - fprintf(stderr, "At main.c:%d:\n", l); - - while ((e = ERR_get_error_line(&file, &line))) { - ERR_error_string(e, buf); - fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); - } -} - -static void drain_openssl_errors(void) -{ - const char *file; - int line; - - if (ERR_peek_error() == 0) - return; - while (ERR_get_error_line(&file, &line)) {} -} - -#define ERR(cond, fmt, ...) \ - do { \ - bool __cond = (cond); \ - display_openssl_errors(__LINE__); \ - if (__cond) { \ - err(1, fmt, ## __VA_ARGS__); \ - } \ - } while(0) - static const char *key_pass; static BIO *wb; static char *cert_dst; diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 3edb156ae52c..39ba58db5d4e 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -29,6 +29,8 @@ #include #include +#include "ssl-common.h" + /* * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. * @@ -83,41 +85,6 @@ void format(void) exit(2); } -static void display_openssl_errors(int l) -{ - const char *file; - char buf[120]; - int e, line; - - if (ERR_peek_error() == 0) - return; - fprintf(stderr, "At main.c:%d:\n", l); - - while ((e = ERR_get_error_line(&file, &line))) { - ERR_error_string(e, buf); - fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); - } -} - -static void drain_openssl_errors(void) -{ - const char *file; - int line; - - if (ERR_peek_error() == 0) - return; - while (ERR_get_error_line(&file, &line)) {} -} - -#define ERR(cond, fmt, ...) \ - do { \ - bool __cond = (cond); \ - display_openssl_errors(__LINE__); \ - if (__cond) { \ - errx(1, fmt, ## __VA_ARGS__); \ - } \ - } while(0) - static const char *key_pass; static int pem_pw_cb(char *buf, int len, int w, void *v) diff --git a/scripts/ssl-common.h b/scripts/ssl-common.h new file mode 100644 index 000000000000..e6711c75ed91 --- /dev/null +++ b/scripts/ssl-common.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* + * SSL helper functions shared by sign-file and extract-cert. + */ + +static void display_openssl_errors(int l) +{ + const char *file; + char buf[120]; + int e, line; + + if (ERR_peek_error() == 0) + return; + fprintf(stderr, "At main.c:%d:\n", l); + + while ((e = ERR_get_error_line(&file, &line))) { + ERR_error_string(e, buf); + fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); + } +} + +static void drain_openssl_errors(void) +{ + const char *file; + int line; + + if (ERR_peek_error() == 0) + return; + while (ERR_get_error_line(&file, &line)) {} +} + +#define ERR(cond, fmt, ...) \ + do { \ + bool __cond = (cond); \ + display_openssl_errors(__LINE__); \ + if (__cond) { \ + errx(1, fmt, ## __VA_ARGS__); \ + } \ + } while (0) From 467d60eddf55588add232feda325da7215ddaf30 Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Fri, 12 Jul 2024 09:11:15 +0200 Subject: [PATCH 4/5] sign-file,extract-cert: avoid using deprecated ERR_get_error_line() ERR_get_error_line() is deprecated since OpenSSL 3.0. Use ERR_peek_error_line() instead, and combine display_openssl_errors() and drain_openssl_errors() to a single function where parameter decides if it should consume errors silently. Signed-off-by: Jan Stancek Reviewed-by: Jarkko Sakkinen Tested-by: R Nageswara Sastry Reviewed-by: Neal Gompa Signed-off-by: Jarkko Sakkinen --- certs/extract-cert.c | 4 ++-- scripts/sign-file.c | 6 +++--- scripts/ssl-common.h | 23 ++++++++--------------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/certs/extract-cert.c b/certs/extract-cert.c index 8e7ba9974a1f..61bbe0085671 100644 --- a/certs/extract-cert.c +++ b/certs/extract-cert.c @@ -99,11 +99,11 @@ int main(int argc, char **argv) parms.cert = NULL; ENGINE_load_builtin_engines(); - drain_openssl_errors(); + drain_openssl_errors(__LINE__, 1); e = ENGINE_by_id("pkcs11"); ERR(!e, "Load PKCS#11 ENGINE"); if (ENGINE_init(e)) - drain_openssl_errors(); + drain_openssl_errors(__LINE__, 1); else ERR(1, "ENGINE_init"); if (key_pass) diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 39ba58db5d4e..bb3fdf1a617c 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -114,11 +114,11 @@ static EVP_PKEY *read_private_key(const char *private_key_name) ENGINE *e; ENGINE_load_builtin_engines(); - drain_openssl_errors(); + drain_openssl_errors(__LINE__, 1); e = ENGINE_by_id("pkcs11"); ERR(!e, "Load PKCS#11 ENGINE"); if (ENGINE_init(e)) - drain_openssl_errors(); + drain_openssl_errors(__LINE__, 1); else ERR(1, "ENGINE_init"); if (key_pass) @@ -273,7 +273,7 @@ int main(int argc, char **argv) /* Digest the module data. */ OpenSSL_add_all_digests(); - display_openssl_errors(__LINE__); + drain_openssl_errors(__LINE__, 0); digest_algo = EVP_get_digestbyname(hash_algo); ERR(!digest_algo, "EVP_get_digestbyname"); diff --git a/scripts/ssl-common.h b/scripts/ssl-common.h index e6711c75ed91..2db0e181143c 100644 --- a/scripts/ssl-common.h +++ b/scripts/ssl-common.h @@ -3,7 +3,7 @@ * SSL helper functions shared by sign-file and extract-cert. */ -static void display_openssl_errors(int l) +static void drain_openssl_errors(int l, int silent) { const char *file; char buf[120]; @@ -11,28 +11,21 @@ static void display_openssl_errors(int l) if (ERR_peek_error() == 0) return; - fprintf(stderr, "At main.c:%d:\n", l); + if (!silent) + fprintf(stderr, "At main.c:%d:\n", l); - while ((e = ERR_get_error_line(&file, &line))) { + while ((e = ERR_peek_error_line(&file, &line))) { ERR_error_string(e, buf); - fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); + if (!silent) + fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); + ERR_get_error(); } } -static void drain_openssl_errors(void) -{ - const char *file; - int line; - - if (ERR_peek_error() == 0) - return; - while (ERR_get_error_line(&file, &line)) {} -} - #define ERR(cond, fmt, ...) \ do { \ bool __cond = (cond); \ - display_openssl_errors(__LINE__); \ + drain_openssl_errors(__LINE__, 0); \ if (__cond) { \ errx(1, fmt, ## __VA_ARGS__); \ } \ From 558bdc45dfb2669e1741384a0c80be9c82fa052c Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Fri, 20 Sep 2024 19:52:48 +0300 Subject: [PATCH 5/5] sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3 ENGINE API has been deprecated since OpenSSL version 3.0 [1]. Distros have started dropping support from headers and in future it will likely disappear also from library. It has been superseded by the PROVIDER API, so use it instead for OPENSSL MAJOR >= 3. [1] https://github.com/openssl/openssl/blob/master/README-ENGINES.md [jarkko: fixed up alignment issues reported by checkpatch.pl --strict] Signed-off-by: Jan Stancek Reviewed-by: Jarkko Sakkinen Tested-by: R Nageswara Sastry Reviewed-by: Neal Gompa Signed-off-by: Jarkko Sakkinen --- certs/extract-cert.c | 103 ++++++++++++++++++++++++++++++------------- scripts/sign-file.c | 95 +++++++++++++++++++++++++++------------ 2 files changed, 139 insertions(+), 59 deletions(-) diff --git a/certs/extract-cert.c b/certs/extract-cert.c index 61bbe0085671..7d6d468ed612 100644 --- a/certs/extract-cert.c +++ b/certs/extract-cert.c @@ -21,17 +21,18 @@ #include #include #include -#include - +#if OPENSSL_VERSION_MAJOR >= 3 +# define USE_PKCS11_PROVIDER +# include +# include +#else +# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0) +# define USE_PKCS11_ENGINE +# include +# endif +#endif #include "ssl-common.h" -/* - * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. - * - * Remove this if/when that API is no longer used - */ -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - #define PKEY_ID_PKCS7 2 static __attribute__((noreturn)) @@ -61,6 +62,66 @@ static void write_cert(X509 *x509) fprintf(stderr, "Extracted cert: %s\n", buf); } +static X509 *load_cert_pkcs11(const char *cert_src) +{ + X509 *cert = NULL; +#ifdef USE_PKCS11_PROVIDER + OSSL_STORE_CTX *store; + + if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true)) + ERR(1, "OSSL_PROVIDER_try_load(pkcs11)"); + if (!OSSL_PROVIDER_try_load(NULL, "default", true)) + ERR(1, "OSSL_PROVIDER_try_load(default)"); + + store = OSSL_STORE_open(cert_src, NULL, NULL, NULL, NULL); + ERR(!store, "OSSL_STORE_open"); + + while (!OSSL_STORE_eof(store)) { + OSSL_STORE_INFO *info = OSSL_STORE_load(store); + + if (!info) { + drain_openssl_errors(__LINE__, 0); + continue; + } + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_CERT) { + cert = OSSL_STORE_INFO_get1_CERT(info); + ERR(!cert, "OSSL_STORE_INFO_get1_CERT"); + } + OSSL_STORE_INFO_free(info); + if (cert) + break; + } + OSSL_STORE_close(store); +#elif defined(USE_PKCS11_ENGINE) + ENGINE *e; + struct { + const char *cert_id; + X509 *cert; + } parms; + + parms.cert_id = cert_src; + parms.cert = NULL; + + ENGINE_load_builtin_engines(); + drain_openssl_errors(__LINE__, 1); + e = ENGINE_by_id("pkcs11"); + ERR(!e, "Load PKCS#11 ENGINE"); + if (ENGINE_init(e)) + drain_openssl_errors(__LINE__, 1); + else + ERR(1, "ENGINE_init"); + if (key_pass) + ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); + ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1); + ERR(!parms.cert, "Get X.509 from PKCS#11"); + cert = parms.cert; +#else + fprintf(stderr, "no pkcs11 engine/provider available\n"); + exit(1); +#endif + return cert; +} + int main(int argc, char **argv) { char *cert_src; @@ -89,28 +150,10 @@ int main(int argc, char **argv) fclose(f); exit(0); } else if (!strncmp(cert_src, "pkcs11:", 7)) { - ENGINE *e; - struct { - const char *cert_id; - X509 *cert; - } parms; + X509 *cert = load_cert_pkcs11(cert_src); - parms.cert_id = cert_src; - parms.cert = NULL; - - ENGINE_load_builtin_engines(); - drain_openssl_errors(__LINE__, 1); - e = ENGINE_by_id("pkcs11"); - ERR(!e, "Load PKCS#11 ENGINE"); - if (ENGINE_init(e)) - drain_openssl_errors(__LINE__, 1); - else - ERR(1, "ENGINE_init"); - if (key_pass) - ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); - ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1); - ERR(!parms.cert, "Get X.509 from PKCS#11"); - write_cert(parms.cert); + ERR(!cert, "load_cert_pkcs11 failed"); + write_cert(cert); } else { BIO *b; X509 *x509; diff --git a/scripts/sign-file.c b/scripts/sign-file.c index bb3fdf1a617c..7070245edfc1 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -27,17 +27,18 @@ #include #include #include -#include - +#if OPENSSL_VERSION_MAJOR >= 3 +# define USE_PKCS11_PROVIDER +# include +# include +#else +# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0) +# define USE_PKCS11_ENGINE +# include +# endif +#endif #include "ssl-common.h" -/* - * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. - * - * Remove this if/when that API is no longer used - */ -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - /* * Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to * assume that it's not available and its header file is missing and that we @@ -106,28 +107,64 @@ static int pem_pw_cb(char *buf, int len, int w, void *v) return pwlen; } +static EVP_PKEY *read_private_key_pkcs11(const char *private_key_name) +{ + EVP_PKEY *private_key = NULL; +#ifdef USE_PKCS11_PROVIDER + OSSL_STORE_CTX *store; + + if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true)) + ERR(1, "OSSL_PROVIDER_try_load(pkcs11)"); + if (!OSSL_PROVIDER_try_load(NULL, "default", true)) + ERR(1, "OSSL_PROVIDER_try_load(default)"); + + store = OSSL_STORE_open(private_key_name, NULL, NULL, NULL, NULL); + ERR(!store, "OSSL_STORE_open"); + + while (!OSSL_STORE_eof(store)) { + OSSL_STORE_INFO *info = OSSL_STORE_load(store); + + if (!info) { + drain_openssl_errors(__LINE__, 0); + continue; + } + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) { + private_key = OSSL_STORE_INFO_get1_PKEY(info); + ERR(!private_key, "OSSL_STORE_INFO_get1_PKEY"); + } + OSSL_STORE_INFO_free(info); + if (private_key) + break; + } + OSSL_STORE_close(store); +#elif defined(USE_PKCS11_ENGINE) + ENGINE *e; + + ENGINE_load_builtin_engines(); + drain_openssl_errors(__LINE__, 1); + e = ENGINE_by_id("pkcs11"); + ERR(!e, "Load PKCS#11 ENGINE"); + if (ENGINE_init(e)) + drain_openssl_errors(__LINE__, 1); + else + ERR(1, "ENGINE_init"); + if (key_pass) + ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); + private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL); + ERR(!private_key, "%s", private_key_name); +#else + fprintf(stderr, "no pkcs11 engine/provider available\n"); + exit(1); +#endif + return private_key; +} + static EVP_PKEY *read_private_key(const char *private_key_name) { - EVP_PKEY *private_key; - if (!strncmp(private_key_name, "pkcs11:", 7)) { - ENGINE *e; - - ENGINE_load_builtin_engines(); - drain_openssl_errors(__LINE__, 1); - e = ENGINE_by_id("pkcs11"); - ERR(!e, "Load PKCS#11 ENGINE"); - if (ENGINE_init(e)) - drain_openssl_errors(__LINE__, 1); - else - ERR(1, "ENGINE_init"); - if (key_pass) - ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), - "Set PKCS#11 PIN"); - private_key = ENGINE_load_private_key(e, private_key_name, - NULL, NULL); - ERR(!private_key, "%s", private_key_name); + return read_private_key_pkcs11(private_key_name); } else { + EVP_PKEY *private_key; BIO *b; b = BIO_new_file(private_key_name, "rb"); @@ -136,9 +173,9 @@ static EVP_PKEY *read_private_key(const char *private_key_name) NULL); ERR(!private_key, "%s", private_key_name); BIO_free(b); - } - return private_key; + return private_key; + } } static X509 *read_x509(const char *x509_name)