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 : };
52 :
53 : hx509_lock _hx509_empty_lock = &empty_lock_data;
54 :
55 : /*
56 : *
57 : */
58 :
59 : int
60 122 : hx509_lock_init(hx509_context context, hx509_lock *lock)
61 : {
62 : hx509_lock l;
63 : int ret;
64 :
65 122 : *lock = NULL;
66 :
67 122 : l = calloc(1, sizeof(*l));
68 122 : if (l == NULL)
69 0 : return ENOMEM;
70 :
71 122 : ret = hx509_certs_init(context,
72 : "MEMORY:locks-internal",
73 : 0,
74 : NULL,
75 : &l->certs);
76 122 : if (ret) {
77 0 : free(l);
78 0 : return ret;
79 : }
80 :
81 122 : *lock = l;
82 :
83 122 : return 0;
84 : }
85 :
86 : int
87 0 : hx509_lock_add_password(hx509_lock lock, const char *password)
88 : {
89 : void *d;
90 : char *s;
91 :
92 0 : s = strdup(password);
93 0 : if (s == NULL)
94 0 : return ENOMEM;
95 :
96 0 : d = realloc(lock->password.val,
97 0 : (lock->password.len + 1) * sizeof(lock->password.val[0]));
98 0 : if (d == NULL) {
99 0 : free(s);
100 0 : return ENOMEM;
101 : }
102 0 : lock->password.val = d;
103 0 : lock->password.val[lock->password.len] = s;
104 0 : lock->password.len++;
105 :
106 0 : return 0;
107 : }
108 :
109 : const struct _hx509_password *
110 0 : _hx509_lock_get_passwords(hx509_lock lock)
111 : {
112 0 : return &lock->password;
113 : }
114 :
115 : hx509_certs
116 0 : _hx509_lock_unlock_certs(hx509_lock lock)
117 : {
118 0 : return lock->certs;
119 : }
120 :
121 : void
122 122 : hx509_lock_reset_passwords(hx509_lock lock)
123 : {
124 : size_t i;
125 122 : for (i = 0; i < lock->password.len; i++)
126 0 : free(lock->password.val[i]);
127 122 : free(lock->password.val);
128 122 : lock->password.val = NULL;
129 122 : lock->password.len = 0;
130 122 : }
131 :
132 : int
133 0 : hx509_lock_add_cert(hx509_context context, hx509_lock lock, hx509_cert cert)
134 : {
135 0 : return hx509_certs_add(context, lock->certs, cert);
136 : }
137 :
138 : int
139 0 : hx509_lock_add_certs(hx509_context context, hx509_lock lock, hx509_certs certs)
140 : {
141 0 : return hx509_certs_merge(context, lock->certs, certs);
142 : }
143 :
144 : void
145 0 : hx509_lock_reset_certs(hx509_context context, hx509_lock lock)
146 : {
147 0 : hx509_certs certs = lock->certs;
148 : int ret;
149 :
150 0 : ret = hx509_certs_init(context,
151 : "MEMORY:locks-internal",
152 : 0,
153 : NULL,
154 : &lock->certs);
155 0 : if (ret == 0)
156 0 : hx509_certs_free(&certs);
157 : else
158 0 : lock->certs = certs;
159 0 : }
160 :
161 : int
162 0 : _hx509_lock_find_cert(hx509_lock lock, const hx509_query *q, hx509_cert *c)
163 : {
164 0 : *c = NULL;
165 0 : return 0;
166 : }
167 :
168 : int
169 30 : hx509_lock_set_prompter(hx509_lock lock, hx509_prompter_fct prompt, void *data)
170 : {
171 30 : lock->prompt = prompt;
172 30 : lock->prompt_data = data;
173 30 : return 0;
174 : }
175 :
176 : void
177 0 : hx509_lock_reset_promper(hx509_lock lock)
178 : {
179 0 : lock->prompt = NULL;
180 0 : lock->prompt_data = NULL;
181 0 : }
182 :
183 : static int
184 0 : default_prompter(void *data, const hx509_prompt *prompter)
185 : {
186 0 : if (hx509_prompt_hidden(prompter->type)) {
187 0 : if(UI_UTIL_read_pw_string(prompter->reply.data,
188 0 : prompter->reply.length,
189 : prompter->prompt,
190 : 0))
191 0 : return 1;
192 : } else {
193 0 : char *s = prompter->reply.data;
194 :
195 0 : fputs (prompter->prompt, stdout);
196 0 : fflush (stdout);
197 0 : if(fgets(prompter->reply.data,
198 0 : prompter->reply.length,
199 : stdin) == NULL)
200 0 : return 1;
201 0 : s[strcspn(s, "\n")] = '\0';
202 : }
203 0 : return 0;
204 : }
205 :
206 : int
207 0 : hx509_lock_prompt(hx509_lock lock, hx509_prompt *prompt)
208 : {
209 0 : if (lock->prompt == NULL)
210 0 : return HX509_CRYPTO_NO_PROMPTER;
211 0 : return (*lock->prompt)(lock->prompt_data, prompt);
212 : }
213 :
214 : void
215 122 : hx509_lock_free(hx509_lock lock)
216 : {
217 122 : if (lock) {
218 122 : hx509_certs_free(&lock->certs);
219 122 : hx509_lock_reset_passwords(lock);
220 122 : memset(lock, 0, sizeof(*lock));
221 122 : free(lock);
222 : }
223 122 : }
224 :
225 : int
226 0 : hx509_prompt_hidden(hx509_prompt_type type)
227 : {
228 : /* default to hidden if unknown */
229 :
230 0 : switch (type) {
231 0 : case HX509_PROMPT_TYPE_QUESTION:
232 : case HX509_PROMPT_TYPE_INFO:
233 0 : return 0;
234 0 : default:
235 0 : return 1;
236 : }
237 : }
238 :
239 : int
240 0 : hx509_lock_command_string(hx509_lock lock, const char *string)
241 : {
242 0 : if (strncasecmp(string, "PASS:", 5) == 0) {
243 0 : hx509_lock_add_password(lock, string + 5);
244 0 : } else if (strcasecmp(string, "PROMPT") == 0) {
245 0 : hx509_lock_set_prompter(lock, default_prompter, NULL);
246 : } else
247 0 : return HX509_UNKNOWN_LOCK_COMMAND;
248 0 : return 0;
249 : }
|