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