]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 Apr 2025 13:07:05 +0000 (15:07 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 Apr 2025 13:07:05 +0000 (15:07 +0200)
added patches:
sign-file-extract-cert-avoid-using-deprecated-err_get_error_line.patch
sign-file-extract-cert-move-common-ssl-helper-functions-to-a-header.patch
sign-file-extract-cert-use-pkcs11-provider-for-openssl-major-3.patch

queue-6.6/series
queue-6.6/sign-file-extract-cert-avoid-using-deprecated-err_get_error_line.patch [new file with mode: 0644]
queue-6.6/sign-file-extract-cert-move-common-ssl-helper-functions-to-a-header.patch [new file with mode: 0644]
queue-6.6/sign-file-extract-cert-use-pkcs11-provider-for-openssl-major-3.patch [new file with mode: 0644]

index 512256c3bbbf2b0e932e5f05a4eacb71ab03c76f..eb1636e992142dd43f4016c04b77fd966f22f358 100644 (file)
@@ -383,3 +383,6 @@ drm-amd-display-stop-amdgpu_dm-initialize-when-link-nums-greater-than-max_links.
 landlock-add-the-errata-interface.patch
 nvmet-fc-remove-unused-functions.patch
 xdp-reset-bpf_redirect_info-before-running-a-xdp-s-bpf-prog.patch
+sign-file-extract-cert-move-common-ssl-helper-functions-to-a-header.patch
+sign-file-extract-cert-avoid-using-deprecated-err_get_error_line.patch
+sign-file-extract-cert-use-pkcs11-provider-for-openssl-major-3.patch
diff --git a/queue-6.6/sign-file-extract-cert-avoid-using-deprecated-err_get_error_line.patch b/queue-6.6/sign-file-extract-cert-avoid-using-deprecated-err_get_error_line.patch
new file mode 100644 (file)
index 0000000..031863b
--- /dev/null
@@ -0,0 +1,116 @@
+From 467d60eddf55588add232feda325da7215ddaf30 Mon Sep 17 00:00:00 2001
+From: Jan Stancek <jstancek@redhat.com>
+Date: Fri, 12 Jul 2024 09:11:15 +0200
+Subject: sign-file,extract-cert: avoid using deprecated ERR_get_error_line()
+
+From: Jan Stancek <jstancek@redhat.com>
+
+commit 467d60eddf55588add232feda325da7215ddaf30 upstream.
+
+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 <jstancek@redhat.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
+Reviewed-by: Neal Gompa <neal@gompa.dev>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ certs/extract-cert.c |    4 ++--
+ scripts/sign-file.c  |    6 +++---
+ scripts/ssl-common.h |   23 ++++++++---------------
+ 3 files changed, 13 insertions(+), 20 deletions(-)
+
+--- 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)
+--- a/scripts/sign-file.c
++++ b/scripts/sign-file.c
+@@ -114,11 +114,11 @@ static EVP_PKEY *read_private_key(const
+               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");
+--- 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__);   \
+               }                                       \
diff --git a/queue-6.6/sign-file-extract-cert-move-common-ssl-helper-functions-to-a-header.patch b/queue-6.6/sign-file-extract-cert-move-common-ssl-helper-functions-to-a-header.patch
new file mode 100644 (file)
index 0000000..51c7850
--- /dev/null
@@ -0,0 +1,195 @@
+From 300e6d4116f956b035281ec94297dc4dc8d4e1d3 Mon Sep 17 00:00:00 2001
+From: Jan Stancek <jstancek@redhat.com>
+Date: Fri, 12 Jul 2024 09:11:14 +0200
+Subject: sign-file,extract-cert: move common SSL helper functions to a header
+
+From: Jan Stancek <jstancek@redhat.com>
+
+commit 300e6d4116f956b035281ec94297dc4dc8d4e1d3 upstream.
+
+Couple error handling helpers are repeated in both tools, so
+move them to a common header.
+
+Signed-off-by: Jan Stancek <jstancek@redhat.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
+Reviewed-by: Neal Gompa <neal@gompa.dev>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -4784,6 +4784,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
+--- 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)
+--- a/certs/extract-cert.c
++++ b/certs/extract-cert.c
+@@ -23,6 +23,8 @@
+ #include <openssl/err.h>
+ #include <openssl/engine.h>
++#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;
+--- a/scripts/sign-file.c
++++ b/scripts/sign-file.c
+@@ -29,6 +29,8 @@
+ #include <openssl/err.h>
+ #include <openssl/engine.h>
++#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)
+--- /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)
diff --git a/queue-6.6/sign-file-extract-cert-use-pkcs11-provider-for-openssl-major-3.patch b/queue-6.6/sign-file-extract-cert-use-pkcs11-provider-for-openssl-major-3.patch
new file mode 100644 (file)
index 0000000..429a31f
--- /dev/null
@@ -0,0 +1,287 @@
+From 558bdc45dfb2669e1741384a0c80be9c82fa052c Mon Sep 17 00:00:00 2001
+From: Jan Stancek <jstancek@redhat.com>
+Date: Fri, 20 Sep 2024 19:52:48 +0300
+Subject: sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3
+
+From: Jan Stancek <jstancek@redhat.com>
+
+commit 558bdc45dfb2669e1741384a0c80be9c82fa052c upstream.
+
+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 <jstancek@redhat.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
+Reviewed-by: Neal Gompa <neal@gompa.dev>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ certs/extract-cert.c |  103 ++++++++++++++++++++++++++++++++++++---------------
+ scripts/sign-file.c  |   95 ++++++++++++++++++++++++++++++++---------------
+ 2 files changed, 139 insertions(+), 59 deletions(-)
+
+--- a/certs/extract-cert.c
++++ b/certs/extract-cert.c
+@@ -21,17 +21,18 @@
+ #include <openssl/bio.h>
+ #include <openssl/pem.h>
+ #include <openssl/err.h>
+-#include <openssl/engine.h>
+-
++#if OPENSSL_VERSION_MAJOR >= 3
++# define USE_PKCS11_PROVIDER
++# include <openssl/provider.h>
++# include <openssl/store.h>
++#else
++# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
++#  define USE_PKCS11_ENGINE
++#  include <openssl/engine.h>
++# 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;
+-
+-              parms.cert_id = cert_src;
+-              parms.cert = NULL;
++              X509 *cert = load_cert_pkcs11(cert_src);
+-              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;
+--- a/scripts/sign-file.c
++++ b/scripts/sign-file.c
+@@ -27,18 +27,19 @@
+ #include <openssl/evp.h>
+ #include <openssl/pem.h>
+ #include <openssl/err.h>
+-#include <openssl/engine.h>
+-
++#if OPENSSL_VERSION_MAJOR >= 3
++# define USE_PKCS11_PROVIDER
++# include <openssl/provider.h>
++# include <openssl/store.h>
++#else
++# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
++#  define USE_PKCS11_ENGINE
++#  include <openssl/engine.h>
++# 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
+  * should use PKCS#7 instead.  Switching to the older PKCS#7 format restricts
+@@ -106,28 +107,64 @@ static int pem_pw_cb(char *buf, int len,
+       return pwlen;
+ }
+-static EVP_PKEY *read_private_key(const char *private_key_name)
++static EVP_PKEY *read_private_key_pkcs11(const char *private_key_name)
+ {
+-      EVP_PKEY *private_key;
++      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)
++{
+       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
+                                                     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)