Add an application data field in the UI_METHOD
authorRichard Levitte <levitte@openssl.org>
Tue, 6 Dec 2016 13:36:04 +0000 (14:36 +0100)
committerRichard Levitte <levitte@openssl.org>
Wed, 11 Jan 2017 17:27:27 +0000 (18:27 +0100)
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2204)

crypto/ui/ui_lib.c
crypto/ui/ui_locl.h
doc/man3/CRYPTO_get_ex_new_index.pod
include/openssl/crypto.h
include/openssl/ui.h

index fa98f96..ceda7e9 100644 (file)
@@ -561,15 +561,17 @@ const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
 
 UI_METHOD *UI_create_method(const char *name)
 {
-    UI_METHOD *ui_method = OPENSSL_zalloc(sizeof(*ui_method));
-
-    if (ui_method != NULL) {
-        ui_method->name = OPENSSL_strdup(name);
-        if (ui_method->name == NULL) {
-            OPENSSL_free(ui_method);
-            UIerr(UI_F_UI_CREATE_METHOD, ERR_R_MALLOC_FAILURE);
-            return NULL;
-        }
+    UI_METHOD *ui_method = NULL;
+
+    if ((ui_method = OPENSSL_zalloc(sizeof(*ui_method))) == NULL
+        || (ui_method->name = OPENSSL_strdup(name)) == NULL
+        || !CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI_METHOD, ui_method,
+                               &ui_method->ex_data)) {
+        if (ui_method)
+            OPENSSL_free(ui_method->name);
+        OPENSSL_free(ui_method);
+        UIerr(UI_F_UI_CREATE_METHOD, ERR_R_MALLOC_FAILURE);
+        return NULL;
     }
     return ui_method;
 }
@@ -581,6 +583,10 @@ UI_METHOD *UI_create_method(const char *name)
  */
 void UI_destroy_method(UI_METHOD *ui_method)
 {
+    if (ui_method == NULL)
+        return;
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI_METHOD, ui_method,
+                        &ui_method->ex_data);
     OPENSSL_free(ui_method->name);
     ui_method->name = NULL;
     OPENSSL_free(ui_method);
@@ -647,6 +653,11 @@ int UI_method_set_prompt_constructor(UI_METHOD *method,
     return -1;
 }
 
+int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data)
+{
+    return CRYPTO_set_ex_data(&method->ex_data, idx, data);
+}
+
 int (*UI_method_get_opener(const UI_METHOD *method)) (UI *)
 {
     if (method != NULL)
@@ -690,6 +701,11 @@ char *(*UI_method_get_prompt_constructor(const UI_METHOD *method))
     return NULL;
 }
 
+const void *UI_method_get_ex_data(const UI_METHOD *method, int idx)
+{
+    return CRYPTO_get_ex_data(&method->ex_data, idx);
+}
+
 enum UI_string_types UI_get_string_type(UI_STRING *uis)
 {
     return uis->type;
index 2953739..94a9e35 100644 (file)
@@ -46,6 +46,10 @@ struct ui_method_st {
      */
     char *(*ui_construct_prompt) (UI *ui, const char *object_desc,
                                   const char *object_name);
+    /*
+     * UI_METHOD specific application data.
+     */
+    CRYPTO_EX_DATA ex_data;
 };
 
 struct ui_string_st {
index 98085f5..ed32bb2 100644 (file)
@@ -52,6 +52,7 @@ The specific structures are:
     RSA
     ENGINE
     UI
+    UI_METHOD
     BIO
 
 Each is identified by an B<CRYPTO_EX_INDEX_xxx> define in the B<crypto.h>
index bd0b140..8ee3e8a 100644 (file)
@@ -110,7 +110,8 @@ DEFINE_STACK_OF(void)
 # define CRYPTO_EX_INDEX_UI              11
 # define CRYPTO_EX_INDEX_BIO             12
 # define CRYPTO_EX_INDEX_APP             13
-# define CRYPTO_EX_INDEX__COUNT          14
+# define CRYPTO_EX_INDEX_UI_METHOD       14
+# define CRYPTO_EX_INDEX__COUNT          15
 
 /*
  * This is the default callbacks, but we can have others as well: this is
index b4b182f..ff25205 100644 (file)
@@ -284,6 +284,7 @@ int UI_method_set_prompt_constructor(UI_METHOD *method,
                                                                   *object_desc,
                                                                   const char
                                                                   *object_name));
+int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data);
 int (*UI_method_get_opener(const UI_METHOD *method)) (UI *);
 int (*UI_method_get_writer(const UI_METHOD *method)) (UI *, UI_STRING *);
 int (*UI_method_get_flusher(const UI_METHOD *method)) (UI *);
@@ -291,6 +292,7 @@ int (*UI_method_get_reader(const UI_METHOD *method)) (UI *, UI_STRING *);
 int (*UI_method_get_closer(const UI_METHOD *method)) (UI *);
 char *(*UI_method_get_prompt_constructor(const UI_METHOD *method))
     (UI *, const char *, const char *);
+const void *UI_method_get_ex_data(const UI_METHOD *method, int idx);
 
 /*
  * The following functions are helpers for method writers to access relevant