FS-9466: Use system MD5 if available

- Use system MD5 on BSD and Solaris based platforms
- Use OpenSSL if system library is not available
- Fallback to included APR
- Optimize switch_md5_string()
- replace libsofia MD5 routines in mod_sofia with switch_md5() ones

FS-9466 #resolve
This commit is contained in:
Spencer Thomason 2016-08-29 20:53:02 -07:00
parent bf3b0ca3d1
commit 5a2f9d7a78
3 changed files with 45 additions and 21 deletions

View File

@ -814,6 +814,12 @@ esac
APR_REMOVEFROM(SWITCH_AM_CXXFLAGS, -std=c99)
# check for usable system MD5 library
AS_CASE([$host],
[*-solaris2*], [AC_CHECK_LIB(md5, MD5Init)],
[*-freebsd*], [AC_CHECK_LIB(md, MD5Init)],
[*-openbsd*|*-netbsd*], [AC_CHECK_FUNCS([MD5Init])])
AC_CHECK_LIB(z, inflateReset, have_libz=yes, AC_MSG_ERROR([no usable zlib; please install zlib devel package or equivalent]))
if test "x$have_libz" = "xyes" ; then
APR_ADDTO([PLATFORM_CORE_LIBS], [-lz])

View File

@ -2692,9 +2692,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
{
int indexnum;
const char *cur;
su_md5_t ctx;
char uridigest[2 * SU_MD5_DIGEST_SIZE + 1];
char bigdigest[2 * SU_MD5_DIGEST_SIZE + 1];
char uridigest[SWITCH_MD5_DIGEST_STRING_SIZE];
char bigdigest[SWITCH_MD5_DIGEST_STRING_SIZE];
char *username, *realm, *nonce, *uri, *qop, *cnonce, *nc, *response, *input = NULL, *input2 = NULL;
auth_res_t ret = AUTH_FORBIDDEN;
int first = 0;
@ -2706,7 +2705,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
char *sql;
char *number_alias = NULL;
switch_xml_t user = NULL, param, uparams;
char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1] = "";
char hexdigest[SWITCH_MD5_DIGEST_STRING_SIZE] = "";
char *domain_name = NULL;
switch_event_t *params = NULL;
const char *auth_acl = NULL;
@ -3028,10 +3027,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
if (!a1_hash) {
input = switch_mprintf("%s:%s:%s", username, realm, passwd);
su_md5_init(&ctx);
su_md5_strupdate(&ctx, input);
su_md5_hexdigest(&ctx, hexdigest);
su_md5_deinit(&ctx);
switch_md5_string(hexdigest, (void *) input, strlen(input));
switch_safe_free(input);
a1_hash = hexdigest;
@ -3081,10 +3077,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
for_the_sake_of_interop:
if ((input = switch_mprintf("%s:%q", regstr, uri))) {
su_md5_init(&ctx);
su_md5_strupdate(&ctx, input);
su_md5_hexdigest(&ctx, uridigest);
su_md5_deinit(&ctx);
switch_md5_string(uridigest, (void *) input, strlen(input));
}
if (nc && cnonce && qop) {
@ -3094,11 +3087,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
}
if (input2) {
memset(&ctx, 0, sizeof(ctx));
su_md5_init(&ctx);
su_md5_strupdate(&ctx, input2);
su_md5_hexdigest(&ctx, bigdigest);
su_md5_deinit(&ctx);
switch_md5_string(bigdigest, (void *) input2, strlen(input2));
}
if (input2 && !strcasecmp(bigdigest, response)) {

View File

@ -65,7 +65,13 @@
/* apr-util headers */
#include <apr_queue.h>
#include <apr_uuid.h>
#if (defined(HAVE_LIBMD5) || defined(HAVE_LIBMD) || defined(HAVE_MD5INIT))
#include <md5.h>
#elif defined(HAVE_LIBCRYPTO)
#include <openssl/md5.h>
#else
#include <apr_md5.h>
#endif
/* apr stubs */
@ -1086,20 +1092,43 @@ SWITCH_DECLARE(switch_status_t) switch_uuid_parse(switch_uuid_t *uuid, const cha
SWITCH_DECLARE(switch_status_t) switch_md5(unsigned char digest[SWITCH_MD5_DIGESTSIZE], const void *input, switch_size_t inputLen)
{
#if (defined(HAVE_LIBMD5) || defined(HAVE_LIBMD) || defined(HAVE_MD5INIT))
MD5_CTX md5_context;
MD5Init(&md5_context);
MD5Update(&md5_context, input, inputLen);
MD5Final(digest, &md5_context);
return SWITCH_STATUS_SUCCESS;
#elif defined(HAVE_LIBCRYPTO)
MD5_CTX md5_context;
MD5_Init(&md5_context);
MD5_Update(&md5_context, input, inputLen);
MD5_Final(digest, &md5_context);
return SWITCH_STATUS_SUCCESS;
#else
return apr_md5(digest, input, inputLen);
#endif
}
SWITCH_DECLARE(switch_status_t) switch_md5_string(char digest_str[SWITCH_MD5_DIGEST_STRING_SIZE], const void *input, switch_size_t inputLen)
{
unsigned char digest[SWITCH_MD5_DIGESTSIZE];
apr_status_t status = apr_md5(digest, input, inputLen);
int x;
switch_status_t status = switch_md5(digest, input, inputLen);
short i, x;
uint8_t b;
digest_str[SWITCH_MD5_DIGEST_STRING_SIZE - 1] = '\0';
for (x = 0; x < SWITCH_MD5_DIGESTSIZE; x++) {
switch_snprintf(digest_str + (x * 2), 3, "%02x", digest[x]);
for (x = i = 0; x < SWITCH_MD5_DIGESTSIZE; x++) {
b = (digest[x] >> 4) & 15;
digest_str[i++] = b + (b > 9 ? 'a' - 10 : '0');
b = digest[x] & 15;
digest_str[i++] = b + (b > 9 ? 'a' - 10 : '0');
}
digest_str[i] = '\0';
return status;
}