Commit 545360c4 authored by Richard Levitte's avatar Richard Levitte
Browse files

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: default avatarMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3575)
parent 72d8b823
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
/*
 * 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}
};

+57 −0
Original line number Diff line number Diff line
@@ -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);
+7 −0
Original line number Diff line number Diff line
@@ -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;

+29 −10
Original line number Diff line number Diff line
@@ -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.
Loading