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 <stdio.h> 9 10#include "ntp_types.h" 11#include "ntp_fp.h" 12#include "ntp.h" 13#include "ntpd.h" 14#include "ntp_string.h" 15#include "ntp_malloc.h" 16#include "ntp_stdlib.h" 17 18/* 19 * Structure to store keys in in the hash table. 20 */ 21struct savekey { 22 struct savekey *next; 23 union { 24 u_char MD5_key[64]; /* for keys up to to 512 bits */ 25 } k; 26 keyid_t keyid; /* key identifier */ 27 int type; /* key type */ 28 u_short flags; /* flags that wave */ 29 u_long lifetime; /* remaining lifetime */ 30 int keylen; /* key length */ 31}; 32 33#define KEY_TRUSTED 0x001 /* this key is trusted */ 34 35/* 36 * The hash table. This is indexed by the low order bits of the 37 * keyid. We make this fairly big for potentially busy servers. 38 */ 39#define HASHSIZE 64 40#define HASHMASK ((HASHSIZE)-1) 41#define KEYHASH(keyid) ((keyid) & HASHMASK) 42 43struct savekey *key_hash[HASHSIZE]; 44 45u_long authkeynotfound; /* keys not found */ 46u_long authkeylookups; /* calls to lookup keys */ 47u_long authnumkeys; /* number of active keys */ 48u_long authkeyexpired; /* key lifetime expirations */ 49u_long authkeyuncached; /* cache misses */ 50u_long authnokey; /* calls to encrypt with no key */ 51u_long authencryptions; /* calls to encrypt */ 52u_long authdecryptions; /* calls to decrypt */ 53 54/* 55 * Storage for free key structures. We malloc() such things but 56 * never free them. 57 */ 58struct savekey *authfreekeys; 59int authnumfreekeys; 60 61#define MEMINC 12 /* number of new free ones to get */ 62 63/* 64 * The key cache. We cache the last key we looked at here. 65 */ 66keyid_t cache_keyid; /* key identifier */ 67u_char *cache_key; /* key pointer */ 68u_int cache_keylen; /* key length */ 69int cache_type; /* key type */ 70u_short cache_flags; /* flags that wave */ 71 72 73/* 74 * init_auth - initialize internal data 75 */ 76void 77init_auth(void) 78{ 79 /* 80 * Initialize hash table and free list 81 */ 82 memset((char *)key_hash, 0, sizeof key_hash); 83} 84 85 86/* 87 * auth_findkey - find a key in the hash table 88 */ 89struct savekey * 90auth_findkey( 91 keyid_t keyno 92 ) 93{ 94 struct savekey *sk; 95 96 sk = key_hash[KEYHASH(keyno)]; 97 while (sk != 0) { 98 if (keyno == sk->keyid) 99 return (sk); 100 101 sk = sk->next; 102 } 103 return (0); 104} 105 106 107/* 108 * auth_havekey - return one if the key is known 109 */ 110int 111auth_havekey( 112 keyid_t keyno 113 ) 114{ 115 struct savekey *sk; 116 117 if (keyno == 0 || (keyno == cache_keyid)) 118 return (1); 119 120 sk = key_hash[KEYHASH(keyno)]; 121 while (sk != 0) { 122 if (keyno == sk->keyid) 123 return (1); 124 125 sk = sk->next; 126 } 127 return (0); 128} 129 130 131/* 132 * authhavekey - return one and cache the key, if known and trusted. 133 */ 134int 135authhavekey( 136 keyid_t keyno 137 ) 138{ 139 struct savekey *sk; 140 141 authkeylookups++; 142 if (keyno == 0 || keyno == cache_keyid) 143 return (1); 144 145 /* 146 * Seach the bin for the key. If found and the key type 147 * is zero, somebody marked it trusted without specifying 148 * a key or key type. In this case consider the key missing. 149 */ 150 authkeyuncached++; 151 sk = key_hash[KEYHASH(keyno)]; 152 while (sk != NULL) { 153 if (keyno == sk->keyid) { 154 if (sk->type == 0) { 155 authkeynotfound++; 156 return (0); 157 } 158 break; 159 } 160 sk = sk->next; 161 } 162 163 /* 164 * If the key is not found, or if it is found but not trusted, 165 * the key is not considered found. 166 */ 167 if (sk == NULL) { 168 authkeynotfound++; 169 return (0); 170 171 } 172 if (!(sk->flags & KEY_TRUSTED)) { 173 authnokey++; 174 return (0); 175 } 176 177 /* 178 * The key is found and trusted. Initialize the key cache. 179 */ 180 cache_keyid = sk->keyid; 181 cache_type = sk->type; 182 cache_flags = sk->flags; 183 cache_key = sk->k.MD5_key; 184 cache_keylen = sk->keylen; 185 return (1); 186} 187 188 189/* 190 * auth_moremem - get some more free key structures 191 */ 192int 193auth_moremem(void) 194{ 195 struct savekey *sk; 196 int i; 197 198 sk = (struct savekey *)calloc(MEMINC, sizeof(struct savekey)); 199 if (sk == 0) 200 return (0); 201 202 for (i = MEMINC; i > 0; i--) { 203 sk->next = authfreekeys; 204 authfreekeys = sk++; 205 } 206 authnumfreekeys += MEMINC; 207 return (authnumfreekeys); 208} 209 210 211/* 212 * authtrust - declare a key to be trusted/untrusted 213 */ 214void 215authtrust( 216 keyid_t keyno, 217 u_long trust 218 ) 219{ 220 struct savekey *sk; 221 222 /* 223 * Search bin for key; if it does not exist and is untrusted, 224 * forget it. 225 */ 226 sk = key_hash[KEYHASH(keyno)]; 227 while (sk != 0) { 228 if (keyno == sk->keyid) 229 break; 230 231 sk = sk->next; 232 } 233 if (sk == 0 && !trust) 234 return; 235 236 /* 237 * There are two conditions remaining. Either it does not 238 * exist and is to be trusted or it does exist and is or is 239 * not to be trusted. 240 */ 241 if (sk != 0) { 242 if (cache_keyid == keyno) { 243 cache_flags = 0; 244 cache_keyid = 0; 245 } 246 247 /* 248 * Key exists. If it is to be trusted, say so and 249 * update its lifetime. If not, return it to the 250 * free list. 251 */ 252 if (trust > 0) { 253 sk->flags |= KEY_TRUSTED; 254 if (trust > 1) 255 sk->lifetime = current_time + trust; 256 else 257 sk->lifetime = 0; 258 return; 259 } 260 sk->flags &= ~KEY_TRUSTED; { 261 struct savekey *skp; 262 263 skp = key_hash[KEYHASH(keyno)]; 264 if (skp == sk) { 265 key_hash[KEYHASH(keyno)] = sk->next; 266 } else { 267 while (skp->next != sk) 268 skp = skp->next; 269 skp->next = sk->next; 270 } 271 authnumkeys--; 272 273 sk->next = authfreekeys; 274 authfreekeys = sk; 275 authnumfreekeys++; 276 } 277 return; 278 } 279 280 /* 281 * Here there is not key, but the key is to be trusted. There 282 * seems to be a disconnect here. Here we allocate a new key, 283 * but do not specify a key type, key or key length. 284 */ 285 if (authnumfreekeys == 0) 286 if (auth_moremem() == 0) 287 return; 288 289 sk = authfreekeys; 290 authfreekeys = sk->next; 291 authnumfreekeys--; 292 sk->keyid = keyno; 293 sk->type = 0; 294 sk->keylen = 0; 295 sk->flags = KEY_TRUSTED; 296 sk->next = key_hash[KEYHASH(keyno)]; 297 key_hash[KEYHASH(keyno)] = sk; 298 authnumkeys++; 299 return; 300} 301 302 303/* 304 * authistrusted - determine whether a key is trusted 305 */ 306int 307authistrusted( 308 keyid_t keyno 309 ) 310{ 311 struct savekey *sk; 312 313 if (keyno == cache_keyid) 314 return ((cache_flags & KEY_TRUSTED) != 0); 315 316 authkeyuncached++; 317 sk = key_hash[KEYHASH(keyno)]; 318 while (sk != 0) { 319 if (keyno == sk->keyid) 320 break; 321 sk = sk->next; 322 } 323 if (sk == 0) { 324 authkeynotfound++; 325 return (0); 326 327 } else if (!(sk->flags & KEY_TRUSTED)) { 328 authkeynotfound++; 329 return (0); 330 } 331 return (1); 332} 333 334 335void 336MD5auth_setkey( 337 keyid_t keyno, 338 int keytype, 339 const u_char *key, 340 const int len 341 ) 342{ 343 struct savekey *sk; 344 345 /* 346 * See if we already have the key. If so just stick in the 347 * new value. 348 */ 349 sk = key_hash[KEYHASH(keyno)]; 350 while (sk != NULL) { 351 if (keyno == sk->keyid) { 352 sk->type = keytype; 353 sk->keylen = min(len, sizeof(sk->k.MD5_key)); 354#ifndef DISABLE_BUG1243_FIX 355 memcpy(sk->k.MD5_key, key, sk->keylen); 356#else 357 strncpy((char *)sk->k.MD5_key, (const char *)key, 358 sizeof(sk->k.MD5_key)); 359#endif 360 if (cache_keyid == keyno) { 361 cache_flags = 0; 362 cache_keyid = 0; 363 } 364 return; 365 } 366 sk = sk->next; 367 } 368 369 /* 370 * Need to allocate new structure. Do it. 371 */ 372 if (0 == authnumfreekeys && !auth_moremem()) 373 return; 374 375 sk = authfreekeys; 376 authfreekeys = sk->next; 377 authnumfreekeys--; 378 379 sk->keyid = keyno; 380 sk->type = keytype; 381 sk->flags = 0; 382 sk->lifetime = 0; 383 sk->keylen = min(len, sizeof(sk->k.MD5_key)); 384#ifndef DISABLE_BUG1243_FIX 385 memcpy(sk->k.MD5_key, key, sk->keylen); 386#else 387 strncpy((char *)sk->k.MD5_key, (const char *)key, 388 sizeof(sk->k.MD5_key)); 389#endif 390 sk->next = key_hash[KEYHASH(keyno)]; 391 key_hash[KEYHASH(keyno)] = sk; 392#ifdef DEBUG 393 if (debug > 1) { 394 char hex[] = "0123456789abcdef"; 395 int j; 396 397 printf("auth_setkey: key %d type %d len %d ", sk->keyid, 398 sk->type, sk->keylen); 399 for (j = 0; j < sk->keylen; j++) 400 printf("%c%c", hex[key[j] >> 4], 401 hex[key[j] & 0xf]); 402 printf("\n"); 403 } 404#endif 405 authnumkeys++; 406} 407 408 409/* 410 * auth_delkeys - delete all known keys, in preparation for rereading 411 * the keys file (presumably) 412 */ 413void 414auth_delkeys(void) 415{ 416 struct savekey *sk; 417 struct savekey **skp; 418 int i; 419 420 for (i = 0; i < HASHSIZE; i++) { 421 skp = &(key_hash[i]); 422 sk = key_hash[i]; 423 /* 424 * Leave autokey keys alone. 425 */ 426 while (sk != 0 && sk->keyid <= NTP_MAXKEY) { 427 /* 428 * Don't lose info as to which keys are trusted. 429 */ 430 if (sk->flags & KEY_TRUSTED) { 431 skp = &(sk->next); 432 memset(&sk->k, 0, sizeof(sk->k)); 433 sk->lifetime = 0; 434 sk->keylen = 0; 435 sk = sk->next; 436 } else { 437 *skp = sk->next; 438 authnumkeys--; 439 sk->next = authfreekeys; 440 authfreekeys = sk; 441 authnumfreekeys++; 442 sk = *skp; 443 } 444 } 445 } 446} 447 448/* 449 * auth_agekeys - delete keys whose lifetimes have expired 450 */ 451void 452auth_agekeys(void) 453{ 454 struct savekey *sk; 455 struct savekey *skp; 456 int i; 457 458 for (i = 0; i < HASHSIZE; i++) { 459 sk = skp = key_hash[i]; 460 while (sk != 0) { 461 skp = sk->next; 462 if (sk->lifetime > 0 && current_time > 463 sk->lifetime) { 464 authtrust(sk->keyid, 0); 465 authkeyexpired++; 466 } 467 sk = skp; 468 } 469 } 470#ifdef DEBUG 471 if (debug) 472 printf("auth_agekeys: at %lu keys %lu expired %lu\n", 473 current_time, authnumkeys, authkeyexpired); 474#endif 475} 476 477/* 478 * authencrypt - generate message authenticator 479 * 480 * Returns length of authenticator field, zero if key not found. 481 */ 482int 483authencrypt( 484 keyid_t keyno, 485 u_int32 *pkt, 486 int length 487 ) 488{ 489 490 /* 491 * A zero key identifier means the sender has not verified 492 * the last message was correctly authenticated. The MAC 493 * consists of a single word with value zero. 494 */ 495 authencryptions++; 496 pkt[length / 4] = htonl(keyno); 497 if (keyno == 0) { 498 return (4); 499 } 500 if (!authhavekey(keyno)) 501 return (0); 502 503 return (MD5authencrypt(cache_type, cache_key, pkt, length)); 504} 505 506/* 507 * authdecrypt - verify message authenticator 508 * 509 * Returns one if authenticator valid, zero if invalid or key not found. 510 */ 511int 512authdecrypt( 513 keyid_t keyno, 514 u_int32 *pkt, 515 int length, 516 int size 517 ) 518{ 519 520 /* 521 * A zero key identifier means the sender has not verified 522 * the last message was correctly authenticated. Nevertheless, 523 * the authenticator itself is considered valid. 524 */ 525 authdecryptions++; 526 if (keyno == 0) 527 return (0); 528 529 if (!authhavekey(keyno) || size < 4) 530 return (0); 531 532 return (MD5authdecrypt(cache_type, cache_key, pkt, length, 533 size)); 534} 535