xref: /freebsd/contrib/ntp/libntp/authkeys.c (revision a4e5e0106ac7145f56eb39a691e302cabb4635be)
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 <math.h>
9 #include <stdio.h>
10 
11 #include "ntp.h"
12 #include "ntp_fp.h"
13 #include "ntpd.h"
14 #include "ntp_lists.h"
15 #include "ntp_string.h"
16 #include "ntp_malloc.h"
17 #include "ntp_stdlib.h"
18 #include "ntp_keyacc.h"
19 
20 /*
21  * Structure to store keys in in the hash table.
22  */
23 typedef struct savekey symkey;
24 
25 struct savekey {
26 	symkey *	hlink;		/* next in hash bucket */
27 	DECL_DLIST_LINK(symkey, llink);	/* for overall & free lists */
28 	u_char *	secret;		/* shared secret */
29 	KeyAccT *	keyacclist;	/* Private key access list */
30 	u_long		lifetime;	/* remaining lifetime */
31 	keyid_t		keyid;		/* key identifier */
32 	u_short		type;		/* OpenSSL digest NID */
33 	size_t		secretsize;	/* secret octets */
34 	u_short		flags;		/* KEY_ flags that wave */
35 };
36 
37 /* define the payload region of symkey beyond the list pointers */
38 #define symkey_payload	secret
39 
40 #define	KEY_TRUSTED	0x001	/* this key is trusted */
41 
42 #ifdef DEBUG
43 typedef struct symkey_alloc_tag symkey_alloc;
44 
45 struct symkey_alloc_tag {
46 	symkey_alloc *	link;
47 	void *		mem;		/* enable free() atexit */
48 };
49 
50 symkey_alloc *	authallocs;
51 #endif	/* DEBUG */
52 
53 static u_short	auth_log2(size_t);
54 static void		auth_resize_hashtable(void);
55 static void		allocsymkey(keyid_t,	u_short,
56 				    u_short, u_long, size_t, u_char *, KeyAccT *);
57 static void		freesymkey(symkey *);
58 #ifdef DEBUG
59 static void		free_auth_mem(void);
60 #endif
61 
62 symkey	key_listhead;		/* list of all in-use keys */;
63 /*
64  * The hash table. This is indexed by the low order bits of the
65  * keyid. We make this fairly big for potentially busy servers.
66  */
67 #define	DEF_AUTHHASHSIZE	64
68 /*#define	HASHMASK	((HASHSIZE)-1)*/
69 #define	KEYHASH(keyid)	((keyid) & authhashmask)
70 
71 int	authhashdisabled;
72 u_short	authhashbuckets = DEF_AUTHHASHSIZE;
73 u_short authhashmask = DEF_AUTHHASHSIZE - 1;
74 symkey **key_hash;
75 
76 u_long authkeynotfound;		/* keys not found */
77 u_long authkeylookups;		/* calls to lookup keys */
78 u_long authnumkeys;		/* number of active keys */
79 u_long authkeyexpired;		/* key lifetime expirations */
80 u_long authkeyuncached;		/* cache misses */
81 u_long authnokey;		/* calls to encrypt with no key */
82 u_long authencryptions;		/* calls to encrypt */
83 u_long authdecryptions;		/* calls to decrypt */
84 
85 /*
86  * Storage for free symkey structures.  We malloc() such things but
87  * never free them.
88  */
89 symkey *authfreekeys;
90 int authnumfreekeys;
91 
92 #define	MEMINC	16		/* number of new free ones to get */
93 
94 /*
95  * The key cache. We cache the last key we looked at here.
96  * Note: this should hold the last *trusted* key. Also the
97  * cache is only loaded when the digest type / MAC algorithm
98  * is valid.
99  */
100 keyid_t	cache_keyid;		/* key identifier */
101 u_char *cache_secret;		/* secret */
102 size_t	cache_secretsize;	/* secret length */
103 int	cache_type;		/* OpenSSL digest NID */
104 u_short cache_flags;		/* flags that wave */
105 KeyAccT *cache_keyacclist;	/* key access list */
106 
107 /* --------------------------------------------------------------------
108  * manage key access lists
109  * --------------------------------------------------------------------
110  */
111 /* allocate and populate new access node and pushes it on the list.
112  * Returns the new head.
113  */
114 KeyAccT*
115 keyacc_new_push(
116 	KeyAccT          * head,
117 	const sockaddr_u * addr,
118 	unsigned int	   subnetbits
119 	)
120 {
121 	KeyAccT *	node = emalloc(sizeof(KeyAccT));
122 
123 	memcpy(&node->addr, addr, sizeof(sockaddr_u));
124 	node->subnetbits = subnetbits;
125 	node->next = head;
126 
127 	return node;
128 }
129 
130 /* ----------------------------------------------------------------- */
131 /* pop and deallocate the first node of a list of access nodes, if
132  * the list is not empty. Returns the tail of the list.
133  */
134 KeyAccT*
135 keyacc_pop_free(
136 	KeyAccT *head
137 	)
138 {
139 	KeyAccT *	next = NULL;
140 	if (head) {
141 		next = head->next;
142 		free(head);
143 	}
144 	return next;
145 }
146 
147 /* ----------------------------------------------------------------- */
148 /* deallocate the list; returns an empty list. */
149 KeyAccT*
150 keyacc_all_free(
151 	KeyAccT * head
152 	)
153 {
154 	while (head)
155 		head = keyacc_pop_free(head);
156 	return head;
157 }
158 
159 /* ----------------------------------------------------------------- */
160 /* scan a list to see if it contains a given address. Return the
161  * default result value in case of an empty list.
162  */
163 int /*BOOL*/
164 keyacc_contains(
165 	const KeyAccT    *head,
166 	const sockaddr_u *addr,
167 	int               defv)
168 {
169 	if (head) {
170 		do {
171 			if (keyacc_amatch(&head->addr, addr,
172 					  head->subnetbits))
173 				return TRUE;
174 		} while (NULL != (head = head->next));
175 		return FALSE;
176 	} else {
177 		return !!defv;
178 	}
179 }
180 
181 #if CHAR_BIT != 8
182 # error "don't know how to handle bytes with that bit size"
183 #endif
184 
185 /* ----------------------------------------------------------------- */
186 /* check two addresses for a match, taking a prefix length into account
187  * when doing the compare.
188  *
189  * The ISC lib contains a similar function with not entirely specified
190  * semantics, so it seemed somewhat cleaner to do this from scratch.
191  *
192  * Note 1: It *is* assumed that the addresses are stored in network byte
193  * order, that is, most significant byte first!
194  *
195  * Note 2: "no address" compares unequal to all other addresses, even to
196  * itself. This has the same semantics as NaNs have for floats: *any*
197  * relational or equality operation involving a NaN returns FALSE, even
198  * equality with itself. "no address" is either a NULL pointer argument
199  * or an address of type AF_UNSPEC.
200  */
201 int/*BOOL*/
202 keyacc_amatch(
203 	const sockaddr_u *	a1,
204 	const sockaddr_u *	a2,
205 	unsigned int		mbits
206 	)
207 {
208 	const uint8_t * pm1;
209 	const uint8_t * pm2;
210 	uint8_t         msk;
211 	unsigned int    len;
212 
213 	/* 1st check: If any address is not an address, it's inequal. */
214 	if ( !a1 || (AF_UNSPEC == AF(a1)) ||
215 	     !a2 || (AF_UNSPEC == AF(a2))  )
216 		return FALSE;
217 
218 	/* We could check pointers for equality here and shortcut the
219 	 * other checks if we find object identity. But that use case is
220 	 * too rare to care for it.
221 	 */
222 
223 	/* 2nd check: Address families must be the same. */
224 	if (AF(a1) != AF(a2))
225 		return FALSE;
226 
227 	/* type check: address family determines buffer & size */
228 	switch (AF(a1)) {
229 	case AF_INET:
230 		/* IPv4 is easy: clamp size, get byte pointers */
231 		if (mbits > sizeof(NSRCADR(a1)) * 8)
232 			mbits = sizeof(NSRCADR(a1)) * 8;
233 		pm1 = (const void*)&NSRCADR(a1);
234 		pm2 = (const void*)&NSRCADR(a2);
235 		break;
236 
237 	case AF_INET6:
238 		/* IPv6 is slightly different: Both scopes must match,
239 		 * too, before we even consider doing a match!
240 		 */
241 		if ( ! SCOPE_EQ(a1, a2))
242 			return FALSE;
243 		if (mbits > sizeof(NSRCADR6(a1)) * 8)
244 			mbits = sizeof(NSRCADR6(a1)) * 8;
245 		pm1 = (const void*)&NSRCADR6(a1);
246 		pm2 = (const void*)&NSRCADR6(a2);
247 		break;
248 
249 	default:
250 		/* don't know how to compare that!?! */
251 		return FALSE;
252 	}
253 
254 	/* Split bit length into byte length and partial byte mask.
255 	 * Note that the byte mask extends from the MSB of a byte down,
256 	 * and that zero shift (--> mbits % 8 == 0) results in an
257 	 * all-zero mask.
258 	 */
259 	msk = 0xFFu ^ (0xFFu >> (mbits & 7));
260 	len = mbits >> 3;
261 
262 	/* 3rd check: Do memcmp() over full bytes, if any */
263 	if (len && memcmp(pm1, pm2, len))
264 		return FALSE;
265 
266 	/* 4th check: compare last incomplete byte, if any */
267 	if (msk && ((pm1[len] ^ pm2[len]) & msk))
268 		return FALSE;
269 
270 	/* If none of the above failed, we're successfully through. */
271 	return TRUE;
272 }
273 
274 /*
275  * init_auth - initialize internal data
276  */
277 void
278 init_auth(void)
279 {
280 	size_t newalloc;
281 
282 	/*
283 	 * Initialize hash table and free list
284 	 */
285 	newalloc = authhashbuckets * sizeof(key_hash[0]);
286 
287 	key_hash = emalloc_zero(newalloc);
288 
289 	INIT_DLIST(key_listhead, llink);
290 
291 #ifdef DEBUG
292 	atexit(&free_auth_mem);
293 #endif
294 }
295 
296 
297 /*
298  * free_auth_mem - assist in leak detection by freeing all dynamic
299  *		   allocations from this module.
300  */
301 #ifdef DEBUG
302 static void
303 free_auth_mem(void)
304 {
305 	symkey *	sk;
306 	symkey_alloc *	alloc;
307 	symkey_alloc *	next_alloc;
308 
309 	while (NULL != (sk = HEAD_DLIST(key_listhead, llink))) {
310 		freesymkey(sk);
311 	}
312 	free(key_hash);
313 	key_hash = NULL;
314 	cache_keyid = 0;
315 	cache_flags = 0;
316 	cache_keyacclist = NULL;
317 	for (alloc = authallocs; alloc != NULL; alloc = next_alloc) {
318 		next_alloc = alloc->link;
319 		free(alloc->mem);
320 	}
321 	authfreekeys = NULL;
322 	authnumfreekeys = 0;
323 }
324 #endif	/* DEBUG */
325 
326 
327 /*
328  * auth_moremem - get some more free key structures
329  */
330 void
331 auth_moremem(
332 	int	keycount
333 	)
334 {
335 	symkey *	sk;
336 	int		i;
337 #ifdef DEBUG
338 	void *		base;
339 	symkey_alloc *	allocrec;
340 # define MOREMEM_EXTRA_ALLOC	(sizeof(*allocrec))
341 #else
342 # define MOREMEM_EXTRA_ALLOC	(0)
343 #endif
344 
345 	i = (keycount > 0)
346 		? keycount
347 		: MEMINC;
348 	sk = eallocarrayxz(i, sizeof(*sk), MOREMEM_EXTRA_ALLOC);
349 #ifdef DEBUG
350 	base = sk;
351 #endif
352 	authnumfreekeys += i;
353 
354 	for (; i > 0; i--, sk++) {
355 		LINK_SLIST(authfreekeys, sk, llink.f);
356 	}
357 
358 #ifdef DEBUG
359 	allocrec = (void *)sk;
360 	allocrec->mem = base;
361 	LINK_SLIST(authallocs, allocrec, link);
362 #endif
363 }
364 
365 
366 /*
367  * auth_prealloc_symkeys
368  */
369 void
370 auth_prealloc_symkeys(
371 	int	keycount
372 	)
373 {
374 	int	allocated;
375 	int	additional;
376 
377 	allocated = authnumkeys + authnumfreekeys;
378 	additional = keycount - allocated;
379 	if (additional > 0)
380 		auth_moremem(additional);
381 	auth_resize_hashtable();
382 }
383 
384 
385 static u_short
386 auth_log2(size_t x)
387 {
388 	/*
389 	** bithack to calculate floor(log2(x))
390 	**
391 	** This assumes
392 	**   - (sizeof(size_t) is a power of two
393 	**   - CHAR_BITS is a power of two
394 	**   - returning zero for arguments <= 0 is OK.
395 	**
396 	** Does only shifts, masks and sums in integer arithmetic in
397 	** log2(CHAR_BIT*sizeof(size_t)) steps. (that is, 5/6 steps for
398 	** 32bit/64bit size_t)
399 	*/
400 	int	s;
401 	int	r = 0;
402 	size_t  m = ~(size_t)0;
403 
404 	for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) {
405 		m <<= s;
406 		if (x & m)
407 			r += s;
408 		else
409 			x <<= s;
410 	}
411 	return (u_short)r;
412 }
413 
414 int/*BOOL*/
415 ipaddr_match_masked(const sockaddr_u *,const sockaddr_u *,
416 		    unsigned int mbits);
417 
418 static void
419 authcache_flush_id(
420 	keyid_t id
421 	)
422 {
423 	if (cache_keyid == id) {
424 		cache_keyid = 0;
425 		cache_type = 0;
426 		cache_flags = 0;
427 		cache_secret = NULL;
428 		cache_secretsize = 0;
429 		cache_keyacclist = NULL;
430 	}
431 }
432 
433 
434 /*
435  * auth_resize_hashtable
436  *
437  * Size hash table to average 4 or fewer entries per bucket initially,
438  * within the bounds of at least 4 and no more than 15 bits for the hash
439  * table index.  Populate the hash table.
440  */
441 static void
442 auth_resize_hashtable(void)
443 {
444 	u_long		totalkeys;
445 	u_short		hashbits;
446 	u_short		hash;
447 	size_t		newalloc;
448 	symkey *	sk;
449 
450 	totalkeys = authnumkeys + authnumfreekeys;
451 	hashbits = auth_log2(totalkeys / 4) + 1;
452 	hashbits = max(4, hashbits);
453 	hashbits = min(15, hashbits);
454 
455 	authhashbuckets = 1 << hashbits;
456 	authhashmask = authhashbuckets - 1;
457 	newalloc = authhashbuckets * sizeof(key_hash[0]);
458 
459 	key_hash = erealloc(key_hash, newalloc);
460 	zero_mem(key_hash, newalloc);
461 
462 	ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
463 		hash = KEYHASH(sk->keyid);
464 		LINK_SLIST(key_hash[hash], sk, hlink);
465 	ITER_DLIST_END()
466 }
467 
468 
469 /*
470  * allocsymkey - common code to allocate and link in symkey
471  *
472  * secret must be allocated with a free-compatible allocator.  It is
473  * owned by the referring symkey structure, and will be free()d by
474  * freesymkey().
475  */
476 static void
477 allocsymkey(
478 	keyid_t		id,
479 	u_short		flags,
480 	u_short		type,
481 	u_long		lifetime,
482 	size_t		secretsize,
483 	u_char *	secret,
484 	KeyAccT *	ka
485 	)
486 {
487 	symkey *	sk;
488 	symkey **	bucket;
489 
490 	bucket = &key_hash[KEYHASH(id)];
491 
492 
493 	if (authnumfreekeys < 1)
494 		auth_moremem(-1);
495 	UNLINK_HEAD_SLIST(sk, authfreekeys, llink.f);
496 	DEBUG_ENSURE(sk != NULL);
497 	sk->keyid = id;
498 	sk->flags = flags;
499 	sk->type = type;
500 	sk->secretsize = secretsize;
501 	sk->secret = secret;
502 	sk->keyacclist = ka;
503 	sk->lifetime = lifetime;
504 	LINK_SLIST(*bucket, sk, hlink);
505 	LINK_TAIL_DLIST(key_listhead, sk, llink);
506 	authnumfreekeys--;
507 	authnumkeys++;
508 }
509 
510 
511 /*
512  * freesymkey - common code to remove a symkey and recycle its entry.
513  */
514 static void
515 freesymkey(
516 	symkey *	sk
517 	)
518 {
519 	symkey **	bucket;
520 	symkey *	unlinked;
521 
522 	if (NULL == sk)
523 		return;
524 
525 	authcache_flush_id(sk->keyid);
526 	keyacc_all_free(sk->keyacclist);
527 
528 	bucket = &key_hash[KEYHASH(sk->keyid)];
529 	if (sk->secret != NULL) {
530 		zero_mem(sk->secret, sk->secretsize);
531 		free(sk->secret);
532 	}
533 	UNLINK_SLIST(unlinked, *bucket, sk, hlink, symkey);
534 	DEBUG_ENSURE(sk == unlinked);
535 	UNLINK_DLIST(sk, llink);
536 	zero_mem((char *)sk + offsetof(symkey, symkey_payload),
537 		 sizeof(*sk) - offsetof(symkey, symkey_payload));
538 	LINK_SLIST(authfreekeys, sk, llink.f);
539 	authnumkeys--;
540 	authnumfreekeys++;
541 }
542 
543 
544 /*
545  * auth_findkey - find a key in the hash table
546  */
547 struct savekey *
548 auth_findkey(
549 	keyid_t		id
550 	)
551 {
552 	symkey *	sk;
553 
554 	for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink)
555 		if (id == sk->keyid)
556 			return sk;
557 	return NULL;
558 }
559 
560 
561 /*
562  * auth_havekey - return TRUE if the key id is zero or known. The
563  * key needs not to be trusted.
564  */
565 int
566 auth_havekey(
567 	keyid_t		id
568 	)
569 {
570 	return
571 	    (0           == id) ||
572 	    (cache_keyid == id) ||
573 	    (NULL        != auth_findkey(id));
574 }
575 
576 
577 /*
578  * authhavekey - return TRUE and cache the key, if zero or both known
579  *		 and trusted.
580  */
581 int
582 authhavekey(
583 	keyid_t		id
584 	)
585 {
586 	symkey *	sk;
587 
588 	authkeylookups++;
589 	if (0 == id || cache_keyid == id)
590 		return !!(KEY_TRUSTED & cache_flags);
591 
592 	/*
593 	 * Search the bin for the key. If not found, or found but the key
594 	 * type is zero, somebody marked it trusted without specifying a
595 	 * key or key type. In this case consider the key missing.
596 	 */
597 	authkeyuncached++;
598 	sk = auth_findkey(id);
599 	if ((sk == NULL) || (sk->type == 0)) {
600 		authkeynotfound++;
601 		return FALSE;
602 	}
603 
604 	/*
605 	 * If the key is not trusted, the key is not considered found.
606 	 */
607 	if ( ! (KEY_TRUSTED & sk->flags)) {
608 		authnokey++;
609 		return FALSE;
610 	}
611 
612 	/*
613 	 * The key is found and trusted. Initialize the key cache.
614 	 */
615 	cache_keyid = sk->keyid;
616 	cache_type = sk->type;
617 	cache_flags = sk->flags;
618 	cache_secret = sk->secret;
619 	cache_secretsize = sk->secretsize;
620 	cache_keyacclist = sk->keyacclist;
621 
622 	return TRUE;
623 }
624 
625 
626 /*
627  * authtrust - declare a key to be trusted/untrusted
628  */
629 void
630 authtrust(
631 	keyid_t		id,
632 	u_long		trust
633 	)
634 {
635 	symkey *	sk;
636 	u_long		lifetime;
637 
638 	/*
639 	 * Search bin for key; if it does not exist and is untrusted,
640 	 * forget it.
641 	 */
642 
643 	sk = auth_findkey(id);
644 	if (!trust && sk == NULL)
645 		return;
646 
647 	/*
648 	 * There are two conditions remaining. Either it does not
649 	 * exist and is to be trusted or it does exist and is or is
650 	 * not to be trusted.
651 	 */
652 	if (sk != NULL) {
653 		/*
654 		 * Key exists. If it is to be trusted, say so and update
655 		 * its lifetime. If no longer trusted, return it to the
656 		 * free list. Flush the cache first to be sure there are
657 		 * no discrepancies.
658 		 */
659 		authcache_flush_id(id);
660 		if (trust > 0) {
661 			sk->flags |= KEY_TRUSTED;
662 			if (trust > 1)
663 				sk->lifetime = current_time + trust;
664 			else
665 				sk->lifetime = 0;
666 		} else {
667 			freesymkey(sk);
668 		}
669 		return;
670 	}
671 
672 	/*
673 	 * keyid is not present, but the is to be trusted.  We allocate
674 	 * a new key, but do not specify a key type or secret.
675 	 */
676 	if (trust > 1) {
677 		lifetime = current_time + trust;
678 	} else {
679 		lifetime = 0;
680 	}
681 	allocsymkey(id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL);
682 }
683 
684 
685 /*
686  * authistrusted - determine whether a key is trusted
687  */
688 int
689 authistrusted(
690 	keyid_t		id
691 	)
692 {
693 	symkey *	sk;
694 
695 	if (id == cache_keyid)
696 		return !!(KEY_TRUSTED & cache_flags);
697 
698 	authkeyuncached++;
699 	sk = auth_findkey(id);
700 	if (sk == NULL || !(KEY_TRUSTED & sk->flags)) {
701 		authkeynotfound++;
702 		return FALSE;
703 	}
704 	return TRUE;
705 }
706 
707 
708 /*
709  * authistrustedip - determine if the IP is OK for the keyid
710  */
711  int
712  authistrustedip(
713  	keyid_t		keyno,
714 	sockaddr_u *	sau
715 	)
716 {
717 	symkey *	sk;
718 
719 	if (keyno == cache_keyid) {
720 		return (KEY_TRUSTED & cache_flags) &&
721 			keyacc_contains(cache_keyacclist, sau, TRUE);
722 	}
723 
724 	if (NULL != (sk = auth_findkey(keyno))) {
725 		authkeyuncached++;
726 		return (KEY_TRUSTED & sk->flags) &&
727 			keyacc_contains(sk->keyacclist, sau, TRUE);
728 	}
729 
730 	authkeynotfound++;
731 	return FALSE;
732 }
733 
734 /* Note: There are two locations below where 'strncpy()' is used. While
735  * this function is a hazard by itself, it's essential that it is used
736  * here. Bug 1243 involved that the secret was filled with NUL bytes
737  * after the first NUL encountered, and 'strlcpy()' simply does NOT have
738  * this behaviour. So disabling the fix and reverting to the buggy
739  * behaviour due to compatibility issues MUST also fill with NUL and
740  * this needs 'strncpy'. Also, the secret is managed as a byte blob of a
741  * given size, and eventually truncating it and replacing the last byte
742  * with a NUL would be a bug.
743  * perlinger@ntp.org 2015-10-10
744  */
745 void
746 MD5auth_setkey(
747 	keyid_t keyno,
748 	int	keytype,
749 	const u_char *key,
750 	size_t secretsize,
751 	KeyAccT *ka
752 	)
753 {
754 	symkey *	sk;
755 	u_char *	secret;
756 
757 	DEBUG_ENSURE(keytype <= USHRT_MAX);
758 	DEBUG_ENSURE(secretsize < 4 * 1024);
759 	/*
760 	 * See if we already have the key.  If so just stick in the
761 	 * new value.
762 	 */
763 	sk = auth_findkey(keyno);
764 	if (sk != NULL && keyno == sk->keyid) {
765 			/* TALOS-CAN-0054: make sure we have a new buffer! */
766 		if (NULL != sk->secret) {
767 			memset(sk->secret, 0, sk->secretsize);
768 			free(sk->secret);
769 		}
770 		sk->secret = emalloc(secretsize + 1);
771 		sk->type = (u_short)keytype;
772 		sk->secretsize = secretsize;
773 		/* make sure access lists don't leak here! */
774 		if (ka != sk->keyacclist) {
775 			keyacc_all_free(sk->keyacclist);
776 			sk->keyacclist = ka;
777 		}
778 #ifndef DISABLE_BUG1243_FIX
779 		memcpy(sk->secret, key, secretsize);
780 #else
781 		/* >MUST< use 'strncpy()' here! See above! */
782 		strncpy((char *)sk->secret, (const char *)key,
783 			secretsize);
784 #endif
785 		authcache_flush_id(keyno);
786 		return;
787 	}
788 
789 	/*
790 	 * Need to allocate new structure.  Do it.
791 	 */
792 	secret = emalloc(secretsize + 1);
793 #ifndef DISABLE_BUG1243_FIX
794 	memcpy(secret, key, secretsize);
795 #else
796 	/* >MUST< use 'strncpy()' here! See above! */
797 	strncpy((char *)secret, (const char *)key, secretsize);
798 #endif
799 	allocsymkey(keyno, 0, (u_short)keytype, 0,
800 		    secretsize, secret, ka);
801 #ifdef DEBUG
802 	if (debug >= 1) {
803 		size_t	j;
804 
805 		printf("auth_setkey: key %d type %d len %d ", (int)keyno,
806 		    keytype, (int)secretsize);
807 		for (j = 0; j < secretsize; j++) {
808 			printf("%02x", secret[j]);
809 		}
810 		printf("\n");
811 	}
812 #endif
813 }
814 
815 
816 /*
817  * auth_delkeys - delete non-autokey untrusted keys, and clear all info
818  *		  except the trusted bit of non-autokey trusted keys, in
819  *		  preparation for rereading the keys file.
820  */
821 void
822 auth_delkeys(void)
823 {
824 	symkey *	sk;
825 
826 	ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
827 		if (sk->keyid > NTP_MAXKEY) {	/* autokey */
828 			continue;
829 		}
830 
831 		/*
832 		 * Don't lose info as to which keys are trusted. Make
833 		 * sure there are no dangling pointers!
834 		 */
835 		if (KEY_TRUSTED & sk->flags) {
836 			if (sk->secret != NULL) {
837 				zero_mem(sk->secret, sk->secretsize);
838 				free(sk->secret);
839 				sk->secret = NULL; /* TALOS-CAN-0054 */
840 			}
841 			sk->keyacclist = keyacc_all_free(sk->keyacclist);
842 			sk->secretsize = 0;
843 			sk->lifetime = 0;
844 		} else {
845 			freesymkey(sk);
846 		}
847 	ITER_DLIST_END()
848 }
849 
850 
851 /*
852  * auth_agekeys - delete keys whose lifetimes have expired
853  */
854 void
855 auth_agekeys(void)
856 {
857 	symkey *	sk;
858 
859 	ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
860 		if (sk->lifetime > 0 && current_time > sk->lifetime) {
861 			freesymkey(sk);
862 			authkeyexpired++;
863 		}
864 	ITER_DLIST_END()
865 	DPRINTF(1, ("auth_agekeys: at %lu keys %lu expired %lu\n",
866 		    current_time, authnumkeys, authkeyexpired));
867 }
868 
869 
870 /*
871  * authencrypt - generate message authenticator
872  *
873  * Returns length of authenticator field, zero if key not found.
874  */
875 size_t
876 authencrypt(
877 	keyid_t		keyno,
878 	u_int32 *	pkt,
879 	size_t		length
880 	)
881 {
882 	/*
883 	 * A zero key identifier means the sender has not verified
884 	 * the last message was correctly authenticated. The MAC
885 	 * consists of a single word with value zero.
886 	 */
887 	authencryptions++;
888 	pkt[length / KEY_MAC_LEN] = htonl(keyno);
889 	if (0 == keyno) {
890 		return KEY_MAC_LEN;
891 	}
892 	if (!authhavekey(keyno)) {
893 		return 0;
894 	}
895 
896 	return MD5authencrypt(cache_type,
897 			      cache_secret, cache_secretsize,
898 			      pkt, length);
899 }
900 
901 
902 /*
903  * authdecrypt - verify message authenticator
904  *
905  * Returns TRUE if authenticator valid, FALSE if invalid or not found.
906  */
907 int
908 authdecrypt(
909 	keyid_t		keyno,
910 	u_int32 *	pkt,
911 	size_t		length,
912 	size_t		size
913 	)
914 {
915 	/*
916 	 * A zero key identifier means the sender has not verified
917 	 * the last message was correctly authenticated.  For our
918 	 * purpose this is an invalid authenticator.
919 	 */
920 	authdecryptions++;
921 	if (0 == keyno || !authhavekey(keyno) || size < 4) {
922 		return FALSE;
923 	}
924 
925 	return MD5authdecrypt(cache_type,
926 			      cache_secret, cache_secretsize,
927 			      pkt, length, size, keyno);
928 }
929 
930 /* password decoding helpers */
931 static size_t
932 pwdecode_plain(
933 	u_char *	dst,
934 	size_t 		dstlen,
935 	const char *	src
936 	)
937 {
938 	size_t		srclen = strlen(src);
939 	if (srclen > dstlen) {
940 		errno = ENOMEM;
941 		return (size_t)-1;
942 	}
943 	memcpy(dst, src, srclen);
944 	return srclen;
945 }
946 
947 static size_t
948 pwdecode_hex(
949 	u_char *	dst,
950 	size_t 		dstlen,
951 	const char *	src
952 	)
953 {
954 	static const char hex[] = "00112233445566778899AaBbCcDdEeFf";
955 
956 	size_t		srclen = strlen(src);
957 	size_t		reslen = (srclen >> 1) + (srclen & 1);
958 	u_char		tmp;
959 	char		*ptr;
960 	size_t		j;
961 
962 	if (reslen > dstlen) {
963 		errno = ENOMEM;
964 		reslen = (size_t)-1;
965 	} else {
966 		for (j = 0; j < srclen; ++j) {
967 			tmp = *(const unsigned char*)(src + j);
968 			ptr = strchr(hex, tmp);
969 			if (ptr == NULL) {
970 				errno = EINVAL;
971 				reslen = (size_t)-1;
972 				break;
973 			}
974 			tmp = (u_char)((ptr - hex) >> 1);
975 			if (j & 1)
976 				dst[j >> 1] |= tmp;
977 			else
978 				dst[j >> 1] = tmp << 4;
979 		}
980 	}
981 	return reslen;
982 }
983 /*
984  * authdecodepw - decode plaintext or hex-encoded password to binary
985  * secret.  Returns size of secret in bytes or -1 on error.
986  */
987 size_t
988 authdecodepw(
989 	u_char *	dst,
990 	size_t 		dstlen,
991 	const char *	src,
992 	enum AuthPwdEnc	enc
993 	)
994 {
995 	size_t		reslen;
996 
997 	if ( !(dst && dstlen && src)) {
998 		errno  = EINVAL;
999 		reslen = (size_t)-1;
1000 	} else {
1001 		switch (enc) {
1002 		case AUTHPWD_UNSPEC:
1003 			if (strlen(src) <= 20)
1004 				reslen = pwdecode_plain(dst, dstlen, src);
1005 			else
1006 				reslen = pwdecode_hex(dst, dstlen, src);
1007 			break;
1008 		case AUTHPWD_PLAIN:
1009 			reslen = pwdecode_plain(dst, dstlen, src);
1010 			break;
1011 		case AUTHPWD_HEX:
1012 			reslen = pwdecode_hex(dst, dstlen, src);
1013 			break;
1014 		default:
1015 			errno = EINVAL;
1016 			reslen = (size_t)-1;
1017 		}
1018 	}
1019 	return reslen;
1020 }
1021