Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/apps/lib/apps_ui.c
34878 views
1
/*
2
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (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
8
*/
9
10
#include <string.h>
11
#include <openssl/err.h>
12
#include <openssl/ui.h>
13
#include "apps_ui.h"
14
15
static UI_METHOD *ui_method = NULL;
16
static const UI_METHOD *ui_base_method = NULL;
17
18
static int ui_open(UI *ui)
19
{
20
int (*opener)(UI *ui) = UI_method_get_opener(ui_base_method);
21
22
if (opener != NULL)
23
return opener(ui);
24
return 1;
25
}
26
27
static 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;
39
40
if (password != NULL) {
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
54
reader = UI_method_get_reader(ui_base_method);
55
if (reader != NULL)
56
return reader(ui, uis);
57
/* Default to the empty password if we've got nothing better */
58
UI_set_result(ui, uis, "");
59
return 1;
60
}
61
62
static 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;
74
75
if (password != NULL)
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
87
writer = UI_method_get_writer(ui_base_method);
88
if (writer != NULL)
89
return writer(ui, uis);
90
return 1;
91
}
92
93
static int ui_close(UI *ui)
94
{
95
int (*closer)(UI *ui) = UI_method_get_closer(ui_base_method);
96
97
if (closer != NULL)
98
return closer(ui);
99
return 1;
100
}
101
102
/* object_name defaults to prompt_info from ui user data if present */
103
static 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
115
int 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
123
int setup_ui_method(void)
124
{
125
ui_base_method = UI_null();
126
#ifndef OPENSSL_NO_UI_CONSOLE
127
ui_base_method = UI_OpenSSL();
128
#endif
129
ui_method = UI_create_method("OpenSSL application user interface");
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);
137
}
138
139
void destroy_ui_method(void)
140
{
141
if (ui_method != NULL) {
142
UI_destroy_method(ui_method);
143
ui_method = NULL;
144
}
145
}
146
147
const UI_METHOD *get_ui_method(void)
148
{
149
return ui_method;
150
}
151
152
static 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
164
int 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
}
224
225