From: Dave Hart Date: Mon, 10 May 2010 13:16:18 +0000 (+0000) Subject: Simplify hash client code by providing OpenSSL EVP_*() API when built X-Git-Tag: NTP_4_2_6P2_RC3~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef5df2027deb7c39c0614bdf0cadd7508c465d98;p=thirdparty%2Fntp.git Simplify hash client code by providing OpenSSL EVP_*() API when built without OpenSSL. (from ntp-dev) Do not depend on ASCII values for ('A' - '0'), ('a' - '0') in sntp. bk: 4be80722zgUE2PfQm4EEyWQN9ltRzA --- diff --git a/ChangeLog b/ChangeLog index 4caef4488..bb37a1d06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,9 @@ 12. Eliminated LOTS of blank lines. * sntp/configure.ac OpenSSL support now that sntp optionally uses it. * Escape unprintable characters in a refid in ntpq -p billboard. +* Simplify hash client code by providing OpenSSL EVP_*() API when built + without OpenSSL. (from ntp-dev) +* Do not depend on ASCII values for ('A' - '0'), ('a' - '0') in sntp. --- (4.2.6p2-RC2) 2010/04/27 Released by Harlan Stenn diff --git a/include/ntp_md5.h b/include/ntp_md5.h index 5e2206b00..458962fda 100644 --- a/include/ntp_md5.h +++ b/include/ntp_md5.h @@ -1,13 +1,29 @@ /* * ntp_md5.h: deal with md5.h headers + * + * Use the system MD5 if available, otherwise libisc's. */ - #if defined HAVE_MD5_H && defined HAVE_MD5INIT # include #else # include "isc/md5.h" -# define MD5_CTX isc_md5_t -# define MD5Init isc_md5_init -# define MD5Update isc_md5_update -# define MD5Final(d,c) isc_md5_final(c,d) + typedef isc_md5_t MD5_CTX; +# define MD5Init(c) isc_md5_init(c) +# define MD5Update(c, p, s) isc_md5_update(c, p, s) +# define MD5Final(d, c) isc_md5_final((c), (d)) /* swapped */ +#endif + +/* + * Provide OpenSSL-alike MD5 API if we're not using OpenSSL + */ +#ifndef OPENSSL + typedef MD5_CTX EVP_MD_CTX; +# define EVP_get_digestbynid(t) NULL +# define EVP_DigestInit(c, dt) MD5Init(c) +# define EVP_DigestUpdate(c, p, s) MD5Update(c, p, s) +# define EVP_DigestFinal(c, d, pdl) \ + do { \ + MD5Final((d), (c)); \ + *(pdl) = 16; \ + } while (0) #endif diff --git a/libntp/a_md5encrypt.c b/libntp/a_md5encrypt.c index bd30ba2c6..05c109a9f 100644 --- a/libntp/a_md5encrypt.c +++ b/libntp/a_md5encrypt.c @@ -10,10 +10,10 @@ #include "ntp_stdlib.h" #include "ntp.h" #ifdef OPENSSL -#include "openssl/evp.h" +# include "openssl/evp.h" #else -#include "ntp_md5.h" -#endif /* OPENSSSL */ +# include "ntp_md5.h" /* provides clone of OpenSSL MD5 API */ +#endif /* * MD5authencrypt - generate message digest @@ -30,30 +30,18 @@ MD5authencrypt( { u_char digest[EVP_MAX_MD_SIZE]; u_int len; -#ifdef OPENSSL EVP_MD_CTX ctx; -#else - MD5_CTX md5; -#endif /* OPENSSL */ /* * Compute digest of key concatenated with packet. Note: the * key type and digest type have been verified when the key * was creaded. */ -#ifdef OPENSSL INIT_SSL(); 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 /* 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 */ memmove((u_char *)pkt + length + 4, digest, len); return (len + 4); } @@ -75,30 +63,18 @@ MD5authdecrypt( { u_char digest[EVP_MAX_MD_SIZE]; u_int len; -#ifdef OPENSSL EVP_MD_CTX ctx; -#else - MD5_CTX md5; -#endif /* OPENSSL */ /* * Compute digest of key concatenated with packet. Note: the * key type and digest type have been verified when the key * was created. */ -#ifdef OPENSSL INIT_SSL(); 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 /* 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 ((u_int)size != len + 4) { msyslog(LOG_ERR, "MAC decrypt: MAC length error"); @@ -117,28 +93,17 @@ addr2refid(sockaddr_u *addr) { u_char digest[20]; u_int32 addr_refid; -#ifdef OPENSSL EVP_MD_CTX ctx; u_int len; -#else - MD5_CTX md5; -#endif /* OPENSSL */ if (IS_IPV4(addr)) return (NSRCADR(addr)); -#ifdef OPENSSL INIT_SSL(); EVP_DigestInit(&ctx, EVP_get_digestbynid(NID_md5)); EVP_DigestUpdate(&ctx, (u_char *)PSOCK_ADDR6(addr), sizeof(struct in6_addr)); EVP_DigestFinal(&ctx, digest, &len); -#else - MD5Init(&md5); - MD5Update(&md5, (u_char *)PSOCK_ADDR6(addr), - sizeof(struct in6_addr)); - MD5Final(digest, &md5); -#endif /* OPENSSL */ memcpy(&addr_refid, digest, 4); return (addr_refid); } diff --git a/sntp/crypto.c b/sntp/crypto.c index c646d3108..ce4748091 100644 --- a/sntp/crypto.c +++ b/sntp/crypto.c @@ -4,35 +4,6 @@ struct key *key_ptr; int key_cnt = 0; -static int -s_keytype_from_text( - const char *text - ) -{ - int key_type; -#ifdef OPENSSL - char upcased[EVP_MAX_MD_SIZE]; - char * pch; - - /* - * OpenSSL digest short names are capitalized, so uppercase the - * digest name before passing to OBJ_sn2nid(). If it is not - * recognized but begins with 'M' use NID_md5 to be consistent - * with past behavior. - */ - strncpy(upcased, text, sizeof upcased); - for (pch = upcased; '\0' != *pch; pch++) - *pch = (char)toupper(*pch); - key_type = OBJ_sn2nid(upcased); -#else - key_type = 0; -#endif - - if (!key_type && 'm' == tolower(text[0])) - key_type = NID_md5; - return key_type; -} - int make_mac( char *pkt_data, @@ -42,36 +13,21 @@ make_mac( char * digest ) { - unsigned int len = mac_size; -#ifdef OPENSSL - int key_type; - EVP_MD_CTX ctx; -#else - MD5_CTX ctx; -#endif /* OPENSSL */ + u_int len = mac_size; + int key_type; + EVP_MD_CTX ctx; if (cmp_key->key_len > 64) return 0; if (pkt_size % 4 != 0) return 0; -#ifdef OPENSSL + INIT_SSL(); - key_type = s_keytype_from_text(cmp_key->type); + key_type = keytype_from_text(cmp_key->type, NULL); EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type)); EVP_DigestUpdate(&ctx, (u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len); EVP_DigestUpdate(&ctx, (u_char *)pkt_data, (u_int)pkt_size); EVP_DigestFinal(&ctx, (u_char *)digest, &len); -#else /* OPENSSL */ - if ((cmp_key->type[0] | 0x20) != 'm') - return 0; - if (mac_size < 16) - return 0; - MD5Init(&ctx); - MD5Update(&ctx, (u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len); - MD5Update(&ctx, (u_char *)pkt_data, (u_int)pkt_size); - MD5Final((u_char *)digest, &ctx); - len = 16; -#endif /* OPENSSL */ return (int)len; } @@ -90,25 +46,39 @@ auth_md5( struct key *cmp_key ) { - int rv; + int hash_len; + int authentic; char digest[20]; - if (mac_size > sizeof digest) + if (mac_size > sizeof(digest)) return 0; - rv = make_mac(pkt_data, pkt_size, sizeof digest, cmp_key, digest); - return rv ? !memcmp(digest, pkt_data + pkt_size + 4, rv) : rv; + hash_len = make_mac(pkt_data, pkt_size, sizeof(digest), cmp_key, + digest); + if (!hash_len) + authentic = FALSE; + else + authentic = !memcmp(digest, pkt_data + pkt_size + 4, + hash_len); + return authentic; } static int -hex_val( unsigned char x) +hex_val( + unsigned char x + ) { - static const short vals [] = - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15 }; - - return (x < '0' || x > 'f') ? -1 : vals[x - '0']; + int val; + + if ('0' <= x && x <= '9') + val = x - '0'; + else if ('a' <= x && x <= 'f') + val = x - 'a' + 0xa; + else if ('A' <= x && x <= 'F') + val = x - 'A' + 0xA; + else + val = -1; + + return val; } /* Load keys from the specified keyfile into the key structures. @@ -145,24 +115,24 @@ auth_init( int goodline = 0; fgets(kbuf, sizeof(kbuf), keyf); - kbuf[199] = '\0'; + kbuf[sizeof(kbuf) - 1] = '\0'; octothorpe = strchr(kbuf, '#'); if (octothorpe) *octothorpe = '\0'; #ifdef DEBUG printf("sntp auth_init: fgets: %s", kbuf); #endif - scan_cnt = sscanf(kbuf, "%i %10s %128s", &act->key_id, act->type, keystring); + scan_cnt = sscanf(kbuf, "%d %9s %128s", &act->key_id, act->type, keystring); if (scan_cnt == 3) { int len = strlen(keystring); if (len <= 20) { act->key_len = len; - memcpy(act->key_seq, keystring, len+1); + memcpy(act->key_seq, keystring, len + 1); goodline = 1; } else if ((len & 1) != 0) { goodline = 0; /* it's bad */ } else { - int j; + int j; goodline = 1; act->key_len = len >> 1; for (j = 0; j < len; j+=2) { diff --git a/sntp/crypto.h b/sntp/crypto.h index 6edbf442c..5f184b06b 100644 --- a/sntp/crypto.h +++ b/sntp/crypto.h @@ -7,15 +7,12 @@ #include #include - +#include #ifdef OPENSSL -#include "openssl/evp.h" +# include "openssl/evp.h" #else -#include "ntp_md5.h" -#endif /* OPENSSSL */ - -#include - +# include /* provides clone of OpenSSL MD5 API */ +#endif #include "utilities.h" #include "sntp-opts.h" diff --git a/sntp/networking.c b/sntp/networking.c index 75b977107..91f3a284b 100644 --- a/sntp/networking.c +++ b/sntp/networking.c @@ -220,8 +220,8 @@ recv_bcst_data ( } memset(&mdevadr, 0, sizeof(mdevadr)); mdevadr.ipv6mr_multiaddr = SOCK_ADDR6(sas); - if(!IN6_IS_ADDR_MULTICAST(&mdevadr.ipv6mr_multiaddr)) { - if(ENABLED_OPT(NORMALVERBOSE)) { + if (!IN6_IS_ADDR_MULTICAST(&mdevadr.ipv6mr_multiaddr)) { + if (ENABLED_OPT(NORMALVERBOSE)) { buf = ss_to_str(sas); printf("sntp recv_bcst_data: %s is not a broad-/multicast address, aborting...\n", buf); free(buf); @@ -229,7 +229,7 @@ recv_bcst_data ( return BROADCAST_FAILED; } if (setsockopt(rsock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mdevadr, sizeof(mdevadr)) < 0) { - if(ENABLED_OPT(NORMALVERBOSE)) { + if (ENABLED_OPT(NORMALVERBOSE)) { buf = ss_to_str(sas); printf("sntp recv_bcst_data: Couldn't join group for %s\n", buf); free(buf); @@ -240,20 +240,20 @@ recv_bcst_data ( #endif /* ISC_PLATFORM_HAVEIPV6 */ FD_ZERO(&bcst_fd); FD_SET(rsock, &bcst_fd); - if(ENABLED_OPT(TIMEOUT)) + if (ENABLED_OPT(TIMEOUT)) timeout_tv.tv_sec = (int) OPT_ARG(TIMEOUT); else timeout_tv.tv_sec = 68; /* ntpd broadcasts every 64s */ timeout_tv.tv_usec = 0; rdy_socks = select(rsock + 1, &bcst_fd, 0, 0, &timeout_tv); - switch(rdy_socks) { + switch (rdy_socks) { case -1: - if(ENABLED_OPT(NORMALVERBOSE)) + if (ENABLED_OPT(NORMALVERBOSE)) perror("sntp recv_bcst_data: select()"); return BROADCAST_FAILED; break; case 0: - if(ENABLED_OPT(NORMALVERBOSE)) + if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recv_bcst_data: select() reached timeout (%u sec), aborting.\n", (unsigned)timeout_tv.tv_sec); return BROADCAST_FAILED; @@ -264,7 +264,7 @@ recv_bcst_data ( break; } if (recv_bytes == -1) { - if(ENABLED_OPT(NORMALVERBOSE)) + if (ENABLED_OPT(NORMALVERBOSE)) perror("sntp recv_bcst_data: recvfrom:"); recv_bytes = BROADCAST_FAILED; } @@ -307,7 +307,7 @@ process_pkt ( */ if (pkt_len < LEN_PKT_NOMAC || (pkt_len & 3) != 0) { unusable: - if(ENABLED_OPT(NORMALVERBOSE)) + if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp %s: Funny packet length: %i. Discarding package.\n", func_name, pkt_len); return PACKET_UNUSEABLE; } @@ -462,20 +462,20 @@ recvpkt ( FD_ZERO(&recv_fd); FD_SET(rsock, &recv_fd); - if(ENABLED_OPT(TIMEOUT)) + if (ENABLED_OPT(TIMEOUT)) timeout_tv.tv_sec = (int) OPT_ARG(TIMEOUT); else timeout_tv.tv_sec = 68; /* ntpd broadcasts every 64s */ timeout_tv.tv_usec = 0; rdy_socks = select(rsock + 1, &recv_fd, 0, 0, &timeout_tv); - switch(rdy_socks) { + switch (rdy_socks) { case -1: - if(ENABLED_OPT(NORMALVERBOSE)) + if (ENABLED_OPT(NORMALVERBOSE)) perror("sntp recvpkt: select()"); return PACKET_UNUSEABLE; break; case 0: - if(ENABLED_OPT(NORMALVERBOSE)) + if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: select() reached timeout (%u sec), aborting.\n", (unsigned)timeout_tv.tv_sec); return PACKET_UNUSEABLE; @@ -484,9 +484,8 @@ recvpkt ( break; } pkt_len = recvdata(rsock, &sender, (char *)rpkt, rsize); - if (pkt_len > 0) { - pkt_len = process_pkt(rpkt, &sender, pkt_len, MODE_SERVER, "recvpkt"); - } + if (pkt_len > 0) + pkt_len = process_pkt(rpkt, &sender, pkt_len, MODE_SERVER, "recvpkt"); if (pkt_len < 0) return pkt_len; /*