diff options
author | Ole André Vadla Ravnås <oleavr@gmail.com> | 2021-04-06 22:47:17 +0200 |
---|---|---|
committer | Olivier Crête <olivier.crete@ocrete.ca> | 2021-11-01 19:55:51 +0000 |
commit | 48a8a4983f68ba23b6f7b2b0ccbd60a3ab973d30 (patch) | |
tree | fb4efa560ffcf5bbb8951a1e88574e21ca8edc15 | |
parent | 47a96334448838c43d7e72f4ef51b317befbfae1 (diff) | |
download | libnice-48a8a4983f68ba23b6f7b2b0ccbd60a3ab973d30.tar.gz |
Use native crypto support on Windows by default
As we only need a few primitives there isn't much OS-specific code
needed, and for applications that don't already depend on OpenSSL or
GnuTLS it simplifies the build process quite a lot.
Note that we use the vintage WinCrypt APIs as the Cryptography Next
Generation APIs are only available on Vista and newer.
-rw-r--r-- | meson.build | 4 | ||||
-rw-r--r-- | stun/rand.c | 15 | ||||
-rw-r--r-- | stun/stunhmac.c | 92 |
3 files changed, 106 insertions, 5 deletions
diff --git a/meson.build b/meson.build index e1d525e..30b565e 100644 --- a/meson.build +++ b/meson.build @@ -190,7 +190,9 @@ gthread_dep = dependency('gthread-2.0', # Cryto library opt_cryptolib = get_option('crypto-library') message('Crypto library requested: ' + opt_cryptolib) -if opt_cryptolib != 'openssl' +if opt_cryptolib == 'auto' and host_machine.system() == 'windows' + crypto_dep = cc.find_library('advapi32') +elif opt_cryptolib != 'openssl' crypto_dep = dependency('gnutls', version: gnutls_req, required: false) cdata.set('HAVE_GNUTLS', crypto_dep.found()) if not crypto_dep.found() and opt_cryptolib == 'auto' diff --git a/stun/rand.c b/stun/rand.c index 1361245..43d9149 100644 --- a/stun/rand.c +++ b/stun/rand.c @@ -39,7 +39,20 @@ #include "rand.h" -#if defined(HAVE_OPENSSL) +#if defined(_WIN32) + +#include <windows.h> + +void nice_RAND_nonce (uint8_t *dst, int len) +{ + HCRYPTPROV prov; + + CryptAcquireContextW (&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + CryptGenRandom (prov, len, dst); + CryptReleaseContext (prov, 0); +} + +#elif defined(HAVE_OPENSSL) #include <openssl/rand.h> diff --git a/stun/stunhmac.c b/stun/stunhmac.c index c9d183f..b42fc2e 100644 --- a/stun/stunhmac.c +++ b/stun/stunhmac.c @@ -48,7 +48,14 @@ #include <string.h> #include <assert.h> -#ifdef HAVE_OPENSSL +#if defined(_WIN32) +#include <malloc.h> +typedef struct _StunKeyBlob { + BLOBHEADER header; + DWORD key_size; + BYTE key_data[0]; +} StunKeyBlob; +#elif defined(HAVE_OPENSSL) #include <openssl/hmac.h> #include <openssl/sha.h> #else @@ -64,7 +71,67 @@ void stun_sha1 (const uint8_t *msg, size_t len, size_t msg_len, uint8_t *sha, assert (len >= 44u); -#ifdef HAVE_OPENSSL +#if defined(_WIN32) +{ + HCRYPTPROV prov; + size_t blob_size; + StunKeyBlob *blob; + BLOBHEADER *header; + HCRYPTKEY key_handle; + HCRYPTHASH hash; + HMAC_INFO info = {0}; + DWORD sha_digest_len; + +#ifdef NDEBUG +#define TRY(x) x; +#else + BOOL success; +#define TRY(x) \ + success = x; \ + assert (success); +#endif + + TRY (CryptAcquireContextW (&prov, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)); + + blob_size = sizeof (StunKeyBlob) + keylen; + blob = _malloca (blob_size); + header = &blob->header; + header->bType = PLAINTEXTKEYBLOB; + header->bVersion = CUR_BLOB_VERSION; + header->reserved = 0; + header->aiKeyAlg = CALG_RC2; + blob->key_size = keylen; + memcpy (blob->key_data, key, keylen); + TRY (CryptImportKey (prov, (const BYTE *) blob, blob_size, 0, + CRYPT_IPSEC_HMAC_KEY, &key_handle)); + _freea (blob); + + TRY (CryptCreateHash (prov, CALG_HMAC, key_handle, 0, &hash)); + + info.HashAlgid = CALG_SHA1; + TRY (CryptSetHashParam (hash, HP_HMAC_INFO, (const BYTE *) &info, 0)); + + TRY (CryptHashData (hash, msg, 2, 0)); + TRY (CryptHashData (hash, (const BYTE *) &fakelen, 2, 0)); + TRY (CryptHashData (hash, msg + 4, len - 28, 0)); + + /* 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 (CryptHashData (hash, pad_char, pad_size, 0)); + } + + sha_digest_len = 20; + TRY (CryptGetHashParam (hash, HP_HASHVAL, sha, &sha_digest_len, 0)); + + TRY (CryptDestroyHash (hash)); + TRY (CryptDestroyKey (key_handle)); + TRY (CryptReleaseContext (prov, 0)); +} +#elif defined(HAVE_OPENSSL) { #ifdef NDEBUG #define TRY(x) x; @@ -171,7 +238,26 @@ void stun_hash_creds (const uint8_t *realm, size_t realm_len, const uint8_t *realm_trimmed = priv_trim_var (realm, &realm_len); const uint8_t *colon = (uint8_t *)":"; -#ifdef HAVE_OPENSSL +#if defined(_WIN32) + HCRYPTPROV prov; + HCRYPTHASH hash; + DWORD md5_digest_len; + + CryptAcquireContextW (&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + CryptCreateHash (prov, CALG_MD5, 0, 0, &hash); + + CryptHashData (hash, username_trimmed, username_len, 0); + CryptHashData (hash, colon, 1, 0); + CryptHashData (hash, realm_trimmed, realm_len, 0); + CryptHashData (hash, colon, 1, 0); + CryptHashData (hash, password_trimmed, password_len, 0); + + md5_digest_len = 16; + CryptGetHashParam (hash, HP_HASHVAL, md5, &md5_digest_len, 0); + + CryptDestroyHash (hash); + CryptReleaseContext (prov, 0); +#elif defined(HAVE_OPENSSL) EVP_MD_CTX *ctx; #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ |