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