diff options
author | Richard Levitte <levitte@openssl.org> | 2017-05-28 09:35:11 +0200 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2017-05-31 19:00:24 +0200 |
commit | 545360c4dfbf90f63918be3d98e344adc7ca2d7f (patch) | |
tree | de6f313d6a48aa2e468cdba0d3137b099ac2c597 /crypto/ui | |
parent | 72d8b823bbe749da528f386408541ae1daa644c9 (diff) |
Add UI functionality to duplicate the user data
This can be used by engines that need to retain the data for a longer time
than just the call where this user data is passed.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3575)
Diffstat (limited to 'crypto/ui')
-rw-r--r-- | crypto/ui/ui_err.c | 5 | ||||
-rw-r--r-- | crypto/ui/ui_lib.c | 57 | ||||
-rw-r--r-- | crypto/ui/ui_locl.h | 7 |
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; |