1 | /*
|
---|
2 | * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
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
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include <string.h>
|
---|
11 | #include <openssl/pem.h> /* PEM_def_callback() */
|
---|
12 | #include "internal/thread_once.h"
|
---|
13 | #include "ui_local.h"
|
---|
14 |
|
---|
15 | #ifndef BUFSIZ
|
---|
16 | #define BUFSIZ 256
|
---|
17 | #endif
|
---|
18 |
|
---|
19 | int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
|
---|
20 | int verify)
|
---|
21 | {
|
---|
22 | char buff[BUFSIZ];
|
---|
23 | int ret;
|
---|
24 |
|
---|
25 | ret =
|
---|
26 | UI_UTIL_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length,
|
---|
27 | prompt, verify);
|
---|
28 | OPENSSL_cleanse(buff, BUFSIZ);
|
---|
29 | return ret;
|
---|
30 | }
|
---|
31 |
|
---|
32 | int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
|
---|
33 | int verify)
|
---|
34 | {
|
---|
35 | int ok = 0;
|
---|
36 | UI *ui;
|
---|
37 |
|
---|
38 | if (size < 1)
|
---|
39 | return -1;
|
---|
40 |
|
---|
41 | ui = UI_new();
|
---|
42 | if (ui != NULL) {
|
---|
43 | ok = UI_add_input_string(ui, prompt, 0, buf, 0, size - 1);
|
---|
44 | if (ok >= 0 && verify)
|
---|
45 | ok = UI_add_verify_string(ui, prompt, 0, buff, 0, size - 1, buf);
|
---|
46 | if (ok >= 0)
|
---|
47 | ok = UI_process(ui);
|
---|
48 | UI_free(ui);
|
---|
49 | }
|
---|
50 | if (ok > 0)
|
---|
51 | ok = 0;
|
---|
52 | return ok;
|
---|
53 | }
|
---|
54 |
|
---|
55 | /*
|
---|
56 | * Wrapper around pem_password_cb, a method to help older APIs use newer
|
---|
57 | * ones.
|
---|
58 | */
|
---|
59 | struct pem_password_cb_data {
|
---|
60 | pem_password_cb *cb;
|
---|
61 | int rwflag;
|
---|
62 | };
|
---|
63 |
|
---|
64 | static void ui_new_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
|
---|
65 | int idx, long argl, void *argp)
|
---|
66 | {
|
---|
67 | /*
|
---|
68 | * Do nothing, the data is allocated externally and assigned later with
|
---|
69 | * CRYPTO_set_ex_data()
|
---|
70 | */
|
---|
71 | }
|
---|
72 |
|
---|
73 | static int ui_dup_method_data(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
|
---|
74 | void *from_d, int idx, long argl, void *argp)
|
---|
75 | {
|
---|
76 | void **pptr = (void **)from_d;
|
---|
77 | if (*pptr != NULL)
|
---|
78 | *pptr = OPENSSL_memdup(*pptr, sizeof(struct pem_password_cb_data));
|
---|
79 | return 1;
|
---|
80 | }
|
---|
81 |
|
---|
82 | static void ui_free_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
|
---|
83 | int idx, long argl, void *argp)
|
---|
84 | {
|
---|
85 | OPENSSL_free(ptr);
|
---|
86 | }
|
---|
87 |
|
---|
88 | static CRYPTO_ONCE get_index_once = CRYPTO_ONCE_STATIC_INIT;
|
---|
89 | static int ui_method_data_index = -1;
|
---|
90 | DEFINE_RUN_ONCE_STATIC(ui_method_data_index_init)
|
---|
91 | {
|
---|
92 | ui_method_data_index = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI_METHOD,
|
---|
93 | 0, NULL, ui_new_method_data,
|
---|
94 | ui_dup_method_data,
|
---|
95 | ui_free_method_data);
|
---|
96 | return 1;
|
---|
97 | }
|
---|
98 |
|
---|
99 | static int ui_open(UI *ui)
|
---|
100 | {
|
---|
101 | return 1;
|
---|
102 | }
|
---|
103 | static int ui_read(UI *ui, UI_STRING *uis)
|
---|
104 | {
|
---|
105 | switch (UI_get_string_type(uis)) {
|
---|
106 | case UIT_PROMPT:
|
---|
107 | {
|
---|
108 | char result[PEM_BUFSIZE + 1];
|
---|
109 | const struct pem_password_cb_data *data =
|
---|
110 | UI_method_get_ex_data(UI_get_method(ui), ui_method_data_index);
|
---|
111 | int maxsize = UI_get_result_maxsize(uis);
|
---|
112 | int len = data->cb(result,
|
---|
113 | maxsize > PEM_BUFSIZE ? PEM_BUFSIZE : maxsize,
|
---|
114 | data->rwflag, UI_get0_user_data(ui));
|
---|
115 |
|
---|
116 | if (len >= 0)
|
---|
117 | result[len] = '\0';
|
---|
118 | if (len <= 0)
|
---|
119 | return len;
|
---|
120 | if (UI_set_result_ex(ui, uis, result, len) >= 0)
|
---|
121 | return 1;
|
---|
122 | return 0;
|
---|
123 | }
|
---|
124 | case UIT_VERIFY:
|
---|
125 | case UIT_NONE:
|
---|
126 | case UIT_BOOLEAN:
|
---|
127 | case UIT_INFO:
|
---|
128 | case UIT_ERROR:
|
---|
129 | break;
|
---|
130 | }
|
---|
131 | return 1;
|
---|
132 | }
|
---|
133 | static int ui_write(UI *ui, UI_STRING *uis)
|
---|
134 | {
|
---|
135 | return 1;
|
---|
136 | }
|
---|
137 | static int ui_close(UI *ui)
|
---|
138 | {
|
---|
139 | return 1;
|
---|
140 | }
|
---|
141 |
|
---|
142 | UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag)
|
---|
143 | {
|
---|
144 | struct pem_password_cb_data *data = NULL;
|
---|
145 | UI_METHOD *ui_method = NULL;
|
---|
146 |
|
---|
147 | if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL
|
---|
148 | || (ui_method = UI_create_method("PEM password callback wrapper")) == NULL
|
---|
149 | || UI_method_set_opener(ui_method, ui_open) < 0
|
---|
150 | || UI_method_set_reader(ui_method, ui_read) < 0
|
---|
151 | || UI_method_set_writer(ui_method, ui_write) < 0
|
---|
152 | || UI_method_set_closer(ui_method, ui_close) < 0
|
---|
153 | || !RUN_ONCE(&get_index_once, ui_method_data_index_init)
|
---|
154 | || UI_method_set_ex_data(ui_method, ui_method_data_index, data) < 0) {
|
---|
155 | UI_destroy_method(ui_method);
|
---|
156 | OPENSSL_free(data);
|
---|
157 | return NULL;
|
---|
158 | }
|
---|
159 | data->rwflag = rwflag;
|
---|
160 | data->cb = cb != NULL ? cb : PEM_def_callback;
|
---|
161 |
|
---|
162 | return ui_method;
|
---|
163 | }
|
---|