GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libkeynote/auxil.c Lines: 0 201 0.0 %
Date: 2017-11-07 Branches: 0 132 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: auxil.c,v 1.11 2015/12/14 03:35:40 mmcc Exp $ */
2
/*
3
 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
4
 *
5
 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
6
 * in April-May 1998
7
 *
8
 * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
9
 *
10
 * Permission to use, copy, and modify this software with or without fee
11
 * is hereby granted, provided that this entire notice is included in
12
 * all copies of any software which is or includes a copy or
13
 * modification of this software.
14
 *
15
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
16
 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
17
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
18
 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
19
 * PURPOSE.
20
 */
21
22
#include <sys/types.h>
23
24
#include <ctype.h>
25
#include <limits.h>
26
#include <regex.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <string.h>
30
31
#include <openssl/dsa.h>
32
#include <openssl/rsa.h>
33
34
#include "keynote.h"
35
#include "assertion.h"
36
#include "signature.h"
37
38
/*
39
 * Get some sort of key-hash for hash table indexing purposes.
40
 */
41
static int
42
keynote_keyhash(void *key, int alg)
43
{
44
    struct keynote_binary *bn;
45
    unsigned int res = 0, i;
46
    DSA *dsa;
47
    RSA *rsa;
48
49
    if (key == NULL)
50
      return 0;
51
52
    switch (alg)
53
    {
54
	case KEYNOTE_ALGORITHM_DSA:
55
	    dsa = (DSA *) key;
56
	    res += BN_mod_word(dsa->p, HASHTABLESIZE);
57
	    res += BN_mod_word(dsa->q, HASHTABLESIZE);
58
	    res += BN_mod_word(dsa->g, HASHTABLESIZE);
59
	    res += BN_mod_word(dsa->pub_key, HASHTABLESIZE);
60
	    return res % HASHTABLESIZE;
61
62
        case KEYNOTE_ALGORITHM_RSA:
63
	    rsa = (RSA *) key;
64
            res += BN_mod_word(rsa->n, HASHTABLESIZE);
65
            res += BN_mod_word(rsa->e, HASHTABLESIZE);
66
	    return res % HASHTABLESIZE;
67
68
	case KEYNOTE_ALGORITHM_X509: /* RSA-specific */
69
	    rsa = (RSA *) key;
70
            res += BN_mod_word(rsa->n, HASHTABLESIZE);
71
            res += BN_mod_word(rsa->e, HASHTABLESIZE);
72
	    return res % HASHTABLESIZE;
73
74
	case KEYNOTE_ALGORITHM_BINARY:
75
	    bn = (struct keynote_binary *) key;
76
	    for (i = 0; i < bn->bn_len; i++)
77
	      res = (res + ((unsigned char) bn->bn_key[i])) % HASHTABLESIZE;
78
79
	    return res;
80
81
	case KEYNOTE_ALGORITHM_NONE:
82
	    return keynote_stringhash(key, HASHTABLESIZE);
83
84
	default:
85
	    return 0;
86
    }
87
}
88
89
/*
90
 * Return RESULT_TRUE if key appears in the action authorizers.
91
 */
92
int
93
keynote_in_action_authorizers(void *key, int algorithm)
94
{
95
    struct keylist *kl, *kl2;
96
    void *s;
97
    int alg;
98
99
    if (algorithm == KEYNOTE_ALGORITHM_UNSPEC)
100
    {
101
	kl2 = keynote_keylist_find(keynote_current_assertion->as_keylist, key);
102
	if (kl2 == NULL)
103
	  return RESULT_FALSE;   /* Shouldn't ever happen */
104
105
	s = kl2->key_key;
106
	alg = kl2->key_alg;
107
    }
108
    else
109
    {
110
	s = key;
111
	alg = algorithm;
112
    }
113
114
    for (kl = keynote_current_session->ks_action_authorizers;
115
	 kl != NULL;
116
	 kl = kl->key_next)
117
      if ((kl->key_alg == alg) ||
118
	  ((kl->key_alg == KEYNOTE_ALGORITHM_RSA) &&
119
	   (alg == KEYNOTE_ALGORITHM_X509)) ||
120
	  ((kl->key_alg == KEYNOTE_ALGORITHM_X509) &&
121
	   (alg == KEYNOTE_ALGORITHM_RSA)))
122
	if (kn_keycompare(kl->key_key, s, alg) == RESULT_TRUE)
123
	  return RESULT_TRUE;
124
125
    return RESULT_FALSE;
126
}
127
128
/*
129
 * Add a key to the keylist. Return RESULT_TRUE on success, -1 (and set
130
 * keynote_errno) otherwise. We are not supposed to make a copy of the
131
 * argument.
132
 */
133
int
134
keynote_keylist_add(struct keylist **keylist, char *key)
135
{
136
    struct keynote_deckey dc;
137
    struct keylist *kl;
138
139
    if (keylist == NULL)
140
    {
141
	keynote_errno = ERROR_MEMORY;
142
	return -1;
143
    }
144
145
    kl = calloc(1, sizeof(struct keylist));
146
    if (kl == NULL)
147
    {
148
	keynote_errno = ERROR_MEMORY;
149
	return -1;
150
    }
151
152
    if (kn_decode_key(&dc, key, KEYNOTE_PUBLIC_KEY) != 0)
153
    {
154
	free(kl);
155
	return -1;
156
    }
157
158
    kl->key_key = dc.dec_key;
159
    kl->key_alg = dc.dec_algorithm;
160
    kl->key_stringkey = key;
161
    kl->key_next = *keylist;
162
    *keylist = kl;
163
    return RESULT_TRUE;
164
}
165
166
/*
167
 * Remove an action authorizer.
168
 */
169
int
170
kn_remove_authorizer(int sessid, char *key)
171
{
172
    struct keynote_session *ks;
173
    struct keylist *kl, *kl2;
174
175
    keynote_errno = 0;
176
    if ((keynote_current_session == NULL) ||
177
	(keynote_current_session->ks_id != sessid))
178
    {
179
	keynote_current_session = keynote_find_session(sessid);
180
	if (keynote_current_session == NULL)
181
	{
182
	    keynote_errno = ERROR_NOTFOUND;
183
	    return -1;
184
	}
185
    }
186
187
    ks = keynote_current_session;
188
189
    /* If no action authorizers present */
190
    if ((kl = ks->ks_action_authorizers) == NULL)
191
    {
192
	keynote_errno = ERROR_NOTFOUND;
193
	return -1;
194
    }
195
196
    /* First in list */
197
    if (!strcmp(kl->key_stringkey, key))
198
    {
199
	ks->ks_action_authorizers = kl->key_next;
200
	kl->key_next = NULL;
201
	keynote_keylist_free(kl);
202
	return 0;
203
    }
204
205
    for (; kl->key_next != NULL; kl = kl->key_next)
206
      if (!strcmp(kl->key_next->key_stringkey, key))
207
      {
208
	  kl2 = kl->key_next;
209
	  kl->key_next = kl2->key_next;
210
	  kl2->key_next = NULL;
211
	  keynote_keylist_free(kl2);
212
	  return 0;
213
      }
214
215
    keynote_errno = ERROR_NOTFOUND;
216
    return -1;
217
}
218
219
/*
220
 * Add an action authorizer.
221
 */
222
int
223
kn_add_authorizer(int sessid, char *key)
224
{
225
    char *stringkey;
226
227
    keynote_errno = 0;
228
    if ((keynote_current_session == NULL) ||
229
	(keynote_current_session->ks_id != sessid))
230
    {
231
	keynote_current_session = keynote_find_session(sessid);
232
	if (keynote_current_session == NULL)
233
	{
234
	    keynote_errno = ERROR_NOTFOUND;
235
	    return -1;
236
	}
237
    }
238
239
    stringkey = strdup(key);
240
    if (stringkey == NULL)
241
    {
242
	keynote_errno = ERROR_MEMORY;
243
	return -1;
244
    }
245
246
    if (keynote_keylist_add(&(keynote_current_session->ks_action_authorizers),
247
			    stringkey) == -1)
248
    {
249
	free(stringkey);
250
	return -1;
251
    }
252
253
    return 0;
254
}
255
256
/*
257
 * Find a keylist entry based on the key_stringkey entry.
258
 */
259
struct keylist *
260
keynote_keylist_find(struct keylist *kl, char *s)
261
{
262
    for (; kl != NULL; kl = kl->key_next)
263
      if (!strcmp(kl->key_stringkey, s))
264
	return kl;
265
266
    return kl;
267
}
268
269
/*
270
 * Free keylist list.
271
 */
272
void
273
keynote_keylist_free(struct keylist *kl)
274
{
275
    struct keylist *kl2;
276
277
    while (kl != NULL)
278
    {
279
	kl2 = kl->key_next;
280
	free(kl->key_stringkey);
281
	keynote_free_key(kl->key_key, kl->key_alg);
282
	free(kl);
283
	kl = kl2;
284
    }
285
}
286
287
/*
288
 * Free a key.
289
 */
290
void
291
kn_free_key(struct keynote_deckey *dc)
292
{
293
    if (dc)
294
      keynote_free_key(dc->dec_key, dc->dec_algorithm);
295
}
296
297
/*
298
 * Find the num-th assertion given the authorizer. Return NULL if not found.
299
 */
300
struct assertion *
301
keynote_find_assertion(void *authorizer, int num, int algorithm)
302
{
303
    struct assertion *as;
304
    unsigned int h;
305
306
    if (authorizer == NULL)
307
      return NULL;
308
309
    h = keynote_keyhash(authorizer, algorithm);
310
    for (as = keynote_current_session->ks_assertion_table[h];
311
	 as != NULL;
312
	 as = as->as_next)
313
      if ((as->as_authorizer != NULL) &&
314
	  ((as->as_signeralgorithm == algorithm) ||
315
	   ((as->as_signeralgorithm == KEYNOTE_ALGORITHM_RSA) &&
316
	    (algorithm == KEYNOTE_ALGORITHM_X509)) ||
317
	   ((as->as_signeralgorithm == KEYNOTE_ALGORITHM_X509) &&
318
	    (algorithm == KEYNOTE_ALGORITHM_RSA))))
319
	if (kn_keycompare(authorizer, as->as_authorizer, algorithm) ==
320
	    RESULT_TRUE)
321
	  if (num-- == 0)
322
	    return as;
323
324
    return NULL;
325
}
326
327
/*
328
 * Add an assertion to the hash table. Return RESULT_TRUE on success,
329
 * ERROR_MEMORY for memory failure, ERROR_SYNTAX if some problem with
330
 * the assertion is detected.
331
 */
332
int
333
keynote_add_htable(struct assertion *as, int which)
334
{
335
    char *hashname;
336
    unsigned int i;
337
338
    if (as == NULL)
339
    {
340
	keynote_errno = ERROR_MEMORY;
341
	return -1;
342
    }
343
344
    if (!which)
345
      hashname = as->as_authorizer_string_s;
346
    else
347
      hashname = as->as_authorizer;
348
349
    if (hashname == NULL)
350
    {
351
	keynote_errno = ERROR_SYNTAX;
352
	return -1;
353
    }
354
355
    i = keynote_keyhash(hashname, as->as_signeralgorithm);
356
    as->as_next = keynote_current_session->ks_assertion_table[i];
357
    keynote_current_session->ks_assertion_table[i] = as;
358
    return RESULT_TRUE;
359
}
360
361
/*
362
 * Parse and store an assertion in the internal hash table.
363
 * Return the result of the evaluation, if doing early evaluation.
364
 * If an error was encountered, set keynote_errno.
365
 */
366
int
367
kn_add_assertion(int sessid, char *asrt, int len, int assertion_flags)
368
{
369
    struct assertion *as;
370
371
    keynote_errno = 0;
372
    if ((keynote_current_session == NULL) ||
373
	(keynote_current_session->ks_id != sessid))
374
    {
375
	keynote_current_session = keynote_find_session(sessid);
376
	if (keynote_current_session == NULL)
377
	{
378
	    keynote_errno = ERROR_NOTFOUND;
379
	    return -1;
380
	}
381
    }
382
383
    as = keynote_parse_assertion(asrt, len, assertion_flags);
384
    if ((as == NULL) || (keynote_errno != 0))
385
    {
386
	if (keynote_errno == 0)
387
	  keynote_errno = ERROR_SYNTAX;
388
389
	return -1;
390
    }
391
392
    as->as_id = keynote_current_session->ks_assertioncounter++;
393
394
    /* Check for wrap around...there has to be a better solution to this */
395
    if (keynote_current_session->ks_assertioncounter < 0)
396
    {
397
	keynote_free_assertion(as);
398
	keynote_errno = ERROR_SYNTAX;
399
	return -1;
400
    }
401
402
    if (keynote_add_htable(as, 0) != RESULT_TRUE)
403
    {
404
	keynote_free_assertion(as);
405
	return -1;
406
    }
407
408
    as->as_internalflags |= ASSERT_IFLAG_NEEDPROC;
409
    return as->as_id;
410
}
411
412
/*
413
 * Remove an assertion from the hash table.
414
 */
415
static int
416
keynote_remove_assertion(int sessid, int assertid, int deleteflag)
417
{
418
    struct assertion *ht, *ht2;
419
    int i;
420
421
    if ((keynote_current_session == NULL) ||
422
	(keynote_current_session->ks_id != sessid))
423
    {
424
	keynote_current_session = keynote_find_session(sessid);
425
	if (keynote_current_session == NULL)
426
	{
427
	    keynote_errno = ERROR_NOTFOUND;
428
	    return -1;
429
	}
430
    }
431
432
    for (i = 0; i < HASHTABLESIZE; i++)
433
    {
434
	ht = keynote_current_session->ks_assertion_table[i];
435
	if (ht == NULL)
436
	  continue;
437
438
	/* If first entry in bucket */
439
	if (ht->as_id == assertid)
440
	{
441
	    keynote_current_session->ks_assertion_table[i] = ht->as_next;
442
	    if (deleteflag)
443
	      keynote_free_assertion(ht);
444
	    return 0;
445
	}
446
447
	for (; ht->as_next != NULL; ht = ht->as_next)
448
	  if (ht->as_next->as_id == assertid)  /* Got it */
449
	  {
450
	      ht2 = ht->as_next;
451
	      ht->as_next = ht2->as_next;
452
	      if (deleteflag)
453
		keynote_free_assertion(ht2);
454
	      return 0;
455
	  }
456
    }
457
458
    keynote_errno = ERROR_NOTFOUND;
459
    return -1;
460
}
461
462
/*
463
 * API wrapper for deleting assertions.
464
 */
465
int
466
kn_remove_assertion(int sessid, int assertid)
467
{
468
    keynote_errno = 0;
469
    return keynote_remove_assertion(sessid, assertid, 1);
470
}
471
472
/*
473
 * Internally-used wrapper for removing but not deleting assertions.
474
 */
475
int
476
keynote_sremove_assertion(int sessid, int assertid)
477
{
478
    return keynote_remove_assertion(sessid, assertid, 0);
479
}
480
481
/*
482
 * Free an assertion structure.
483
 */
484
void
485
keynote_free_assertion(struct assertion *as)
486
{
487
    if (as == NULL)
488
      return;
489
490
    free(as->as_buf);
491
492
    free(as->as_signature);
493
494
    if (as->as_env != NULL)
495
      keynote_env_cleanup(&(as->as_env), 1);
496
497
    if (as->as_keylist != NULL)
498
      keynote_keylist_free(as->as_keylist);
499
500
    if (as->as_authorizer != NULL)
501
      keynote_free_key(as->as_authorizer, as->as_signeralgorithm);
502
503
    free(as);
504
}
505
506
unsigned int
507
keynote_stringhash(char *name, unsigned int size)
508
{
509
    unsigned int hash_val = 0;
510
    unsigned int i;
511
512
    if ((size == 0) || (size == 1))
513
      return 0;
514
515
    for (; *name; name++)
516
    {
517
        hash_val = (hash_val << 2) + *name;
518
        if ((i = hash_val & 0x3fff) != 0)
519
	  hash_val = ((hash_val ^ (i >> 12)) & 0x3fff);
520
    }
521
522
    return hash_val % size;
523
}