]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
openssl-util: pass the UI callback for interactive PIN prompts
authorKai Lüke <kai@amutable.com>
Thu, 19 Feb 2026 07:01:06 +0000 (16:01 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 27 Feb 2026 21:57:05 +0000 (21:57 +0000)
Observed with the tpm2 provider and the tpm2tss engine was that the
auth process failed because the provider/engine could not ask for the
PIN through the callback, resulting in:
  "Failed to load private key from ...: Input/output error"
Apparently the default UI method is not enough and the key setup
functions expect an explicit method.
Pass the existing UI method through as callback for the key setup.

(cherry picked from commit bad16f324acc2a4624dca18a6586306698da7d0a)
(cherry picked from commit 6242200238b76f82838d76142daa5bdee57444f3)
(cherry picked from commit 6957f06dce0456fb7a4d8d25762318d89b473146)

src/shared/openssl-util.c

index 1fe6d07602c1fa976d63ff255dc2a9d8a9e95faf..a48bb1cc9713bfd3e4b6587111ae70cdaae392ff 100644 (file)
@@ -1319,6 +1319,7 @@ int pkey_generate_volume_keys(
 static int load_key_from_provider(
                 const char *provider,
                 const char *private_key_uri,
+                UI_METHOD *ui_method,
                 EVP_PKEY **ret) {
 
         assert(provider);
@@ -1335,8 +1336,8 @@ static int load_key_from_provider(
 
         _cleanup_(OSSL_STORE_closep) OSSL_STORE_CTX *store = OSSL_STORE_open(
                         private_key_uri,
-                        /*ui_method=*/ NULL,
-                        /*ui_method=*/ NULL,
+                        ui_method,
+                        /* ui_data= */ NULL,
                         /* post_process= */ NULL,
                         /* post_process_data= */ NULL);
         if (!store)
@@ -1361,7 +1362,7 @@ static int load_key_from_provider(
 #endif
 }
 
-static int load_key_from_engine(const char *engine, const char *private_key_uri, EVP_PKEY **ret) {
+static int load_key_from_engine(const char *engine, const char *private_key_uri, UI_METHOD *ui_method, EVP_PKEY **ret) {
         assert(engine);
         assert(private_key_uri);
         assert(ret);
@@ -1375,7 +1376,7 @@ static int load_key_from_engine(const char *engine, const char *private_key_uri,
         if (ENGINE_init(e) == 0)
                 return log_openssl_errors("Failed to initialize signing engine '%s'", engine);
 
-        _cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = ENGINE_load_private_key(e, private_key_uri, /*ui_method=*/ NULL, /*callback_data=*/ NULL);
+        _cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = ENGINE_load_private_key(e, private_key_uri, ui_method, /* callback_data= */ NULL);
         if (!private_key)
                 return log_openssl_errors("Failed to load private key from '%s'", private_key_uri);
         REENABLE_WARNING;
@@ -1658,13 +1659,18 @@ int openssl_load_private_key(
                 if (r < 0)
                         return log_debug_errno(r, "Failed to allocate ask-password user interface: %m");
 
+                UI_METHOD *ui_method = NULL;
+#ifndef OPENSSL_NO_UI_CONSOLE
+                ui_method = ui->method;
+#endif
+
                 switch (private_key_source_type) {
 
                 case OPENSSL_KEY_SOURCE_ENGINE:
-                        r = load_key_from_engine(private_key_source, private_key, ret_private_key);
+                        r = load_key_from_engine(private_key_source, private_key, ui_method, ret_private_key);
                         break;
                 case OPENSSL_KEY_SOURCE_PROVIDER:
-                        r = load_key_from_provider(private_key_source, private_key, ret_private_key);
+                        r = load_key_from_provider(private_key_source, private_key, ui_method, ret_private_key);
                         break;
                 default:
                         assert_not_reached();