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*
keyacc_new_push(KeyAccT * head,const sockaddr_u * addr,unsigned int subnetbits)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*
keyacc_pop_free(KeyAccT * head)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*
keyacc_all_free(KeyAccT * head)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*/
keyacc_contains(const KeyAccT * head,const sockaddr_u * addr,int defv)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*/
keyacc_amatch(const sockaddr_u * a1,const sockaddr_u * a2,unsigned int mbits)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
init_auth(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
free_auth_mem(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
auth_moremem(int keycount)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
auth_prealloc_symkeys(int keycount)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
auth_log2(size_t x)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
authcache_flush_id(keyid_t id)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
auth_resize_hashtable(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
allocsymkey(keyid_t id,u_short flags,u_short type,u_long lifetime,size_t secretsize,u_char * secret,KeyAccT * ka)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
freesymkey(symkey * sk)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 *
auth_findkey(keyid_t id)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
auth_havekey(keyid_t id)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
authhavekey(keyid_t id)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
authtrust(keyid_t id,u_long trust)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
authistrusted(keyid_t id)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
authistrustedip(keyid_t keyno,sockaddr_u * sau)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@ntp.org 2015-10-10
749 */
750 void
MD5auth_setkey(keyid_t keyno,int keytype,const u_char * key,size_t secretsize,KeyAccT * ka)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
auth_delkeys(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
auth_agekeys(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
authencrypt(keyid_t keyno,u_int32 * pkt,size_t length)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
authdecrypt(keyid_t keyno,u_int32 * pkt,size_t length,size_t size)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
pwdecode_plain(u_char * dst,size_t dstlen,const char * src)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
pwdecode_hex(u_char * dst,size_t dstlen,const char * src)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
authdecodepw(u_char * dst,size_t dstlen,const char * src,enum AuthPwdEnc enc)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