From 16409ef3d2db0c010e42ee68f469930cb6f870d2 Mon Sep 17 00:00:00 2001 From: Brendan Shanks Date: Wed, 9 May 2018 17:18:44 -0700 Subject: stun: Add implementation using OpenSSL for rand/SHA1/MD5 --- stun/Makefile.am | 3 +- stun/rand.c | 13 +++++++++ stun/stunhmac.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/stun/Makefile.am b/stun/Makefile.am index c9b0cb2..9afcc75 100644 --- a/stun/Makefile.am +++ b/stun/Makefile.am @@ -15,6 +15,7 @@ AM_CFLAGS = \ -DG_LOG_DOMAIN=\"libnice-stun\" \ $(LIBNICE_CFLAGS) \ $(GNUTLS_CFLAGS) \ + $(OPENSSL_CFLAGS) \ $(NULL) AM_CPPFLAGS = -I$(top_srcdir) @@ -38,7 +39,7 @@ libstun_la_SOURCES = constants.h \ usages/turn.c usages/turn.h \ usages/timer.c usages/timer.h -libstun_la_LIBADD = $(LIBRT) $(GNUTLS_LIBS) +libstun_la_LIBADD = $(LIBRT) $(GNUTLS_LIBS) $(OPENSSL_LIBS) EXTRA_DIST = win32_common.h diff --git a/stun/rand.c b/stun/rand.c index 25dc402..cc0927f 100644 --- a/stun/rand.c +++ b/stun/rand.c @@ -68,6 +68,17 @@ void nice_RAND_nonce (uint8_t *dst, int len) } #else +#ifdef HAVE_OPENSSL + +#include + +void nice_RAND_nonce (uint8_t *dst, int len) +{ + RAND_bytes (dst, len); +} + +#else + #include #include #include @@ -77,4 +88,6 @@ void nice_RAND_nonce (uint8_t *dst, int len) gnutls_rnd (GNUTLS_RND_NONCE, dst, len); } +#endif /* HAVE_OPENSSL */ + #endif /* _WIN32 */ diff --git a/stun/stunhmac.c b/stun/stunhmac.c index c1e5180..c7d1432 100644 --- a/stun/stunhmac.c +++ b/stun/stunhmac.c @@ -47,14 +47,68 @@ #include #include + +#ifdef HAVE_OPENSSL +#include +#include +#else #include #include +#endif void stun_sha1 (const uint8_t *msg, size_t len, size_t msg_len, uint8_t *sha, const void *key, size_t keylen, int padding) { uint16_t fakelen = htons (msg_len); uint8_t pad_char[64] = {0}; + + assert (len >= 44u); + +#ifdef HAVE_OPENSSL +{ +#ifdef NDEBUG +#define TRY(x) x; +#else + int ret; +#define TRY(x) \ + ret = x; \ + assert (ret == 1); +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + HMAC_CTX stackctx; + HMAC_CTX *ctx = &stackctx; + HMAC_CTX_init (ctx); +#else + HMAC_CTX *ctx = HMAC_CTX_new (); +#endif /* OPENSSL_VERSION_NUMBER */ + + assert (SHA_DIGEST_LENGTH == 20); + + TRY (HMAC_Init_ex (ctx, key, keylen, EVP_sha1(), NULL)); + + TRY (HMAC_Update (ctx, msg, 2)); + TRY (HMAC_Update (ctx, (unsigned char *)&fakelen, 2)); + TRY (HMAC_Update (ctx, msg + 4, len - 28)); + + /* RFC 3489 specifies that the message's size should be 64 bytes, + and \x00 padding should be done */ + if (padding && ((len - 24) % 64) > 0) { + uint16_t pad_size = 64 - ((len - 24) % 64); + + TRY (HMAC_Update (ctx, pad_char, pad_size)); + } + + TRY (HMAC_Final (ctx, sha, NULL)); + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + HMAC_CTX_cleanup (ctx); +#else + HMAC_CTX_free (ctx); +#endif /* OPENSSL_VERSION_NUMBER */ +} +#else +{ gnutls_hmac_hd_t handle; #ifdef NDEBUG @@ -66,8 +120,6 @@ void stun_sha1 (const uint8_t *msg, size_t len, size_t msg_len, uint8_t *sha, assert (ret >= 0); #endif - assert (len >= 44u); - assert (gnutls_hmac_get_len (GNUTLS_MAC_SHA1) == 20); TRY (gnutls_hmac_init (&handle, GNUTLS_MAC_SHA1, key, keylen)); @@ -87,6 +139,8 @@ void stun_sha1 (const uint8_t *msg, size_t len, size_t msg_len, uint8_t *sha, #undef TRY } +#endif /* HAVE_OPENSSL */ +} static const uint8_t *priv_trim_var (const uint8_t *var, size_t *var_len) { @@ -114,6 +168,31 @@ void stun_hash_creds (const uint8_t *realm, size_t realm_len, const uint8_t *password_trimmed = priv_trim_var (password, &password_len); const uint8_t *realm_trimmed = priv_trim_var (realm, &realm_len); const uint8_t *colon = (uint8_t *)":"; + +#ifdef HAVE_OPENSSL + EVP_MD_CTX *ctx; + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + ctx = EVP_MD_CTX_create (); +#else + ctx = EVP_MD_CTX_new (); +#endif /* OPENSSL_VERSION_NUMBER */ + + EVP_DigestInit_ex (ctx, EVP_md5(), NULL); + EVP_DigestUpdate (ctx, username_trimmed, username_len); + EVP_DigestUpdate (ctx, colon, 1); + EVP_DigestUpdate (ctx, realm_trimmed, realm_len); + EVP_DigestUpdate (ctx, colon, 1); + EVP_DigestUpdate (ctx, password_trimmed, password_len); + EVP_DigestFinal_ex (ctx, md5, NULL); + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + EVP_MD_CTX_destroy (ctx); +#else + EVP_MD_CTX_free (ctx); +#endif /* OPENSSL_VERSION_NUMBER */ + +#else gnutls_hash_hd_t handle; gnutls_hash_init (&handle, GNUTLS_DIG_MD5); @@ -124,6 +203,7 @@ void stun_hash_creds (const uint8_t *realm, size_t realm_len, gnutls_hash (handle, password_trimmed, password_len); gnutls_hash_deinit (handle, md5); +#endif /* HAVE_OPENSSL */ } -- cgit v1.2.1