]> git.ipfire.org Git - thirdparty/openssl.git/blame - apps/lib/apps_ui.c
Add SSL_OP_ALLOW_CLIENT_RENEGOTIATION
[thirdparty/openssl.git] / apps / lib / apps_ui.c
CommitLineData
a43ce58f 1/*
454afd98 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
a43ce58f 3 *
a6ed19dc 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
a43ce58f
SL
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
8 */
9
10#include <string.h>
11#include <openssl/err.h>
12#include <openssl/ui.h>
13#include "apps_ui.h"
14
15static UI_METHOD *ui_method = NULL;
a6a5dec6 16static const UI_METHOD *ui_base_method = NULL;
a43ce58f 17
a43ce58f
SL
18static int ui_open(UI *ui)
19{
a6a5dec6 20 int (*opener)(UI *ui) = UI_method_get_opener(ui_base_method);
a43ce58f 21
ca3245a6 22 if (opener != NULL)
a43ce58f
SL
23 return opener(ui);
24 return 1;
25}
26
27static int ui_read(UI *ui, UI_STRING *uis)
28{
29 int (*reader)(UI *ui, UI_STRING *uis) = NULL;
30
31 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
32 && UI_get0_user_data(ui)) {
33 switch (UI_get_string_type(uis)) {
34 case UIT_PROMPT:
35 case UIT_VERIFY:
36 {
37 const char *password =
38 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
ca3245a6
MC
39
40 if (password != NULL) {
a43ce58f
SL
41 UI_set_result(ui, uis, password);
42 return 1;
43 }
44 }
45 break;
46 case UIT_NONE:
47 case UIT_BOOLEAN:
48 case UIT_INFO:
49 case UIT_ERROR:
50 break;
51 }
52 }
53
a6a5dec6 54 reader = UI_method_get_reader(ui_base_method);
ca3245a6 55 if (reader != NULL)
a43ce58f 56 return reader(ui, uis);
ca3245a6
MC
57 /* Default to the empty password if we've got nothing better */
58 UI_set_result(ui, uis, "");
a43ce58f
SL
59 return 1;
60}
61
62static int ui_write(UI *ui, UI_STRING *uis)
63{
64 int (*writer)(UI *ui, UI_STRING *uis) = NULL;
65
66 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
67 && UI_get0_user_data(ui)) {
68 switch (UI_get_string_type(uis)) {
69 case UIT_PROMPT:
70 case UIT_VERIFY:
71 {
72 const char *password =
73 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
591ceedd
DDO
74
75 if (password != NULL)
a43ce58f
SL
76 return 1;
77 }
78 break;
79 case UIT_NONE:
80 case UIT_BOOLEAN:
81 case UIT_INFO:
82 case UIT_ERROR:
83 break;
84 }
85 }
86
a6a5dec6 87 writer = UI_method_get_writer(ui_base_method);
ca3245a6 88 if (writer != NULL)
a43ce58f
SL
89 return writer(ui, uis);
90 return 1;
91}
92
93static int ui_close(UI *ui)
94{
a6a5dec6 95 int (*closer)(UI *ui) = UI_method_get_closer(ui_base_method);
a43ce58f 96
ca3245a6 97 if (closer != NULL)
a43ce58f
SL
98 return closer(ui);
99 return 1;
100}
101
d3dbc9b5
DDO
102/* object_name defaults to prompt_info from ui user data if present */
103static char *ui_prompt_construct(UI *ui, const char *phrase_desc,
104 const char *object_name)
105{
106 PW_CB_DATA *cb_data = (PW_CB_DATA *)UI_get0_user_data(ui);
107
108 if (phrase_desc == NULL)
109 phrase_desc = "pass phrase";
110 if (object_name == NULL && cb_data != NULL)
111 object_name = cb_data->prompt_info;
112 return UI_construct_prompt(NULL, phrase_desc, object_name);
113}
114
a6a5dec6
RL
115int set_base_ui_method(const UI_METHOD *ui_meth)
116{
117 if (ui_meth == NULL)
118 ui_meth = UI_null();
119 ui_base_method = ui_meth;
120 return 1;
121}
122
a43ce58f
SL
123int setup_ui_method(void)
124{
a6a5dec6 125 ui_base_method = UI_null();
a43ce58f 126#ifndef OPENSSL_NO_UI_CONSOLE
a6a5dec6 127 ui_base_method = UI_OpenSSL();
a43ce58f
SL
128#endif
129 ui_method = UI_create_method("OpenSSL application user interface");
f84de16f
DDO
130 return ui_method != NULL
131 && 0 == UI_method_set_opener(ui_method, ui_open)
132 && 0 == UI_method_set_reader(ui_method, ui_read)
133 && 0 == UI_method_set_writer(ui_method, ui_write)
134 && 0 == UI_method_set_closer(ui_method, ui_close)
135 && 0 == UI_method_set_prompt_constructor(ui_method,
136 ui_prompt_construct);
a43ce58f
SL
137}
138
139void destroy_ui_method(void)
140{
ca3245a6 141 if (ui_method != NULL) {
a43ce58f
SL
142 UI_destroy_method(ui_method);
143 ui_method = NULL;
144 }
145}
146
a6a5dec6 147const UI_METHOD *get_ui_method(void)
a43ce58f
SL
148{
149 return ui_method;
150}
151
152static void *ui_malloc(int sz, const char *what)
153{
154 void *vp = OPENSSL_malloc(sz);
155
156 if (vp == NULL) {
157 BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what);
158 ERR_print_errors(bio_err);
159 exit(1);
160 }
161 return vp;
162}
163
164int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data)
165{
166 int res = 0;
167 UI *ui;
168 int ok = 0;
169 char *buff = NULL;
170 int ui_flags = 0;
171 const char *prompt_info = NULL;
172 char *prompt;
173
174 if ((ui = UI_new_method(ui_method)) == NULL)
175 return 0;
176
177 if (cb_data != NULL && cb_data->prompt_info != NULL)
178 prompt_info = cb_data->prompt_info;
179 prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
180 if (prompt == NULL) {
181 BIO_printf(bio_err, "Out of memory\n");
182 UI_free(ui);
183 return 0;
184 }
185
186 ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
187 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
188
189 /* We know that there is no previous user data to return to us */
190 (void)UI_add_user_data(ui, cb_data);
191
192 ok = UI_add_input_string(ui, prompt, ui_flags, buf,
193 PW_MIN_LENGTH, bufsiz - 1);
194
195 if (ok >= 0 && verify) {
196 buff = ui_malloc(bufsiz, "password buffer");
197 ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
198 PW_MIN_LENGTH, bufsiz - 1, buf);
199 }
200 if (ok >= 0)
201 do {
202 ok = UI_process(ui);
203 } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
204
205 OPENSSL_clear_free(buff, (unsigned int)bufsiz);
206
207 if (ok >= 0)
208 res = strlen(buf);
209 if (ok == -1) {
210 BIO_printf(bio_err, "User interface error\n");
211 ERR_print_errors(bio_err);
212 OPENSSL_cleanse(buf, (unsigned int)bufsiz);
213 res = 0;
214 }
215 if (ok == -2) {
216 BIO_printf(bio_err, "aborted!\n");
217 OPENSSL_cleanse(buf, (unsigned int)bufsiz);
218 res = 0;
219 }
220 UI_free(ui);
221 OPENSSL_free(prompt);
222 return res;
223}