+* Remove unused file from sntp/Makefile.am's distribution list.
+* new crypto signature cleanup.
(4.2.5p240-RC) 2009/11/05 Released by Harlan Stenn <stenn@ntp.org>
* [Bug 1364] clock_gettime() not detected, need -lrt on Debian 5.0.3.
* Provide all of OpenSSL's signature methods for ntp.keys (FIPS 140-2).
/*
* digest support for NTP, MD5 and with OpenSSL more
*/
-
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "ntp_fp.h"
#include "ntp_string.h"
#include "ntp_stdlib.h"
-#include "ntp_assert.h"
#include "ntp.h"
#ifdef OPENSSL
#include "openssl/evp.h"
#endif /* OPENSSSL */
/*
- * MD5authencrypt - generate MD5 message authenticator
+ * MD5authencrypt - generate message digest
*
- * Returns length of authenticator field.
+ * Returns length of MAC including key ID and digest.
*/
int
MD5authencrypt(
int length /* packet length */
)
{
- u_char digest[64]; /* for SHA-512 */
- unsigned len;
+ u_char digest[32];
+ u_int len;
#ifdef OPENSSL
- const EVP_MD * digest_type;
- EVP_MD_CTX ctx;
+ EVP_MD_CTX ctx;
#else
- MD5_CTX md5;
+ MD5_CTX md5;
#endif /* OPENSSL */
/*
- * MD5 with key identifier concatenated with packet.
+ * Compute digest of key concatenated with packet. Note: the
+ * key type and digest type have been verified when the key
+ * was creaded.
*/
#ifdef OPENSSL
- digest_type = EVP_get_digestbynid(type);
- NTP_INSIST(digest_type != NULL);
- EVP_DigestInit(&ctx, digest_type);
+ EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
EVP_DigestUpdate(&ctx, key, (u_int)cache_keylen);
EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length);
EVP_DigestFinal(&ctx, digest, &len);
-#else
+#else /* OPENSSL */
MD5Init(&md5);
MD5Update(&md5, key, (u_int)cache_keylen);
MD5Update(&md5, (u_char *)pkt, (u_int)length);
/*
* MD5authdecrypt - verify MD5 message authenticator
*
- * Returns one if authenticator valid, zero if invalid.
+ * Returns one if digest valid, zero if invalid.
*/
int
MD5authdecrypt(
int size /* MAC size */
)
{
- u_char digest[64]; /* for SHA-512 */
- unsigned len;
+ u_char digest[32];
+ u_int len;
#ifdef OPENSSL
- EVP_MD_CTX ctx;
+ EVP_MD_CTX ctx;
#else
- MD5_CTX md5;
#endif /* OPENSSL */
/*
- * MD5 with key identifier concatenated with packet.
+ * Compute digest of key concatenated with packet. Note: the
+ * key type and digest type have been verified when the key
+ * was created.
*/
#ifdef OPENSSL
EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
EVP_DigestUpdate(&ctx, key, (u_int)cache_keylen);
EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length);
EVP_DigestFinal(&ctx, digest, &len);
-#else
+#else /* OPENSSL */
MD5Init(&md5);
MD5Update(&md5, key, (u_int)cache_keylen);
MD5Update(&md5, (u_char *)pkt, (u_int)length);
MD5Final(digest, &md5);
len = 16;
#endif /* OPENSSL */
- if ((unsigned)size != len + 4)
+ if ((unsigned)size != len + 4) {
+ msyslog(LOG_ERR,
+ "MAC decrypt: MAC length error");
return (0);
-
+ }
return (!memcmp(digest, (char *)pkt + length + 4, len));
}
/*
* authkeys.c - routines to manage the storage of authentication keys
*/
-
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
if (keyno == 0 || keyno == cache_keyid)
return (1);
+ /*
+ * Seach the bin for the key. If found and the key type
+ * is zero, somebody marked it trusted without specifying
+ * a key or key type. In this case consider the key missing.
+ */
authkeyuncached++;
sk = key_hash[KEYHASH(keyno)];
while (sk != 0) {
- if (keyno == sk->keyid)
- break;
+ if (keyno == sk->keyid) {
+ if (sk->type == 0) {
+ authkeynotfound++;
+ return (0);
+ }
+ }
+ break;
+
sk = sk->next;
}
+
+ /*
+ * If the key is not found, or if it is found but not trusted,
+ * the key is not considered found.
+ */
if (sk == 0) {
authkeynotfound++;
return (0);
- } else if (!(sk->flags & KEY_TRUSTED)) {
+
+ }
+ if (!(sk->flags & KEY_TRUSTED)) {
authnokey++;
return (0);
}
+
+ /*
+ * The key is found and trusted. Initialize the key cache.
+ */
cache_keyid = sk->keyid;
cache_type = sk->type;
cache_flags = sk->flags;
{
struct savekey *sk;
-#ifdef DEBUG
- if (debug > 2)
- printf("authtrust: keyid %08x life %lu\n", keyno, trust);
-#endif
+ /*
+ * Search bin for key; if it does not exist and is untrusted,
+ * forget it.
+ */
sk = key_hash[KEYHASH(keyno)];
while (sk != 0) {
if (keyno == sk->keyid)
break;
+
sk = sk->next;
}
-
if (sk == 0 && !trust)
return;
-
+
+ /*
+ * There are two conditions remaining. Either it does not
+ * exist and is to be trusted or it does exist and is or is
+ * not to be trusted.
+ */
if (sk != 0) {
if (cache_keyid == keyno) {
cache_flags = 0;
cache_keyid = 0;
}
+ /*
+ * Key exists. If it is to be trusted, say so and
+ * update its lifetime. If not, return it to the
+ * free list.
+ */
if (trust > 0) {
sk->flags |= KEY_TRUSTED;
if (trust > 1)
sk->lifetime = 0;
return;
}
-
sk->flags &= ~KEY_TRUSTED; {
struct savekey *skp;
return;
}
+ /*
+ * Here there is not key, but the key is to be trusted. There
+ * seems to be a disconnect here. Here we allocate a new key,
+ * but do not specify a key type, key or key length.
+ */
if (authnumfreekeys == 0)
if (auth_moremem() == 0)
return;
sk = authfreekeys;
authfreekeys = sk->next;
authnumfreekeys--;
-
sk->keyid = keyno;
+ sk->type = 0;
+ sk->keylen = 0;
sk->flags = KEY_TRUSTED;
sk->next = key_hash[KEYHASH(keyno)];
key_hash[KEYHASH(keyno)] = sk;
if (sk == 0) {
authkeynotfound++;
return (0);
+
} else if (!(sk->flags & KEY_TRUSTED)) {
authkeynotfound++;
return (0);
sk = key_hash[KEYHASH(keyno)];
while (sk != NULL) {
if (keyno == sk->keyid) {
- sk->type = keytype;;
+ sk->type = keytype;
sk->keylen = min(len, sizeof(sk->k.MD5_key));
#ifndef DISABLE_BUG1243_FIX
memcpy(sk->k.MD5_key, key, sk->keylen);
#endif
sk->next = key_hash[KEYHASH(keyno)];
key_hash[KEYHASH(keyno)] = sk;
+#ifdef DEBUG
+ if (debug)
+ printf("auth_setkey: key %d type %d\n", sk->keyid, sk->type);
+#endif
authnumkeys++;
}
#ifdef OPENSSL
#include "openssl/objects.h"
-#endif /* OPENSSL *.
+#endif /* OPENSSL */
/* Forwards */
static char *nexttok (char **);
{
FILE *fp;
char *line;
- char *token;
- u_long keyno;
+ char *token, *keystr;
+ keyid_t keyno;
int keytype;
char buf[512]; /* lots of room for line */
*/
fp = fopen(file, "r");
if (fp == NULL) {
- msyslog(LOG_ERR, "can't open key file %s: %m", file);
+ msyslog(LOG_ERR, "authreadkeys: file %s: %m",
+ file);
return (0);
}
#ifdef OPENSSL
keyno = atoi(token);
if (keyno == 0) {
msyslog(LOG_ERR,
- "cannot change key %s", token);
+ "authreadkeys: cannot change key %s", token);
continue;
}
if (keyno > NTP_MAXKEY) {
msyslog(LOG_ERR,
- "key %s > %d reserved for autokeyd", token,
- NTP_MAXKEY);
+ "authreadkeys: key %s > %d reserved for Autokey",
+ token, NTP_MAXKEY);
continue;
}
/*
- * Next is keytype. See if that is all right.
+ * Next is keytype. See if that is all right.
*/
token = nexttok(&line);
if (token == NULL) {
msyslog(LOG_ERR,
- "no key type for key %ld", keyno);
+ "authreadkeys: no key type for key %d", keyno);
continue;
}
#ifdef OPENSSL
* If the key type is 'M' or 'm', it is replaced by 'MD5".
* In any case, it must be one of the algorithms supported
* by OpenSSL. The key type is the NID used by the message
- * digest algorithm.
+ * digest algorithm. Ther are a number of inconsistencies in
+ * the OpenSSL database. We attempt to discover them here
+ * and prevent use of inconsistent data.
*/
- if (*token == 'M' || *token == 'm')
+ if (strcmp(token, "M") == 0 || strcmp(token, "m") == 0)
token = "MD5";
keytype = OBJ_sn2nid(token);
- if (keytype == 0) {
+ if (keytype == 0 || keytype > 255) {
msyslog(LOG_ERR,
- "invalid key type for key %ld", keyno);
+ "authreadkeys: invalid type for key %d", keyno);
continue;
}
-#else /* !OPENSSL */
+ if (EVP_get_digestbynid(keytype) == NULL) {
+ msyslog(LOG_ERR,
+ "authreadkeys: no algorithm for key %d", keyno);
+ continue;
+ }
+#else /* OPENSSL */
/*
* The key type is unused, but is required to be 'M' or
*/
if (!(*token == 'M' || *token == 'm')) {
msyslog(LOG_ERR,
- "invalid key type for key %ld", keyno);
+ "authreadkeys: invalid type for key %d", keyno);
continue;
}
- keytype = NID_md5;
-#endif /* !OPENSSL */
+ keytype = KEY_TYPE_MD5
+#endif /* OPENSSL */
+ keystr = token;
/*
* Finally, get key and insert it
*/
token = nexttok(&line);
- if (token == NULL)
+ if (token == NULL) {
msyslog(LOG_ERR,
- "no key for key %ld", keyno);
- else
- MD5auth_setkey(keyno, keytype, token,
- strlen(token));
+ "authreadkeys: no key for key %d", keyno);
+ continue;
+ }
+ MD5auth_setkey(keyno, keytype, token, strlen(token));
}
fclose(fp);
return (1);
log.c \
log.h \
main.c \
- netutils.h \
networking.c \
networking.h \
sntp-opts.c \