winpr/crypt api changes and memory leak fixes
- winpr_HMAC_New() now just returnes the opaque WINPR_HMAC_CTX* pointer which has to be passed to winpr_HMAC_Init() for (re)initialization and since winpr_HMAC_Final() no more frees the context you always have to use the new function winpr_HMAC_Free() once winpr_HMAC_New() has succeded - winpr_Digest_New() now just returns the opaque WINPR_DIGEST_CTX* pointer which has to be passed to winpr_Digest_Init() for (re)initialization and since winpr_Digest_Final() no more frees the context you always have to use the new function winpr_Digest_Free() once winpr_Digest_New() has succeded
This commit is contained in:
parent
7befab856c
commit
53bd98883e
@ -490,19 +490,19 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
||||
|
||||
if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
rdp->fips_encrypt = winpr_Cipher_New( WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_ENCRYPT,
|
||||
rdp->fips_encrypt_key,
|
||||
fips_ivec);
|
||||
rdp->fips_encrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_ENCRYPT,
|
||||
rdp->fips_encrypt_key,
|
||||
fips_ivec);
|
||||
if (!rdp->fips_encrypt)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 encrypt key");
|
||||
goto end;
|
||||
}
|
||||
rdp->fips_decrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_DECRYPT,
|
||||
rdp->fips_decrypt_key,
|
||||
fips_ivec);
|
||||
WINPR_DECRYPT,
|
||||
rdp->fips_decrypt_key,
|
||||
fips_ivec);
|
||||
if (!rdp->fips_decrypt)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 decrypt key");
|
||||
|
@ -45,7 +45,6 @@ static const char* const INFO_TYPE_LOGON_STRINGS[4] =
|
||||
|
||||
BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp)
|
||||
{
|
||||
WINPR_HMAC_CTX* hmac;
|
||||
BYTE ClientRandom[32];
|
||||
BYTE AutoReconnectRandom[32];
|
||||
ARC_SC_PRIVATE_PACKET* serverCookie;
|
||||
@ -70,11 +69,7 @@ BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp)
|
||||
|
||||
/* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */
|
||||
|
||||
if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, AutoReconnectRandom, 16)))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Update(hmac, ClientRandom, 32))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Final(hmac, clientCookie->securityVerifier, 16))
|
||||
if (!winpr_HMAC(WINPR_MD_MD5, AutoReconnectRandom, 16, ClientRandom, 32, clientCookie->securityVerifier, 16))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -127,36 +127,46 @@ fips_oddparity_table[256] =
|
||||
static BOOL security_salted_hash(const BYTE* salt, const BYTE* input, int length,
|
||||
const BYTE* salt1, const BYTE* salt2, BYTE* output)
|
||||
{
|
||||
WINPR_DIGEST_CTX* md5;
|
||||
WINPR_DIGEST_CTX* sha1;
|
||||
WINPR_DIGEST_CTX* sha1 = NULL;
|
||||
WINPR_DIGEST_CTX* md5 = NULL;
|
||||
BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BOOL result = FALSE;
|
||||
|
||||
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */
|
||||
|
||||
/* SHA1_Digest = SHA1(Input + Salt + Salt1 + Salt2) */
|
||||
if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1)))
|
||||
return FALSE;
|
||||
if (!(sha1 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, input, length)) /* Input */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, salt, 48)) /* Salt (48 bytes) */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, salt1, 32)) /* Salt1 (32 bytes) */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, salt2, 32)) /* Salt2 (32 bytes) */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
return FALSE;
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, salt, 48)) /* Salt (48 bytes) */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
goto out;
|
||||
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(sha1);
|
||||
winpr_Digest_Free(md5);
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL security_premaster_hash(const char* input, int length, const BYTE* premaster_secret,
|
||||
@ -200,19 +210,26 @@ void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_rand
|
||||
|
||||
BOOL security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output)
|
||||
{
|
||||
WINPR_DIGEST_CTX* md5;
|
||||
WINPR_DIGEST_CTX* md5 = NULL;
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, in0, 16))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, in1, 32))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, in2, 32))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
goto out;
|
||||
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(md5);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random,
|
||||
@ -233,92 +250,112 @@ void security_UINT32_le(BYTE* output, UINT32 value)
|
||||
BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length,
|
||||
BYTE* output)
|
||||
{
|
||||
WINPR_DIGEST_CTX* md5;
|
||||
WINPR_DIGEST_CTX* sha1;
|
||||
WINPR_DIGEST_CTX* sha1 = NULL;
|
||||
WINPR_DIGEST_CTX* md5 = NULL;
|
||||
BYTE length_le[4];
|
||||
BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BOOL result = FALSE;
|
||||
|
||||
/* MacData = MD5(MacSaltKey + pad2 + SHA1(MacSaltKey + pad1 + length + data)) */
|
||||
|
||||
security_UINT32_le(length_le, length); /* length must be little-endian */
|
||||
|
||||
/* SHA1_Digest = SHA1(MacSaltKey + pad1 + length + data) */
|
||||
if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1)))
|
||||
return FALSE;
|
||||
if (!(sha1 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, mac_salt_key, 16)) /* MacSaltKey */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, data, length)) /* data */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
/* MacData = MD5(MacSaltKey + pad2 + SHA1_Digest) */
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
return FALSE;
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, mac_salt_key, 16)) /* MacSaltKey */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(md5, output, WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
goto out;
|
||||
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(sha1);
|
||||
winpr_Digest_Free(md5);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output)
|
||||
{
|
||||
WINPR_DIGEST_CTX* md5;
|
||||
WINPR_DIGEST_CTX* sha1;
|
||||
WINPR_DIGEST_CTX* sha1 = NULL;
|
||||
WINPR_DIGEST_CTX* md5 = NULL;
|
||||
BYTE length_le[4];
|
||||
BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH];
|
||||
BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BOOL result = FALSE;
|
||||
|
||||
security_UINT32_le(length_le, length); /* length must be little-endian */
|
||||
|
||||
/* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */
|
||||
if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1)))
|
||||
return FALSE;
|
||||
if (!(sha1 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, data, length)) /* data */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
/* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
return FALSE;
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(md5, md5_digest, sizeof(md5_digest)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
memcpy(output, md5_digest, 8);
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(sha1);
|
||||
winpr_Digest_Free(md5);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
||||
BOOL encryption, BYTE* output)
|
||||
{
|
||||
WINPR_DIGEST_CTX* md5;
|
||||
WINPR_DIGEST_CTX* sha1;
|
||||
WINPR_DIGEST_CTX* sha1 = NULL;
|
||||
WINPR_DIGEST_CTX* md5 = NULL;
|
||||
BYTE length_le[4];
|
||||
BYTE use_count_le[4];
|
||||
BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH];
|
||||
BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BOOL result = FALSE;
|
||||
|
||||
security_UINT32_le(length_le, length); /* length must be little-endian */
|
||||
|
||||
@ -336,35 +373,43 @@ BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
||||
}
|
||||
|
||||
/* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */
|
||||
if (!(sha1 = winpr_Digest_New( WINPR_MD_SHA1)))
|
||||
return FALSE;
|
||||
if (!(sha1 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1))) /* pad1 */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, length_le, sizeof(length_le))) /* length */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, data, length)) /* data */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, use_count_le, sizeof(use_count_le))) /* encryptionCount */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(sha1, sha1_digest, sizeof(sha1_digest)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
/* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
return FALSE;
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, pad2, sizeof(pad2))) /* pad2 */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(md5, md5_digest, sizeof(md5_digest)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
memcpy(output, md5_digest, 8);
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(sha1);
|
||||
winpr_Digest_Free(md5);
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL security_A(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
|
||||
@ -437,34 +482,39 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
|
||||
BYTE client_encrypt_key_t[WINPR_SHA1_DIGEST_LENGTH + 1];
|
||||
BYTE client_decrypt_key_t[WINPR_SHA1_DIGEST_LENGTH + 1];
|
||||
|
||||
if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1)))
|
||||
if (!(sha1 = winpr_Digest_New()))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Update(sha1, client_random + 16, 16))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Update(sha1, server_random + 16, 16))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Final(sha1, client_encrypt_key_t, sizeof(client_encrypt_key_t)))
|
||||
|
||||
if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1) ||
|
||||
!winpr_Digest_Update(sha1, client_random + 16, 16) ||
|
||||
!winpr_Digest_Update(sha1, server_random + 16, 16) ||
|
||||
!winpr_Digest_Final(sha1, client_encrypt_key_t, sizeof(client_encrypt_key_t)))
|
||||
{
|
||||
winpr_Digest_Free(sha1);
|
||||
return FALSE;
|
||||
}
|
||||
client_encrypt_key_t[20] = client_encrypt_key_t[0];
|
||||
|
||||
if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1)))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Update(sha1, client_random, 16))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Update(sha1, server_random, 16))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Final(sha1, client_decrypt_key_t, sizeof(client_decrypt_key_t)))
|
||||
if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1) ||
|
||||
!winpr_Digest_Update(sha1, client_random, 16) ||
|
||||
!winpr_Digest_Update(sha1, server_random, 16) ||
|
||||
!winpr_Digest_Final(sha1, client_decrypt_key_t, sizeof(client_decrypt_key_t)))
|
||||
{
|
||||
winpr_Digest_Free(sha1);
|
||||
return FALSE;
|
||||
}
|
||||
client_decrypt_key_t[20] = client_decrypt_key_t[0];
|
||||
|
||||
if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1)))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Update(sha1, client_decrypt_key_t, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Update(sha1, client_encrypt_key_t, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
if (!winpr_Digest_Final(sha1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))
|
||||
if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1) ||
|
||||
!winpr_Digest_Update(sha1, client_decrypt_key_t, WINPR_SHA1_DIGEST_LENGTH) ||
|
||||
!winpr_Digest_Update(sha1, client_encrypt_key_t, WINPR_SHA1_DIGEST_LENGTH) ||
|
||||
!winpr_Digest_Final(sha1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))
|
||||
{
|
||||
winpr_Digest_Free(sha1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
winpr_Digest_Free(sha1);
|
||||
|
||||
if (rdp->settings->ServerMode)
|
||||
{
|
||||
@ -536,48 +586,56 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
|
||||
BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
|
||||
{
|
||||
BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH];
|
||||
WINPR_DIGEST_CTX* md5;
|
||||
WINPR_DIGEST_CTX* sha1;
|
||||
WINPR_RC4_CTX* rc4;
|
||||
WINPR_DIGEST_CTX* sha1 = NULL;
|
||||
WINPR_DIGEST_CTX* md5 = NULL;
|
||||
WINPR_RC4_CTX* rc4 = NULL;
|
||||
BOOL rc;
|
||||
BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!(sha1 = winpr_Digest_New(WINPR_MD_SHA1)))
|
||||
return FALSE;
|
||||
if (!(sha1 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, update_key, key_len))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, pad1, sizeof(pad1)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(sha1, key, key_len))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(sha1, sha1h, sizeof(sha1h)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
return FALSE;
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
goto out;
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, update_key, key_len))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, pad2, sizeof(pad2)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(md5, sha1h, sizeof(sha1h)))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(md5, key, WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
if (!(rc4 = winpr_RC4_New(key, key_len)))
|
||||
return FALSE;
|
||||
rc = winpr_RC4_Update(rc4, key_len, key, key);
|
||||
winpr_RC4_Free(rc4);
|
||||
|
||||
if (!rc)
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_RC4_Update(rc4, key_len, key, key))
|
||||
goto out;
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
|
||||
memcpy(key, salt, 3);
|
||||
else if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_56BIT)
|
||||
memcpy(key, salt, 1);
|
||||
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(sha1);
|
||||
winpr_Digest_Free(md5);
|
||||
winpr_RC4_Free(rc4);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
@ -631,20 +689,26 @@ BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp*
|
||||
BYTE buf[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BYTE use_count_le[4];
|
||||
WINPR_HMAC_CTX* hmac;
|
||||
BOOL result = FALSE;
|
||||
|
||||
security_UINT32_le(use_count_le, rdp->encrypt_use_count);
|
||||
|
||||
if (!(hmac = winpr_HMAC_New(WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)))
|
||||
if (!(hmac = winpr_HMAC_New()))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Init(hmac, WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))
|
||||
goto out;
|
||||
if (!winpr_HMAC_Update(hmac, data, length))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_HMAC_Update(hmac, use_count_le, 4))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_HMAC_Final(hmac, buf, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
memmove(output, buf, 8);
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_HMAC_Free(hmac);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
@ -671,22 +735,26 @@ BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig
|
||||
BYTE buf[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BYTE use_count_le[4];
|
||||
WINPR_HMAC_CTX* hmac;
|
||||
BOOL result = FALSE;
|
||||
|
||||
security_UINT32_le(use_count_le, rdp->decrypt_use_count);
|
||||
|
||||
if (!(hmac = winpr_HMAC_New(WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH)))
|
||||
if (!(hmac = winpr_HMAC_New()))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Init(hmac, WINPR_MD_SHA1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))
|
||||
goto out;
|
||||
if (!winpr_HMAC_Update(hmac, data, length))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_HMAC_Update(hmac, use_count_le, 4))
|
||||
return FALSE;
|
||||
goto out;
|
||||
if (!winpr_HMAC_Final(hmac, buf, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
rdp->decrypt_use_count++;
|
||||
|
||||
if (memcmp(sig, buf, 8))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
if (!memcmp(sig, buf, 8))
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_HMAC_Free(hmac);
|
||||
return result;
|
||||
}
|
||||
|
@ -249,17 +249,11 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr)
|
||||
{
|
||||
case BIO_CTRL_RESET:
|
||||
SSL_shutdown(tls->ssl);
|
||||
#if 1
|
||||
|
||||
if (SSL_in_connect_init(tls->ssl))
|
||||
SSL_set_connect_state(tls->ssl);
|
||||
else if (SSL_in_accept_init(tls->ssl))
|
||||
SSL_set_accept_state(tls->ssl);
|
||||
#else
|
||||
if (tls->ssl->handshake_func == tls->ssl->method->ssl_connect)
|
||||
SSL_set_connect_state(tls->ssl);
|
||||
else if (tls->ssl->handshake_func == tls->ssl->method->ssl_accept)
|
||||
SSL_set_accept_state(tls->ssl);
|
||||
#endif
|
||||
|
||||
SSL_clear(tls->ssl);
|
||||
|
||||
|
@ -642,10 +642,11 @@ typedef struct _winpr_hmac_ctx_private_st WINPR_HMAC_CTX;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WINPR_API WINPR_HMAC_CTX* winpr_HMAC_New(WINPR_MD_TYPE md, const BYTE* key, size_t keylen);
|
||||
WINPR_API WINPR_HMAC_CTX* winpr_HMAC_New(void);
|
||||
WINPR_API BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen);
|
||||
WINPR_API BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen);
|
||||
WINPR_API BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t ilen);
|
||||
//WINPR_API void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx);
|
||||
WINPR_API void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx);
|
||||
WINPR_API BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen,
|
||||
const BYTE* input, size_t ilen, BYTE* output, size_t olen);
|
||||
|
||||
@ -663,7 +664,8 @@ typedef struct _winpr_digest_ctx_private_st WINPR_DIGEST_CTX;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WINPR_API WINPR_DIGEST_CTX* winpr_Digest_New(WINPR_MD_TYPE md);
|
||||
WINPR_API WINPR_DIGEST_CTX* winpr_Digest_New(void);
|
||||
WINPR_API BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md);
|
||||
WINPR_API BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen);
|
||||
WINPR_API BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t ilen);
|
||||
WINPR_API void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx);
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include <mbedtls/cipher.h>
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* RC4
|
||||
*/
|
||||
@ -69,12 +68,13 @@ BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
RC4((RC4_KEY*) ctx, length, input, output);
|
||||
return TRUE;
|
||||
|
||||
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
|
||||
if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) != 0)
|
||||
return FALSE;
|
||||
if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
|
||||
@ -308,6 +308,7 @@ const EVP_CIPHER* winpr_openssl_get_evp_cipher(int cipher)
|
||||
|
||||
return evp;
|
||||
}
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher)
|
||||
{
|
||||
@ -592,15 +593,18 @@ BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const BYTE* input, size_t ilen,
|
||||
#if defined(WITH_OPENSSL)
|
||||
int outl = (int) *olen;
|
||||
|
||||
if (EVP_CipherUpdate((EVP_CIPHER_CTX*) ctx, output, &outl, input, ilen) != 1)
|
||||
return FALSE;
|
||||
if (EVP_CipherUpdate((EVP_CIPHER_CTX*) ctx, output, &outl, input, ilen) == 1)
|
||||
{
|
||||
*olen = (size_t) outl;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*olen = (size_t) outl;
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
if (mbedtls_cipher_update((mbedtls_cipher_context_t*) ctx, input, ilen, output, olen) != 0)
|
||||
return FALSE;
|
||||
if (mbedtls_cipher_update((mbedtls_cipher_context_t*) ctx, input, ilen, output, olen) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen)
|
||||
@ -608,15 +612,18 @@ BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen)
|
||||
#if defined(WITH_OPENSSL)
|
||||
int outl = (int) *olen;
|
||||
|
||||
if (EVP_CipherFinal_ex((EVP_CIPHER_CTX*) ctx, output, &outl) != 1)
|
||||
return FALSE;
|
||||
if (EVP_CipherFinal_ex((EVP_CIPHER_CTX*) ctx, output, &outl) == 1)
|
||||
{
|
||||
*olen = (size_t) outl;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*olen = (size_t) outl;
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
if (mbedtls_cipher_finish((mbedtls_cipher_context_t*) ctx, output, olen) != 0)
|
||||
return FALSE;
|
||||
if (mbedtls_cipher_finish((mbedtls_cipher_context_t*) ctx, output, olen) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
|
||||
|
@ -142,32 +142,126 @@ mbedtls_md_type_t winpr_mbedtls_get_md_type(int md)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
WINPR_HMAC_CTX* winpr_HMAC_New(WINPR_MD_TYPE md, const BYTE* key, size_t keylen)
|
||||
WINPR_HMAC_CTX* winpr_HMAC_New(void)
|
||||
{
|
||||
WINPR_HMAC_CTX* ctx = NULL;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
HMAC_CTX* hmac;
|
||||
|
||||
if (!evp)
|
||||
return NULL;
|
||||
|
||||
HMAC_CTX* hmac = NULL;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
if (!(hmac = calloc(1, sizeof(HMAC_CTX))))
|
||||
if (!(hmac = (HMAC_CTX*) calloc(1, sizeof(HMAC_CTX))))
|
||||
return NULL;
|
||||
|
||||
HMAC_CTX_init(hmac);
|
||||
#else
|
||||
if (!(hmac = HMAC_CTX_new()))
|
||||
return NULL;
|
||||
#endif
|
||||
ctx = (WINPR_HMAC_CTX*) hmac;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* hmac;
|
||||
if (!(hmac = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t))))
|
||||
return NULL;
|
||||
|
||||
mbedtls_md_init(hmac);
|
||||
|
||||
ctx = (WINPR_HMAC_CTX*) hmac;
|
||||
#endif
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*) ctx;
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
|
||||
if (!evp || !hmac)
|
||||
return FALSE;
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
HMAC_Init_ex(hmac, key, keylen, evp, NULL);
|
||||
HMAC_Init_ex(hmac, key, keylen, evp, NULL); /* no return value on OpenSSL 0.9.x */
|
||||
return TRUE;
|
||||
#else
|
||||
if (HMAC_Init_ex(hmac, key, keylen, evp, NULL) != 1)
|
||||
if (HMAC_Init_ex(hmac, key, keylen, evp, NULL) == 1)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* hmac = (mbedtls_md_context_t*) ctx;
|
||||
mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
|
||||
const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
|
||||
|
||||
if (!md_info || !hmac)
|
||||
return FALSE;
|
||||
|
||||
if (hmac->md_info != md_info)
|
||||
{
|
||||
mbedtls_md_free(hmac); /* can be called at any time after mbedtls_md_init */
|
||||
|
||||
if (mbedtls_md_setup(hmac, md_info, 1) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mbedtls_md_hmac_starts(hmac, key, keylen) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*) ctx;
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
HMAC_Update(hmac, input, ilen); /* no return value on OpenSSL 0.9.x */
|
||||
return TRUE;
|
||||
#else
|
||||
if (HMAC_Update(hmac, input, ilen) == 1)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
if (mbedtls_md_hmac_update(mdctx, input, ilen) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
|
||||
{
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*) ctx;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
HMAC_Final(hmac, output, NULL); /* no return value on OpenSSL 0.9.x */
|
||||
return TRUE;
|
||||
#else
|
||||
if (HMAC_Final(hmac, output, NULL) == 1)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
if (mbedtls_md_hmac_finish(mdctx, output) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*) ctx;
|
||||
if (hmac)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
HMAC_CTX_cleanup(hmac);
|
||||
@ -175,178 +269,103 @@ WINPR_HMAC_CTX* winpr_HMAC_New(WINPR_MD_TYPE md, const BYTE* key, size_t keylen)
|
||||
#else
|
||||
HMAC_CTX_free(hmac);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
ctx = (WINPR_HMAC_CTX*) hmac;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx;
|
||||
mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
|
||||
const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
|
||||
|
||||
if (!md_info)
|
||||
return NULL;
|
||||
|
||||
if (!(mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t))))
|
||||
return NULL;
|
||||
|
||||
mbedtls_md_init(mdctx);
|
||||
|
||||
if (mbedtls_md_setup(mdctx, md_info, 1) != 0)
|
||||
mbedtls_md_context_t* hmac = (mbedtls_md_context_t*) ctx;
|
||||
if (hmac)
|
||||
{
|
||||
mbedtls_md_free(mdctx);
|
||||
free(mdctx);
|
||||
return NULL;
|
||||
mbedtls_md_free(hmac);
|
||||
free(hmac);
|
||||
}
|
||||
|
||||
if (mbedtls_md_hmac_starts(mdctx, key, keylen) != 0)
|
||||
{
|
||||
mbedtls_md_free(mdctx);
|
||||
free(mdctx);
|
||||
return NULL;
|
||||
}
|
||||
ctx = (WINPR_HMAC_CTX*) mdctx;
|
||||
#endif
|
||||
return ctx;
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*) ctx;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
HMAC_Update(hmac, input, ilen);
|
||||
#else
|
||||
if (HMAC_Update(hmac, input, ilen) != 1)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
if (mbedtls_md_hmac_update(mdctx, input, ilen) != 0)
|
||||
return FALSE;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
|
||||
{
|
||||
/* TODO
|
||||
if (olen < ctx->digestLength)
|
||||
return FALSE;
|
||||
*/
|
||||
BOOL ret = TRUE;
|
||||
#if defined(WITH_OPENSSL)
|
||||
HMAC_CTX* hmac = (HMAC_CTX*) ctx;
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
HMAC_Final(hmac, output, NULL);
|
||||
#else
|
||||
if (HMAC_Final(hmac, output, NULL) != 1)
|
||||
ret = FALSE;
|
||||
#endif
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
HMAC_CTX_cleanup(hmac);
|
||||
free(hmac);
|
||||
#else
|
||||
HMAC_CTX_free(hmac);
|
||||
#endif
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
if (mbedtls_md_hmac_finish(mdctx, output) != 0)
|
||||
ret = FALSE;
|
||||
|
||||
mbedtls_md_free((mbedtls_md_context_t*) ctx);
|
||||
free(mdctx);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen,
|
||||
const BYTE* input, size_t ilen, BYTE* output, size_t olen)
|
||||
{
|
||||
WINPR_HMAC_CTX *ctx = winpr_HMAC_New(md, key, keylen);
|
||||
BOOL result = FALSE;
|
||||
WINPR_HMAC_CTX *ctx = winpr_HMAC_New();
|
||||
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
if (!winpr_HMAC_Init(ctx, md, key, keylen))
|
||||
goto out;
|
||||
if (!winpr_HMAC_Update(ctx, input, ilen))
|
||||
return FALSE;
|
||||
|
||||
goto out;
|
||||
if (!winpr_HMAC_Final(ctx, output, olen))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_HMAC_Free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Digest API
|
||||
*/
|
||||
|
||||
WINPR_DIGEST_CTX* winpr_Digest_New(WINPR_MD_TYPE md)
|
||||
WINPR_DIGEST_CTX* winpr_Digest_New(void)
|
||||
{
|
||||
WINPR_DIGEST_CTX* ctx = NULL;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
EVP_MD_CTX* mdctx;
|
||||
|
||||
if (!evp)
|
||||
return NULL;
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
mdctx = EVP_MD_CTX_create();
|
||||
#else
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
#endif
|
||||
if (!mdctx)
|
||||
return NULL;
|
||||
|
||||
if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
#else
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
ctx = (WINPR_DIGEST_CTX*) mdctx;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx;
|
||||
mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
|
||||
const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
|
||||
|
||||
if (!md_info)
|
||||
return NULL;
|
||||
|
||||
if (!(mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t))))
|
||||
return NULL;
|
||||
|
||||
mbedtls_md_init(mdctx);
|
||||
|
||||
if (mbedtls_md_setup(mdctx, md_info, 0) != 0)
|
||||
{
|
||||
mbedtls_md_free(mdctx);
|
||||
free(mdctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mbedtls_md_starts(mdctx) != 0)
|
||||
{
|
||||
mbedtls_md_free(mdctx);
|
||||
free(mdctx);
|
||||
return NULL;
|
||||
}
|
||||
mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t));
|
||||
if (mdctx)
|
||||
mbedtls_md_init(mdctx);
|
||||
ctx = (WINPR_DIGEST_CTX*) mdctx;
|
||||
#endif
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx;
|
||||
const EVP_MD* evp = winpr_openssl_get_evp_md(md);
|
||||
|
||||
if (!mdctx || !evp)
|
||||
return FALSE;
|
||||
|
||||
if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1)
|
||||
return FALSE;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
|
||||
const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
|
||||
|
||||
if (!md_info)
|
||||
return FALSE;
|
||||
|
||||
if (mdctx->md_info != md_info)
|
||||
{
|
||||
mbedtls_md_free(mdctx); /* can be called at any time after mbedtls_md_init */
|
||||
|
||||
if (mbedtls_md_setup(mdctx, md_info, 0) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mbedtls_md_starts(mdctx) != 0)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
@ -363,42 +382,60 @@ BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen)
|
||||
|
||||
BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen)
|
||||
{
|
||||
// TODO: output length check
|
||||
BOOL ret = TRUE;
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx;
|
||||
if (EVP_DigestFinal_ex(mdctx, output, NULL) != 1)
|
||||
ret = FALSE;
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
#else
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
#endif
|
||||
if (EVP_DigestFinal_ex(mdctx, output, NULL) == 1)
|
||||
return TRUE;
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
if (mbedtls_md_finish(mdctx, output) != 0)
|
||||
ret = FALSE;
|
||||
|
||||
mbedtls_md_free(mdctx);
|
||||
free(mdctx);
|
||||
if (mbedtls_md_finish(mdctx, output) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx)
|
||||
{
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx;
|
||||
if (mdctx)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
#else
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx;
|
||||
if (mdctx)
|
||||
{
|
||||
mbedtls_md_free(mdctx);
|
||||
free(mdctx);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen)
|
||||
{
|
||||
WINPR_DIGEST_CTX *ctx = winpr_Digest_New(md);
|
||||
BOOL result = FALSE;
|
||||
WINPR_DIGEST_CTX *ctx = winpr_Digest_New();
|
||||
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
if (!winpr_Digest_Init(ctx, md))
|
||||
goto out;
|
||||
if (!winpr_Digest_Update(ctx, input, ilen))
|
||||
return FALSE;
|
||||
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(ctx, output, olen))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
@ -8,25 +8,30 @@ static const BYTE* TEST_MD5_HASH = (BYTE*) "\x09\x8f\x6b\xcd\x46\x21\xd3\x73\xca
|
||||
|
||||
static BOOL test_crypto_hash_md5(void)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
BYTE hash[WINPR_MD5_DIGEST_LENGTH];
|
||||
WINPR_DIGEST_CTX* ctx;
|
||||
|
||||
if (!(ctx = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
if (!(ctx = winpr_Digest_New()))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
if (!winpr_Digest_Init(ctx, WINPR_MD_MD5))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Init failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_Digest_Update(ctx, (BYTE*) TEST_MD5_DATA, strlen(TEST_MD5_DATA)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_Digest_Final(ctx, hash, sizeof(hash)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (memcmp(hash, TEST_MD5_HASH, WINPR_MD5_DIGEST_LENGTH) != 0)
|
||||
{
|
||||
char* actual;
|
||||
@ -40,10 +45,13 @@ static BOOL test_crypto_hash_md5(void)
|
||||
free(actual);
|
||||
free(expected);
|
||||
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
static const char* TEST_MD4_DATA = "test";
|
||||
@ -51,25 +59,30 @@ static const BYTE* TEST_MD4_HASH = (BYTE*) "\xdb\x34\x6d\x69\x1d\x7a\xcc\x4d\xc2
|
||||
|
||||
static BOOL test_crypto_hash_md4(void)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
BYTE hash[WINPR_MD4_DIGEST_LENGTH];
|
||||
WINPR_DIGEST_CTX* ctx;
|
||||
|
||||
if (!(ctx = winpr_Digest_New(WINPR_MD_MD4)))
|
||||
if (!(ctx = winpr_Digest_New()))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
if (!winpr_Digest_Init(ctx, WINPR_MD_MD4))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Init failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_Digest_Update(ctx, (BYTE*) TEST_MD4_DATA, strlen(TEST_MD4_DATA)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_Digest_Final(ctx, hash, sizeof(hash)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (memcmp(hash, TEST_MD4_HASH, WINPR_MD4_DIGEST_LENGTH) != 0)
|
||||
{
|
||||
char* actual;
|
||||
@ -83,10 +96,13 @@ static BOOL test_crypto_hash_md4(void)
|
||||
free(actual);
|
||||
free(expected);
|
||||
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
static const char* TEST_SHA1_DATA = "test";
|
||||
@ -94,23 +110,29 @@ static const BYTE* TEST_SHA1_HASH = (BYTE*) "\xa9\x4a\x8f\xe5\xcc\xb1\x9b\xa6\x1
|
||||
|
||||
static BOOL test_crypto_hash_sha1(void)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
BYTE hash[WINPR_SHA1_DIGEST_LENGTH];
|
||||
WINPR_DIGEST_CTX* ctx;
|
||||
|
||||
if (!(ctx = winpr_Digest_New(WINPR_MD_SHA1)))
|
||||
if (!(ctx = winpr_Digest_New()))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_New failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
if (!winpr_Digest_Init(ctx, WINPR_MD_SHA1))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Init failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_Digest_Update(ctx, (BYTE*) TEST_SHA1_DATA, strlen(TEST_SHA1_DATA)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Update failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_Digest_Final(ctx, hash, sizeof(hash)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_Digest_Final failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (memcmp(hash, TEST_SHA1_HASH, WINPR_MD5_DIGEST_LENGTH) != 0)
|
||||
@ -126,10 +148,13 @@ static BOOL test_crypto_hash_sha1(void)
|
||||
free(actual);
|
||||
free(expected);
|
||||
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_Digest_Free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
static const char* TEST_HMAC_MD5_DATA = "Hi There";
|
||||
@ -140,21 +165,28 @@ static BOOL test_crypto_hash_hmac_md5(void)
|
||||
{
|
||||
BYTE hash[WINPR_MD5_DIGEST_LENGTH];
|
||||
WINPR_HMAC_CTX* ctx;
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!(ctx = winpr_HMAC_New(WINPR_MD_MD5, TEST_HMAC_MD5_KEY, WINPR_MD5_DIGEST_LENGTH)))
|
||||
if (!(ctx = winpr_HMAC_New()))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_New failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!winpr_HMAC_Init(ctx, WINPR_MD_MD5, TEST_HMAC_MD5_KEY, WINPR_MD5_DIGEST_LENGTH))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Init failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_HMAC_Update(ctx, (BYTE*) TEST_HMAC_MD5_DATA, strlen(TEST_HMAC_MD5_DATA)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_HMAC_Final(ctx, hash, sizeof(hash)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Final failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (memcmp(hash, TEST_HMAC_MD5_HASH, WINPR_MD5_DIGEST_LENGTH) != 0)
|
||||
@ -170,10 +202,13 @@ static BOOL test_crypto_hash_hmac_md5(void)
|
||||
free(actual);
|
||||
free(expected);
|
||||
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_HMAC_Free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
static const char* TEST_HMAC_SHA1_DATA = "Hi There";
|
||||
@ -184,21 +219,28 @@ static BOOL test_crypto_hash_hmac_sha1(void)
|
||||
{
|
||||
BYTE hash[WINPR_SHA1_DIGEST_LENGTH];
|
||||
WINPR_HMAC_CTX* ctx;
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!(ctx = winpr_HMAC_New(WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, WINPR_SHA1_DIGEST_LENGTH)))
|
||||
if (!(ctx = winpr_HMAC_New()))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_New failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!winpr_HMAC_Init(ctx, WINPR_MD_SHA1, TEST_HMAC_SHA1_KEY, WINPR_SHA1_DIGEST_LENGTH))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Init failed\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_HMAC_Update(ctx, (BYTE*) TEST_HMAC_SHA1_DATA, strlen(TEST_HMAC_SHA1_DATA)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Update failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
if (!winpr_HMAC_Final(ctx, hash, sizeof(hash)))
|
||||
{
|
||||
fprintf(stderr, "%s: winpr_HMAC_Final failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (memcmp(hash, TEST_HMAC_SHA1_HASH, WINPR_SHA1_DIGEST_LENGTH) != 0)
|
||||
@ -214,10 +256,13 @@ static BOOL test_crypto_hash_hmac_sha1(void)
|
||||
free(actual);
|
||||
free(expected);
|
||||
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
result = TRUE;
|
||||
out:
|
||||
winpr_HMAC_Free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
int TestCryptoHash(int argc, char* argv[])
|
||||
|
@ -943,17 +943,22 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
|
||||
|
||||
CopyMemory(data, data_buffer->pvBuffer, length);
|
||||
/* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */
|
||||
if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH)))
|
||||
hmac = winpr_HMAC_New();
|
||||
if (hmac && winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH))
|
||||
{
|
||||
Data_Write_UINT32(&value, SeqNo);
|
||||
winpr_HMAC_Update(hmac, (void*) &value, 4);
|
||||
winpr_HMAC_Update(hmac, (void*) data, length);
|
||||
winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH);
|
||||
winpr_HMAC_Free(hmac);
|
||||
}
|
||||
else
|
||||
{
|
||||
winpr_HMAC_Free(hmac);
|
||||
free(data);
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
Data_Write_UINT32(&value, SeqNo);
|
||||
winpr_HMAC_Update(hmac, (void*) &value, 4);
|
||||
winpr_HMAC_Update(hmac, (void*) data, length);
|
||||
winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH);
|
||||
|
||||
/* Encrypt message using with RC4, result overwrites original buffer */
|
||||
|
||||
if (context->confidentiality)
|
||||
@ -1032,15 +1037,21 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD
|
||||
CopyMemory(data_buffer->pvBuffer, data, length);
|
||||
|
||||
/* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */
|
||||
if (!(hmac = winpr_HMAC_New(WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH)))
|
||||
hmac = winpr_HMAC_New();
|
||||
if (hmac && winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH))
|
||||
{
|
||||
Data_Write_UINT32(&value, SeqNo);
|
||||
winpr_HMAC_Update(hmac, (void*) &value, 4);
|
||||
winpr_HMAC_Update(hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer);
|
||||
winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH);
|
||||
winpr_HMAC_Free(hmac);
|
||||
}
|
||||
else
|
||||
{
|
||||
winpr_HMAC_Free(hmac);
|
||||
free(data);
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
Data_Write_UINT32(&value, SeqNo);
|
||||
winpr_HMAC_Update(hmac, (void*) &value, 4);
|
||||
winpr_HMAC_Update(hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer);
|
||||
winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH);
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
WLog_DBG(TAG, "Encrypted Data Buffer (length = %d)", length);
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, data, length);
|
||||
|
@ -246,14 +246,14 @@ typedef struct gss_channel_bindings_struct {
|
||||
} *gss_channel_bindings_t;
|
||||
*/
|
||||
|
||||
static void ntlm_md5_update_uint32_be(WINPR_DIGEST_CTX* md5, UINT32 num)
|
||||
static BOOL ntlm_md5_update_uint32_be(WINPR_DIGEST_CTX* md5, UINT32 num)
|
||||
{
|
||||
BYTE be32[4];
|
||||
be32[0] = (num >> 0) & 0xFF;
|
||||
be32[1] = (num >> 8) & 0xFF;
|
||||
be32[2] = (num >> 16) & 0xFF;
|
||||
be32[3] = (num >> 24) & 0xFF;
|
||||
winpr_Digest_Update(md5, be32, 4);
|
||||
return winpr_Digest_Update(md5, be32, 4);
|
||||
}
|
||||
|
||||
void ntlm_compute_channel_bindings(NTLM_CONTEXT* context)
|
||||
@ -269,20 +269,33 @@ void ntlm_compute_channel_bindings(NTLM_CONTEXT* context)
|
||||
if (!ChannelBindings)
|
||||
return;
|
||||
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
if (!(md5 = winpr_Digest_New()))
|
||||
return;
|
||||
|
||||
if (!winpr_Digest_Init(md5, WINPR_MD_MD5))
|
||||
goto out;
|
||||
|
||||
ChannelBindingTokenLength = context->Bindings.BindingsLength - sizeof(SEC_CHANNEL_BINDINGS);
|
||||
ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset];
|
||||
|
||||
ntlm_md5_update_uint32_be(md5, ChannelBindings->dwInitiatorAddrType);
|
||||
ntlm_md5_update_uint32_be(md5, ChannelBindings->cbInitiatorLength);
|
||||
ntlm_md5_update_uint32_be(md5, ChannelBindings->dwAcceptorAddrType);
|
||||
ntlm_md5_update_uint32_be(md5, ChannelBindings->cbAcceptorLength);
|
||||
ntlm_md5_update_uint32_be(md5, ChannelBindings->cbApplicationDataLength);
|
||||
if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->dwInitiatorAddrType))
|
||||
goto out;
|
||||
if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbInitiatorLength))
|
||||
goto out;
|
||||
if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->dwAcceptorAddrType))
|
||||
goto out;
|
||||
if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbAcceptorLength))
|
||||
goto out;
|
||||
if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbApplicationDataLength))
|
||||
goto out;
|
||||
|
||||
winpr_Digest_Update(md5, (void*) ChannelBindingToken, ChannelBindingTokenLength);
|
||||
winpr_Digest_Final(md5, context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH);
|
||||
if (!winpr_Digest_Update(md5, (void*) ChannelBindingToken, ChannelBindingTokenLength))
|
||||
goto out;
|
||||
if (!winpr_Digest_Final(md5, context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH))
|
||||
goto out;
|
||||
|
||||
out:
|
||||
winpr_Digest_Free(md5);
|
||||
}
|
||||
|
||||
void ntlm_compute_single_host_data(NTLM_CONTEXT* context)
|
||||
|
@ -549,7 +549,6 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic,
|
||||
{
|
||||
int length;
|
||||
BYTE* value;
|
||||
WINPR_DIGEST_CTX* md5;
|
||||
|
||||
length = WINPR_MD5_DIGEST_LENGTH + sign_magic->cbBuffer;
|
||||
value = (BYTE*) malloc(length);
|
||||
@ -561,13 +560,11 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic,
|
||||
CopyMemory(value, exported_session_key, WINPR_MD5_DIGEST_LENGTH);
|
||||
CopyMemory(&value[WINPR_MD5_DIGEST_LENGTH], sign_magic->pvBuffer, sign_magic->cbBuffer);
|
||||
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
if (!winpr_Digest(WINPR_MD_MD5, value, length, signing_key, WINPR_MD5_DIGEST_LENGTH))
|
||||
{
|
||||
free(value);
|
||||
return -1;
|
||||
}
|
||||
winpr_Digest_Update(md5, value, length);
|
||||
winpr_Digest_Final(md5, signing_key, WINPR_MD5_DIGEST_LENGTH);
|
||||
free(value);
|
||||
return 1;
|
||||
}
|
||||
@ -611,7 +608,6 @@ void ntlm_generate_server_signing_key(NTLM_CONTEXT* context)
|
||||
int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic, BYTE* sealing_key)
|
||||
{
|
||||
BYTE* p;
|
||||
WINPR_DIGEST_CTX* md5;
|
||||
SecBuffer buffer;
|
||||
|
||||
if (!sspi_SecBufferAlloc(&buffer, WINPR_MD5_DIGEST_LENGTH + seal_magic->cbBuffer))
|
||||
@ -622,13 +618,12 @@ int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic,
|
||||
CopyMemory(p, exported_session_key, WINPR_MD5_DIGEST_LENGTH);
|
||||
CopyMemory(&p[WINPR_MD5_DIGEST_LENGTH], seal_magic->pvBuffer, seal_magic->cbBuffer);
|
||||
|
||||
if (!(md5 = winpr_Digest_New(WINPR_MD_MD5)))
|
||||
if (!winpr_Digest(WINPR_MD_MD5, buffer.pvBuffer, buffer.cbBuffer, sealing_key, WINPR_MD5_DIGEST_LENGTH))
|
||||
{
|
||||
sspi_SecBufferFree(&buffer);
|
||||
return -1;
|
||||
}
|
||||
winpr_Digest_Update(md5, buffer.pvBuffer, buffer.cbBuffer);
|
||||
winpr_Digest_Final(md5, sealing_key, WINPR_MD5_DIGEST_LENGTH);
|
||||
|
||||
sspi_SecBufferFree(&buffer);
|
||||
return 1;
|
||||
}
|
||||
@ -695,13 +690,17 @@ void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context)
|
||||
* CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey
|
||||
*/
|
||||
|
||||
WINPR_HMAC_CTX* hmac = winpr_HMAC_New(WINPR_MD_MD5, context->ExportedSessionKey, WINPR_MD5_DIGEST_LENGTH);
|
||||
WINPR_HMAC_CTX* hmac = winpr_HMAC_New();
|
||||
|
||||
if (hmac)
|
||||
if (!hmac)
|
||||
return;
|
||||
|
||||
if (winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->ExportedSessionKey, WINPR_MD5_DIGEST_LENGTH))
|
||||
{
|
||||
winpr_HMAC_Update(hmac, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer);
|
||||
winpr_HMAC_Update(hmac, (BYTE*) context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
|
||||
winpr_HMAC_Update(hmac, (BYTE*) context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer);
|
||||
winpr_HMAC_Final(hmac, context->MessageIntegrityCheck, WINPR_MD5_DIGEST_LENGTH);
|
||||
}
|
||||
winpr_HMAC_Free(hmac);
|
||||
}
|
||||
|
@ -35,22 +35,20 @@
|
||||
BYTE* NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash)
|
||||
{
|
||||
BOOL allocate = !NtHash;
|
||||
WINPR_DIGEST_CTX* md4;
|
||||
|
||||
if (!Password)
|
||||
return NULL;
|
||||
|
||||
if (!(md4 = winpr_Digest_New(WINPR_MD_MD4)))
|
||||
return NULL;
|
||||
if (!winpr_Digest_Update(md4, (BYTE*) Password, (size_t) PasswordLength))
|
||||
return NULL;
|
||||
if (!NtHash && !(NtHash = malloc(WINPR_MD4_DIGEST_LENGTH)))
|
||||
return NULL;
|
||||
if (!winpr_Digest_Final(md4, NtHash, WINPR_MD4_DIGEST_LENGTH))
|
||||
|
||||
if (!winpr_Digest(WINPR_MD_MD4, (BYTE*) Password, (size_t) PasswordLength, NtHash, WINPR_MD4_DIGEST_LENGTH))
|
||||
{
|
||||
if (allocate)
|
||||
{
|
||||
free(NtHash);
|
||||
return NULL;
|
||||
NtHash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NtHash;
|
||||
|
Loading…
Reference in New Issue
Block a user