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