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