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