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