diff options
Diffstat (limited to 'stun/stunhmac.c')
-rw-r--r-- | stun/stunhmac.c | 84 |
1 files changed, 82 insertions, 2 deletions
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 */ } |