2 * authkeys.c - routines to manage the storage of authentication keys
11 #include "ntp_types.h"
15 #include "ntp_string.h"
16 #include "ntp_malloc.h"
17 #include "ntp_stdlib.h"
20 * Structure to store keys in in the hash table.
25 long bogon; /* Make sure nonempty */
26 u_char MD5_key[32]; /* MD5 key */
28 keyid_t keyid; /* key identifier */
29 u_short flags; /* flags that wave */
30 u_long lifetime; /* remaining lifetime */
31 int keylen; /* key length */
34 #define KEY_TRUSTED 0x001 /* this key is trusted */
35 #define KEY_MD5 0x200 /* this is a MD5 type key */
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.
42 #define HASHMASK ((HASHSIZE)-1)
43 #define KEYHASH(keyid) ((keyid) & HASHMASK)
45 struct savekey *key_hash[HASHSIZE];
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 */
57 * Storage for free key structures. We malloc() such things but
60 struct savekey *authfreekeys;
63 #define MEMINC 12 /* number of new free ones to get */
66 * The key cache. We cache the last key we looked at here.
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 */
75 * init_auth - initialize internal data
81 * Initialize hash table and free list
83 memset((char *)key_hash, 0, sizeof key_hash);
88 * auth_findkey - find a key in the hash table
97 sk = key_hash[KEYHASH(keyno)];
99 if (keyno == sk->keyid)
109 * auth_havekey - return one if the key is known
118 if (keyno == 0 || (keyno == cache_keyid))
121 sk = key_hash[KEYHASH(keyno)];
123 if (keyno == sk->keyid)
133 * authhavekey - return one and cache the key, if known and trusted.
143 if (keyno == 0 || keyno == cache_keyid)
147 sk = key_hash[KEYHASH(keyno)];
149 if (keyno == sk->keyid)
156 } else if (!(sk->flags & KEY_TRUSTED)) {
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;
172 * auth_moremem - get some more free key structures
180 sk = (struct savekey *)calloc(MEMINC, sizeof(struct savekey));
184 for (i = MEMINC; i > 0; i--) {
185 sk->next = authfreekeys;
188 authnumfreekeys += MEMINC;
189 return (authnumfreekeys);
194 * authtrust - declare a key to be trusted/untrusted
206 printf("authtrust: keyid %08x life %lu\n", keyno, trust);
208 sk = key_hash[KEYHASH(keyno)];
210 if (keyno == sk->keyid)
215 if (sk == 0 && !trust)
219 if (cache_keyid == keyno) {
225 sk->flags |= KEY_TRUSTED;
227 sk->lifetime = current_time + trust;
233 sk->flags &= ~KEY_TRUSTED; {
236 skp = key_hash[KEYHASH(keyno)];
238 key_hash[KEYHASH(keyno)] = sk->next;
240 while (skp->next != sk)
242 skp->next = sk->next;
246 sk->next = authfreekeys;
253 if (authnumfreekeys == 0)
254 if (auth_moremem() == 0)
258 authfreekeys = sk->next;
262 sk->flags = KEY_TRUSTED;
263 sk->next = key_hash[KEYHASH(keyno)];
264 key_hash[KEYHASH(keyno)] = sk;
271 * authistrusted - determine whether a key is trusted
280 if (keyno == cache_keyid)
281 return ((cache_flags & KEY_TRUSTED) != 0);
284 sk = key_hash[KEYHASH(keyno)];
286 if (keyno == sk->keyid)
293 } else if (!(sk->flags & KEY_TRUSTED)) {
311 * See if we already have the key. If so just stick in the
314 sk = key_hash[KEYHASH(keyno)];
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);
322 sk->flags |= KEY_MD5;
323 if (cache_keyid == keyno) {
333 * Need to allocate new structure. Do it.
335 if (authnumfreekeys == 0) {
336 if (auth_moremem() == 0)
341 authfreekeys = sk->next;
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);
352 sk->next = key_hash[KEYHASH(keyno)];
353 key_hash[KEYHASH(keyno)] = sk;
359 * auth_delkeys - delete all known keys, in preparation for rereading
360 * the keys file (presumably)
366 struct savekey **skp;
369 for (i = 0; i < HASHSIZE; i++) {
370 skp = &(key_hash[i]);
373 * Leave autokey keys alone.
375 while (sk != 0 && sk->keyid <= NTP_MAXKEY) {
377 * Don't lose info as to which keys are trusted.
379 if (sk->flags & KEY_TRUSTED) {
381 memset(&sk->k, 0, sizeof(sk->k));
388 sk->next = authfreekeys;
398 * auth_agekeys - delete keys whose lifetimes have expired
407 for (i = 0; i < HASHSIZE; i++) {
408 sk = skp = key_hash[i];
411 if (sk->lifetime > 0 && current_time >
413 authtrust(sk->keyid, 0);
421 printf("auth_agekeys: at %lu keys %lu expired %lu\n",
422 current_time, authnumkeys, authkeyexpired);
427 * authencrypt - generate message authenticator
429 * Returns length of authenticator field, zero if key not found.
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.
445 pkt[length / 4] = htonl(keyno);
449 if (!authhavekey(keyno))
452 if (cache_flags & KEY_MD5)
453 return (MD5authencrypt(cache_key, pkt, length));
459 * authdecrypt - verify message authenticator
461 * Returns one if authenticator valid, zero if invalid or key not found.
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.
481 if (!authhavekey(keyno) || size < 4)
484 if (cache_flags & KEY_MD5)
485 return (MD5authdecrypt(cache_key, pkt, length, size));