4 * authkeys.c - routines to manage the storage of authentication keys
12 #include "ntp_types.h"
16 #include "ntp_string.h"
17 #include "ntp_malloc.h"
18 #include "ntp_stdlib.h"
21 * Structure to store keys in in the hash table.
26 u_char MD5_key
[64]; /* for keys up to to 512 bits */
28 keyid_t keyid
; /* key identifier */
29 int type
; /* key type */
30 u_short flags
; /* flags that wave */
31 u_long lifetime
; /* remaining lifetime */
32 int keylen
; /* key length */
35 #define KEY_TRUSTED 0x001 /* this key is trusted */
38 * The hash table. This is indexed by the low order bits of the
39 * keyid. We make this fairly big for potentially busy servers.
42 #define HASHMASK ((HASHSIZE)-1)
43 #define KEYHASH(keyid) ((keyid) & HASHMASK)
45 struct savekey
*key_hash
[HASHSIZE
];
47 u_long authkeynotfound
; /* keys not found */
48 u_long authkeylookups
; /* calls to lookup keys */
49 u_long authnumkeys
; /* number of active keys */
50 u_long authkeyexpired
; /* key lifetime expirations */
51 u_long authkeyuncached
; /* cache misses */
52 u_long authnokey
; /* calls to encrypt with no key */
53 u_long authencryptions
; /* calls to encrypt */
54 u_long authdecryptions
; /* calls to decrypt */
57 * Storage for free key structures. We malloc() such things but
60 struct savekey
*authfreekeys
;
63 #define MEMINC 12 /* number of new free ones to get */
66 * The key cache. We cache the last key we looked at here.
68 keyid_t cache_keyid
; /* key identifier */
69 u_char
*cache_key
; /* key pointer */
70 u_int cache_keylen
; /* key length */
71 int cache_type
; /* key type */
72 u_short cache_flags
; /* flags that wave */
76 * init_auth - initialize internal data
82 * Initialize hash table and free list
84 memset((char *)key_hash
, 0, sizeof key_hash
);
89 * auth_findkey - find a key in the hash table
98 sk
= key_hash
[KEYHASH(keyno
)];
100 if (keyno
== sk
->keyid
)
110 * auth_havekey - return one if the key is known
119 if (keyno
== 0 || (keyno
== cache_keyid
))
122 sk
= key_hash
[KEYHASH(keyno
)];
124 if (keyno
== sk
->keyid
)
134 * authhavekey - return one and cache the key, if known and trusted.
144 if (keyno
== 0 || keyno
== cache_keyid
)
148 * Seach the bin for the key. If found and the key type
149 * is zero, somebody marked it trusted without specifying
150 * a key or key type. In this case consider the key missing.
153 sk
= key_hash
[KEYHASH(keyno
)];
155 if (keyno
== sk
->keyid
) {
166 * If the key is not found, or if it is found but not trusted,
167 * the key is not considered found.
174 if (!(sk
->flags
& KEY_TRUSTED
)) {
180 * The key is found and trusted. Initialize the key cache.
182 cache_keyid
= sk
->keyid
;
183 cache_type
= sk
->type
;
184 cache_flags
= sk
->flags
;
185 cache_key
= sk
->k
.MD5_key
;
186 cache_keylen
= sk
->keylen
;
192 * auth_moremem - get some more free key structures
200 sk
= (struct savekey
*)calloc(MEMINC
, sizeof(struct savekey
));
204 for (i
= MEMINC
; i
> 0; i
--) {
205 sk
->next
= authfreekeys
;
208 authnumfreekeys
+= MEMINC
;
209 return (authnumfreekeys
);
214 * authtrust - declare a key to be trusted/untrusted
225 * Search bin for key; if it does not exist and is untrusted,
228 sk
= key_hash
[KEYHASH(keyno
)];
230 if (keyno
== sk
->keyid
)
235 if (sk
== 0 && !trust
)
239 * There are two conditions remaining. Either it does not
240 * exist and is to be trusted or it does exist and is or is
244 if (cache_keyid
== keyno
) {
250 * Key exists. If it is to be trusted, say so and
251 * update its lifetime. If not, return it to the
255 sk
->flags
|= KEY_TRUSTED
;
257 sk
->lifetime
= current_time
+ trust
;
262 sk
->flags
&= ~KEY_TRUSTED
; {
265 skp
= key_hash
[KEYHASH(keyno
)];
267 key_hash
[KEYHASH(keyno
)] = sk
->next
;
269 while (skp
->next
!= sk
)
271 skp
->next
= sk
->next
;
275 sk
->next
= authfreekeys
;
283 * Here there is not key, but the key is to be trusted. There
284 * seems to be a disconnect here. Here we allocate a new key,
285 * but do not specify a key type, key or key length.
287 if (authnumfreekeys
== 0)
288 if (auth_moremem() == 0)
292 authfreekeys
= sk
->next
;
297 sk
->flags
= KEY_TRUSTED
;
298 sk
->next
= key_hash
[KEYHASH(keyno
)];
299 key_hash
[KEYHASH(keyno
)] = sk
;
306 * authistrusted - determine whether a key is trusted
315 if (keyno
== cache_keyid
)
316 return ((cache_flags
& KEY_TRUSTED
) != 0);
319 sk
= key_hash
[KEYHASH(keyno
)];
321 if (keyno
== sk
->keyid
)
329 } else if (!(sk
->flags
& KEY_TRUSTED
)) {
348 * See if we already have the key. If so just stick in the
351 sk
= key_hash
[KEYHASH(keyno
)];
353 if (keyno
== sk
->keyid
) {
355 sk
->keylen
= min(len
, sizeof(sk
->k
.MD5_key
));
356 #ifndef DISABLE_BUG1243_FIX
357 memcpy(sk
->k
.MD5_key
, key
, sk
->keylen
);
359 strncpy((char *)sk
->k
.MD5_key
, (const char *)key
,
360 sizeof(sk
->k
.MD5_key
));
362 if (cache_keyid
== keyno
) {
372 * Need to allocate new structure. Do it.
374 if (0 == authnumfreekeys
&& !auth_moremem())
378 authfreekeys
= sk
->next
;
385 sk
->keylen
= min(len
, sizeof(sk
->k
.MD5_key
));
386 #ifndef DISABLE_BUG1243_FIX
387 memcpy(sk
->k
.MD5_key
, key
, sk
->keylen
);
389 strncpy((char *)sk
->k
.MD5_key
, (const char *)key
,
390 sizeof(sk
->k
.MD5_key
));
392 sk
->next
= key_hash
[KEYHASH(keyno
)];
393 key_hash
[KEYHASH(keyno
)] = sk
;
396 char hex
[] = "0123456789abcdef";
399 printf("auth_setkey: key %d type %d len %d ", sk
->keyid
,
400 sk
->type
, sk
->keylen
);
401 for (j
= 0; j
< sk
->keylen
; j
++)
402 printf("%c%c", hex
[key
[j
] >> 4],
412 * auth_delkeys - delete all known keys, in preparation for rereading
413 * the keys file (presumably)
419 struct savekey
**skp
;
422 for (i
= 0; i
< HASHSIZE
; i
++) {
423 skp
= &(key_hash
[i
]);
426 * Leave autokey keys alone.
428 while (sk
!= 0 && sk
->keyid
<= NTP_MAXKEY
) {
430 * Don't lose info as to which keys are trusted.
432 if (sk
->flags
& KEY_TRUSTED
) {
434 memset(&sk
->k
, 0, sizeof(sk
->k
));
441 sk
->next
= authfreekeys
;
451 * auth_agekeys - delete keys whose lifetimes have expired
460 for (i
= 0; i
< HASHSIZE
; i
++) {
461 sk
= skp
= key_hash
[i
];
464 if (sk
->lifetime
> 0 && current_time
>
466 authtrust(sk
->keyid
, 0);
474 printf("auth_agekeys: at %lu keys %lu expired %lu\n",
475 current_time
, authnumkeys
, authkeyexpired
);
480 * authencrypt - generate message authenticator
482 * Returns length of authenticator field, zero if key not found.
493 * A zero key identifier means the sender has not verified
494 * the last message was correctly authenticated. The MAC
495 * consists of a single word with value zero.
498 pkt
[length
/ 4] = htonl(keyno
);
502 if (!authhavekey(keyno
))
505 return (MD5authencrypt(cache_type
, cache_key
, pkt
, length
));
509 * authdecrypt - verify message authenticator
511 * Returns one if authenticator valid, zero if invalid or key not found.
523 * A zero key identifier means the sender has not verified
524 * the last message was correctly authenticated. Nevertheless,
525 * the authenticator itself is considered valid.
531 if (!authhavekey(keyno
) || size
< 4)
534 return (MD5authdecrypt(cache_type
, cache_key
, pkt
, length
,