1178825Sdfr/*
2233294Sstas * Copyright (c) 2005 - 2006 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
5178825Sdfr *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
9178825Sdfr *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
12178825Sdfr *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
16178825Sdfr *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
20178825Sdfr *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
32178825Sdfr */
33178825Sdfr
34178825Sdfr#include "hx_locl.h"
35178825Sdfr
36178825Sdfr/**
37178825Sdfr * @page page_lock Locking and unlocking certificates and encrypted data.
38178825Sdfr *
39178825Sdfr * See the library functions here: @ref hx509_lock
40178825Sdfr */
41178825Sdfr
42178825Sdfrstruct hx509_lock_data {
43178825Sdfr    struct _hx509_password password;
44178825Sdfr    hx509_certs certs;
45178825Sdfr    hx509_prompter_fct prompt;
46178825Sdfr    void *prompt_data;
47178825Sdfr};
48178825Sdfr
49178825Sdfrstatic struct hx509_lock_data empty_lock_data = {
50178825Sdfr    { 0, NULL }
51178825Sdfr};
52178825Sdfr
53178825Sdfrhx509_lock _hx509_empty_lock = &empty_lock_data;
54178825Sdfr
55178825Sdfr/*
56178825Sdfr *
57178825Sdfr */
58178825Sdfr
59178825Sdfrint
60178825Sdfrhx509_lock_init(hx509_context context, hx509_lock *lock)
61178825Sdfr{
62178825Sdfr    hx509_lock l;
63178825Sdfr    int ret;
64178825Sdfr
65178825Sdfr    *lock = NULL;
66178825Sdfr
67178825Sdfr    l = calloc(1, sizeof(*l));
68178825Sdfr    if (l == NULL)
69178825Sdfr	return ENOMEM;
70178825Sdfr
71233294Sstas    ret = hx509_certs_init(context,
72233294Sstas			   "MEMORY:locks-internal",
73178825Sdfr			   0,
74178825Sdfr			   NULL,
75178825Sdfr			   &l->certs);
76178825Sdfr    if (ret) {
77178825Sdfr	free(l);
78178825Sdfr	return ret;
79178825Sdfr    }
80178825Sdfr
81178825Sdfr    *lock = l;
82178825Sdfr
83178825Sdfr    return 0;
84178825Sdfr}
85178825Sdfr
86178825Sdfrint
87178825Sdfrhx509_lock_add_password(hx509_lock lock, const char *password)
88178825Sdfr{
89178825Sdfr    void *d;
90178825Sdfr    char *s;
91178825Sdfr
92178825Sdfr    s = strdup(password);
93178825Sdfr    if (s == NULL)
94178825Sdfr	return ENOMEM;
95178825Sdfr
96178825Sdfr    d = realloc(lock->password.val,
97178825Sdfr		(lock->password.len + 1) * sizeof(lock->password.val[0]));
98178825Sdfr    if (d == NULL) {
99178825Sdfr	free(s);
100178825Sdfr	return ENOMEM;
101178825Sdfr    }
102178825Sdfr    lock->password.val = d;
103178825Sdfr    lock->password.val[lock->password.len] = s;
104178825Sdfr    lock->password.len++;
105178825Sdfr
106178825Sdfr    return 0;
107178825Sdfr}
108178825Sdfr
109178825Sdfrconst struct _hx509_password *
110178825Sdfr_hx509_lock_get_passwords(hx509_lock lock)
111178825Sdfr{
112178825Sdfr    return &lock->password;
113178825Sdfr}
114178825Sdfr
115178825Sdfrhx509_certs
116178825Sdfr_hx509_lock_unlock_certs(hx509_lock lock)
117178825Sdfr{
118178825Sdfr    return lock->certs;
119178825Sdfr}
120178825Sdfr
121178825Sdfrvoid
122178825Sdfrhx509_lock_reset_passwords(hx509_lock lock)
123178825Sdfr{
124233294Sstas    size_t i;
125178825Sdfr    for (i = 0; i < lock->password.len; i++)
126178825Sdfr	free(lock->password.val[i]);
127178825Sdfr    free(lock->password.val);
128178825Sdfr    lock->password.val = NULL;
129178825Sdfr    lock->password.len = 0;
130178825Sdfr}
131178825Sdfr
132178825Sdfrint
133178825Sdfrhx509_lock_add_cert(hx509_context context, hx509_lock lock, hx509_cert cert)
134178825Sdfr{
135178825Sdfr    return hx509_certs_add(context, lock->certs, cert);
136178825Sdfr}
137178825Sdfr
138178825Sdfrint
139178825Sdfrhx509_lock_add_certs(hx509_context context, hx509_lock lock, hx509_certs certs)
140178825Sdfr{
141178825Sdfr    return hx509_certs_merge(context, lock->certs, certs);
142178825Sdfr}
143178825Sdfr
144178825Sdfrvoid
145178825Sdfrhx509_lock_reset_certs(hx509_context context, hx509_lock lock)
146178825Sdfr{
147178825Sdfr    hx509_certs certs = lock->certs;
148178825Sdfr    int ret;
149233294Sstas
150233294Sstas    ret = hx509_certs_init(context,
151178825Sdfr			   "MEMORY:locks-internal",
152178825Sdfr			   0,
153178825Sdfr			   NULL,
154178825Sdfr			   &lock->certs);
155178825Sdfr    if (ret == 0)
156178825Sdfr	hx509_certs_free(&certs);
157178825Sdfr    else
158178825Sdfr	lock->certs = certs;
159178825Sdfr}
160178825Sdfr
161178825Sdfrint
162178825Sdfr_hx509_lock_find_cert(hx509_lock lock, const hx509_query *q, hx509_cert *c)
163178825Sdfr{
164178825Sdfr    *c = NULL;
165178825Sdfr    return 0;
166178825Sdfr}
167178825Sdfr
168178825Sdfrint
169178825Sdfrhx509_lock_set_prompter(hx509_lock lock, hx509_prompter_fct prompt, void *data)
170178825Sdfr{
171178825Sdfr    lock->prompt = prompt;
172178825Sdfr    lock->prompt_data = data;
173178825Sdfr    return 0;
174178825Sdfr}
175178825Sdfr
176178825Sdfrvoid
177178825Sdfrhx509_lock_reset_promper(hx509_lock lock)
178178825Sdfr{
179178825Sdfr    lock->prompt = NULL;
180178825Sdfr    lock->prompt_data = NULL;
181178825Sdfr}
182178825Sdfr
183233294Sstasstatic int
184178825Sdfrdefault_prompter(void *data, const hx509_prompt *prompter)
185178825Sdfr{
186178825Sdfr    if (hx509_prompt_hidden(prompter->type)) {
187178825Sdfr	if(UI_UTIL_read_pw_string(prompter->reply.data,
188178825Sdfr				  prompter->reply.length,
189178825Sdfr				  prompter->prompt,
190178825Sdfr				  0))
191178825Sdfr	    return 1;
192178825Sdfr    } else {
193178825Sdfr	char *s = prompter->reply.data;
194178825Sdfr
195178825Sdfr	fputs (prompter->prompt, stdout);
196178825Sdfr	fflush (stdout);
197178825Sdfr	if(fgets(prompter->reply.data,
198178825Sdfr		 prompter->reply.length,
199178825Sdfr		 stdin) == NULL)
200178825Sdfr	    return 1;
201178825Sdfr	s[strcspn(s, "\n")] = '\0';
202178825Sdfr    }
203178825Sdfr    return 0;
204178825Sdfr}
205178825Sdfr
206178825Sdfrint
207178825Sdfrhx509_lock_prompt(hx509_lock lock, hx509_prompt *prompt)
208178825Sdfr{
209178825Sdfr    if (lock->prompt == NULL)
210178825Sdfr	return HX509_CRYPTO_NO_PROMPTER;
211178825Sdfr    return (*lock->prompt)(lock->prompt_data, prompt);
212178825Sdfr}
213178825Sdfr
214178825Sdfrvoid
215178825Sdfrhx509_lock_free(hx509_lock lock)
216178825Sdfr{
217233294Sstas    if (lock) {
218233294Sstas	hx509_certs_free(&lock->certs);
219233294Sstas	hx509_lock_reset_passwords(lock);
220233294Sstas	memset(lock, 0, sizeof(*lock));
221233294Sstas	free(lock);
222233294Sstas    }
223178825Sdfr}
224178825Sdfr
225178825Sdfrint
226178825Sdfrhx509_prompt_hidden(hx509_prompt_type type)
227178825Sdfr{
228178825Sdfr    /* default to hidden if unknown */
229178825Sdfr
230178825Sdfr    switch (type) {
231178825Sdfr    case HX509_PROMPT_TYPE_QUESTION:
232178825Sdfr    case HX509_PROMPT_TYPE_INFO:
233178825Sdfr	return 0;
234178825Sdfr    default:
235178825Sdfr	return 1;
236178825Sdfr    }
237178825Sdfr}
238178825Sdfr
239178825Sdfrint
240178825Sdfrhx509_lock_command_string(hx509_lock lock, const char *string)
241178825Sdfr{
242178825Sdfr    if (strncasecmp(string, "PASS:", 5) == 0) {
243178825Sdfr	hx509_lock_add_password(lock, string + 5);
244178825Sdfr    } else if (strcasecmp(string, "PROMPT") == 0) {
245178825Sdfr	hx509_lock_set_prompter(lock, default_prompter, NULL);
246178825Sdfr    } else
247178825Sdfr	return HX509_UNKNOWN_LOCK_COMMAND;
248178825Sdfr    return 0;
249178825Sdfr}
250