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