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