GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libkeynote/parse_assertion.c Lines: 0 276 0.0 %
Date: 2017-11-13 Branches: 0 242 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: parse_assertion.c,v 1.16 2015/12/14 03:25:59 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 "keynote.h"
32
#include "assertion.h"
33
#include "signature.h"
34
35
/*
36
 * Recurse on graph discovery.
37
 */
38
static int
39
rec_evaluate_query(struct assertion *as)
40
{
41
    struct assertion *ast;
42
    struct keylist *kl;
43
    int i, s;
44
45
    as->as_kresult = KRESULT_IN_PROGRESS;
46
47
    /*
48
     * If we get the minimum result or an error from evaluating this
49
     * assertion, we don't need to recurse.
50
     */
51
    keynote_evaluate_assertion(as);
52
    if (keynote_errno != 0)
53
    {
54
	as->as_kresult = KRESULT_DONE;
55
	if (keynote_errno)
56
	  as->as_error = keynote_errno;
57
	if (keynote_errno == ERROR_MEMORY)
58
	  return -1;
59
	else
60
	{
61
	    keynote_errno = 0;  /* Ignore syntax errors for now */
62
	    return 0;
63
	}
64
    }
65
66
    if (as->as_result == 0)
67
    {
68
        as->as_kresult = KRESULT_DONE;
69
        return as->as_result;
70
    }
71
72
    for (kl = as->as_keylist;
73
	 kl != NULL;
74
	 kl = kl->key_next)
75
    {
76
	switch (keynote_in_action_authorizers(kl->key_key, kl->key_alg))
77
	{
78
	    case -1:
79
		as->as_kresult = KRESULT_DONE;
80
		if (keynote_errno == ERROR_MEMORY)
81
		{
82
		    as->as_error = ERROR_MEMORY;
83
		    return -1;
84
		}
85
		else
86
		{
87
		    keynote_errno = 0; /* Reset */
88
		    continue;
89
		}
90
91
	    case RESULT_FALSE:    /* Not there, check for assertions instead */
92
		break;
93
94
	    case RESULT_TRUE:     /* Ok, don't bother with assertions */
95
		keynote_current_assertion = NULL;
96
		continue;
97
	}
98
99
	for (i = 0;; i++)
100
	{
101
	    ast = keynote_find_assertion(kl->key_key, i, kl->key_alg);
102
	    if (ast == NULL)
103
	      break;
104
105
	    if (ast->as_kresult == KRESULT_IN_PROGRESS) /* Cycle detected */
106
	      continue;
107
108
	    if (ast->as_kresult == KRESULT_UNTOUCHED)   /* Recurse if needed */
109
	      rec_evaluate_query(ast);
110
111
	    /* Check for errors */
112
	    if (keynote_errno == ERROR_MEMORY)
113
	    {
114
		as->as_error = ERROR_MEMORY;
115
		as->as_kresult = KRESULT_DONE;
116
		return -1;
117
	    }
118
	    else
119
	      keynote_errno = 0; /* Reset */
120
	}
121
    }
122
123
    keynote_current_assertion = as;
124
    s = keynote_parse_keypred(as, 0);
125
    keynote_current_assertion = NULL;
126
127
    if (keynote_errno == ERROR_MEMORY)
128
    {
129
	as->as_error = ERROR_MEMORY;
130
	as->as_kresult = KRESULT_DONE;
131
	return -1;
132
    }
133
    else
134
      if (keynote_errno)
135
      {
136
	  keynote_errno = 0;
137
	  s = 0;
138
      }
139
140
    /* Keep lower of two */
141
    as->as_result = (as->as_result < s ? as->as_result : s);
142
143
    /* Check the signature now if we haven't done so already */
144
    if (as->as_sigresult == SIGRESULT_UNTOUCHED)
145
    {
146
	if (!(as->as_flags & ASSERT_FLAG_LOCAL))
147
	  as->as_sigresult = keynote_sigverify_assertion(as);
148
	else
149
	  as->as_sigresult = SIGRESULT_TRUE;    /* Trusted assertion */
150
    }
151
152
    if (as->as_sigresult != SIGRESULT_TRUE)
153
    {
154
	as->as_result = 0;
155
	as->as_sigresult = SIGRESULT_FALSE;
156
	if (keynote_errno != ERROR_MEMORY)
157
	  keynote_errno = 0; /* Reset */
158
	else
159
	{
160
	    as->as_error = ERROR_MEMORY;
161
	    as->as_kresult = KRESULT_DONE;
162
	    return -1;
163
	}
164
    }
165
166
    as->as_kresult = KRESULT_DONE;
167
    return as->as_result;
168
}
169
170
/*
171
 * Fix the Authorizer/Licencees/Signature fields. If the first argument is
172
 * empty, fix all assertions. The second argument specifies whether the
173
 * Signature field should be parsed or not.
174
 */
175
static int
176
keynote_fix_fields(struct assertion *ast, int sigfield)
177
{
178
    struct assertion *as;
179
    int i;
180
181
    /* Signature generation/verification handling, no need to eval Licensees */
182
    if (ast != NULL)
183
    {
184
	/* Authorizer */
185
	if (keynote_evaluate_authorizer(ast, 1) != RESULT_TRUE)
186
	  return -1;
187
188
	/* Signature */
189
	if ((sigfield) && (ast->as_signature_string_s != NULL))
190
	  if (keynote_evaluate_authorizer(ast, 0) != RESULT_TRUE)
191
	    return -1;
192
193
	return RESULT_TRUE;
194
    }
195
196
    for (i = 0; i < HASHTABLESIZE; i++)
197
      for (as = keynote_current_session->ks_assertion_table[i];
198
	   as != NULL;
199
	   as = as->as_next)
200
      {
201
	  if (!(as->as_internalflags & ASSERT_IFLAG_NEEDPROC) &&
202
	      !(as->as_internalflags & ASSERT_IFLAG_WEIRDLICS) &&
203
	      !(as->as_internalflags & ASSERT_IFLAG_WEIRDAUTH) &&
204
	      !(as->as_internalflags & ASSERT_IFLAG_WEIRDSIG))
205
	    continue;
206
207
	  /* Parse the Signature field */
208
	  if (((as->as_internalflags & ASSERT_IFLAG_WEIRDSIG) ||
209
	       (as->as_internalflags & ASSERT_IFLAG_NEEDPROC)) &&
210
	      (as->as_signature_string_s != NULL))
211
	    if (keynote_evaluate_authorizer(as, 0) == -1)
212
	    {
213
		if (keynote_errno)
214
		  as->as_error = keynote_errno;
215
		if (keynote_errno == ERROR_MEMORY)
216
		  return -1;
217
		else
218
		  keynote_errno = 0;
219
	    }
220
221
	  /* Parse the Licensees field */
222
	  if ((as->as_internalflags & ASSERT_IFLAG_WEIRDLICS) ||
223
	      (as->as_internalflags & ASSERT_IFLAG_NEEDPROC))
224
	    if (keynote_parse_keypred(as, 1) == -1)
225
	    {
226
		if (keynote_errno)
227
		    as->as_error = keynote_errno;
228
		if (keynote_errno == ERROR_MEMORY)
229
		  return -1;
230
		else
231
		  keynote_errno = 0;
232
	    }
233
234
	  /* Parse the Authorizer field */
235
	  if ((as->as_internalflags & ASSERT_IFLAG_WEIRDAUTH) ||
236
	      (as->as_internalflags & ASSERT_IFLAG_NEEDPROC))
237
	    if (keynote_evaluate_authorizer(as, 1) == -1)
238
	    {
239
		if (keynote_errno)
240
		  as->as_error = keynote_errno;
241
		if (keynote_errno == ERROR_MEMORY)
242
		  return -1;
243
		else
244
		  keynote_errno = 0;
245
	    }
246
      }
247
248
    /* Reposition if necessary */
249
    for (i = 0; i < HASHTABLESIZE; i++)
250
      for (as = keynote_current_session->ks_assertion_table[i];
251
	   as != NULL;
252
	   as = as->as_next)
253
	if (((as->as_internalflags & ASSERT_IFLAG_WEIRDAUTH) &&
254
	     !(as->as_internalflags & ASSERT_IFLAG_PROCESSED)) ||
255
	    (as->as_internalflags & ASSERT_IFLAG_NEEDPROC))
256
	{
257
	    as->as_internalflags &= ~ASSERT_IFLAG_NEEDPROC;
258
	    as->as_internalflags |= ASSERT_IFLAG_PROCESSED;
259
	    keynote_sremove_assertion(keynote_current_session->ks_id,
260
				      as->as_id);
261
262
	    if (keynote_add_htable(as, 1) != RESULT_TRUE)
263
	      return -1;
264
265
	    /* Point to beginning of the previous list. */
266
	    i--;
267
	    break;
268
	}
269
270
    return RESULT_TRUE;
271
}
272
273
/*
274
 * Find the trust graph. This is a depth-first search, starting at
275
 * POLICY assertions.
276
 */
277
int
278
keynote_evaluate_query(void)
279
{
280
    struct assertion *as;
281
    int p, prev;
282
    int i;
283
284
    /* Fix the authorizer/licensees/signature fields */
285
    if (keynote_fix_fields(NULL, 0) != RESULT_TRUE)
286
      return -1;
287
288
    /* Find POLICY assertions and try to evaluate the query. */
289
    for (i = 0, prev = 0; i < HASHTABLESIZE; i++)
290
      for (as = keynote_current_session->ks_assertion_table[i];
291
	   as != NULL;
292
	   as = as->as_next)
293
	if ((as->as_authorizer != NULL) &&      /* Paranoid */
294
            (as->as_signeralgorithm == KEYNOTE_ALGORITHM_NONE))
295
	  if ((!strcmp("POLICY", as->as_authorizer)) &&
296
	      (as->as_flags & ASSERT_FLAG_LOCAL))
297
	  {
298
	      if ((p = rec_evaluate_query(as)) == -1)
299
	      {
300
		  if (keynote_errno)
301
		    as->as_error = keynote_errno;
302
		  if (keynote_errno == ERROR_MEMORY)
303
		    return -1;
304
		  else
305
		  {
306
		      keynote_errno = 0;
307
		      continue;
308
		  }
309
	      }
310
311
	      if (p > prev)
312
		prev = p;
313
314
	      /* If we get the highest possible return value, just return */
315
	      if (prev == (keynote_current_session->ks_values_num - 1))
316
		return prev;
317
	  }
318
319
    return prev;
320
}
321
322
/*
323
 * Return keyword type.
324
 */
325
static int
326
whichkeyword(char *start, char *end)
327
{
328
    int len = (end - start);
329
330
    if (len <= 0)
331
    {
332
	keynote_errno = ERROR_MEMORY;
333
	return -1;
334
    }
335
336
    if (!strncasecmp("keynote-version:", start, len))
337
      return KEYWORD_VERSION;
338
339
    if (!strncasecmp("local-constants:", start, len))
340
      return KEYWORD_LOCALINIT;
341
342
    if (!strncasecmp("authorizer:", start, len))
343
      return KEYWORD_AUTHORIZER;
344
345
    if (!strncasecmp("licensees:", start, len))
346
      return KEYWORD_LICENSEES;
347
348
    if (!strncasecmp("conditions:", start, len))
349
      return KEYWORD_CONDITIONS;
350
351
    if (!strncasecmp("signature:", start, len))
352
      return KEYWORD_SIGNATURE;
353
354
    if (!strncasecmp("comment:", start, len))
355
      return KEYWORD_COMMENT;
356
357
    keynote_errno = ERROR_SYNTAX;
358
    return -1;
359
}
360
361
/*
362
 * Parse an assertion. Set keynote_errno to ERROR_SYNTAX if parsing
363
 * failed due to certificate badness, and ERROR_MEMORY if memory
364
 * problem. If more than one assertions have been passed in the
365
 * buffer, they will be linked.
366
 */
367
struct assertion *
368
keynote_parse_assertion(char *buf, int len, int assertion_flags)
369
{
370
    int k, i, j, seen_field = 0, ver = 0, end_of_assertion = 0;
371
    char *ks, *ke, *ts, *te = NULL;
372
    struct assertion *as;
373
374
    /* Allocate memory for assertion */
375
    as = calloc(1, sizeof(struct assertion));
376
    if (as == NULL)
377
    {
378
	keynote_errno = ERROR_MEMORY;
379
	return NULL;
380
    }
381
382
    /* Keep a copy of the assertion around */
383
    as->as_buf = strdup(buf);
384
    if (as->as_buf == NULL)
385
    {
386
	keynote_errno = ERROR_MEMORY;
387
	keynote_free_assertion(as);
388
	return NULL;
389
    }
390
391
    as->as_flags = assertion_flags & ~(ASSERT_FLAG_SIGGEN |
392
				       ASSERT_FLAG_SIGVER);
393
394
    /* Skip any leading whitespace */
395
    for (i = 0, j = len; i < j && isspace((unsigned char)as->as_buf[i]); i++)
396
     ;
397
398
    /* Keyword must start at begining of buffer or line */
399
    if ((i >= j) || ((i != 0) && (as->as_buf[i - 1] != '\n')))
400
    {
401
	keynote_free_assertion(as);
402
	keynote_errno = ERROR_SYNTAX;
403
	return NULL;
404
    }
405
406
    while (i < j)			/* Decomposition loop */
407
    {
408
	ks = as->as_buf + i;
409
410
	/* Mark begining of assertion for signature purposes */
411
	if (as->as_startofsignature == NULL)
412
	  as->as_startofsignature = ks;
413
414
	/* This catches comments at the begining of an assertion only */
415
	if (as->as_buf[i] == '#')	/* Comment */
416
	{
417
	    seen_field = 1;
418
419
   	    /* Skip until the end of line */
420
	    while ((i< j) && as->as_buf[++i] != '\n')
421
	      ;
422
423
	    i++;
424
	    continue;  /* Loop */
425
	}
426
427
	/* Advance until we find a keyword separator */
428
	for (; (as->as_buf[i] != ':') && (i < j); i++)
429
	  ;
430
431
	if (i + 1 > j)
432
	{
433
	    keynote_free_assertion(as);
434
	    keynote_errno = ERROR_SYNTAX;
435
	    return NULL;
436
	}
437
438
	/* ks points at begining of keyword, ke points at end */
439
	ke = as->as_buf + i;
440
441
	/* ts points at begining of value field */
442
	ts = as->as_buf + i + 1;	/* Skip ':' */
443
444
	/*
445
	 * Find the end of the field -- means end of buffer,
446
	 * a newline followed by a non-whitespace character,
447
	 * or two newlines.
448
	 */
449
	while (++i <= j)
450
	{
451
	    /* If end of buffer, we're at the end of the field */
452
	    if (i == j)
453
	    {
454
		end_of_assertion = 1;
455
		te = as->as_buf + i;
456
		break;
457
	    }
458
459
	    /* If two newlines, end of assertion */
460
	    if ((as->as_buf[i] == '\n') && (i + 1 < j) &&
461
		(as->as_buf[i + 1] == '\n'))
462
	    {
463
		end_of_assertion = 1;
464
		te = as->as_buf + i;
465
		break;
466
	    }
467
468
	    /* If newline followed by non-whitespace or comment character */
469
	    if ((as->as_buf[i] == '\n') &&
470
		(!isspace((unsigned char)as->as_buf[i + 1])) &&
471
                (as->as_buf[i + 1] != '#'))
472
	    {
473
	        te = as->as_buf + i;
474
	        break;
475
	    }
476
	}
477
478
	i++;
479
480
	/*
481
	 * On each of the cases (except the first), we check that:
482
	 *  - we've already seen a keynote-version field (and that
483
	 *    it's the first one that appears in the assertion)
484
	 *  - the signature field, if present, is the last one
485
	 *  - no field appears more than once
486
	 */
487
	switch (whichkeyword(ks, ke))
488
	{
489
	    case -1:
490
		keynote_free_assertion(as);
491
		return NULL;
492
493
	    case KEYWORD_VERSION:
494
		if ((ver == 1) || (seen_field == 1))
495
		{
496
		    keynote_free_assertion(as);
497
		    keynote_errno = ERROR_SYNTAX;
498
		    return NULL;
499
		}
500
501
		/* Test for version correctness */
502
		keynote_get_envlist(ts, te, 1);
503
		if (keynote_errno != 0)
504
		{
505
		    keynote_free_assertion(as);
506
		    return NULL;
507
		}
508
509
		ver = 1;
510
		break;
511
512
	    case KEYWORD_LOCALINIT:
513
		if (as->as_env != NULL)
514
		{
515
		    keynote_free_assertion(as);
516
		    keynote_errno = ERROR_SYNTAX;
517
		    return NULL;
518
		}
519
520
		as->as_env = keynote_get_envlist(ts, te, 0);
521
		if (keynote_errno != 0)
522
		{
523
		    keynote_free_assertion(as);
524
		    return NULL;
525
		}
526
		break;
527
528
	    case KEYWORD_AUTHORIZER:
529
		if (as->as_authorizer_string_s != NULL)
530
		{
531
		    keynote_free_assertion(as);
532
		    keynote_errno = ERROR_SYNTAX;
533
		    return NULL;
534
		}
535
536
		as->as_authorizer_string_s = ts;
537
		as->as_authorizer_string_e = te;
538
		break;
539
540
	    case KEYWORD_LICENSEES:
541
		if (as->as_keypred_s != NULL)
542
		{
543
		    keynote_free_assertion(as);
544
		    keynote_errno = ERROR_SYNTAX;
545
		    return NULL;
546
		}
547
548
		as->as_keypred_s = ts;
549
		as->as_keypred_e = te;
550
		break;
551
552
	    case KEYWORD_CONDITIONS:
553
		if (as->as_conditions_s != NULL)
554
		{
555
		    keynote_free_assertion(as);
556
		    keynote_errno = ERROR_SYNTAX;
557
		    return NULL;
558
		}
559
560
		as->as_conditions_s = ts;
561
		as->as_conditions_e = te;
562
		break;
563
564
	    case KEYWORD_SIGNATURE:
565
		if (as->as_signature_string_s != NULL)
566
		{
567
		    keynote_free_assertion(as);
568
		    keynote_errno = ERROR_SYNTAX;
569
		    return NULL;
570
		}
571
572
		end_of_assertion = 1;
573
		as->as_allbutsignature = ks;
574
		as->as_signature_string_s = ts;
575
		as->as_signature_string_e = te;
576
		break;
577
578
	    case KEYWORD_COMMENT:
579
		if (as->as_comment_s != NULL)
580
		{
581
		    keynote_free_assertion(as);
582
		    keynote_errno = ERROR_SYNTAX;
583
		    return NULL;
584
		}
585
586
		as->as_comment_s = ts;
587
		as->as_comment_e = te;
588
		break;
589
	}
590
591
	seen_field = 1;
592
	if (end_of_assertion == 1)
593
	{
594
	    /* End of buffer, good termination */
595
	    if ((te == as->as_buf + len) || (te + 1 == as->as_buf + len) ||
596
		(*(te) == '\0') || (*(te + 1) == '\0'))
597
	      break;
598
599
	    /* Check whether there's something else following */
600
	    for (k = 1; te + k < as->as_buf + len && *(te + k) != '\n'; k++)
601
	      if (!isspace((unsigned char)*(te + k)))
602
	      {
603
		  keynote_free_assertion(as);
604
		  keynote_errno = ERROR_SYNTAX;
605
		  return NULL;
606
	      }
607
608
	    break; /* Assertion is "properly" terminated */
609
	}
610
    }
611
612
    /* Check that the basic fields are there */
613
    if (as->as_authorizer_string_s == NULL)
614
    {
615
	keynote_free_assertion(as);
616
	keynote_errno = ERROR_SYNTAX;
617
	return NULL;
618
    }
619
620
    /* Signature generation/verification handling */
621
    if (assertion_flags & ASSERT_FLAG_SIGGEN)
622
    {
623
        if (keynote_fix_fields(as, 0) != RESULT_TRUE)
624
        {
625
	    keynote_free_assertion(as);
626
	    return NULL;
627
        }
628
    }
629
    else
630
      if (assertion_flags & ASSERT_FLAG_SIGVER)
631
	if (keynote_fix_fields(as, 1) != RESULT_TRUE)
632
	{
633
	    keynote_free_assertion(as);
634
	    return NULL;
635
	}
636
637
    return as;
638
}