Line data Source code
1 : /*
2 : * Copyright (c) 2005 - 2006 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "hx_locl.h"
35 :
36 : /**
37 : * @page page_lock Locking and unlocking certificates and encrypted data.
38 : *
39 : * See the library functions here: @ref hx509_lock
40 : */
41 :
42 : struct hx509_lock_data {
43 : struct _hx509_password password;
44 : hx509_certs certs;
45 : hx509_prompter_fct prompt;
46 : void *prompt_data;
47 : };
48 :
49 : static struct hx509_lock_data empty_lock_data = {
50 : { 0, NULL },
51 : NULL,
52 : NULL,
53 : NULL
54 : };
55 :
56 : hx509_lock _hx509_empty_lock = &empty_lock_data;
57 :
58 : /*
59 : *
60 : */
61 :
62 : HX509_LIB_FUNCTION int HX509_LIB_CALL
63 113 : hx509_lock_init(hx509_context context, hx509_lock *lock)
64 : {
65 8 : hx509_lock l;
66 8 : int ret;
67 :
68 113 : *lock = NULL;
69 :
70 113 : l = calloc(1, sizeof(*l));
71 113 : if (l == NULL)
72 0 : return ENOMEM;
73 :
74 113 : ret = hx509_certs_init(context,
75 : "MEMORY:locks-internal",
76 : 0,
77 : NULL,
78 : &l->certs);
79 113 : if (ret) {
80 0 : free(l);
81 0 : return ret;
82 : }
83 :
84 113 : *lock = l;
85 :
86 113 : return 0;
87 : }
88 :
89 : HX509_LIB_FUNCTION int HX509_LIB_CALL
90 0 : hx509_lock_add_password(hx509_lock lock, const char *password)
91 : {
92 0 : void *d;
93 0 : char *s;
94 :
95 0 : s = strdup(password);
96 0 : if (s == NULL)
97 0 : return ENOMEM;
98 :
99 0 : d = realloc(lock->password.val,
100 0 : (lock->password.len + 1) * sizeof(lock->password.val[0]));
101 0 : if (d == NULL) {
102 0 : free(s);
103 0 : return ENOMEM;
104 : }
105 0 : lock->password.val = d;
106 0 : lock->password.val[lock->password.len] = s;
107 0 : lock->password.len++;
108 :
109 0 : return 0;
110 : }
111 :
112 : HX509_LIB_FUNCTION const struct _hx509_password * HX509_LIB_CALL
113 0 : _hx509_lock_get_passwords(hx509_lock lock)
114 : {
115 0 : return &lock->password;
116 : }
117 :
118 : HX509_LIB_FUNCTION hx509_certs HX509_LIB_CALL
119 0 : _hx509_lock_unlock_certs(hx509_lock lock)
120 : {
121 0 : return lock->certs;
122 : }
123 :
124 : HX509_LIB_FUNCTION void HX509_LIB_CALL
125 113 : hx509_lock_reset_passwords(hx509_lock lock)
126 : {
127 8 : size_t i;
128 113 : for (i = 0; i < lock->password.len; i++)
129 0 : free(lock->password.val[i]);
130 113 : free(lock->password.val);
131 113 : lock->password.val = NULL;
132 113 : lock->password.len = 0;
133 113 : }
134 :
135 : HX509_LIB_FUNCTION int HX509_LIB_CALL
136 0 : hx509_lock_add_cert(hx509_context context, hx509_lock lock, hx509_cert cert)
137 : {
138 0 : return hx509_certs_add(context, lock->certs, cert);
139 : }
140 :
141 : HX509_LIB_FUNCTION int HX509_LIB_CALL
142 0 : hx509_lock_add_certs(hx509_context context, hx509_lock lock, hx509_certs certs)
143 : {
144 0 : return hx509_certs_merge(context, lock->certs, certs);
145 : }
146 :
147 : HX509_LIB_FUNCTION void HX509_LIB_CALL
148 0 : hx509_lock_reset_certs(hx509_context context, hx509_lock lock)
149 : {
150 0 : hx509_certs certs = lock->certs;
151 0 : int ret;
152 :
153 0 : ret = hx509_certs_init(context,
154 : "MEMORY:locks-internal",
155 : 0,
156 : NULL,
157 : &lock->certs);
158 0 : if (ret == 0)
159 0 : hx509_certs_free(&certs);
160 : else
161 0 : lock->certs = certs;
162 0 : }
163 :
164 : HX509_LIB_FUNCTION int HX509_LIB_CALL
165 0 : _hx509_lock_find_cert(hx509_lock lock, const hx509_query *q, hx509_cert *c)
166 : {
167 0 : *c = NULL;
168 0 : return 0;
169 : }
170 :
171 : HX509_LIB_FUNCTION int HX509_LIB_CALL
172 20 : hx509_lock_set_prompter(hx509_lock lock, hx509_prompter_fct prompt, void *data)
173 : {
174 20 : lock->prompt = prompt;
175 20 : lock->prompt_data = data;
176 20 : return 0;
177 : }
178 :
179 : HX509_LIB_FUNCTION void HX509_LIB_CALL
180 0 : hx509_lock_reset_promper(hx509_lock lock)
181 : {
182 0 : lock->prompt = NULL;
183 0 : lock->prompt_data = NULL;
184 0 : }
185 :
186 : static int
187 0 : default_prompter(void *data, const hx509_prompt *prompter)
188 : {
189 0 : if (hx509_prompt_hidden(prompter->type)) {
190 0 : if(UI_UTIL_read_pw_string(prompter->reply.data,
191 0 : prompter->reply.length,
192 0 : prompter->prompt,
193 : 0))
194 0 : return 1;
195 : } else {
196 0 : char *s = prompter->reply.data;
197 :
198 0 : fputs (prompter->prompt, stdout);
199 0 : fflush (stdout);
200 0 : if(fgets(prompter->reply.data,
201 0 : prompter->reply.length,
202 : stdin) == NULL)
203 0 : return 1;
204 0 : s[strcspn(s, "\n")] = '\0';
205 : }
206 0 : return 0;
207 : }
208 :
209 : HX509_LIB_FUNCTION int HX509_LIB_CALL
210 0 : hx509_lock_prompt(hx509_lock lock, hx509_prompt *prompt)
211 : {
212 0 : if (lock->prompt == NULL)
213 0 : return HX509_CRYPTO_NO_PROMPTER;
214 0 : return (*lock->prompt)(lock->prompt_data, prompt);
215 : }
216 :
217 : HX509_LIB_FUNCTION void HX509_LIB_CALL
218 113 : hx509_lock_free(hx509_lock lock)
219 : {
220 113 : if (lock) {
221 113 : hx509_certs_free(&lock->certs);
222 113 : hx509_lock_reset_passwords(lock);
223 113 : memset(lock, 0, sizeof(*lock));
224 113 : free(lock);
225 : }
226 113 : }
227 :
228 : HX509_LIB_FUNCTION int HX509_LIB_CALL
229 0 : hx509_prompt_hidden(hx509_prompt_type type)
230 : {
231 : /* default to hidden if unknown */
232 :
233 0 : switch (type) {
234 0 : case HX509_PROMPT_TYPE_QUESTION:
235 : case HX509_PROMPT_TYPE_INFO:
236 0 : return 0;
237 0 : default:
238 0 : return 1;
239 : }
240 : }
241 :
242 : HX509_LIB_FUNCTION int HX509_LIB_CALL
243 0 : hx509_lock_command_string(hx509_lock lock, const char *string)
244 : {
245 0 : if (strncasecmp(string, "PASS:", 5) == 0) {
246 0 : hx509_lock_add_password(lock, string + 5);
247 0 : } else if (strcasecmp(string, "PROMPT") == 0) {
248 0 : hx509_lock_set_prompter(lock, default_prompter, NULL);
249 : } else
250 0 : return HX509_UNKNOWN_LOCK_COMMAND;
251 0 : return 0;
252 : }
|