mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 05:21:51 +08:00
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)
This commit is contained in:
parent
72d8b823bb
commit
545360c4df
5
CHANGES
5
CHANGES
@ -4,6 +4,11 @@
|
||||
|
||||
Changes between 1.1.0f and 1.1.1 [xx XXX xxxx]
|
||||
|
||||
*) In the UI interface, make it possible 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.
|
||||
[Richard Levitte]
|
||||
|
||||
*) Fragmented SSL/TLS alerts are no longer accepted. An alert message is 2
|
||||
bytes long. In theory it is permissible in SSLv3 - TLSv1.2 to fragment such
|
||||
alerts across multiple records (some of which could be empty). In practice
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -37,6 +37,12 @@ struct ui_method_st {
|
||||
int (*ui_flush) (UI *ui);
|
||||
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
|
||||
@ -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;
|
||||
|
||||
|
@ -5,9 +5,11 @@
|
||||
UI_METHOD,
|
||||
UI_create_method, UI_destroy_method, UI_method_set_opener,
|
||||
UI_method_set_writer, UI_method_set_flusher, UI_method_set_reader,
|
||||
UI_method_set_closer, UI_method_set_prompt_constructor,
|
||||
UI_method_set_ex_data, UI_method_get_opener, UI_method_get_writer,
|
||||
UI_method_get_flusher, UI_method_get_reader, UI_method_get_closer,
|
||||
UI_method_set_closer, UI_method_set_data_duplicator,
|
||||
UI_method_set_prompt_constructor, UI_method_set_ex_data,
|
||||
UI_method_get_opener, UI_method_get_writer, UI_method_get_flusher,
|
||||
UI_method_get_reader, UI_method_get_closer,
|
||||
UI_method_get_data_duplicator, UI_method_get_data_destructor,
|
||||
UI_method_get_prompt_constructor, UI_method_get_ex_data - user
|
||||
interface method creation and destruction
|
||||
|
||||
@ -26,6 +28,9 @@ interface method creation and destruction
|
||||
int UI_method_set_reader(UI_METHOD *method,
|
||||
int (*reader) (UI *ui, UI_STRING *uis));
|
||||
int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui));
|
||||
int UI_method_set_data_duplicator(UI_METHOD *method,
|
||||
void *(*duplicator) (UI *ui, void *ui_data),
|
||||
void (*destructor)(UI *ui, void *ui_data));
|
||||
int UI_method_set_prompt_constructor(UI_METHOD *method,
|
||||
char *(*prompt_constructor) (UI *ui,
|
||||
const char
|
||||
@ -40,6 +45,8 @@ interface method creation and destruction
|
||||
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 *);
|
||||
void *(*UI_method_get_data_duplicator(const UI_METHOD *method)) (UI *, void *);
|
||||
void (*UI_method_get_data_destructor(const UI_METHOD *method)) (UI *, void *);
|
||||
const void *UI_method_get_ex_data(const UI_METHOD *method, int idx);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@ -148,6 +155,9 @@ UI_method_set_flusher(), UI_method_set_reader() and
|
||||
UI_method_set_closer() set the five main method function to the given
|
||||
function pointer.
|
||||
|
||||
UI_method_set_data_duplicator() sets the user data duplicator and destructor.
|
||||
See L<UI_dup_user_data(3)>.
|
||||
|
||||
UI_method_set_prompt_constructor() sets the prompt constructor.
|
||||
See L<UI_construct_prompt(3)>.
|
||||
|
||||
@ -158,8 +168,9 @@ get that index.
|
||||
|
||||
UI_method_get_opener(), UI_method_get_writer(),
|
||||
UI_method_get_flusher(), UI_method_get_reader(),
|
||||
UI_method_get_closer() and UI_method_get_prompt_constructor() return
|
||||
the different method functions.
|
||||
UI_method_get_closer(), UI_method_get_data_duplicator(),
|
||||
UI_method_get_data_destructor() and UI_method_get_prompt_constructor()
|
||||
return the different method functions.
|
||||
|
||||
UI_method_get_ex_data() returns the application data previously stored
|
||||
with UI_method_set_ex_data().
|
||||
@ -171,17 +182,19 @@ error.
|
||||
|
||||
UI_method_set_opener(), UI_method_set_writer(),
|
||||
UI_method_set_flusher(), UI_method_set_reader(),
|
||||
UI_method_set_closer() and UI_method_set_prompt_constructor() return
|
||||
0 on success, -1 if the given B<method> is NULL.
|
||||
UI_method_set_closer(), UI_method_set_data_duplicator() and
|
||||
UI_method_set_prompt_constructor()
|
||||
return 0 on success, -1 if the given B<method> is NULL.
|
||||
|
||||
UI_method_set_ex_data() returns 1 on success and 0 on error (because
|
||||
CRYPTO_set_ex_data() does so).
|
||||
|
||||
UI_method_get_opener(), UI_method_get_writer(),
|
||||
UI_method_get_flusher(), UI_method_get_reader(),
|
||||
UI_method_get_closer() and UI_method_get_prompt_constructor() return
|
||||
the requested function pointer if it's set in the method, otherwise
|
||||
NULL.
|
||||
UI_method_get_closer(), UI_method_get_data_duplicator(),
|
||||
UI_method_get_data_destructor() and UI_method_get_prompt_constructor()
|
||||
return the requested function pointer if it's set in the method,
|
||||
otherwise NULL.
|
||||
|
||||
UI_method_get_ex_data() returns a pointer to the application specific
|
||||
data associated with the method.
|
||||
@ -190,6 +203,12 @@ data associated with the method.
|
||||
|
||||
L<UI(3)>, L<CRYPTO_get_ex_data(3)>, L<UI_STRING(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
UI_method_set_data_duplicator(), UI_method_get_data_duplicator() and
|
||||
UI_method_get_data_destructor()
|
||||
were added in OpenSSL 1.1.1.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
@ -7,9 +7,9 @@ UI_new, UI_new_method, UI_free, UI_add_input_string, UI_dup_input_string,
|
||||
UI_add_verify_string, UI_dup_verify_string, UI_add_input_boolean,
|
||||
UI_dup_input_boolean, UI_add_info_string, UI_dup_info_string,
|
||||
UI_add_error_string, UI_dup_error_string, UI_construct_prompt,
|
||||
UI_add_user_data, UI_get0_user_data, UI_get0_result, UI_process,
|
||||
UI_ctrl, UI_set_default_method, UI_get_default_method, UI_get_method,
|
||||
UI_set_method, UI_OpenSSL, UI_null - user interface
|
||||
UI_add_user_data, UI_dup_user_data, UI_get0_user_data, UI_get0_result,
|
||||
UI_process, UI_ctrl, UI_set_default_method, UI_get_default_method,
|
||||
UI_get_method, UI_set_method, UI_OpenSSL, UI_null - user interface
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
@ -44,6 +44,7 @@ UI_set_method, UI_OpenSSL, UI_null - user interface
|
||||
const char *object_desc, const char *object_name);
|
||||
|
||||
void *UI_add_user_data(UI *ui, void *user_data);
|
||||
int UI_dup_user_data(UI *ui, void *user_data);
|
||||
void *UI_get0_user_data(UI *ui);
|
||||
|
||||
const char *UI_get0_result(UI *ui, int i);
|
||||
@ -76,16 +77,19 @@ carry out the actual prompting.
|
||||
The first thing to do is to create a UI with UI_new() or UI_new_method(),
|
||||
then add information to it with the UI_add or UI_dup functions. Also,
|
||||
user-defined random data can be passed down to the underlying method
|
||||
through calls to UI_add_user_data. The default UI method doesn't care
|
||||
about these data, but other methods might. Finally, use UI_process()
|
||||
to actually perform the prompting and UI_get0_result() to find the result
|
||||
to the prompt.
|
||||
through calls to UI_add_user_data() or UI_dup_user_data(). The default
|
||||
UI method doesn't care about these data, but other methods might. Finally,
|
||||
use UI_process() to actually perform the prompting and UI_get0_result()
|
||||
to find the result to the prompt.
|
||||
|
||||
A UI can contain more than one prompt, which are performed in the given
|
||||
sequence. Each prompt gets an index number which is returned by the
|
||||
UI_add and UI_dup functions, and has to be used to get the corresponding
|
||||
result with UI_get0_result().
|
||||
|
||||
UI_process() can be called more than once on the same UI, thereby allowing
|
||||
a UI to have a long lifetime, but can just as well have a short lifetime.
|
||||
|
||||
The functions are as follows:
|
||||
|
||||
UI_new() creates a new UI using the default UI method. When done with
|
||||
@ -149,13 +153,20 @@ description "pass phrase" and the file name "foo.key", that becomes
|
||||
string and may include encodings that will be processed by the other
|
||||
method functions.
|
||||
|
||||
UI_add_user_data() adds a piece of memory for the method to use at any
|
||||
UI_add_user_data() adds a user data pointer for the method to use at any
|
||||
time. The builtin UI method doesn't care about this info. Note that several
|
||||
calls to this function doesn't add data, it replaces the previous blob
|
||||
with the one given as argument.
|
||||
|
||||
UI_dup_user_data() duplicates the user data and works as an alternative
|
||||
to UI_add_user_data() when the user data needs to be preserved for a longer
|
||||
duration, perhaps even the lifetime of the application. The UI object takes
|
||||
ownership of this duplicate and will free it whenever it gets replaced or
|
||||
the UI is destroyed. UI_dup_user_data() returns 0 on success, or -1 on memory
|
||||
allocation failure or if the method doesn't have a duplicator function.
|
||||
|
||||
UI_get0_user_data() retrieves the data that has last been given to the
|
||||
UI with UI_add_user_data().
|
||||
UI with UI_add_user_data() or UI_dup_user_data.
|
||||
|
||||
UI_get0_result() returns a pointer to the result buffer associated with
|
||||
the information indexed by I<i>.
|
||||
@ -191,6 +202,11 @@ For Windows, if the OPENSSL_WIN32_UTF8 environment variable is set,
|
||||
the built-in method UI_OpenSSL() will produce UTF-8 encoded strings
|
||||
instead.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
UI_dup_user_data()
|
||||
was added in OpenSSL 1.1.1.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
@ -158,6 +158,12 @@ char *UI_construct_prompt(UI *ui_method,
|
||||
* methods may not, however.
|
||||
*/
|
||||
void *UI_add_user_data(UI *ui, void *user_data);
|
||||
/*
|
||||
* Alternatively, this function is used to duplicate the user data.
|
||||
* This uses the duplicator method function. The destroy function will
|
||||
* be used to free the user data in this case.
|
||||
*/
|
||||
int UI_dup_user_data(UI *ui, void *user_data);
|
||||
/* We need a user data retrieving function as well. */
|
||||
void *UI_get0_user_data(UI *ui);
|
||||
|
||||
@ -285,6 +291,9 @@ int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui));
|
||||
int UI_method_set_reader(UI_METHOD *method,
|
||||
int (*reader) (UI *ui, UI_STRING *uis));
|
||||
int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui));
|
||||
int UI_method_set_data_duplicator(UI_METHOD *method,
|
||||
void *(*duplicator) (UI *ui, void *ui_data),
|
||||
void (*destructor)(UI *ui, void *ui_data));
|
||||
int UI_method_set_prompt_constructor(UI_METHOD *method,
|
||||
char *(*prompt_constructor) (UI *ui,
|
||||
const char
|
||||
@ -299,6 +308,8 @@ 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 *);
|
||||
void *(*UI_method_get_data_duplicator(const UI_METHOD *method)) (UI *, void *);
|
||||
void (*UI_method_get_data_destructor(const UI_METHOD *method)) (UI *, void *);
|
||||
const void *UI_method_get_ex_data(const UI_METHOD *method, int idx);
|
||||
|
||||
/*
|
||||
@ -335,7 +346,7 @@ int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
|
||||
int verify);
|
||||
int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
|
||||
int verify);
|
||||
UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag);
|
||||
UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag);
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
/*
|
||||
@ -360,6 +371,7 @@ int ERR_load_UI_strings(void);
|
||||
# define UI_F_UI_DUP_INFO_STRING 102
|
||||
# define UI_F_UI_DUP_INPUT_BOOLEAN 110
|
||||
# define UI_F_UI_DUP_INPUT_STRING 103
|
||||
# define UI_F_UI_DUP_USER_DATA 118
|
||||
# define UI_F_UI_DUP_VERIFY_STRING 106
|
||||
# define UI_F_UI_GET0_RESULT 107
|
||||
# define UI_F_UI_NEW_METHOD 104
|
||||
@ -379,6 +391,7 @@ int ERR_load_UI_strings(void);
|
||||
# define UI_R_SYSQIOW_ERROR 111
|
||||
# define UI_R_UNKNOWN_CONTROL_COMMAND 106
|
||||
# define UI_R_UNKNOWN_TTYGET_ERRNO_VALUE 108
|
||||
# define UI_R_USER_DATA_DUPLICATION_UNSUPPORTED 112
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
@ -4292,3 +4292,7 @@ PEM_read_bio_ex 4234 1_1_1 EXIST::FUNCTION:
|
||||
PEM_bytes_read_bio_secmem 4235 1_1_1 EXIST::FUNCTION:
|
||||
EVP_DigestSign 4236 1_1_1 EXIST::FUNCTION:
|
||||
EVP_DigestVerify 4237 1_1_1 EXIST::FUNCTION:
|
||||
UI_method_get_data_duplicator 4238 1_1_1 EXIST::FUNCTION:UI
|
||||
UI_method_set_data_duplicator 4239 1_1_1 EXIST::FUNCTION:UI
|
||||
UI_dup_user_data 4240 1_1_1 EXIST::FUNCTION:UI
|
||||
UI_method_get_data_destructor 4241 1_1_1 EXIST::FUNCTION:UI
|
||||
|
Loading…
Reference in New Issue
Block a user