1 /* 2 * authkeys.c - routines to manage the storage of authentication keys 3 */ 4 #ifdef HAVE_CONFIG_H 5 # include <config.h> 6 #endif 7 8 #include <math.h> 9 #include <stdio.h> 10 11 #include "ntp.h" 12 #include "ntp_fp.h" 13 #include "ntpd.h" 14 #include "ntp_lists.h" 15 #include "ntp_string.h" 16 #include "ntp_malloc.h" 17 #include "ntp_stdlib.h" 18 #include "ntp_keyacc.h" 19 20 /* 21 * Structure to store keys in in the hash table. 22 */ 23 typedef struct savekey symkey; 24 25 struct savekey { 26 symkey * hlink; /* next in hash bucket */ 27 DECL_DLIST_LINK(symkey, llink); /* for overall & free lists */ 28 u_char * secret; /* shared secret */ 29 KeyAccT * keyacclist; /* Private key access list */ 30 u_long lifetime; /* remaining lifetime */ 31 keyid_t keyid; /* key identifier */ 32 u_short type; /* OpenSSL digest NID */ 33 size_t secretsize; /* secret octets */ 34 u_short flags; /* KEY_ flags that wave */ 35 }; 36 37 /* define the payload region of symkey beyond the list pointers */ 38 #define symkey_payload secret 39 40 #define KEY_TRUSTED 0x001 /* this key is trusted */ 41 42 #ifdef DEBUG 43 typedef struct symkey_alloc_tag symkey_alloc; 44 45 struct symkey_alloc_tag { 46 symkey_alloc * link; 47 void * mem; /* enable free() atexit */ 48 }; 49 50 symkey_alloc * authallocs; 51 #endif /* DEBUG */ 52 53 static u_short auth_log2(size_t); 54 static void auth_resize_hashtable(void); 55 static void allocsymkey(keyid_t, u_short, 56 u_short, u_long, size_t, u_char *, KeyAccT *); 57 static void freesymkey(symkey *); 58 #ifdef DEBUG 59 static void free_auth_mem(void); 60 #endif 61 62 symkey key_listhead; /* list of all in-use keys */; 63 /* 64 * The hash table. This is indexed by the low order bits of the 65 * keyid. We make this fairly big for potentially busy servers. 66 */ 67 #define DEF_AUTHHASHSIZE 64 68 /*#define HASHMASK ((HASHSIZE)-1)*/ 69 #define KEYHASH(keyid) ((keyid) & authhashmask) 70 71 int authhashdisabled; 72 u_short authhashbuckets = DEF_AUTHHASHSIZE; 73 u_short authhashmask = DEF_AUTHHASHSIZE - 1; 74 symkey **key_hash; 75 76 u_long authkeynotfound; /* keys not found */ 77 u_long authkeylookups; /* calls to lookup keys */ 78 u_long authnumkeys; /* number of active keys */ 79 u_long authkeyexpired; /* key lifetime expirations */ 80 u_long authkeyuncached; /* cache misses */ 81 u_long authnokey; /* calls to encrypt with no key */ 82 u_long authencryptions; /* calls to encrypt */ 83 u_long authdecryptions; /* calls to decrypt */ 84 85 /* 86 * Storage for free symkey structures. We malloc() such things but 87 * never free them. 88 */ 89 symkey *authfreekeys; 90 int authnumfreekeys; 91 92 #define MEMINC 16 /* number of new free ones to get */ 93 94 /* 95 * The key cache. We cache the last key we looked at here. 96 * Note: this should hold the last *trusted* key. Also the 97 * cache is only loaded when the digest type / MAC algorithm 98 * is valid. 99 */ 100 keyid_t cache_keyid; /* key identifier */ 101 u_char *cache_secret; /* secret */ 102 size_t cache_secretsize; /* secret length */ 103 int cache_type; /* OpenSSL digest NID */ 104 u_short cache_flags; /* flags that wave */ 105 KeyAccT *cache_keyacclist; /* key access list */ 106 107 /* -------------------------------------------------------------------- 108 * manage key access lists 109 * -------------------------------------------------------------------- 110 */ 111 /* allocate and populate new access node and pushes it on the list. 112 * Returns the new head. 113 */ 114 KeyAccT* 115 keyacc_new_push( 116 KeyAccT * head, 117 const sockaddr_u * addr, 118 unsigned int subnetbits 119 ) 120 { 121 KeyAccT * node = emalloc(sizeof(KeyAccT)); 122 123 memcpy(&node->addr, addr, sizeof(sockaddr_u)); 124 node->subnetbits = subnetbits; 125 node->next = head; 126 127 return node; 128 } 129 130 /* ----------------------------------------------------------------- */ 131 /* pop and deallocate the first node of a list of access nodes, if 132 * the list is not empty. Returns the tail of the list. 133 */ 134 KeyAccT* 135 keyacc_pop_free( 136 KeyAccT *head 137 ) 138 { 139 KeyAccT * next = NULL; 140 if (head) { 141 next = head->next; 142 free(head); 143 } 144 return next; 145 } 146 147 /* ----------------------------------------------------------------- */ 148 /* deallocate the list; returns an empty list. */ 149 KeyAccT* 150 keyacc_all_free( 151 KeyAccT * head 152 ) 153 { 154 while (head) 155 head = keyacc_pop_free(head); 156 return head; 157 } 158 159 /* ----------------------------------------------------------------- */ 160 /* scan a list to see if it contains a given address. Return the 161 * default result value in case of an empty list. 162 */ 163 int /*BOOL*/ 164 keyacc_contains( 165 const KeyAccT *head, 166 const sockaddr_u *addr, 167 int defv) 168 { 169 if (head) { 170 do { 171 if (keyacc_amatch(&head->addr, addr, 172 head->subnetbits)) 173 return TRUE; 174 } while (NULL != (head = head->next)); 175 return FALSE; 176 } else { 177 return !!defv; 178 } 179 } 180 181 #if CHAR_BIT != 8 182 # error "don't know how to handle bytes with that bit size" 183 #endif 184 185 /* ----------------------------------------------------------------- */ 186 /* check two addresses for a match, taking a prefix length into account 187 * when doing the compare. 188 * 189 * The ISC lib contains a similar function with not entirely specified 190 * semantics, so it seemed somewhat cleaner to do this from scratch. 191 * 192 * Note 1: It *is* assumed that the addresses are stored in network byte 193 * order, that is, most significant byte first! 194 * 195 * Note 2: "no address" compares unequal to all other addresses, even to 196 * itself. This has the same semantics as NaNs have for floats: *any* 197 * relational or equality operation involving a NaN returns FALSE, even 198 * equality with itself. "no address" is either a NULL pointer argument 199 * or an address of type AF_UNSPEC. 200 */ 201 int/*BOOL*/ 202 keyacc_amatch( 203 const sockaddr_u * a1, 204 const sockaddr_u * a2, 205 unsigned int mbits 206 ) 207 { 208 const uint8_t * pm1; 209 const uint8_t * pm2; 210 uint8_t msk; 211 unsigned int len; 212 213 /* 1st check: If any address is not an address, it's inequal. */ 214 if ( !a1 || (AF_UNSPEC == AF(a1)) || 215 !a2 || (AF_UNSPEC == AF(a2)) ) 216 return FALSE; 217 218 /* We could check pointers for equality here and shortcut the 219 * other checks if we find object identity. But that use case is 220 * too rare to care for it. 221 */ 222 223 /* 2nd check: Address families must be the same. */ 224 if (AF(a1) != AF(a2)) 225 return FALSE; 226 227 /* type check: address family determines buffer & size */ 228 switch (AF(a1)) { 229 case AF_INET: 230 /* IPv4 is easy: clamp size, get byte pointers */ 231 if (mbits > sizeof(NSRCADR(a1)) * 8) 232 mbits = sizeof(NSRCADR(a1)) * 8; 233 pm1 = (const void*)&NSRCADR(a1); 234 pm2 = (const void*)&NSRCADR(a2); 235 break; 236 237 case AF_INET6: 238 /* IPv6 is slightly different: Both scopes must match, 239 * too, before we even consider doing a match! 240 */ 241 if ( ! SCOPE_EQ(a1, a2)) 242 return FALSE; 243 if (mbits > sizeof(NSRCADR6(a1)) * 8) 244 mbits = sizeof(NSRCADR6(a1)) * 8; 245 pm1 = (const void*)&NSRCADR6(a1); 246 pm2 = (const void*)&NSRCADR6(a2); 247 break; 248 249 default: 250 /* don't know how to compare that!?! */ 251 return FALSE; 252 } 253 254 /* Split bit length into byte length and partial byte mask. 255 * Note that the byte mask extends from the MSB of a byte down, 256 * and that zero shift (--> mbits % 8 == 0) results in an 257 * all-zero mask. 258 */ 259 msk = 0xFFu ^ (0xFFu >> (mbits & 7)); 260 len = mbits >> 3; 261 262 /* 3rd check: Do memcmp() over full bytes, if any */ 263 if (len && memcmp(pm1, pm2, len)) 264 return FALSE; 265 266 /* 4th check: compare last incomplete byte, if any */ 267 if (msk && ((pm1[len] ^ pm2[len]) & msk)) 268 return FALSE; 269 270 /* If none of the above failed, we're successfully through. */ 271 return TRUE; 272 } 273 274 /* 275 * init_auth - initialize internal data 276 */ 277 void 278 init_auth(void) 279 { 280 size_t newalloc; 281 282 /* 283 * Initialize hash table and free list 284 */ 285 newalloc = authhashbuckets * sizeof(key_hash[0]); 286 287 key_hash = erealloc(key_hash, newalloc); 288 memset(key_hash, '\0', newalloc); 289 290 INIT_DLIST(key_listhead, llink); 291 292 #ifdef DEBUG 293 atexit(&free_auth_mem); 294 #endif 295 } 296 297 298 /* 299 * free_auth_mem - assist in leak detection by freeing all dynamic 300 * allocations from this module. 301 */ 302 #ifdef DEBUG 303 static void 304 free_auth_mem(void) 305 { 306 symkey * sk; 307 symkey_alloc * alloc; 308 symkey_alloc * next_alloc; 309 310 while (NULL != (sk = HEAD_DLIST(key_listhead, llink))) { 311 freesymkey(sk); 312 } 313 free(key_hash); 314 key_hash = NULL; 315 cache_keyid = 0; 316 cache_flags = 0; 317 cache_keyacclist = NULL; 318 for (alloc = authallocs; alloc != NULL; alloc = next_alloc) { 319 next_alloc = alloc->link; 320 free(alloc->mem); 321 } 322 authfreekeys = NULL; 323 authnumfreekeys = 0; 324 } 325 #endif /* DEBUG */ 326 327 328 /* 329 * auth_moremem - get some more free key structures 330 */ 331 void 332 auth_moremem( 333 int keycount 334 ) 335 { 336 symkey * sk; 337 int i; 338 #ifdef DEBUG 339 void * base; 340 symkey_alloc * allocrec; 341 # define MOREMEM_EXTRA_ALLOC (sizeof(*allocrec)) 342 #else 343 # define MOREMEM_EXTRA_ALLOC (0) 344 #endif 345 346 i = (keycount > 0) 347 ? keycount 348 : MEMINC; 349 sk = eallocarrayxz(i, sizeof(*sk), MOREMEM_EXTRA_ALLOC); 350 #ifdef DEBUG 351 base = sk; 352 #endif 353 authnumfreekeys += i; 354 355 for (; i > 0; i--, sk++) { 356 LINK_SLIST(authfreekeys, sk, llink.f); 357 } 358 359 #ifdef DEBUG 360 allocrec = (void *)sk; 361 allocrec->mem = base; 362 LINK_SLIST(authallocs, allocrec, link); 363 #endif 364 } 365 366 367 /* 368 * auth_prealloc_symkeys 369 */ 370 void 371 auth_prealloc_symkeys( 372 int keycount 373 ) 374 { 375 int allocated; 376 int additional; 377 378 allocated = authnumkeys + authnumfreekeys; 379 additional = keycount - allocated; 380 if (additional > 0) 381 auth_moremem(additional); 382 auth_resize_hashtable(); 383 } 384 385 386 static u_short 387 auth_log2(size_t x) 388 { 389 /* 390 ** bithack to calculate floor(log2(x)) 391 ** 392 ** This assumes 393 ** - (sizeof(size_t) is a power of two 394 ** - CHAR_BITS is a power of two 395 ** - returning zero for arguments <= 0 is OK. 396 ** 397 ** Does only shifts, masks and sums in integer arithmetic in 398 ** log2(CHAR_BIT*sizeof(size_t)) steps. (that is, 5/6 steps for 399 ** 32bit/64bit size_t) 400 */ 401 int s; 402 int r = 0; 403 size_t m = ~(size_t)0; 404 405 for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) { 406 m <<= s; 407 if (x & m) 408 r += s; 409 else 410 x <<= s; 411 } 412 return (u_short)r; 413 } 414 415 int/*BOOL*/ 416 ipaddr_match_masked(const sockaddr_u *,const sockaddr_u *, 417 unsigned int mbits); 418 419 static void 420 authcache_flush_id( 421 keyid_t id 422 ) 423 { 424 if (cache_keyid == id) { 425 cache_keyid = 0; 426 cache_type = 0; 427 cache_flags = 0; 428 cache_secret = NULL; 429 cache_secretsize = 0; 430 cache_keyacclist = NULL; 431 } 432 } 433 434 435 /* 436 * auth_resize_hashtable 437 * 438 * Size hash table to average 4 or fewer entries per bucket initially, 439 * within the bounds of at least 4 and no more than 15 bits for the hash 440 * table index. Populate the hash table. 441 */ 442 static void 443 auth_resize_hashtable(void) 444 { 445 u_long totalkeys; 446 u_short hashbits; 447 u_short hash; 448 size_t newalloc; 449 symkey * sk; 450 451 totalkeys = authnumkeys + authnumfreekeys; 452 hashbits = auth_log2(totalkeys / 4) + 1; 453 hashbits = max(4, hashbits); 454 hashbits = min(15, hashbits); 455 456 authhashbuckets = 1 << hashbits; 457 authhashmask = authhashbuckets - 1; 458 newalloc = authhashbuckets * sizeof(key_hash[0]); 459 460 key_hash = erealloc(key_hash, newalloc); 461 memset(key_hash, '\0', newalloc); 462 463 ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 464 hash = KEYHASH(sk->keyid); 465 LINK_SLIST(key_hash[hash], sk, hlink); 466 ITER_DLIST_END() 467 } 468 469 470 /* 471 * allocsymkey - common code to allocate and link in symkey 472 * 473 * secret must be allocated with a free-compatible allocator. It is 474 * owned by the referring symkey structure, and will be free()d by 475 * freesymkey(). 476 */ 477 static void 478 allocsymkey( 479 keyid_t id, 480 u_short flags, 481 u_short type, 482 u_long lifetime, 483 size_t secretsize, 484 u_char * secret, 485 KeyAccT * ka 486 ) 487 { 488 symkey * sk; 489 symkey ** bucket; 490 491 bucket = &key_hash[KEYHASH(id)]; 492 493 494 if (authnumfreekeys < 1) 495 auth_moremem(-1); 496 UNLINK_HEAD_SLIST(sk, authfreekeys, llink.f); 497 DEBUG_ENSURE(sk != NULL); 498 sk->keyid = id; 499 sk->flags = flags; 500 sk->type = type; 501 sk->secretsize = secretsize; 502 sk->secret = secret; 503 sk->keyacclist = ka; 504 sk->lifetime = lifetime; 505 LINK_SLIST(*bucket, sk, hlink); 506 LINK_TAIL_DLIST(key_listhead, sk, llink); 507 authnumfreekeys--; 508 authnumkeys++; 509 } 510 511 512 /* 513 * freesymkey - common code to remove a symkey and recycle its entry. 514 */ 515 static void 516 freesymkey( 517 symkey * sk 518 ) 519 { 520 symkey ** bucket; 521 symkey * unlinked; 522 523 if (NULL == sk) 524 return; 525 526 authcache_flush_id(sk->keyid); 527 keyacc_all_free(sk->keyacclist); 528 529 bucket = &key_hash[KEYHASH(sk->keyid)]; 530 if (sk->secret != NULL) { 531 memset(sk->secret, '\0', sk->secretsize); 532 free(sk->secret); 533 } 534 UNLINK_SLIST(unlinked, *bucket, sk, hlink, symkey); 535 DEBUG_ENSURE(sk == unlinked); 536 UNLINK_DLIST(sk, llink); 537 memset((char *)sk + offsetof(symkey, symkey_payload), '\0', 538 sizeof(*sk) - offsetof(symkey, symkey_payload)); 539 LINK_SLIST(authfreekeys, sk, llink.f); 540 authnumkeys--; 541 authnumfreekeys++; 542 } 543 544 545 /* 546 * auth_findkey - find a key in the hash table 547 */ 548 struct savekey * 549 auth_findkey( 550 keyid_t id 551 ) 552 { 553 symkey * sk; 554 555 for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) 556 if (id == sk->keyid) 557 return sk; 558 return NULL; 559 } 560 561 562 /* 563 * auth_havekey - return TRUE if the key id is zero or known. The 564 * key needs not to be trusted. 565 */ 566 int 567 auth_havekey( 568 keyid_t id 569 ) 570 { 571 return 572 (0 == id) || 573 (cache_keyid == id) || 574 (NULL != auth_findkey(id)); 575 } 576 577 578 /* 579 * authhavekey - return TRUE and cache the key, if zero or both known 580 * and trusted. 581 */ 582 int 583 authhavekey( 584 keyid_t id 585 ) 586 { 587 symkey * sk; 588 589 authkeylookups++; 590 if (0 == id || cache_keyid == id) 591 return !!(KEY_TRUSTED & cache_flags); 592 593 /* 594 * Search the bin for the key. If not found, or found but the key 595 * type is zero, somebody marked it trusted without specifying a 596 * key or key type. In this case consider the key missing. 597 */ 598 authkeyuncached++; 599 sk = auth_findkey(id); 600 if ((sk == NULL) || (sk->type == 0)) { 601 authkeynotfound++; 602 return FALSE; 603 } 604 605 /* 606 * If the key is not trusted, the key is not considered found. 607 */ 608 if ( ! (KEY_TRUSTED & sk->flags)) { 609 authnokey++; 610 return FALSE; 611 } 612 613 /* 614 * The key is found and trusted. Initialize the key cache. 615 */ 616 cache_keyid = sk->keyid; 617 cache_type = sk->type; 618 cache_flags = sk->flags; 619 cache_secret = sk->secret; 620 cache_secretsize = sk->secretsize; 621 cache_keyacclist = sk->keyacclist; 622 623 return TRUE; 624 } 625 626 627 /* 628 * authtrust - declare a key to be trusted/untrusted 629 */ 630 void 631 authtrust( 632 keyid_t id, 633 u_long trust 634 ) 635 { 636 symkey * sk; 637 u_long lifetime; 638 639 /* 640 * Search bin for key; if it does not exist and is untrusted, 641 * forget it. 642 */ 643 644 sk = auth_findkey(id); 645 if (!trust && sk == NULL) 646 return; 647 648 /* 649 * There are two conditions remaining. Either it does not 650 * exist and is to be trusted or it does exist and is or is 651 * not to be trusted. 652 */ 653 if (sk != NULL) { 654 /* 655 * Key exists. If it is to be trusted, say so and update 656 * its lifetime. If no longer trusted, return it to the 657 * free list. Flush the cache first to be sure there are 658 * no discrepancies. 659 */ 660 authcache_flush_id(id); 661 if (trust > 0) { 662 sk->flags |= KEY_TRUSTED; 663 if (trust > 1) 664 sk->lifetime = current_time + trust; 665 else 666 sk->lifetime = 0; 667 } else { 668 freesymkey(sk); 669 } 670 return; 671 } 672 673 /* 674 * keyid is not present, but the is to be trusted. We allocate 675 * a new key, but do not specify a key type or secret. 676 */ 677 if (trust > 1) { 678 lifetime = current_time + trust; 679 } else { 680 lifetime = 0; 681 } 682 allocsymkey(id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL); 683 } 684 685 686 /* 687 * authistrusted - determine whether a key is trusted 688 */ 689 int 690 authistrusted( 691 keyid_t id 692 ) 693 { 694 symkey * sk; 695 696 if (id == cache_keyid) 697 return !!(KEY_TRUSTED & cache_flags); 698 699 authkeyuncached++; 700 sk = auth_findkey(id); 701 if (sk == NULL || !(KEY_TRUSTED & sk->flags)) { 702 authkeynotfound++; 703 return FALSE; 704 } 705 return TRUE; 706 } 707 708 709 /* 710 * authistrustedip - determine if the IP is OK for the keyid 711 */ 712 int 713 authistrustedip( 714 keyid_t keyno, 715 sockaddr_u * sau 716 ) 717 { 718 symkey * sk; 719 720 if (keyno == cache_keyid) { 721 return (KEY_TRUSTED & cache_flags) && 722 keyacc_contains(cache_keyacclist, sau, TRUE); 723 } 724 725 if (NULL != (sk = auth_findkey(keyno))) { 726 authkeyuncached++; 727 return (KEY_TRUSTED & sk->flags) && 728 keyacc_contains(sk->keyacclist, sau, TRUE); 729 } 730 731 authkeynotfound++; 732 return FALSE; 733 } 734 735 /* Note: There are two locations below where 'strncpy()' is used. While 736 * this function is a hazard by itself, it's essential that it is used 737 * here. Bug 1243 involved that the secret was filled with NUL bytes 738 * after the first NUL encountered, and 'strlcpy()' simply does NOT have 739 * this behaviour. So disabling the fix and reverting to the buggy 740 * behaviour due to compatibility issues MUST also fill with NUL and 741 * this needs 'strncpy'. Also, the secret is managed as a byte blob of a 742 * given size, and eventually truncating it and replacing the last byte 743 * with a NUL would be a bug. 744 * perlinger@ntp.org 2015-10-10 745 */ 746 void 747 MD5auth_setkey( 748 keyid_t keyno, 749 int keytype, 750 const u_char *key, 751 size_t secretsize, 752 KeyAccT *ka 753 ) 754 { 755 symkey * sk; 756 u_char * secret; 757 758 DEBUG_ENSURE(keytype <= USHRT_MAX); 759 DEBUG_ENSURE(secretsize < 4 * 1024); 760 /* 761 * See if we already have the key. If so just stick in the 762 * new value. 763 */ 764 sk = auth_findkey(keyno); 765 if (sk != NULL && keyno == sk->keyid) { 766 /* TALOS-CAN-0054: make sure we have a new buffer! */ 767 if (NULL != sk->secret) { 768 memset(sk->secret, 0, sk->secretsize); 769 free(sk->secret); 770 } 771 sk->secret = emalloc(secretsize + 1); 772 sk->type = (u_short)keytype; 773 sk->secretsize = secretsize; 774 /* make sure access lists don't leak here! */ 775 if (ka != sk->keyacclist) { 776 keyacc_all_free(sk->keyacclist); 777 sk->keyacclist = ka; 778 } 779 #ifndef DISABLE_BUG1243_FIX 780 memcpy(sk->secret, key, secretsize); 781 #else 782 /* >MUST< use 'strncpy()' here! See above! */ 783 strncpy((char *)sk->secret, (const char *)key, 784 secretsize); 785 #endif 786 authcache_flush_id(keyno); 787 return; 788 } 789 790 /* 791 * Need to allocate new structure. Do it. 792 */ 793 secret = emalloc(secretsize + 1); 794 #ifndef DISABLE_BUG1243_FIX 795 memcpy(secret, key, secretsize); 796 #else 797 /* >MUST< use 'strncpy()' here! See above! */ 798 strncpy((char *)secret, (const char *)key, secretsize); 799 #endif 800 allocsymkey(keyno, 0, (u_short)keytype, 0, 801 secretsize, secret, ka); 802 #ifdef DEBUG 803 if (debug >= 4) { 804 size_t j; 805 806 printf("auth_setkey: key %d type %d len %d ", (int)keyno, 807 keytype, (int)secretsize); 808 for (j = 0; j < secretsize; j++) { 809 printf("%02x", secret[j]); 810 } 811 printf("\n"); 812 } 813 #endif 814 } 815 816 817 /* 818 * auth_delkeys - delete non-autokey untrusted keys, and clear all info 819 * except the trusted bit of non-autokey trusted keys, in 820 * preparation for rereading the keys file. 821 */ 822 void 823 auth_delkeys(void) 824 { 825 symkey * sk; 826 827 ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 828 if (sk->keyid > NTP_MAXKEY) { /* autokey */ 829 continue; 830 } 831 832 /* 833 * Don't lose info as to which keys are trusted. Make 834 * sure there are no dangling pointers! 835 */ 836 if (KEY_TRUSTED & sk->flags) { 837 if (sk->secret != NULL) { 838 memset(sk->secret, 0, sk->secretsize); 839 free(sk->secret); 840 sk->secret = NULL; /* TALOS-CAN-0054 */ 841 } 842 sk->keyacclist = keyacc_all_free(sk->keyacclist); 843 sk->secretsize = 0; 844 sk->lifetime = 0; 845 } else { 846 freesymkey(sk); 847 } 848 ITER_DLIST_END() 849 } 850 851 852 /* 853 * auth_agekeys - delete keys whose lifetimes have expired 854 */ 855 void 856 auth_agekeys(void) 857 { 858 symkey * sk; 859 860 ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 861 if (sk->lifetime > 0 && current_time > sk->lifetime) { 862 freesymkey(sk); 863 authkeyexpired++; 864 } 865 ITER_DLIST_END() 866 DPRINTF(1, ("auth_agekeys: at %lu keys %lu expired %lu\n", 867 current_time, authnumkeys, authkeyexpired)); 868 } 869 870 871 /* 872 * authencrypt - generate message authenticator 873 * 874 * Returns length of authenticator field, zero if key not found. 875 */ 876 size_t 877 authencrypt( 878 keyid_t keyno, 879 u_int32 * pkt, 880 size_t length 881 ) 882 { 883 /* 884 * A zero key identifier means the sender has not verified 885 * the last message was correctly authenticated. The MAC 886 * consists of a single word with value zero. 887 */ 888 authencryptions++; 889 pkt[length / 4] = htonl(keyno); 890 if (0 == keyno) { 891 return 4; 892 } 893 if (!authhavekey(keyno)) { 894 return 0; 895 } 896 897 return MD5authencrypt(cache_type, 898 cache_secret, cache_secretsize, 899 pkt, length); 900 } 901 902 903 /* 904 * authdecrypt - verify message authenticator 905 * 906 * Returns TRUE if authenticator valid, FALSE if invalid or not found. 907 */ 908 int 909 authdecrypt( 910 keyid_t keyno, 911 u_int32 * pkt, 912 size_t length, 913 size_t size 914 ) 915 { 916 /* 917 * A zero key identifier means the sender has not verified 918 * the last message was correctly authenticated. For our 919 * purpose this is an invalid authenticator. 920 */ 921 authdecryptions++; 922 if (0 == keyno || !authhavekey(keyno) || size < 4) { 923 return FALSE; 924 } 925 926 return MD5authdecrypt(cache_type, 927 cache_secret, cache_secretsize, 928 pkt, length, size); 929 } 930