2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include <openssl/err.h>
12 #include <openssl/ui.h>
15 static UI_METHOD *ui_method = NULL;
16 static const UI_METHOD *ui_fallback_method = NULL;
19 static int ui_open(UI *ui)
21 int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method);
28 static int ui_read(UI *ui, UI_STRING *uis)
30 int (*reader)(UI *ui, UI_STRING *uis) = NULL;
32 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
33 && UI_get0_user_data(ui)) {
34 switch (UI_get_string_type(uis)) {
38 const char *password =
39 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
40 if (password && password[0] != '\0') {
41 UI_set_result(ui, uis, password);
54 reader = UI_method_get_reader(ui_fallback_method);
56 return reader(ui, uis);
60 static int ui_write(UI *ui, UI_STRING *uis)
62 int (*writer)(UI *ui, UI_STRING *uis) = NULL;
64 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
65 && UI_get0_user_data(ui)) {
66 switch (UI_get_string_type(uis)) {
70 const char *password =
71 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
72 if (password && password[0] != '\0')
84 writer = UI_method_get_writer(ui_fallback_method);
86 return writer(ui, uis);
90 static int ui_close(UI *ui)
92 int (*closer)(UI *ui) = UI_method_get_closer(ui_fallback_method);
99 int setup_ui_method(void)
101 ui_fallback_method = UI_null();
102 #ifndef OPENSSL_NO_UI_CONSOLE
103 ui_fallback_method = UI_OpenSSL();
105 ui_method = UI_create_method("OpenSSL application user interface");
106 UI_method_set_opener(ui_method, ui_open);
107 UI_method_set_reader(ui_method, ui_read);
108 UI_method_set_writer(ui_method, ui_write);
109 UI_method_set_closer(ui_method, ui_close);
113 void destroy_ui_method(void)
116 UI_destroy_method(ui_method);
121 const UI_METHOD *get_ui_method(void)
126 static void *ui_malloc(int sz, const char *what)
128 void *vp = OPENSSL_malloc(sz);
131 BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what);
132 ERR_print_errors(bio_err);
138 int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data)
145 const char *prompt_info = NULL;
148 if ((ui = UI_new_method(ui_method)) == NULL)
151 if (cb_data != NULL && cb_data->prompt_info != NULL)
152 prompt_info = cb_data->prompt_info;
153 prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
154 if (prompt == NULL) {
155 BIO_printf(bio_err, "Out of memory\n");
160 ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
161 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
163 /* We know that there is no previous user data to return to us */
164 (void)UI_add_user_data(ui, cb_data);
166 ok = UI_add_input_string(ui, prompt, ui_flags, buf,
167 PW_MIN_LENGTH, bufsiz - 1);
169 if (ok >= 0 && verify) {
170 buff = ui_malloc(bufsiz, "password buffer");
171 ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
172 PW_MIN_LENGTH, bufsiz - 1, buf);
177 } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
179 OPENSSL_clear_free(buff, (unsigned int)bufsiz);
184 BIO_printf(bio_err, "User interface error\n");
185 ERR_print_errors(bio_err);
186 OPENSSL_cleanse(buf, (unsigned int)bufsiz);
190 BIO_printf(bio_err, "aborted!\n");
191 OPENSSL_cleanse(buf, (unsigned int)bufsiz);
195 OPENSSL_free(prompt);