summaryrefslogtreecommitdiffstats
path: root/crypto/ui
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2016-12-06 14:36:43 +0100
committerRichard Levitte <levitte@openssl.org>2017-01-11 18:27:27 +0100
commit0fe1fc858a0519c3866c0d2e88513e677b674926 (patch)
tree17c76a74c6310fd893e54f075c38d02670b53116 /crypto/ui
parent18cfc668eae2c296e9bc90ffc989d9bbe61cc82f (diff)
Add a UI utility function with which to wrap pem_callback_cb in a UI_METHOD
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2204)
Diffstat (limited to 'crypto/ui')
-rw-r--r--crypto/ui/ui_util.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/crypto/ui/ui_util.c b/crypto/ui/ui_util.c
index 3b51db92cd..70202a6f73 100644
--- a/crypto/ui/ui_util.c
+++ b/crypto/ui/ui_util.c
@@ -49,3 +49,114 @@ int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
ok = 0;
return (ok);
}
+
+/*
+ * Wrapper around pem_password_cb, a method to help older APIs use newer
+ * ones.
+ */
+struct pem_password_cb_data {
+ pem_password_cb *cb;
+ int rwflag;
+};
+
+static void ui_new_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+ int idx, long argl, void *argp)
+{
+ /*
+ * Do nothing, the data is allocated externally and assigned later with
+ * CRYPTO_set_ex_data()
+ */
+}
+
+static int ui_dup_method_data(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
+ void *from_d, int idx, long argl, void *argp)
+{
+ void **pptr = (void **)from_d;
+ if (*pptr != NULL)
+ *pptr = OPENSSL_memdup(*pptr, sizeof(struct pem_password_cb_data));
+ return 1;
+}
+
+static void ui_free_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+ int idx, long argl, void *argp)
+{
+ OPENSSL_free(ptr);
+}
+
+static int ui_method_data_index()
+{
+ static int idx = -1;
+
+ if (idx == -1)
+ idx = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI_METHOD,
+ 0, NULL,
+ ui_new_method_data,
+ ui_dup_method_data,
+ ui_free_method_data);
+
+ return idx;
+}
+
+static int ui_open(UI *ui)
+{
+ return 1;
+}
+static int ui_read(UI *ui, UI_STRING *uis)
+{
+ switch (UI_get_string_type(uis)) {
+ case UIT_PROMPT:
+ {
+ char result[PEM_BUFSIZE];
+ const struct pem_password_cb_data *data =
+ UI_method_get_ex_data(UI_get_method(ui),
+ ui_method_data_index());
+ int maxsize = UI_get_result_maxsize(uis);
+ int len = data->cb(result,
+ maxsize > PEM_BUFSIZE ? PEM_BUFSIZE : maxsize,
+ data->rwflag, UI_get0_user_data(ui));
+
+ if (len <= 0)
+ return len;
+ if (UI_set_result(ui, uis, result) >= 0)
+ return 1;
+ return 0;
+ }
+ case UIT_VERIFY:
+ case UIT_NONE:
+ case UIT_BOOLEAN:
+ case UIT_INFO:
+ case UIT_ERROR:
+ break;
+ }
+ return 1;
+}
+static int ui_write(UI *ui, UI_STRING *uis)
+{
+ return 1;
+}
+static int ui_close(UI *ui)
+{
+ return 1;
+}
+
+UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag)
+{
+ struct pem_password_cb_data *data = NULL;
+ UI_METHOD *ui_method = NULL;
+
+ if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL
+ || (ui_method = UI_create_method("PEM password callback wrapper")) == NULL
+ || UI_method_set_opener(ui_method, ui_open) < 0
+ || UI_method_set_reader(ui_method, ui_read) < 0
+ || UI_method_set_writer(ui_method, ui_write) < 0
+ || UI_method_set_closer(ui_method, ui_close) < 0
+ || UI_method_set_ex_data(ui_method, ui_method_data_index(), data) < 0) {
+ UI_destroy_method(ui_method);
+ OPENSSL_free(data);
+ return NULL;
+ }
+ data->rwflag = rwflag;
+ data->cb = cb;
+
+ return ui_method;
+}