summaryrefslogtreecommitdiffstats
path: root/crypto/ui
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/ui')
-rw-r--r--crypto/ui/ui_err.c5
-rw-r--r--crypto/ui/ui_lib.c57
-rw-r--r--crypto/ui/ui_locl.h7
3 files changed, 68 insertions, 1 deletions
diff --git a/crypto/ui/ui_err.c b/crypto/ui/ui_err.c
index c8640feaf1..d60c72dcba 100644
--- a/crypto/ui/ui_err.c
+++ b/crypto/ui/ui_err.c
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -31,6 +31,7 @@ static ERR_STRING_DATA UI_str_functs[] = {
{ERR_FUNC(UI_F_UI_DUP_INFO_STRING), "UI_dup_info_string"},
{ERR_FUNC(UI_F_UI_DUP_INPUT_BOOLEAN), "UI_dup_input_boolean"},
{ERR_FUNC(UI_F_UI_DUP_INPUT_STRING), "UI_dup_input_string"},
+ {ERR_FUNC(UI_F_UI_DUP_USER_DATA), "UI_dup_user_data"},
{ERR_FUNC(UI_F_UI_DUP_VERIFY_STRING), "UI_dup_verify_string"},
{ERR_FUNC(UI_F_UI_GET0_RESULT), "UI_get0_result"},
{ERR_FUNC(UI_F_UI_NEW_METHOD), "UI_new_method"},
@@ -54,6 +55,8 @@ static ERR_STRING_DATA UI_str_reasons[] = {
{ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND), "unknown control command"},
{ERR_REASON(UI_R_UNKNOWN_TTYGET_ERRNO_VALUE),
"unknown ttyget errno value"},
+ {ERR_REASON(UI_R_USER_DATA_DUPLICATION_UNSUPPORTED),
+ "user data duplication unsupported"},
{0, NULL}
};
diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c
index e48e4add1d..f4e01bcf38 100644
--- a/crypto/ui/ui_lib.c
+++ b/crypto/ui/ui_lib.c
@@ -73,6 +73,9 @@ void UI_free(UI *ui)
{
if (ui == NULL)
return;
+ if ((ui->flags & UI_FLAG_DUPL_DATA) != 0) {
+ ui->meth->ui_destroy_data(ui, ui->user_data);
+ }
sk_UI_STRING_pop_free(ui->strings, free_string);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
CRYPTO_THREAD_lock_free(ui->lock);
@@ -387,10 +390,38 @@ char *UI_construct_prompt(UI *ui, const char *object_desc,
void *UI_add_user_data(UI *ui, void *user_data)
{
void *old_data = ui->user_data;
+
+ if ((ui->flags & UI_FLAG_DUPL_DATA) != 0) {
+ ui->meth->ui_destroy_data(ui, old_data);
+ old_data = NULL;
+ }
ui->user_data = user_data;
+ ui->flags &= ~UI_FLAG_DUPL_DATA;
return old_data;
}
+int UI_dup_user_data(UI *ui, void *user_data)
+{
+ void *duplicate = NULL;
+
+ if (ui->meth->ui_duplicate_data == NULL
+ || ui->meth->ui_destroy_data == NULL) {
+ UIerr(UI_F_UI_DUP_USER_DATA, UI_R_USER_DATA_DUPLICATION_UNSUPPORTED);
+ return -1;
+ }
+
+ duplicate = ui->meth->ui_duplicate_data(ui, user_data);
+ if (duplicate == NULL) {
+ UIerr(UI_F_UI_DUP_USER_DATA, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ (void)UI_add_user_data(ui, duplicate);
+ ui->flags |= UI_FLAG_DUPL_DATA;
+
+ return 0;
+}
+
void *UI_get0_user_data(UI *ui)
{
return ui->user_data;
@@ -624,6 +655,18 @@ int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
return -1;
}
+int UI_method_set_data_duplicator(UI_METHOD *method,
+ void *(*duplicator) (UI *ui, void *ui_data),
+ void (*destructor)(UI *ui, void *ui_data))
+{
+ if (method != NULL) {
+ method->ui_duplicate_data = duplicator;
+ method->ui_destroy_data = destructor;
+ return 0;
+ }
+ return -1;
+}
+
int UI_method_set_prompt_constructor(UI_METHOD *method,
char *(*prompt_constructor) (UI *ui,
const char
@@ -686,6 +729,20 @@ char *(*UI_method_get_prompt_constructor(const UI_METHOD *method))
return NULL;
}
+void *(*UI_method_get_data_duplicator(const UI_METHOD *method)) (UI *, void *)
+{
+ if (method != NULL)
+ return method->ui_duplicate_data;
+ return NULL;
+}
+
+void (*UI_method_get_data_destructor(const UI_METHOD *method)) (UI *, void *)
+{
+ if (method != NULL)
+ return method->ui_destroy_data;
+ return NULL;
+}
+
const void *UI_method_get_ex_data(const UI_METHOD *method, int idx)
{
return CRYPTO_get_ex_data(&method->ex_data, idx);
diff --git a/crypto/ui/ui_locl.h b/crypto/ui/ui_locl.h
index 94a9e359f0..1b0d596ccd 100644
--- a/crypto/ui/ui_locl.h
+++ b/crypto/ui/ui_locl.h
@@ -38,6 +38,12 @@ struct ui_method_st {
int (*ui_read_string) (UI *ui, UI_STRING *uis);
int (*ui_close_session) (UI *ui);
/*
+ * Duplicate the ui_data that often comes alongside a ui_method. This
+ * allows some backends to save away UI information for later use.
+ */
+ void *(*ui_duplicate_data) (UI *ui, void *ui_data);
+ void (*ui_destroy_data) (UI *ui, void *ui_data);
+ /*
* Construct a prompt in a user-defined manner. object_desc is a textual
* short description of the object, for example "pass phrase", and
* object_name is the name of the object (might be a card name or a file
@@ -92,6 +98,7 @@ struct ui_st {
void *user_data;
CRYPTO_EX_DATA ex_data;
# define UI_FLAG_REDOABLE 0x0001
+# define UI_FLAG_DUPL_DATA 0x0002 /* user_data was duplicated */
# define UI_FLAG_PRINT_ERRORS 0x0100
int flags;