cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH] Pass password to OpenSSL engine by user interface

From: Petr Písař <petr.pisar_at_atlas.cz>
Date: Tue, 20 Aug 2013 17:02:53 +0200

Recent OpenSSL uses user interface abstraction to negotiate access to private
keys in the cryprographical engines. An OpenSSL application is expected to
implement the user interface. Otherwise a default one provided by OpenSSL
(interactive standard I/O) will be used and the aplication will have no way
how to pass a password to the engine.

---
 lib/ssluse.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 26e16d5..85d9105 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -294,6 +294,49 @@ static int do_file_type(const char *type)
   return -1;
 }
 
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+/*
+ * Supply default password to the engine user interface conversation.
+ * The password is passed by OpenSSL engine from ENGINE_load_private_key()
+ * last argument to the ui and can be obtained by UI_get0_user_data(ui) here.
+ */
+static int ssl_ui_reader(UI *ui, UI_STRING *uis)
+{
+  const char *password;
+  switch(UI_get_string_type(uis)) {
+    case UIT_PROMPT:
+    case UIT_VERIFY:
+      password = (const char*)UI_get0_user_data(ui);
+      if (NULL != password &&
+          UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD) {
+        UI_set_result(ui, uis, password);
+        return 1;
+      }
+    default:
+      break;
+  }
+  return (UI_method_get_reader(UI_OpenSSL()))(ui, uis);
+}
+
+/*
+ * Suppress interactive request for a default password if available.
+ */
+static int ssl_ui_writer(UI *ui, UI_STRING *uis)
+{
+  switch(UI_get_string_type(uis)) {
+    case UIT_PROMPT:
+    case UIT_VERIFY:
+      if (NULL != UI_get0_user_data(ui) &&
+          UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD) {
+        return 1;
+      }
+    default:
+      break;
+  }
+  return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
+}
+#endif
+
 static
 int cert_stuff(struct connectdata *conn,
                SSL_CTX* ctx,
@@ -527,7 +570,15 @@ int cert_stuff(struct connectdata *conn,
         EVP_PKEY *priv_key = NULL;
         if(data->state.engine) {
 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
-          UI_METHOD *ui_method = UI_OpenSSL();
+          UI_METHOD *ui_method = UI_create_method("cURL user interface");
+          if (NULL == ui_method) {
+            failf(data, "unable do create OpenSSL user-interface method");
+            return 0;
+          }
+          UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL()));
+          UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL()));
+          UI_method_set_reader(ui_method, ssl_ui_reader);
+          UI_method_set_writer(ui_method, ssl_ui_writer);
 #endif
           /* the typecast below was added to please mingw32 */
           priv_key = (EVP_PKEY *)
@@ -536,6 +587,9 @@ int cert_stuff(struct connectdata *conn,
                                     ui_method,
 #endif
                                     data->set.str[STRING_KEY_PASSWD]);
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+          UI_destroy_method(ui_method);
+#endif
           if(!priv_key) {
             failf(data, "failed to load private key from crypto engine");
             return 0;
-- 
1.8.3.2

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html

  • application/pgp-signature attachment: stored
Received on 2013-08-20