authkeys.c revision 294905
1139826Simp/* 262587Sitojun * authkeys.c - routines to manage the storage of authentication keys 362587Sitojun */ 4120941Sume#ifdef HAVE_CONFIG_H 562587Sitojun# include <config.h> 662587Sitojun#endif 762587Sitojun 862587Sitojun#include <math.h> 962587Sitojun#include <stdio.h> 1062587Sitojun 1162587Sitojun#include "ntp.h" 1262587Sitojun#include "ntp_fp.h" 1362587Sitojun#include "ntpd.h" 1462587Sitojun#include "ntp_lists.h" 1562587Sitojun#include "ntp_string.h" 16120941Sume#include "ntp_malloc.h" 1762587Sitojun#include "ntp_stdlib.h" 1862587Sitojun#include "ntp_keyacc.h" 1962587Sitojun 2062587Sitojun/* 2162587Sitojun * Structure to store keys in in the hash table. 2262587Sitojun */ 2362587Sitojuntypedef struct savekey symkey; 2462587Sitojun 2562587Sitojunstruct savekey { 2662587Sitojun symkey * hlink; /* next in hash bucket */ 2762587Sitojun DECL_DLIST_LINK(symkey, llink); /* for overall & free lists */ 28174510Sobrien u_char * secret; /* shared secret */ 29174510Sobrien KeyAccT * keyacclist; /* Private key access list */ 3062587Sitojun u_long lifetime; /* remaining lifetime */ 3162587Sitojun keyid_t keyid; /* key identifier */ 32174510Sobrien u_short type; /* OpenSSL digest NID */ 33174510Sobrien u_short secretsize; /* secret octets */ 34174510Sobrien u_short flags; /* KEY_ flags that wave */ 3562587Sitojun}; 3662587Sitojun 3762587Sitojun/* define the payload region of symkey beyond the list pointers */ 3862587Sitojun#define symkey_payload secret 3962587Sitojun 4078064Sume#define KEY_TRUSTED 0x001 /* this key is trusted */ 41148385Sume 4262587Sitojun#ifdef DEBUG 4362587Sitojuntypedef struct symkey_alloc_tag symkey_alloc; 44185571Sbz 4562587Sitojunstruct symkey_alloc_tag { 4662587Sitojun symkey_alloc * link; 47185571Sbz void * mem; /* enable free() atexit */ 48183550Szec}; 4962587Sitojun 50195699Srwatsonsymkey_alloc * authallocs; 5162587Sitojun#endif /* DEBUG */ 5262587Sitojun 53207369Sbzstatic u_short auth_log2(size_t); 54207369Sbzstatic void auth_resize_hashtable(void); 55207369Sbzstatic void allocsymkey(symkey **, keyid_t, u_short, u_short, 56207369Sbz u_long, u_short, u_char *, KeyAccT *); 57207369Sbzstatic void freesymkey(symkey *, symkey **); 58148385Sume#ifdef DEBUG 59121343Sumestatic void free_auth_mem(void); 60138184Sgnn#endif 61138184Sgnn 62121343Sumesymkey key_listhead; /* list of all in-use keys */; 63121343Sume/* 64121343Sume * The hash table. This is indexed by the low order bits of the 65121343Sume * keyid. We make this fairly big for potentially busy servers. 66121343Sume */ 67121343Sume#define DEF_AUTHHASHSIZE 64 68121343Sume/*#define HASHMASK ((HASHSIZE)-1)*/ 69215701Sdim#define KEYHASH(keyid) ((keyid) & authhashmask) 70195727Srwatson 71195699Srwatsonint authhashdisabled; 72121161Sumeu_short authhashbuckets = DEF_AUTHHASHSIZE; 73121161Sumeu_short authhashmask = DEF_AUTHHASHSIZE - 1; 7462587Sitojunsymkey **key_hash; 7562587Sitojun 76171259Sdelphiju_long authkeynotfound; /* keys not found */ 77121161Sumeu_long authkeylookups; /* calls to lookup keys */ 78121161Sumeu_long authnumkeys; /* number of active keys */ 79190787Szecu_long authkeyexpired; /* key lifetime expirations */ 80190787Szecu_long authkeyuncached; /* cache misses */ 81190787Szecu_long authnokey; /* calls to encrypt with no key */ 82190787Szecu_long authencryptions; /* calls to encrypt */ 83190787Szecu_long authdecryptions; /* calls to decrypt */ 84121343Sume 85121161Sume/* 86121161Sume * Storage for free symkey structures. We malloc() such things but 87121161Sume * never free them. 88171259Sdelphij */ 8962587Sitojunsymkey *authfreekeys; 90121161Sumeint authnumfreekeys; 9162587Sitojun 92121161Sume#define MEMINC 16 /* number of new free ones to get */ 93121161Sume 9462587Sitojun/* 9562587Sitojun * The key cache. We cache the last key we looked at here. 9662587Sitojun */ 9762587Sitojunkeyid_t cache_keyid; /* key identifier */ 9862587Sitojunu_char *cache_secret; /* secret */ 99121315Sumeu_short cache_secretsize; /* secret length */ 100121161Sumeint cache_type; /* OpenSSL digest NID */ 10162587Sitojunu_short cache_flags; /* flags that wave */ 10262587SitojunKeyAccT *cache_keyacclist; /* key access list */ 103121161Sume 104121161Sume 10562587Sitojun/* 10662587Sitojun * init_auth - initialize internal data 107121161Sume */ 10862587Sitojunvoid 10962587Sitojuninit_auth(void) 110121161Sume{ 111171259Sdelphij size_t newalloc; 112121161Sume 113121161Sume /* 114121161Sume * Initialize hash table and free list 115121161Sume */ 116121161Sume newalloc = authhashbuckets * sizeof(key_hash[0]); 11762587Sitojun 118171259Sdelphij key_hash = erealloc(key_hash, newalloc); 11962587Sitojun memset(key_hash, '\0', newalloc); 120138184Sgnn 12162587Sitojun INIT_DLIST(key_listhead, llink); 122138184Sgnn 12362587Sitojun#ifdef DEBUG 124243382Sae atexit(&free_auth_mem); 125138184Sgnn#endif 126138184Sgnn} 127138184Sgnn 128243382Sae 129120856Sume/* 130138184Sgnn * free_auth_mem - assist in leak detection by freeing all dynamic 13162587Sitojun * allocations from this module. 13262587Sitojun */ 13362587Sitojun#ifdef DEBUG 13462587Sitojunstatic void 13562587Sitojunfree_auth_mem(void) 13662587Sitojun{ 13762587Sitojun symkey * sk; 13862587Sitojun symkey_alloc * alloc; 139120941Sume symkey_alloc * next_alloc; 14062587Sitojun 14162587Sitojun while (NULL != (sk = HEAD_DLIST(key_listhead, llink))) { 14262587Sitojun freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]); 143121161Sume } 144121161Sume free(key_hash); 145121315Sume key_hash = NULL; 146121315Sume cache_keyid = 0; 147121315Sume cache_flags = 0; 148121315Sume cache_keyacclist = NULL; 149121315Sume for (alloc = authallocs; alloc != NULL; alloc = next_alloc) { 150121315Sume next_alloc = alloc->link; 151243382Sae free(alloc->mem); 152121315Sume } 153121315Sume authfreekeys = NULL; 154121315Sume authnumfreekeys = 0; 15562587Sitojun} 156181803Sbz#endif /* DEBUG */ 15762587Sitojun 15862587Sitojun 15962587Sitojun/* 16062587Sitojun * auth_moremem - get some more free key structures 16162587Sitojun */ 16262587Sitojunvoid 163243382Saeauth_moremem( 164120856Sume int keycount 16562587Sitojun ) 16662587Sitojun{ 16762587Sitojun symkey * sk; 16862587Sitojun int i; 16962587Sitojun#ifdef DEBUG 17062587Sitojun void * base; 17162587Sitojun symkey_alloc * allocrec; 172121161Sume# define MOREMEM_EXTRA_ALLOC (sizeof(*allocrec)) 17362587Sitojun#else 17462587Sitojun# define MOREMEM_EXTRA_ALLOC (0) 175243382Sae#endif 17662587Sitojun 177120856Sume i = (keycount > 0) 17862587Sitojun ? keycount 17962587Sitojun : MEMINC; 18062587Sitojun sk = emalloc_zero(i * sizeof(*sk) + MOREMEM_EXTRA_ALLOC); 181171259Sdelphij#ifdef DEBUG 18262587Sitojun base = sk; 183243382Sae#endif 184243382Sae authnumfreekeys += i; 185138184Sgnn 186243382Sae for (; i > 0; i--, sk++) { 187243382Sae LINK_SLIST(authfreekeys, sk, llink.f); 188138184Sgnn } 189243382Sae 190120856Sume#ifdef DEBUG 191138184Sgnn allocrec = (void *)sk; 19262587Sitojun allocrec->mem = base; 193121161Sume LINK_SLIST(authallocs, allocrec, link); 19462587Sitojun#endif 195243382Sae} 196120856Sume 19762587Sitojun 19862587Sitojun/* 19962587Sitojun * auth_prealloc_symkeys 20062587Sitojun */ 20162587Sitojunvoid 20262587Sitojunauth_prealloc_symkeys( 20362587Sitojun int keycount 204171259Sdelphij ) 20562587Sitojun{ 20662587Sitojun int allocated; 20762587Sitojun int additional; 208121315Sume 209121315Sume allocated = authnumkeys + authnumfreekeys; 21062587Sitojun additional = keycount - allocated; 21162587Sitojun if (additional > 0) 21262587Sitojun auth_moremem(additional); 21362587Sitojun auth_resize_hashtable(); 21462587Sitojun} 21562587Sitojun 21662587Sitojun 21762587Sitojunstatic u_short 21862587Sitojunauth_log2(size_t x) 21962587Sitojun{ 22062587Sitojun /* 22162587Sitojun ** bithack to calculate floor(log2(x)) 22262587Sitojun ** 22362587Sitojun ** This assumes 22462587Sitojun ** - (sizeof(size_t) is a power of two 225121315Sume ** - CHAR_BITS is a power of two 226121315Sume ** - returning zero for arguments <= 0 is OK. 22762587Sitojun ** 22862587Sitojun ** Does only shifts, masks and sums in integer arithmetic in 22962587Sitojun ** log2(CHAR_BIT*sizeof(size_t)) steps. (that is, 5/6 steps for 23062587Sitojun ** 32bit/64bit size_t) 23162587Sitojun */ 23262587Sitojun int s; 233121315Sume int r = 0; 234121315Sume size_t m = ~(size_t)0; 23562587Sitojun 23662587Sitojun for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) { 23762587Sitojun m <<= s; 23862587Sitojun if (x & m) 23962587Sitojun r += s; 24062587Sitojun else 24162587Sitojun x <<= s; 24262587Sitojun } 24362587Sitojun return (u_short)r; 24462587Sitojun} 24562587Sitojun 24662587Sitojun 24762587Sitojun/* 248121315Sume * auth_resize_hashtable 249121315Sume * 250121315Sume * Size hash table to average 4 or fewer entries per bucket initially, 251121315Sume * within the bounds of at least 4 and no more than 15 bits for the hash 25293128Sume * table index. Populate the hash table. 253121315Sume */ 25462587Sitojunstatic void 255121315Sumeauth_resize_hashtable(void) 256121315Sume{ 25762587Sitojun u_long totalkeys; 25862587Sitojun u_short hashbits; 25962587Sitojun u_short hash; 26062587Sitojun size_t newalloc; 26162587Sitojun symkey * sk; 262171259Sdelphij 263171259Sdelphij totalkeys = authnumkeys + authnumfreekeys; 264171259Sdelphij hashbits = auth_log2(totalkeys / 4) + 1; 265171259Sdelphij hashbits = max(4, hashbits); 26662587Sitojun hashbits = min(15, hashbits); 267171259Sdelphij 26862587Sitojun authhashbuckets = 1 << hashbits; 269183550Szec authhashmask = authhashbuckets - 1; 27062587Sitojun newalloc = authhashbuckets * sizeof(key_hash[0]); 271138184Sgnn 272121161Sume key_hash = erealloc(key_hash, newalloc); 27362587Sitojun memset(key_hash, '\0', newalloc); 27462587Sitojun 27562587Sitojun ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 276121343Sume hash = KEYHASH(sk->keyid); 27762587Sitojun LINK_SLIST(key_hash[hash], sk, hlink); 278181803Sbz ITER_DLIST_END() 27962587Sitojun} 280181803Sbz 281121161Sume 282120941Sume/* 283181803Sbz * allocsymkey - common code to allocate and link in symkey 284181803Sbz * 28562587Sitojun * secret must be allocated with a free-compatible allocator. It is 286121343Sume * owned by the referring symkey structure, and will be free()d by 28762587Sitojun * freesymkey(). 28862587Sitojun */ 28962587Sitojunstatic void 290171259Sdelphijallocsymkey( 29162587Sitojun symkey ** bucket, 292121343Sume keyid_t id, 293121343Sume u_short flags, 294181803Sbz u_short type, 295121343Sume u_long lifetime, 29662587Sitojun u_short secretsize, 297120856Sume u_char * secret, 29862587Sitojun KeyAccT * ka 29962587Sitojun ) 30062587Sitojun{ 301171259Sdelphij symkey * sk; 30262587Sitojun 303121343Sume if (authnumfreekeys < 1) 304121343Sume auth_moremem(-1); 305121161Sume UNLINK_HEAD_SLIST(sk, authfreekeys, llink.f); 306121161Sume DEBUG_ENSURE(sk != NULL); 307121161Sume sk->keyid = id; 308121161Sume sk->flags = flags; 309121161Sume sk->type = type; 310121161Sume sk->secretsize = secretsize; 311121161Sume sk->secret = secret; 312121343Sume sk->keyacclist = ka; 313121343Sume sk->lifetime = lifetime; 314121343Sume LINK_SLIST(*bucket, sk, hlink); 315121343Sume LINK_TAIL_DLIST(key_listhead, sk, llink); 316121343Sume authnumfreekeys--; 317181803Sbz authnumkeys++; 318121343Sume} 319121343Sume 32062587Sitojun 321148385Sume/* 322148385Sume * freesymkey - common code to remove a symkey and recycle its entry. 323148385Sume */ 324148385Sumestatic void 325148385Sumefreesymkey( 326148385Sume symkey * sk, 327148385Sume symkey ** bucket 328148385Sume ) 329148385Sume{ 330148385Sume symkey * unlinked; 331171259Sdelphij 332148385Sume if (sk->secret != NULL) { 333148385Sume memset(sk->secret, '\0', sk->secretsize); 334148385Sume free(sk->secret); 335148385Sume } 336148385Sume UNLINK_SLIST(unlinked, *bucket, sk, hlink, symkey); 337148385Sume DEBUG_ENSURE(sk == unlinked); 338148385Sume UNLINK_DLIST(sk, llink); 339148385Sume memset((char *)sk + offsetof(symkey, symkey_payload), '\0', 340148385Sume sizeof(*sk) - offsetof(symkey, symkey_payload)); 341148385Sume LINK_SLIST(authfreekeys, sk, llink.f); 342148385Sume authnumkeys--; 343148385Sume authnumfreekeys++; 344148385Sume} 345148385Sume 346148385Sume 347148385Sume/* 348181803Sbz * auth_findkey - find a key in the hash table 349148385Sume */ 350148385Sumestruct savekey * 351148385Sumeauth_findkey( 352148385Sume keyid_t id 353148385Sume ) 354148385Sume{ 355148385Sume symkey * sk; 356148385Sume 357148385Sume for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) { 358148385Sume if (id == sk->keyid) { 359148385Sume return sk; 360148385Sume } 361148385Sume } 362148385Sume 363148385Sume return NULL; 364148385Sume} 365148385Sume 366148385Sume 367171259Sdelphij/* 368148385Sume * auth_havekey - return TRUE if the key id is zero or known 369165118Sbz */ 370148385Sumeint 371148385Sumeauth_havekey( 372148385Sume keyid_t id 373148385Sume ) 374148385Sume{ 375165118Sbz symkey * sk; 376148385Sume 377148385Sume if (0 == id || cache_keyid == id) { 378148385Sume return TRUE; 379148385Sume } 380148385Sume 381148385Sume for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) { 382148385Sume if (id == sk->keyid) { 383148385Sume return TRUE; 384148385Sume } 385148385Sume } 386243382Sae 387148385Sume return FALSE; 388148385Sume} 389148385Sume 390148385Sume 391148385Sume/* 392148385Sume * authhavekey - return TRUE and cache the key, if zero or both known 393148385Sume * and trusted. 394148385Sume */ 395148385Sumeint 396148385Sumeauthhavekey( 397148385Sume keyid_t id 398148385Sume ) 399148385Sume{ 400148385Sume symkey * sk; 401148385Sume 402171259Sdelphij authkeylookups++; 403171259Sdelphij if (0 == id || cache_keyid == id) { 404148385Sume return TRUE; 405148385Sume } 406171259Sdelphij 407148385Sume /* 408148385Sume * Seach the bin for the key. If found and the key type 409148385Sume * is zero, somebody marked it trusted without specifying 410148396Sume * a key or key type. In this case consider the key missing. 411148385Sume */ 412243382Sae authkeyuncached++; 413148396Sume for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) { 414148396Sume if (id == sk->keyid) { 415148396Sume if (0 == sk->type) { 416148385Sume authkeynotfound++; 417148385Sume return FALSE; 418148385Sume } 419148385Sume break; 420148385Sume } 421148385Sume } 422148385Sume 423148385Sume /* 424148385Sume * If the key is not found, or if it is found but not trusted, 425148385Sume * the key is not considered found. 426148385Sume */ 427148385Sume if (NULL == sk) { 428148399Sume authkeynotfound++; 429243382Sae return FALSE; 430148385Sume } 431148399Sume if (!(KEY_TRUSTED & sk->flags)) { 432148385Sume authnokey++; 433148385Sume return FALSE; 434243382Sae } 435148385Sume 436148385Sume /* 437148385Sume * The key is found and trusted. Initialize the key cache. 438148385Sume */ 439148385Sume cache_keyid = sk->keyid; 440148385Sume cache_type = sk->type; 441148385Sume cache_flags = sk->flags; 442148385Sume cache_secret = sk->secret; 443148385Sume cache_secretsize = sk->secretsize; 444148385Sume cache_keyacclist = sk->keyacclist; 445148385Sume 446148385Sume return TRUE; 447148385Sume} 448148385Sume 449148385Sume 450148385Sume/* 451148385Sume * authtrust - declare a key to be trusted/untrusted 452148385Sume */ 453148385Sumevoid 454148385Sumeauthtrust( 455148385Sume keyid_t id, 456148385Sume u_long trust 457148385Sume ) 458148385Sume{ 459148385Sume symkey ** bucket; 460148385Sume symkey * sk; 461243382Sae u_long lifetime; 462148385Sume 463148385Sume /* 464148385Sume * Search bin for key; if it does not exist and is untrusted, 465148385Sume * forget it. 466148385Sume */ 467148385Sume bucket = &key_hash[KEYHASH(id)]; 468148385Sume for (sk = *bucket; sk != NULL; sk = sk->hlink) { 469148385Sume if (id == sk->keyid) 470148385Sume break; 471148385Sume } 472148385Sume if (!trust && NULL == sk) 473148385Sume return; 474148385Sume 475148385Sume /* 476148385Sume * There are two conditions remaining. Either it does not 477171259Sdelphij * exist and is to be trusted or it does exist and is or is 478148385Sume * not to be trusted. 479148385Sume */ 480148385Sume if (sk != NULL) { 481148385Sume if (cache_keyid == id) { 482148385Sume cache_flags = 0; 483148385Sume cache_keyid = 0; 484148385Sume cache_keyacclist = NULL; 485148385Sume } 486148385Sume 487148385Sume /* 488148385Sume * Key exists. If it is to be trusted, say so and 489238224Sbz * update its lifetime. 490238224Sbz */ 491238224Sbz if (trust > 0) { 492238224Sbz sk->flags |= KEY_TRUSTED; 493238224Sbz if (trust > 1) 494238224Sbz sk->lifetime = current_time + trust; 495238224Sbz else 496238224Sbz sk->lifetime = 0; 497238224Sbz return; 498238224Sbz } 499238224Sbz 500238224Sbz /* No longer trusted, return it to the free list. */ 501238224Sbz freesymkey(sk, bucket); 502 return; 503 } 504 505 /* 506 * keyid is not present, but the is to be trusted. We allocate 507 * a new key, but do not specify a key type or secret. 508 */ 509 if (trust > 1) { 510 lifetime = current_time + trust; 511 } else { 512 lifetime = 0; 513 } 514 allocsymkey(bucket, id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL); 515} 516 517 518/* 519 * authistrusted - determine whether a key is trusted 520 */ 521int 522authistrusted( 523 keyid_t keyno 524 ) 525{ 526 symkey * sk; 527 symkey ** bucket; 528 529 if (keyno == cache_keyid) 530 return !!(KEY_TRUSTED & cache_flags); 531 532 authkeyuncached++; 533 bucket = &key_hash[KEYHASH(keyno)]; 534 for (sk = *bucket; sk != NULL; sk = sk->hlink) { 535 if (keyno == sk->keyid) 536 break; 537 } 538 if (NULL == sk || !(KEY_TRUSTED & sk->flags)) { 539 authkeynotfound++; 540 return FALSE; 541 } 542 return TRUE; 543} 544 545 546/* 547 * authistrustedip - determine if the IP is OK for the keyid 548 */ 549 int 550 authistrustedip( 551 keyid_t keyno, 552 sockaddr_u * sau 553 ) 554{ 555 symkey * sk; 556 symkey ** bucket; 557 KeyAccT * kal; 558 KeyAccT * k; 559 560 if (keyno == cache_keyid) 561 kal = cache_keyacclist; 562 else { 563 authkeyuncached++; 564 bucket = &key_hash[KEYHASH(keyno)]; 565 for (sk = *bucket; sk != NULL; sk = sk->hlink) { 566 if (keyno == sk->keyid) 567 break; 568 } 569 if (NULL == sk || !(KEY_TRUSTED & sk->flags)) { 570 INSIST(!"authistrustedip: keyid not found/trusted!"); 571 return FALSE; 572 } 573 kal = sk->keyacclist; 574 } 575 576 if (NULL == kal) 577 return TRUE; 578 579 for (k = kal; k; k = k->next) { 580 if (SOCK_EQ(&k->addr, sau)) 581 return TRUE; 582 } 583 584 return FALSE; 585} 586 587 588/* Note: There are two locations below where 'strncpy()' is used. While 589 * this function is a hazard by itself, it's essential that it is used 590 * here. Bug 1243 involved that the secret was filled with NUL bytes 591 * after the first NUL encountered, and 'strlcpy()' simply does NOT have 592 * this behaviour. So disabling the fix and reverting to the buggy 593 * behaviour due to compatibility issues MUST also fill with NUL and 594 * this needs 'strncpy'. Also, the secret is managed as a byte blob of a 595 * given size, and eventually truncating it and replacing the last byte 596 * with a NUL would be a bug. 597 * perlinger@ntp.org 2015-10-10 598 */ 599void 600MD5auth_setkey( 601 keyid_t keyno, 602 int keytype, 603 const u_char *key, 604 size_t len, 605 KeyAccT *ka 606 ) 607{ 608 symkey * sk; 609 symkey ** bucket; 610 u_char * secret; 611 size_t secretsize; 612 613 DEBUG_ENSURE(keytype <= USHRT_MAX); 614 DEBUG_ENSURE(len < 4 * 1024); 615 /* 616 * See if we already have the key. If so just stick in the 617 * new value. 618 */ 619 bucket = &key_hash[KEYHASH(keyno)]; 620 for (sk = *bucket; sk != NULL; sk = sk->hlink) { 621 if (keyno == sk->keyid) { 622 /* TALOS-CAN-0054: make sure we have a new buffer! */ 623 if (NULL != sk->secret) { 624 memset(sk->secret, 0, sk->secretsize); 625 free(sk->secret); 626 } 627 sk->secret = emalloc(len); 628 sk->type = (u_short)keytype; 629 secretsize = len; 630 sk->secretsize = (u_short)secretsize; 631 sk->keyacclist = ka; 632#ifndef DISABLE_BUG1243_FIX 633 memcpy(sk->secret, key, secretsize); 634#else 635 /* >MUST< use 'strncpy()' here! See above! */ 636 strncpy((char *)sk->secret, (const char *)key, 637 secretsize); 638#endif 639 if (cache_keyid == keyno) { 640 cache_flags = 0; 641 cache_keyid = 0; 642 cache_keyacclist = NULL; 643 } 644 return; 645 } 646 } 647 648 /* 649 * Need to allocate new structure. Do it. 650 */ 651 secretsize = len; 652 secret = emalloc(secretsize); 653#ifndef DISABLE_BUG1243_FIX 654 memcpy(secret, key, secretsize); 655#else 656 /* >MUST< use 'strncpy()' here! See above! */ 657 strncpy((char *)secret, (const char *)key, secretsize); 658#endif 659 allocsymkey(bucket, keyno, 0, (u_short)keytype, 0, 660 (u_short)secretsize, secret, ka); 661#ifdef DEBUG 662 if (debug >= 4) { 663 size_t j; 664 665 printf("auth_setkey: key %d type %d len %d ", (int)keyno, 666 keytype, (int)secretsize); 667 for (j = 0; j < secretsize; j++) 668 printf("%02x", secret[j]); 669 printf("\n"); 670 } 671#endif 672} 673 674 675/* 676 * auth_delkeys - delete non-autokey untrusted keys, and clear all info 677 * except the trusted bit of non-autokey trusted keys, in 678 * preparation for rereading the keys file. 679 */ 680void 681auth_delkeys(void) 682{ 683 symkey * sk; 684 685 ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 686 if (sk->keyid > NTP_MAXKEY) { /* autokey */ 687 continue; 688 } 689 690 /* 691 * Don't lose info as to which keys are trusted. Make 692 * sure there are no dangling pointers! 693 */ 694 if (KEY_TRUSTED & sk->flags) { 695 if (sk->secret != NULL) { 696 memset(sk->secret, 0, sk->secretsize); 697 free(sk->secret); 698 sk->secret = NULL; /* TALOS-CAN-0054 */ 699 } 700 sk->secretsize = 0; 701 sk->lifetime = 0; 702 } else { 703 freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]); 704 } 705 ITER_DLIST_END() 706} 707 708 709/* 710 * auth_agekeys - delete keys whose lifetimes have expired 711 */ 712void 713auth_agekeys(void) 714{ 715 symkey * sk; 716 717 ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 718 if (sk->lifetime > 0 && current_time > sk->lifetime) { 719 freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]); 720 authkeyexpired++; 721 } 722 ITER_DLIST_END() 723 DPRINTF(1, ("auth_agekeys: at %lu keys %lu expired %lu\n", 724 current_time, authnumkeys, authkeyexpired)); 725} 726 727 728/* 729 * authencrypt - generate message authenticator 730 * 731 * Returns length of authenticator field, zero if key not found. 732 */ 733size_t 734authencrypt( 735 keyid_t keyno, 736 u_int32 * pkt, 737 size_t length 738 ) 739{ 740 /* 741 * A zero key identifier means the sender has not verified 742 * the last message was correctly authenticated. The MAC 743 * consists of a single word with value zero. 744 */ 745 authencryptions++; 746 pkt[length / 4] = htonl(keyno); 747 if (0 == keyno) { 748 return 4; 749 } 750 if (!authhavekey(keyno)) { 751 return 0; 752 } 753 754 return MD5authencrypt(cache_type, cache_secret, pkt, length); 755} 756 757 758/* 759 * authdecrypt - verify message authenticator 760 * 761 * Returns TRUE if authenticator valid, FALSE if invalid or not found. 762 */ 763int 764authdecrypt( 765 keyid_t keyno, 766 u_int32 * pkt, 767 size_t length, 768 size_t size 769 ) 770{ 771 /* 772 * A zero key identifier means the sender has not verified 773 * the last message was correctly authenticated. For our 774 * purpose this is an invalid authenticator. 775 */ 776 authdecryptions++; 777 if (0 == keyno || !authhavekey(keyno) || size < 4) { 778 return FALSE; 779 } 780 781 return MD5authdecrypt(cache_type, cache_secret, pkt, length, 782 size); 783} 784