]> www.infradead.org Git - nvme.git/commitdiff
sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3
authorJan Stancek <jstancek@redhat.com>
Fri, 20 Sep 2024 16:52:48 +0000 (19:52 +0300)
committerJarkko Sakkinen <jarkko@kernel.org>
Fri, 20 Sep 2024 16:52:48 +0000 (19:52 +0300)
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>
certs/extract-cert.c
scripts/sign-file.c

index 61bbe0085671787dffd8d8f96e241ac345faef2f..7d6d468ed6129dc8c031bb235641cb94466e858d 100644 (file)
 #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;
+               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;
index bb3fdf1a617c2806811d9b56053023bf138a15a9..7070245edfc121877892638e8008ab8a8122f7bf 100644 (file)
 #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
@@ -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(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 (!strncmp(private_key_name, "pkcs11:", 7)) {
-               ENGINE *e;
+       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");
 
-               ENGINE_load_builtin_engines();
+       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);
-               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
+               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)) {
+               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)