I believe I found the smoking gun by breaking out the call
to EVP_get_digestbynid(crypto_nid) and testing its return
value:
--- ntp_crypto.c.orig 2009-12-08 23:36:35.000000000 -0800
+++ ntp_crypto.c 2012-04-30 22:44:46.094602274 -0700
@@ -197,6 +197,7 @@
)
{
EVP_MD_CTX ctx; /* message digest context */
+ const EVP_MD *type;
u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */
keyid_t keyid; /* key identifer */
u_int32 header[10]; /* data in network byte order */
@@ -229,7 +230,43 @@
hdlen = 10 * sizeof(u_int32);
break;
}
- EVP_DigestInit(&ctx, EVP_get_digestbynid(crypto_nid));
+ if ((type = EVP_get_digestbynid(crypto_nid)) == NULL)
+ msyslog(LOG_ERR, "EVP_get_digestbynid(KEY_TYPE_MD5) "
+ "returned NULL");
+ EVP_DigestInit(&ctx, type);
EVP_DigestUpdate(&ctx, (u_char *)header, hdlen);
EVP_DigestFinal(&ctx, dgst, &len);
memcpy(&keyid, dgst, 4);
Sure enough, this routine returns NULL before the program segfaults.
A web search led me to this:
>
http://stackoverflow.com/questions/6762054/evp-get-digestbyname-what-is-this
Indeed, the Debian man page for evp_get_digestbynid(3) has this
important information:
EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj() return
> an EVP_MD structure when passed a digest name, a digest NID or an
ASN1_OBJECT
> structure respectively. The digest table must be initialized using,
for example,
> OpenSSL_add_all_digests() for these functions to work.
My search of the NTP source code for references to
"OpenSSL_add_all_*" showed the following two locations:
libntp/ssl_init.c:
------------------
#ifdef OPENSSL
#include "openssl/err.h"
#include "openssl/rand.h"
int ssl_init_done;
void
ssl_init(void)
{
if (ssl_init_done)
return;
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
ssl_init_done = 1;
}
void
ssl_check_version(void)
{
INIT_SSL();
}
#endif /* OPENSSL */
include/ntp_stdlib.h:
---------------------
/* ssl_init.c */
#ifdef OPENSSL
extern void ssl_init (void);
extern void ssl_check_version (void);
extern int ssl_init_done;
#define INIT_SSL() \
do { \
if (!ssl_init_done) \
ssl_init(); \
} while (0)
#else /* !OPENSSL follows */
#define INIT_SSL() do {} while (0)
#endif
However, I can't find where the ntpd program ever calls ssl_init()
or the INIT_SSL() macro. So I'm betting that this problem will go
away once I find the proper place to call this important routine.
Perhaps you can keep this ticket open until I can confirm my hunch.
It shouldn't take too long.
Thanks,
Andris
--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org