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
103954 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
const char *password = ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
37
38
if (password != NULL) {
39
UI_set_result(ui, uis, password);
40
return 1;
41
}
42
} break;
43
case UIT_NONE:
44
case UIT_BOOLEAN:
45
case UIT_INFO:
46
case UIT_ERROR:
47
break;
48
}
49
}
50
51
reader = UI_method_get_reader(ui_base_method);
52
if (reader != NULL)
53
return reader(ui, uis);
54
/* Default to the empty password if we've got nothing better */
55
UI_set_result(ui, uis, "");
56
return 1;
57
}
58
59
static int ui_write(UI *ui, UI_STRING *uis)
60
{
61
int (*writer)(UI *ui, UI_STRING *uis) = NULL;
62
63
if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
64
&& UI_get0_user_data(ui)) {
65
switch (UI_get_string_type(uis)) {
66
case UIT_PROMPT:
67
case UIT_VERIFY: {
68
const char *password = ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
69
70
if (password != NULL)
71
return 1;
72
} break;
73
case UIT_NONE:
74
case UIT_BOOLEAN:
75
case UIT_INFO:
76
case UIT_ERROR:
77
break;
78
}
79
}
80
81
writer = UI_method_get_writer(ui_base_method);
82
if (writer != NULL)
83
return writer(ui, uis);
84
return 1;
85
}
86
87
static int ui_close(UI *ui)
88
{
89
int (*closer)(UI *ui) = UI_method_get_closer(ui_base_method);
90
91
if (closer != NULL)
92
return closer(ui);
93
return 1;
94
}
95
96
/* object_name defaults to prompt_info from ui user data if present */
97
static char *ui_prompt_construct(UI *ui, const char *phrase_desc,
98
const char *object_name)
99
{
100
PW_CB_DATA *cb_data = (PW_CB_DATA *)UI_get0_user_data(ui);
101
102
if (phrase_desc == NULL)
103
phrase_desc = "pass phrase";
104
if (object_name == NULL && cb_data != NULL)
105
object_name = cb_data->prompt_info;
106
return UI_construct_prompt(NULL, phrase_desc, object_name);
107
}
108
109
int set_base_ui_method(const UI_METHOD *ui_meth)
110
{
111
if (ui_meth == NULL)
112
ui_meth = UI_null();
113
ui_base_method = ui_meth;
114
return 1;
115
}
116
117
int setup_ui_method(void)
118
{
119
ui_base_method = UI_null();
120
#ifndef OPENSSL_NO_UI_CONSOLE
121
ui_base_method = UI_OpenSSL();
122
#endif
123
ui_method = UI_create_method("OpenSSL application user interface");
124
return ui_method != NULL
125
&& 0 == UI_method_set_opener(ui_method, ui_open)
126
&& 0 == UI_method_set_reader(ui_method, ui_read)
127
&& 0 == UI_method_set_writer(ui_method, ui_write)
128
&& 0 == UI_method_set_closer(ui_method, ui_close)
129
&& 0 == UI_method_set_prompt_constructor(ui_method, ui_prompt_construct);
130
}
131
132
void destroy_ui_method(void)
133
{
134
if (ui_method != NULL) {
135
UI_destroy_method(ui_method);
136
ui_method = NULL;
137
}
138
}
139
140
const UI_METHOD *get_ui_method(void)
141
{
142
return ui_method;
143
}
144
145
static void *ui_malloc(int sz, const char *what)
146
{
147
void *vp = OPENSSL_malloc(sz);
148
149
if (vp == NULL) {
150
BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what);
151
ERR_print_errors(bio_err);
152
exit(1);
153
}
154
return vp;
155
}
156
157
int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data)
158
{
159
int res = 0;
160
UI *ui;
161
int ok = 0;
162
char *buff = NULL;
163
int ui_flags = 0;
164
const char *prompt_info = NULL;
165
char *prompt;
166
167
if ((ui = UI_new_method(ui_method)) == NULL)
168
return 0;
169
170
if (cb_data != NULL && cb_data->prompt_info != NULL)
171
prompt_info = cb_data->prompt_info;
172
prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
173
if (prompt == NULL) {
174
BIO_printf(bio_err, "Out of memory\n");
175
UI_free(ui);
176
return 0;
177
}
178
179
ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
180
UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
181
182
/* We know that there is no previous user data to return to us */
183
(void)UI_add_user_data(ui, cb_data);
184
185
ok = UI_add_input_string(ui, prompt, ui_flags, buf,
186
PW_MIN_LENGTH, bufsiz - 1);
187
188
if (ok >= 0 && verify) {
189
buff = ui_malloc(bufsiz, "password buffer");
190
ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
191
PW_MIN_LENGTH, bufsiz - 1, buf);
192
}
193
if (ok >= 0)
194
do {
195
ok = UI_process(ui);
196
} while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
197
198
OPENSSL_clear_free(buff, (unsigned int)bufsiz);
199
200
if (ok >= 0)
201
res = strlen(buf);
202
if (ok == -1) {
203
BIO_printf(bio_err, "User interface error\n");
204
ERR_print_errors(bio_err);
205
OPENSSL_cleanse(buf, (unsigned int)bufsiz);
206
res = 0;
207
}
208
if (ok == -2) {
209
BIO_printf(bio_err, "aborted!\n");
210
OPENSSL_cleanse(buf, (unsigned int)bufsiz);
211
res = 0;
212
}
213
UI_free(ui);
214
OPENSSL_free(prompt);
215
return res;
216
}
217
218