Coverage Report

Created: 2026-08-31 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntp-dev/libntp/authkeys.c
Line
Count
Source
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
0
#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
0
#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
0
#define MEMINC  16    /* number of new free ones to get */
93
94
/*
95
 * The key cache. We cache the last key we looked at here.
96
 * Note: this should hold the last *trusted* key. Also the
97
 * cache is only loaded when the digest type / MAC algorithm
98
 * is valid.
99
 */
100
keyid_t cache_keyid;    /* key identifier */
101
u_char *cache_secret;   /* secret */
102
size_t  cache_secretsize; /* secret length */
103
int cache_type;   /* OpenSSL digest NID */
104
u_short cache_flags;    /* flags that wave */
105
KeyAccT *cache_keyacclist;  /* key access list */
106
107
/* --------------------------------------------------------------------
108
 * manage key access lists
109
 * --------------------------------------------------------------------
110
 */
111
/* allocate and populate new access node and pushes it on the list.
112
 * Returns the new head.
113
 */
114
KeyAccT*
115
keyacc_new_push(
116
  KeyAccT          * head,
117
  const sockaddr_u * addr,
118
  unsigned int     subnetbits
119
  )
120
0
{
121
0
  KeyAccT * node = emalloc(sizeof(KeyAccT));
122
123
0
  memcpy(&node->addr, addr, sizeof(sockaddr_u));
124
0
  node->subnetbits = subnetbits;
125
0
  node->next = head;
126
127
0
  return node;
128
0
}
129
130
/* ----------------------------------------------------------------- */
131
/* pop and deallocate the first node of a list of access nodes, if
132
 * the list is not empty. Returns the tail of the list.
133
 */
134
KeyAccT*
135
keyacc_pop_free(
136
  KeyAccT *head
137
  )
138
0
{
139
0
  KeyAccT * next = NULL;
140
0
  if (head) {
141
0
    next = head->next;
142
0
    free(head);
143
0
  }
144
0
  return next;
145
0
}
146
147
/* ----------------------------------------------------------------- */
148
/* deallocate the list; returns an empty list. */
149
KeyAccT*
150
keyacc_all_free(
151
  KeyAccT * head
152
  )
153
0
{
154
0
  while (head)
155
0
    head = keyacc_pop_free(head);
156
0
  return head;
157
0
}
158
159
/* ----------------------------------------------------------------- */
160
/* scan a list to see if it contains a given address. Return the
161
 * default result value in case of an empty list.
162
 */
163
int /*BOOL*/
164
keyacc_contains(
165
  const KeyAccT    *head,
166
  const sockaddr_u *addr,
167
  int               defv)
168
0
{
169
0
  if (head) {
170
0
    do {
171
0
      if (keyacc_amatch(&head->addr, addr,
172
0
            head->subnetbits))
173
0
        return TRUE;
174
0
    } while (NULL != (head = head->next));
175
0
    return FALSE;
176
0
  } else {
177
0
    return !!defv;
178
0
  }
179
0
}
180
181
#if CHAR_BIT != 8
182
# error "don't know how to handle bytes with that bit size"
183
#endif
184
185
/* ----------------------------------------------------------------- */
186
/* check two addresses for a match, taking a prefix length into account
187
 * when doing the compare.
188
 *
189
 * The ISC lib contains a similar function with not entirely specified
190
 * semantics, so it seemed somewhat cleaner to do this from scratch.
191
 *
192
 * Note 1: It *is* assumed that the addresses are stored in network byte
193
 * order, that is, most significant byte first!
194
 *
195
 * Note 2: "no address" compares unequal to all other addresses, even to
196
 * itself. This has the same semantics as NaNs have for floats: *any*
197
 * relational or equality operation involving a NaN returns FALSE, even
198
 * equality with itself. "no address" is either a NULL pointer argument
199
 * or an address of type AF_UNSPEC.
200
 */
201
int/*BOOL*/
202
keyacc_amatch(
203
  const sockaddr_u *  a1,
204
  const sockaddr_u *  a2,
205
  unsigned int    mbits
206
  )
207
0
{
208
0
  const uint8_t * pm1;
209
0
  const uint8_t * pm2;
210
0
  uint8_t         msk;
211
0
  unsigned int    len;
212
213
  /* 1st check: If any address is not an address, it's inequal. */
214
0
  if ( !a1 || (AF_UNSPEC == AF(a1)) ||
215
0
       !a2 || (AF_UNSPEC == AF(a2))  )
216
0
    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
0
  if (AF(a1) != AF(a2))
225
0
    return FALSE;
226
227
  /* type check: address family determines buffer & size */
228
0
  switch (AF(a1)) {
229
0
  case AF_INET:
230
    /* IPv4 is easy: clamp size, get byte pointers */
231
0
    if (mbits > sizeof(NSRCADR(a1)) * 8)
232
0
      mbits = sizeof(NSRCADR(a1)) * 8;
233
0
    pm1 = (const void*)&NSRCADR(a1);
234
0
    pm2 = (const void*)&NSRCADR(a2);
235
0
    break;
236
237
0
  case AF_INET6:
238
    /* IPv6 is slightly different: Both scopes must match,
239
     * too, before we even consider doing a match!
240
     */
241
0
    if ( ! SCOPE_EQ(a1, a2))
242
0
      return FALSE;
243
0
    if (mbits > sizeof(NSRCADR6(a1)) * 8)
244
0
      mbits = sizeof(NSRCADR6(a1)) * 8;
245
0
    pm1 = (const void*)&NSRCADR6(a1);
246
0
    pm2 = (const void*)&NSRCADR6(a2);
247
0
    break;
248
249
0
  default:
250
    /* don't know how to compare that!?! */
251
0
    return FALSE;
252
0
  }
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
0
  msk = 0xFFu ^ (0xFFu >> (mbits & 7));
260
0
  len = mbits >> 3;
261
262
  /* 3rd check: Do memcmp() over full bytes, if any */
263
0
  if (len && memcmp(pm1, pm2, len))
264
0
    return FALSE;
265
266
  /* 4th check: compare last incomplete byte, if any */
267
0
  if (msk && ((pm1[len] ^ pm2[len]) & msk))
268
0
    return FALSE;
269
270
  /* If none of the above failed, we're successfully through. */
271
0
  return TRUE;
272
0
}
273
274
/*
275
 * init_auth - initialize internal data
276
 */
277
void
278
init_auth(void)
279
1
{
280
1
  size_t newalloc;
281
282
  /*
283
   * Initialize hash table and free list
284
   */
285
1
  newalloc = authhashbuckets * sizeof(key_hash[0]);
286
287
1
  key_hash = emalloc_zero(newalloc);
288
289
1
  INIT_DLIST(key_listhead, llink);
290
291
1
#ifdef DEBUG
292
1
  atexit(&free_auth_mem);
293
1
#endif
294
1
}
295
296
297
/*
298
 * free_auth_mem - assist in leak detection by freeing all dynamic
299
 *       allocations from this module.
300
 */
301
#ifdef DEBUG
302
static void
303
free_auth_mem(void)
304
1
{
305
1
  symkey *  sk;
306
1
  symkey_alloc *  alloc;
307
1
  symkey_alloc *  next_alloc;
308
309
1
  while (NULL != (sk = HEAD_DLIST(key_listhead, llink))) {
310
0
    freesymkey(sk);
311
0
  }
312
1
  free(key_hash);
313
1
  key_hash = NULL;
314
1
  cache_keyid = 0;
315
1
  cache_flags = 0;
316
1
  cache_keyacclist = NULL;
317
1
  for (alloc = authallocs; alloc != NULL; alloc = next_alloc) {
318
0
    next_alloc = alloc->link;
319
0
    free(alloc->mem);
320
0
  }
321
1
  authfreekeys = NULL;
322
1
  authnumfreekeys = 0;
323
1
}
324
#endif  /* DEBUG */
325
326
327
/*
328
 * auth_moremem - get some more free key structures
329
 */
330
void
331
auth_moremem(
332
  int keycount
333
  )
334
0
{
335
0
  symkey *  sk;
336
0
  int   i;
337
0
#ifdef DEBUG
338
0
  void *    base;
339
0
  symkey_alloc *  allocrec;
340
0
# define MOREMEM_EXTRA_ALLOC  (sizeof(*allocrec))
341
#else
342
# define MOREMEM_EXTRA_ALLOC  (0)
343
#endif
344
345
0
  i = (keycount > 0)
346
0
    ? keycount
347
0
    : MEMINC;
348
0
  sk = eallocarrayxz(i, sizeof(*sk), MOREMEM_EXTRA_ALLOC);
349
0
#ifdef DEBUG
350
0
  base = sk;
351
0
#endif
352
0
  authnumfreekeys += i;
353
354
0
  for (; i > 0; i--, sk++) {
355
0
    LINK_SLIST(authfreekeys, sk, llink.f);
356
0
  }
357
358
0
#ifdef DEBUG
359
0
  allocrec = (void *)sk;
360
0
  allocrec->mem = base;
361
0
  LINK_SLIST(authallocs, allocrec, link);
362
0
#endif
363
0
}
364
365
366
/*
367
 * auth_prealloc_symkeys
368
 */
369
void
370
auth_prealloc_symkeys(
371
  int keycount
372
  )
373
0
{
374
0
  int allocated;
375
0
  int additional;
376
377
0
  allocated = authnumkeys + authnumfreekeys;
378
0
  additional = keycount - allocated;
379
0
  if (additional > 0)
380
0
    auth_moremem(additional);
381
0
  auth_resize_hashtable();
382
0
}
383
384
385
static u_short
386
auth_log2(size_t x)
387
0
{
388
  /*
389
  ** bithack to calculate floor(log2(x))
390
  **
391
  ** This assumes
392
  **   - sizeof(size_t) is a power of two
393
  **   - CHAR_BITS is a power of two
394
  **   - returning zero for arguments <= 0 is OK.
395
  **
396
  ** Does only shifts, masks and sums in integer arithmetic in
397
  ** log2(CHAR_BIT*sizeof(size_t)) steps. (that is, 5/6 steps for
398
  ** 32bit/64bit size_t)
399
  */
400
0
  int s;
401
0
  int r = 0;
402
0
  size_t  m = ~(size_t)0;
403
404
0
  for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) {
405
0
    m <<= s;
406
0
    if (x & m)
407
0
      r += s;
408
0
    else
409
0
      x <<= s;
410
0
  }
411
412
0
  return (u_short)r;
413
0
}
414
415
int/*BOOL*/
416
ipaddr_match_masked(const sockaddr_u *,const sockaddr_u *,
417
        unsigned int mbits);
418
419
static void
420
authcache_flush_id(
421
  keyid_t id
422
  )
423
0
{
424
0
  if (cache_keyid == id) {
425
0
    cache_keyid = 0;
426
0
    cache_type = 0;
427
0
    cache_flags = 0;
428
0
    cache_secret = NULL;
429
0
    cache_secretsize = 0;
430
0
    cache_keyacclist = NULL;
431
0
  }
432
0
}
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
443
auth_resize_hashtable(void)
444
0
{
445
0
  u_long    totalkeys;
446
0
  u_short   hashbits;
447
0
  u_short   hash;
448
0
  size_t    newalloc;
449
0
  symkey *  sk;
450
451
0
  totalkeys = authnumkeys + authnumfreekeys;
452
0
  hashbits = auth_log2(totalkeys / 4) + 1;
453
0
  hashbits = max(4, hashbits);
454
0
  hashbits = min(15, hashbits);
455
456
0
  authhashbuckets = 1 << hashbits;
457
0
  authhashmask = authhashbuckets - 1;
458
0
  newalloc = authhashbuckets * sizeof(key_hash[0]);
459
460
0
  key_hash = erealloc(key_hash, newalloc);
461
0
  zero_mem(key_hash, newalloc);
462
463
0
  ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
464
0
    hash = KEYHASH(sk->keyid);
465
0
    LINK_SLIST(key_hash[hash], sk, hlink);
466
0
  ITER_DLIST_END()
467
0
}
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
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
0
{
488
0
  symkey *  sk;
489
0
  symkey ** bucket;
490
491
0
  bucket = &key_hash[KEYHASH(id)];
492
493
494
0
  if (authnumfreekeys < 1)
495
0
    auth_moremem(-1);
496
0
  UNLINK_HEAD_SLIST(sk, authfreekeys, llink.f);
497
0
  DEBUG_ENSURE(sk != NULL);
498
0
  sk->keyid = id;
499
0
  sk->flags = flags;
500
0
  sk->type = type;
501
0
  sk->secretsize = secretsize;
502
0
  sk->secret = secret;
503
0
  sk->keyacclist = ka;
504
0
  sk->lifetime = lifetime;
505
0
  LINK_SLIST(*bucket, sk, hlink);
506
0
  LINK_TAIL_DLIST(key_listhead, sk, llink);
507
0
  authnumfreekeys--;
508
0
  authnumkeys++;
509
0
}
510
511
512
/*
513
 * freesymkey - common code to remove a symkey and recycle its entry.
514
 */
515
static void
516
freesymkey(
517
  symkey *  sk
518
  )
519
0
{
520
0
  symkey ** bucket;
521
0
  symkey *  unlinked;
522
523
0
  if (NULL == sk)
524
0
    return;
525
526
0
  authcache_flush_id(sk->keyid);
527
0
  keyacc_all_free(sk->keyacclist);
528
529
0
  bucket = &key_hash[KEYHASH(sk->keyid)];
530
0
  if (sk->secret != NULL) {
531
0
    zero_mem(sk->secret, sk->secretsize);
532
0
    free(sk->secret);
533
0
  }
534
0
  UNLINK_SLIST(unlinked, *bucket, sk, hlink, symkey);
535
0
  DEBUG_ENSURE(sk == unlinked);
536
0
  UNLINK_DLIST(sk, llink);
537
0
  zero_mem((char *)sk + offsetof(symkey, symkey_payload),
538
0
     sizeof(*sk) - offsetof(symkey, symkey_payload));
539
0
  LINK_SLIST(authfreekeys, sk, llink.f);
540
0
  authnumkeys--;
541
0
  authnumfreekeys++;
542
0
}
543
544
545
/*
546
 * auth_findkey - find a key in the hash table
547
 */
548
struct savekey *
549
auth_findkey(
550
  keyid_t   id
551
  )
552
0
{
553
0
  symkey *  sk;
554
555
0
  for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink)
556
0
    if (id == sk->keyid)
557
0
      return sk;
558
0
  return NULL;
559
0
}
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
567
auth_havekey(
568
  keyid_t   id
569
  )
570
0
{
571
0
  return
572
0
      (0           == id) ||
573
0
      (cache_keyid == id) ||
574
0
      (NULL        != auth_findkey(id));
575
0
}
576
577
578
/*
579
 * authhavekey - return TRUE and cache the key, if zero or both known
580
 *     and trusted.
581
 */
582
int
583
authhavekey(
584
  keyid_t   id
585
  )
586
0
{
587
0
  symkey *  sk;
588
589
0
  authkeylookups++;
590
0
  if (0 == id || cache_keyid == id)
591
0
    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
0
  authkeyuncached++;
599
0
  sk = auth_findkey(id);
600
0
  if ((sk == NULL) || (sk->type == 0)) {
601
0
    authkeynotfound++;
602
0
    return FALSE;
603
0
  }
604
605
  /*
606
   * If the key is not trusted, the key is not considered found.
607
   */
608
0
  if ( ! (KEY_TRUSTED & sk->flags)) {
609
0
    authnokey++;
610
0
    return FALSE;
611
0
  }
612
613
  /*
614
   * The key is found and trusted. Initialize the key cache.
615
   * The cache really should be a struct savekey to streamline
616
   * this code.  Using a sk pointer would be even faster but more
617
   * fragile around pointing to freed memory.
618
   */
619
0
  cache_keyid = sk->keyid;
620
0
  cache_type = sk->type;
621
0
  cache_flags = sk->flags;
622
0
  cache_secret = sk->secret;
623
0
  cache_secretsize = sk->secretsize;
624
0
  cache_keyacclist = sk->keyacclist;
625
626
0
  return TRUE;
627
0
}
628
629
630
/*
631
 * authtrust - declare a key to be trusted/untrusted (trust is TRUE/FALSE),
632
 *         OR trusted with an automatic expiration after trust seconds.
633
 */
634
void
635
authtrust(
636
  keyid_t   id,
637
  u_long    trust
638
  )
639
0
{
640
0
  symkey *  sk;
641
0
  u_long    lifetime;
642
643
  /*
644
   * Search bin for key; if it does not exist and is untrusted,
645
   * we're done here.
646
   */
647
0
  sk = auth_findkey(id);
648
0
  if (!trust && NULL == sk) {
649
0
    return;
650
0
  }
651
  /*
652
   * There are two conditions remaining. Either it does not
653
   * exist and is to be trusted, or it exists.
654
   */
655
0
  if (sk != NULL) {
656
    /*
657
     * Key exists. If it is to be trusted, say so and update
658
     * its lifetime. If no longer trusted, return it to the
659
     * free list. Flush the cache first to be sure there are
660
     * no discrepancies.
661
     */
662
0
    authcache_flush_id(id);
663
0
    if (trust > 0) {
664
0
      sk->flags |= KEY_TRUSTED;
665
0
      if (trust > 1) {
666
0
        sk->lifetime = current_time + trust;
667
0
      } else {
668
0
        sk->lifetime = 0; /* infinite */
669
0
      }
670
0
    } else {
671
0
      freesymkey(sk);
672
0
    }
673
0
    return;
674
0
  }
675
676
  /*
677
   * keyid is not present, but it is to be trusted.  We allocate
678
   * a new key, but do not specify a key type or secret.  This is
679
   * how we save the trusted state before we have loaded ntp.keys.
680
   */
681
0
  if (trust > 1) {
682
0
    lifetime = current_time + trust;
683
0
  } else {
684
0
    lifetime = 0;
685
0
  }
686
0
  allocsymkey(id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL);
687
0
}
688
689
690
/*
691
 * authistrusted - determine whether a key is trusted
692
 */
693
int
694
authistrusted(
695
  keyid_t   id
696
  )
697
0
{
698
0
  symkey *  sk;
699
700
0
  if (id == cache_keyid)
701
0
    return !!(KEY_TRUSTED & cache_flags);
702
703
0
  authkeyuncached++;
704
0
  sk = auth_findkey(id);
705
0
  if (sk == NULL || !(KEY_TRUSTED & sk->flags)) {
706
0
    authkeynotfound++;
707
0
    return FALSE;
708
0
  }
709
0
  return TRUE;
710
0
}
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
0
{
722
0
  symkey *  sk;
723
724
0
  if (keyno == cache_keyid) {
725
0
    return (KEY_TRUSTED & cache_flags) &&
726
0
      keyacc_contains(cache_keyacclist, sau, TRUE);
727
0
  }
728
729
0
  if (NULL != (sk = auth_findkey(keyno))) {
730
0
    authkeyuncached++;
731
0
    return (KEY_TRUSTED & sk->flags) &&
732
0
      keyacc_contains(sk->keyacclist, sau, TRUE);
733
0
  }
734
735
0
  authkeynotfound++;
736
0
  return FALSE;
737
0
}
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
751
MD5auth_setkey(
752
  keyid_t keyno,
753
  int keytype,
754
  const u_char *key,
755
  size_t secretsize,
756
  KeyAccT *ka
757
  )
758
0
{
759
0
  symkey *  sk;
760
0
  u_char *  secret;
761
762
0
  DEBUG_ENSURE(keytype <= USHRT_MAX);
763
0
  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
0
  sk = auth_findkey(keyno);
769
0
  if (sk != NULL && keyno == sk->keyid) {
770
      /* TALOS-CAN-0054: make sure we have a new buffer! */
771
0
    if (NULL != sk->secret) {
772
0
      memset(sk->secret, 0, sk->secretsize);
773
0
      free(sk->secret);
774
0
    }
775
0
    sk->secret = emalloc(secretsize + 1);
776
0
    sk->type = (u_short)keytype;
777
0
    sk->secretsize = secretsize;
778
    /* make sure access lists don't leak here! */
779
0
    if (ka != sk->keyacclist) {
780
0
      keyacc_all_free(sk->keyacclist);
781
0
      sk->keyacclist = ka;
782
0
    }
783
0
#ifndef DISABLE_BUG1243_FIX
784
0
    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
0
    authcache_flush_id(keyno);
791
0
    return;
792
0
  }
793
794
  /*
795
   * Need to allocate new structure.  Do it.
796
   */
797
0
  secret = emalloc(secretsize + 1);
798
0
#ifndef DISABLE_BUG1243_FIX
799
0
  memcpy(secret, key, secretsize);
800
#else
801
  /* >MUST< use 'strncpy()' here! See above! */
802
  strncpy((char *)secret, (const char *)key, secretsize);
803
#endif
804
0
  allocsymkey(keyno, 0, (u_short)keytype, 0,
805
0
        secretsize, secret, ka);
806
0
#ifdef DEBUG
807
0
  if (debug >= 1) {
808
0
    size_t  j;
809
810
0
    printf("auth_setkey: key %d type %d len %d ", (int)keyno,
811
0
        keytype, (int)secretsize);
812
0
    for (j = 0; j < secretsize; j++) {
813
0
      printf("%02x", secret[j]);
814
0
    }
815
0
    printf("\n");
816
0
  }
817
0
#endif
818
0
}
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
0
{
829
0
  symkey *  sk;
830
831
0
  ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
832
0
    if (sk->keyid > NTP_MAXKEY) { /* autokey */
833
0
      continue;
834
0
    }
835
836
    /*
837
     * Don't lose info as to which keys are trusted. Make
838
     * sure there are no dangling pointers!
839
     */
840
0
    if (KEY_TRUSTED & sk->flags) {
841
0
      if (sk->secret != NULL) {
842
0
        zero_mem(sk->secret, sk->secretsize);
843
0
        free(sk->secret);
844
0
        sk->secret = NULL; /* TALOS-CAN-0054 */
845
0
      }
846
0
      sk->keyacclist = keyacc_all_free(sk->keyacclist);
847
0
      sk->secretsize = 0;
848
0
      sk->lifetime = 0;
849
0
    } else {
850
0
      freesymkey(sk);
851
0
    }
852
0
  ITER_DLIST_END()
853
0
}
854
855
856
/*
857
 * auth_agekeys - delete keys whose lifetimes have expired
858
 */
859
void
860
auth_agekeys(void)
861
0
{
862
0
  symkey *  sk;
863
864
0
  ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
865
0
    if (sk->lifetime > 0 && current_time > sk->lifetime) {
866
0
      freesymkey(sk);
867
0
      authkeyexpired++;
868
0
    }
869
0
  ITER_DLIST_END()
870
0
  DPRINTF(1, ("auth_agekeys: at %lu keys %lu expired %lu\n",
871
0
        current_time, authnumkeys, authkeyexpired));
872
0
}
873
874
875
/*
876
 * authencrypt - generate message authenticator
877
 *
878
 * Returns length of authenticator field, zero if key not found.
879
 * Special case for Crypto NAK: keyid 0 returns KEY_MAC_LEN (4).
880
 */
881
size_t
882
authencrypt(
883
  keyid_t   keyno,
884
  u_int32 * pkt,
885
  size_t    length
886
  )
887
0
{
888
  /*
889
   * A zero key identifier means the sender has not verified
890
   * the last message was correctly authenticated. The MAC
891
   * consists of a single word with value zero.
892
   */
893
0
  authencryptions++;
894
0
  pkt[length / KEY_MAC_LEN] = htonl(keyno);
895
0
  if (0 == keyno) {   /* Crypto NAK */
896
0
    return KEY_MAC_LEN;
897
0
  }
898
0
  if (!authhavekey(keyno)) {
899
0
    return 0;
900
0
  }
901
902
0
  return MD5authencrypt(cache_type,
903
0
            cache_secret, cache_secretsize,
904
0
            pkt, length);
905
0
}
906
907
908
/*
909
 * authdecrypt - verify message authenticator
910
 *
911
 * Returns TRUE if authenticator valid, FALSE if invalid or not found.
912
 */
913
int
914
authdecrypt(
915
  keyid_t   keyno,
916
  u_int32 * pkt,
917
  size_t    length,
918
  size_t    size
919
  )
920
0
{
921
  /*
922
   * A zero key identifier means the sender has not verified
923
   * the last message was correctly authenticated.  For our
924
   * purpose this is an invalid authenticator.
925
   */
926
0
  authdecryptions++;
927
0
  if (0 == keyno || !authhavekey(keyno) || size < 4) {
928
0
    return FALSE;
929
0
  }
930
931
0
  return MD5authdecrypt(cache_type,
932
0
            cache_secret, cache_secretsize,
933
0
            pkt, length, size, keyno);
934
0
}
935
936
937
/* password decoding helpers */
938
static size_t
939
pwdecode_plain(
940
  u_char *  dst,
941
  size_t    dstlen,
942
  const char *  src
943
  )
944
0
{
945
0
  size_t    srclen = strlen(src);
946
0
  if (srclen > dstlen) {
947
0
    errno = ENOMEM;
948
0
    return (size_t)-1;
949
0
  }
950
0
  memcpy(dst, src, srclen);
951
0
  return srclen;
952
0
}
953
954
static size_t
955
pwdecode_hex(
956
  u_char *  dst,
957
  size_t    dstlen,
958
  const char *  src
959
  )
960
0
{
961
0
  static const char hex[] = "00112233445566778899AaBbCcDdEeFf";
962
963
0
  size_t    srclen = strlen(src);
964
0
  size_t    reslen = (srclen >> 1) + (srclen & 1);
965
0
  u_char    tmp;
966
0
  char    *ptr;
967
0
  size_t    j;
968
969
0
  if (reslen > dstlen) {
970
0
    errno = ENOMEM;
971
0
    reslen = (size_t)-1;
972
0
  } else {
973
0
    for (j = 0; j < srclen; ++j) {
974
0
      tmp = *(const unsigned char*)(src + j);
975
0
      ptr = strchr(hex, tmp);
976
0
      if (ptr == NULL) {
977
0
        errno = EINVAL;
978
0
        reslen = (size_t)-1;
979
0
        break;
980
0
      }
981
0
      tmp = (u_char)((ptr - hex) >> 1);
982
0
      if (j & 1)
983
0
        dst[j >> 1] |= tmp;
984
0
      else
985
0
        dst[j >> 1] = tmp << 4;
986
0
    }
987
0
  }
988
0
  return reslen;
989
0
}
990
/*
991
 * authdecodepw - decode plaintext or hex-encoded password to binary
992
 * secret.  Returns size of secret in bytes or -1 on error.
993
 */
994
size_t
995
authdecodepw(
996
  u_char *  dst,
997
  size_t    dstlen,
998
  const char *  src,
999
  enum AuthPwdEnc enc
1000
  )
1001
0
{
1002
0
  size_t    reslen;
1003
1004
0
  if ( !(dst && dstlen && src)) {
1005
0
    errno  = EINVAL;
1006
0
    reslen = (size_t)-1;
1007
0
  } else {
1008
0
    switch (enc) {
1009
0
    case AUTHPWD_UNSPEC:
1010
0
      if (strlen(src) <= 20)
1011
0
        reslen = pwdecode_plain(dst, dstlen, src);
1012
0
      else
1013
0
        reslen = pwdecode_hex(dst, dstlen, src);
1014
0
      break;
1015
0
    case AUTHPWD_PLAIN:
1016
0
      reslen = pwdecode_plain(dst, dstlen, src);
1017
0
      break;
1018
0
    case AUTHPWD_HEX:
1019
0
      reslen = pwdecode_hex(dst, dstlen, src);
1020
0
      break;
1021
0
    default:
1022
0
      errno = EINVAL;
1023
0
      reslen = (size_t)-1;
1024
0
    }
1025
0
  }
1026
0
  return reslen;
1027
0
}