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