summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrendan Shanks <brendan.shanks@teradek.com>2018-05-09 17:18:44 -0700
committerOlivier CrĂȘte <olivier.crete@collabora.com>2018-10-21 03:32:15 -0400
commit16409ef3d2db0c010e42ee68f469930cb6f870d2 (patch)
tree0f1701d259494247392e31af0b2749d4e44b7bce
parente41df5f2f70e002ac09cf0e764a375b8068a0125 (diff)
downloadlibnice-16409ef3d2db0c010e42ee68f469930cb6f870d2.tar.gz
stun: Add implementation using OpenSSL for rand/SHA1/MD5
-rw-r--r--stun/Makefile.am3
-rw-r--r--stun/rand.c13
-rw-r--r--stun/stunhmac.c84
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 <openssl/rand.h>
+
+void nice_RAND_nonce (uint8_t *dst, int len)
+{
+ RAND_bytes (dst, len);
+}
+
+#else
+
#include <sys/types.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
@@ -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 <string.h>
#include <assert.h>
+
+#ifdef HAVE_OPENSSL
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
+#else
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
+#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 */
}