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