]> 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)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 19 Feb 2026 09:21:01 +0000 (10:21 +0100)
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.

src/shared/openssl-util.c

index e564c2cb7b4e76ab4974360af194069630a63f32..9e0b9987463d9b8cc367955cb3501f34709a3dac 100644 (file)
@@ -1208,6 +1208,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);
@@ -1223,8 +1224,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)
@@ -1246,7 +1247,7 @@ static int load_key_from_provider(
         return 0;
 }
 
-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);
@@ -1260,7 +1261,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;
@@ -1533,13 +1534,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();