Commit 0fe1fc85 authored by Richard Levitte's avatar Richard Levitte
Browse files

Add a UI utility function with which to wrap pem_callback_cb in a UI_METHOD

parent 18cfc668
Loading
Loading
Loading
Loading
+111 −0
Original line number Diff line number Diff line
@@ -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;
}
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#   include <openssl/crypto.h>
#  endif
#  include <openssl/safestack.h>
#  include <openssl/pem.h>
#  include <openssl/ossl_typ.h>

#ifdef  __cplusplus
@@ -328,6 +329,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);

/* BEGIN ERROR CODES */
/*