mirror of https://github.com/FreeRDP/FreeRDP
Merge pull request #2513 from hardening/license_and_security_retValues
License and security ret values
This commit is contained in:
commit
879ed36a3c
|
@ -103,15 +103,15 @@ typedef struct crypto_des3_struct* CryptoDes3;
|
|||
|
||||
FREERDP_API CryptoDes3 crypto_des3_encrypt_init(const BYTE* key, const BYTE* ivec);
|
||||
FREERDP_API CryptoDes3 crypto_des3_decrypt_init(const BYTE* key, const BYTE* ivec);
|
||||
FREERDP_API void crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE *out_data);
|
||||
FREERDP_API void crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE* out_data);
|
||||
FREERDP_API BOOL crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE *out_data);
|
||||
FREERDP_API BOOL crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE* out_data);
|
||||
FREERDP_API void crypto_des3_free(CryptoDes3 des3);
|
||||
|
||||
typedef struct crypto_hmac_struct* CryptoHmac;
|
||||
|
||||
FREERDP_API CryptoHmac crypto_hmac_new(void);
|
||||
FREERDP_API void crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||
FREERDP_API void crypto_hmac_md5_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||
FREERDP_API BOOL crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||
FREERDP_API BOOL crypto_hmac_md5_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||
FREERDP_API void crypto_hmac_update(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||
FREERDP_API void crypto_hmac_final(CryptoHmac hmac, BYTE *out_data, UINT32 length);
|
||||
FREERDP_API void crypto_hmac_free(CryptoHmac hmac);
|
||||
|
|
|
@ -817,23 +817,28 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
|
|||
Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/
|
||||
Stream_Write_UINT8(s, pad); /* padding */
|
||||
|
||||
security_hmac_signature(fpInputEvents, fpInputEvents_length, Stream_Pointer(s), rdp);
|
||||
if (!security_hmac_signature(fpInputEvents, fpInputEvents_length, Stream_Pointer(s), rdp))
|
||||
return FALSE;
|
||||
|
||||
if (pad)
|
||||
memset(fpInputEvents + fpInputEvents_length, 0, pad);
|
||||
|
||||
security_fips_encrypt(fpInputEvents, fpInputEvents_length + pad, rdp);
|
||||
if (!security_fips_encrypt(fpInputEvents, fpInputEvents_length + pad, rdp))
|
||||
return FALSE;
|
||||
|
||||
length += pad;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
||||
security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, Stream_Pointer(s));
|
||||
else
|
||||
security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s));
|
||||
BOOL status;
|
||||
|
||||
security_encrypt(fpInputEvents, fpInputEvents_length, rdp);
|
||||
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
||||
status = security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, Stream_Pointer(s));
|
||||
else
|
||||
status = security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s));
|
||||
|
||||
if (!status || !security_encrypt(fpInputEvents, fpInputEvents_length, rdp))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1021,17 +1026,19 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
security_hmac_signature(data, dataSize - pad, pSignature, rdp);
|
||||
if (!security_hmac_signature(data, dataSize - pad, pSignature, rdp))
|
||||
return FALSE;
|
||||
security_fips_encrypt(data, dataSize, rdp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
||||
security_salted_mac_signature(rdp, data, dataSize, TRUE, pSignature);
|
||||
status = security_salted_mac_signature(rdp, data, dataSize, TRUE, pSignature);
|
||||
else
|
||||
security_mac_signature(rdp, data, dataSize, pSignature);
|
||||
status = security_mac_signature(rdp, data, dataSize, pSignature);
|
||||
|
||||
security_encrypt(data, dataSize, rdp);
|
||||
if (!status || !security_encrypt(data, dataSize, rdp))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,8 @@ BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp)
|
|||
|
||||
/* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */
|
||||
|
||||
crypto_hmac_md5_init(hmac, AutoReconnectRandom, 16);
|
||||
if (!crypto_hmac_md5_init(hmac, AutoReconnectRandom, 16))
|
||||
return FALSE;
|
||||
crypto_hmac_update(hmac, ClientRandom, 32);
|
||||
crypto_hmac_final(hmac, clientCookie->securityVerifier, 16);
|
||||
crypto_hmac_free(hmac);
|
||||
|
|
|
@ -179,6 +179,8 @@ wStream* license_send_stream_init(rdpLicense* license)
|
|||
}
|
||||
|
||||
s = transport_send_stream_init(license->rdp->transport, 4096);
|
||||
if (!s)
|
||||
return NULL;
|
||||
rdp_init_stream(license->rdp, s);
|
||||
|
||||
license->rdp->do_crypt = do_crypt;
|
||||
|
@ -268,7 +270,6 @@ int license_recv(rdpLicense* license, wStream* s)
|
|||
Stream_Rewind(s, RDP_SECURITY_HEADER_LENGTH);
|
||||
|
||||
status = rdp_recv_out_of_sequence_pdu(license->rdp, s);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "unexpected license packet.");
|
||||
|
@ -286,31 +287,34 @@ int license_recv(rdpLicense* license, wStream* s)
|
|||
switch (bMsgType)
|
||||
{
|
||||
case LICENSE_REQUEST:
|
||||
|
||||
if (!license_read_license_request_packet(license, s))
|
||||
return -1;
|
||||
|
||||
license_send_new_license_request_packet(license);
|
||||
if (!license_send_new_license_request_packet(license))
|
||||
return -1;
|
||||
break;
|
||||
case PLATFORM_CHALLENGE:
|
||||
|
||||
case PLATFORM_CHALLENGE:
|
||||
if (!license_read_platform_challenge_packet(license, s))
|
||||
return -1;
|
||||
|
||||
license_send_platform_challenge_response_packet(license);
|
||||
if (!license_send_platform_challenge_response_packet(license))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case NEW_LICENSE:
|
||||
license_read_new_license_packet(license, s);
|
||||
break;
|
||||
|
||||
case UPGRADE_LICENSE:
|
||||
license_read_upgrade_license_packet(license, s);
|
||||
break;
|
||||
case ERROR_ALERT:
|
||||
|
||||
case ERROR_ALERT:
|
||||
if (!license_read_error_alert_packet(license, s))
|
||||
return -1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "invalid bMsgType:%d", bMsgType);
|
||||
return FALSE;
|
||||
|
@ -336,15 +340,23 @@ void license_generate_randoms(rdpLicense* license)
|
|||
* @param license license module
|
||||
*/
|
||||
|
||||
void license_generate_keys(rdpLicense* license)
|
||||
BOOL license_generate_keys(rdpLicense* license)
|
||||
{
|
||||
security_master_secret(license->PremasterSecret, license->ClientRandom,
|
||||
license->ServerRandom, license->MasterSecret); /* MasterSecret */
|
||||
security_session_key_blob(license->MasterSecret, license->ClientRandom,
|
||||
license->ServerRandom, license->SessionKeyBlob); /* SessionKeyBlob */
|
||||
BOOL ret;
|
||||
|
||||
if (
|
||||
/* MasterSecret */
|
||||
!security_master_secret(license->PremasterSecret, license->ClientRandom,
|
||||
license->ServerRandom, license->MasterSecret) ||
|
||||
/* SessionKeyBlob */
|
||||
!security_session_key_blob(license->MasterSecret, license->ClientRandom,
|
||||
license->ServerRandom, license->SessionKeyBlob))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
security_mac_salt_key(license->SessionKeyBlob, license->ClientRandom,
|
||||
license->ServerRandom, license->MacSaltKey); /* MacSaltKey */
|
||||
security_licensing_encryption_key(license->SessionKeyBlob, license->ClientRandom,
|
||||
ret = security_licensing_encryption_key(license->SessionKeyBlob, license->ClientRandom,
|
||||
license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */
|
||||
#ifdef WITH_DEBUG_LICENSE
|
||||
WLog_DBG(TAG, "ClientRandom:");
|
||||
|
@ -362,6 +374,7 @@ void license_generate_keys(rdpLicense* license)
|
|||
WLog_DBG(TAG, "LicensingEncryptionKey:");
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -369,7 +382,7 @@ void license_generate_keys(rdpLicense* license)
|
|||
* @param license license module
|
||||
*/
|
||||
|
||||
void license_generate_hwid(rdpLicense* license)
|
||||
BOOL license_generate_hwid(rdpLicense* license)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
BYTE macAddress[6];
|
||||
|
@ -382,14 +395,15 @@ void license_generate_hwid(rdpLicense* license)
|
|||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
crypto_md5_update(md5, macAddress, sizeof(macAddress));
|
||||
crypto_md5_final(md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void license_get_server_rsa_public_key(rdpLicense* license)
|
||||
BOOL license_get_server_rsa_public_key(rdpLicense* license)
|
||||
{
|
||||
BYTE* Exponent;
|
||||
BYTE* Modulus;
|
||||
|
@ -398,8 +412,9 @@ void license_get_server_rsa_public_key(rdpLicense* license)
|
|||
|
||||
if (license->ServerCertificate->length < 1)
|
||||
{
|
||||
certificate_read_server_certificate(license->certificate,
|
||||
settings->ServerCertificate, settings->ServerCertificateLength);
|
||||
if (!certificate_read_server_certificate(license->certificate,
|
||||
settings->ServerCertificate, settings->ServerCertificateLength))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Exponent = license->certificate->cert_info.exponent;
|
||||
|
@ -409,19 +424,26 @@ void license_get_server_rsa_public_key(rdpLicense* license)
|
|||
license->ModulusLength = ModulusLength;
|
||||
license->Modulus = (BYTE*) malloc(ModulusLength);
|
||||
CopyMemory(license->Modulus, Modulus, ModulusLength);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void license_encrypt_premaster_secret(rdpLicense* license)
|
||||
BOOL license_encrypt_premaster_secret(rdpLicense* license)
|
||||
{
|
||||
BYTE* EncryptedPremasterSecret;
|
||||
license_get_server_rsa_public_key(license);
|
||||
|
||||
if (!license_get_server_rsa_public_key(license))
|
||||
return FALSE;
|
||||
|
||||
#ifdef WITH_DEBUG_LICENSE
|
||||
WLog_DBG(TAG, "Modulus (%d bits):", license->ModulusLength * 8);
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, license->Modulus, license->ModulusLength);
|
||||
WLog_DBG(TAG, "Exponent:");
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, license->Exponent, 4);
|
||||
#endif
|
||||
|
||||
EncryptedPremasterSecret = (BYTE*) calloc(1, license->ModulusLength);
|
||||
if (!EncryptedPremasterSecret)
|
||||
return FALSE;
|
||||
|
||||
license->EncryptedPremasterSecret->type = BB_RANDOM_BLOB;
|
||||
license->EncryptedPremasterSecret->length = PREMASTER_SECRET_LENGTH;
|
||||
|
@ -431,21 +453,25 @@ void license_encrypt_premaster_secret(rdpLicense* license)
|
|||
license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret);
|
||||
#endif
|
||||
license->EncryptedPremasterSecret->data = EncryptedPremasterSecret;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void license_decrypt_platform_challenge(rdpLicense* license)
|
||||
BOOL license_decrypt_platform_challenge(rdpLicense* license)
|
||||
{
|
||||
CryptoRc4 rc4;
|
||||
|
||||
license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length);
|
||||
license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length);
|
||||
if (!license->PlatformChallenge->data)
|
||||
return FALSE;
|
||||
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
|
||||
|
||||
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
|
||||
|
||||
if (!rc4)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a rc4");
|
||||
return;
|
||||
free(license->PlatformChallenge->data);
|
||||
license->PlatformChallenge->data = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
|
||||
|
@ -453,6 +479,7 @@ void license_decrypt_platform_challenge(rdpLicense* license)
|
|||
license->PlatformChallenge->data);
|
||||
|
||||
crypto_rc4_free(rc4);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -569,17 +596,20 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob)
|
|||
* @param blob license binary blob
|
||||
*/
|
||||
|
||||
void license_write_binary_blob(wStream* s, LICENSE_BLOB* blob)
|
||||
BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob)
|
||||
{
|
||||
Stream_EnsureRemainingCapacity(s, blob->length + 4);
|
||||
if (!Stream_EnsureRemainingCapacity(s, blob->length + 4))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
|
||||
Stream_Write_UINT16(s, blob->length); /* wBlobLen (2 bytes) */
|
||||
|
||||
if (blob->length > 0)
|
||||
Stream_Write(s, blob->data, blob->length); /* blobData */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength)
|
||||
BOOL license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength)
|
||||
{
|
||||
UINT32 length;
|
||||
length = ModulusLength + 8;
|
||||
|
@ -587,10 +617,11 @@ void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blo
|
|||
if (blob->length > ModulusLength)
|
||||
{
|
||||
WLog_ERR(TAG, "license_write_encrypted_premaster_secret_blob: invalid blob");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Stream_EnsureRemainingCapacity(s, length + 4);
|
||||
if (!Stream_EnsureRemainingCapacity(s, length + 4))
|
||||
return FALSE;
|
||||
Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
|
||||
Stream_Write_UINT16(s, length); /* wBlobLen (2 bytes) */
|
||||
|
||||
|
@ -598,6 +629,7 @@ void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blo
|
|||
Stream_Write(s, blob->data, blob->length); /* blobData */
|
||||
|
||||
Stream_Zero(s, length - blob->length);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -742,9 +774,10 @@ BOOL license_read_license_request_packet(rdpLicense* license, wStream* s)
|
|||
license->ServerCertificate->data, license->ServerCertificate->length))
|
||||
return FALSE;
|
||||
|
||||
license_generate_keys(license);
|
||||
license_generate_hwid(license);
|
||||
license_encrypt_premaster_secret(license);
|
||||
if (!license_generate_keys(license) || !license_generate_hwid(license) ||
|
||||
!license_encrypt_premaster_secret(license))
|
||||
return FALSE;
|
||||
|
||||
#ifdef WITH_DEBUG_LICENSE
|
||||
WLog_DBG(TAG, "ServerRandom:");
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, license->ServerRandom, 32);
|
||||
|
@ -765,6 +798,7 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
|
|||
{
|
||||
BYTE MacData[16];
|
||||
UINT32 ConnectFlags = 0;
|
||||
|
||||
DEBUG_LICENSE("Receiving Platform Challenge Packet");
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
|
@ -780,7 +814,8 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
|
|||
return FALSE;
|
||||
|
||||
Stream_Read(s, MacData, 16); /* MACData (16 bytes) */
|
||||
license_decrypt_platform_challenge(license);
|
||||
if (!license_decrypt_platform_challenge(license))
|
||||
return FALSE;
|
||||
#ifdef WITH_DEBUG_LICENSE
|
||||
WLog_DBG(TAG, "ConnectFlags: 0x%08X", ConnectFlags);
|
||||
WLog_DBG(TAG, "EncryptedPlatformChallenge:");
|
||||
|
@ -878,17 +913,26 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s)
|
|||
* @param s stream
|
||||
*/
|
||||
|
||||
void license_write_new_license_request_packet(rdpLicense* license, wStream* s)
|
||||
BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s)
|
||||
{
|
||||
UINT32 PlatformId;
|
||||
UINT32 PreferredKeyExchangeAlg = KEY_EXCHANGE_ALG_RSA;
|
||||
|
||||
PlatformId = CLIENT_OS_ID_WINNT_POST_52 | CLIENT_IMAGE_ID_MICROSOFT;
|
||||
Stream_Write_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
|
||||
Stream_Write_UINT32(s, PlatformId); /* PlatformId (4 bytes) */
|
||||
Stream_Write(s, license->ClientRandom, 32); /* ClientRandom (32 bytes) */
|
||||
license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret, license->ModulusLength); /* EncryptedPremasterSecret */
|
||||
license_write_binary_blob(s, license->ClientUserName); /* ClientUserName */
|
||||
license_write_binary_blob(s, license->ClientMachineName); /* ClientMachineName */
|
||||
|
||||
/* EncryptedPremasterSecret */
|
||||
if (!license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret, license->ModulusLength) ||
|
||||
/* ClientUserName */
|
||||
!license_write_binary_blob(s, license->ClientUserName) ||
|
||||
/* ClientMachineName */
|
||||
!license_write_binary_blob(s, license->ClientMachineName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_LICENSE
|
||||
WLog_DBG(TAG, "PreferredKeyExchangeAlg: 0x%08X", PreferredKeyExchangeAlg);
|
||||
WLog_DBG(TAG, "ClientRandom:");
|
||||
|
@ -898,6 +942,7 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s)
|
|||
WLog_DBG(TAG, "ClientUserName (%d): %s", license->ClientUserName->length, (char*) license->ClientUserName->data);
|
||||
WLog_DBG(TAG, "ClientMachineName (%d): %s", license->ClientMachineName->length, (char*) license->ClientMachineName->data);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -906,12 +951,14 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s)
|
|||
* @param license license module
|
||||
*/
|
||||
|
||||
void license_send_new_license_request_packet(rdpLicense* license)
|
||||
BOOL license_send_new_license_request_packet(rdpLicense* license)
|
||||
{
|
||||
wStream* s;
|
||||
char* username;
|
||||
DEBUG_LICENSE("Sending New License Packet");
|
||||
s = license_send_stream_init(license);
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
if (license->rdp->settings->Username != NULL)
|
||||
username = license->rdp->settings->Username;
|
||||
|
@ -922,12 +969,17 @@ void license_send_new_license_request_packet(rdpLicense* license)
|
|||
license->ClientUserName->length = strlen(username) + 1;
|
||||
license->ClientMachineName->data = (BYTE*) license->rdp->settings->ClientHostname;
|
||||
license->ClientMachineName->length = strlen(license->rdp->settings->ClientHostname) + 1;
|
||||
license_write_new_license_request_packet(license, s);
|
||||
license_send(license, s, NEW_LICENSE_REQUEST);
|
||||
if (!license_write_new_license_request_packet(license, s) ||
|
||||
!license_send(license, s, NEW_LICENSE_REQUEST))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
license->ClientUserName->data = NULL;
|
||||
license->ClientUserName->length = 0;
|
||||
license->ClientMachineName->data = NULL;
|
||||
license->ClientMachineName->length = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -938,12 +990,17 @@ void license_send_new_license_request_packet(rdpLicense* license)
|
|||
* @param mac_data signature
|
||||
*/
|
||||
|
||||
void license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* macData)
|
||||
BOOL license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* macData)
|
||||
{
|
||||
license_write_binary_blob(s, license->EncryptedPlatformChallenge); /* EncryptedPlatformChallengeResponse */
|
||||
license_write_binary_blob(s, license->EncryptedHardwareId); /* EncryptedHWID */
|
||||
Stream_EnsureRemainingCapacity(s, 16);
|
||||
if (!license_write_binary_blob(s, license->EncryptedPlatformChallenge) || /* EncryptedPlatformChallengeResponse */
|
||||
!license_write_binary_blob(s, license->EncryptedHardwareId) || /* EncryptedHWID */
|
||||
!Stream_EnsureRemainingCapacity(s, 16))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Stream_Write(s, macData, 16); /* MACData */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -952,32 +1009,43 @@ void license_write_platform_challenge_response_packet(rdpLicense* license, wStre
|
|||
* @param license license module
|
||||
*/
|
||||
|
||||
void license_send_platform_challenge_response_packet(rdpLicense* license)
|
||||
BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
|
||||
{
|
||||
wStream* s;
|
||||
int length;
|
||||
BYTE* buffer;
|
||||
CryptoRc4 rc4;
|
||||
BYTE mac_data[16];
|
||||
BOOL status;
|
||||
|
||||
DEBUG_LICENSE("Sending Platform Challenge Response Packet");
|
||||
s = license_send_stream_init(license);
|
||||
license->EncryptedPlatformChallenge->type = BB_DATA_BLOB;
|
||||
length = license->PlatformChallenge->length + HWID_LENGTH;
|
||||
|
||||
buffer = (BYTE*) malloc(length);
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length);
|
||||
CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH);
|
||||
security_mac_data(license->MacSaltKey, buffer, length, mac_data);
|
||||
status = security_mac_data(license->MacSaltKey, buffer, length, mac_data);
|
||||
free(buffer);
|
||||
buffer = (BYTE*) malloc(HWID_LENGTH);
|
||||
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
|
||||
|
||||
if (!status)
|
||||
return FALSE;
|
||||
|
||||
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
|
||||
if (!rc4)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a rc4");
|
||||
free(buffer);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
buffer = (BYTE*) malloc(HWID_LENGTH);
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
|
||||
crypto_rc4_free(rc4);
|
||||
license->EncryptedHardwareId->type = BB_DATA_BLOB;
|
||||
|
@ -991,8 +1059,8 @@ void license_send_platform_challenge_response_packet(rdpLicense* license)
|
|||
WLog_DBG(TAG, "EncryptedHardwareId:");
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedHardwareId->data, HWID_LENGTH);
|
||||
#endif
|
||||
license_write_platform_challenge_response_packet(license, s, mac_data);
|
||||
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
|
||||
return license_write_platform_challenge_response_packet(license, s, mac_data) &&
|
||||
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1005,11 +1073,15 @@ BOOL license_send_valid_client_error_packet(rdpLicense* license)
|
|||
{
|
||||
wStream* s;
|
||||
s = license_send_stream_init(license);
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
DEBUG_LICENSE("Sending Error Alert Packet");
|
||||
Stream_Write_UINT32(s, STATUS_VALID_CLIENT); /* dwErrorCode */
|
||||
Stream_Write_UINT32(s, ST_NO_TRANSITION); /* dwStateTransition */
|
||||
license_write_binary_blob(s, license->ErrorInfo);
|
||||
return license_send(license, s, ERROR_ALERT);
|
||||
|
||||
return license_write_binary_blob(s, license->ErrorInfo) &&
|
||||
license_send(license, s, ERROR_ALERT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -205,10 +205,10 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type);
|
|||
wStream* license_send_stream_init(rdpLicense* license);
|
||||
|
||||
void license_generate_randoms(rdpLicense* license);
|
||||
void license_generate_keys(rdpLicense* license);
|
||||
void license_generate_hwid(rdpLicense* license);
|
||||
void license_encrypt_premaster_secret(rdpLicense* license);
|
||||
void license_decrypt_platform_challenge(rdpLicense* license);
|
||||
BOOL license_generate_keys(rdpLicense* license);
|
||||
BOOL license_generate_hwid(rdpLicense* license);
|
||||
BOOL license_encrypt_premaster_secret(rdpLicense* license);
|
||||
BOOL license_decrypt_platform_challenge(rdpLicense* license);
|
||||
|
||||
LICENSE_PRODUCT_INFO* license_new_product_info(void);
|
||||
void license_free_product_info(LICENSE_PRODUCT_INFO* productInfo);
|
||||
|
@ -217,7 +217,7 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo);
|
|||
LICENSE_BLOB* license_new_binary_blob(UINT16 type);
|
||||
void license_free_binary_blob(LICENSE_BLOB* blob);
|
||||
BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob);
|
||||
void license_write_binary_blob(wStream* s, LICENSE_BLOB* blob);
|
||||
BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob);
|
||||
|
||||
SCOPE_LIST* license_new_scope_list(void);
|
||||
void license_free_scope_list(SCOPE_LIST* scopeList);
|
||||
|
@ -229,11 +229,11 @@ void license_read_new_license_packet(rdpLicense* license, wStream* s);
|
|||
void license_read_upgrade_license_packet(rdpLicense* license, wStream* s);
|
||||
BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s);
|
||||
|
||||
void license_write_new_license_request_packet(rdpLicense* license, wStream* s);
|
||||
void license_send_new_license_request_packet(rdpLicense* license);
|
||||
BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s);
|
||||
BOOL license_send_new_license_request_packet(rdpLicense* license);
|
||||
|
||||
void license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* mac_data);
|
||||
void license_send_platform_challenge_response_packet(rdpLicense* license);
|
||||
BOOL license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* mac_data);
|
||||
BOOL license_send_platform_challenge_response_packet(rdpLicense* license);
|
||||
|
||||
BOOL license_send_valid_client_error_packet(rdpLicense* license);
|
||||
|
||||
|
|
|
@ -429,12 +429,13 @@ void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length, UINT16 channelId)
|
|||
Stream_Write_UINT16_BE(s, length); /* userData (OCTET_STRING) */
|
||||
}
|
||||
|
||||
static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT32 sec_flags)
|
||||
static BOOL rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT32 sec_flags, UINT32 *pad)
|
||||
{
|
||||
BYTE* data;
|
||||
UINT32 pad = 0;
|
||||
BOOL status;
|
||||
|
||||
sec_flags |= rdp->sec_flags;
|
||||
*pad = 0;
|
||||
|
||||
if (sec_flags != 0)
|
||||
{
|
||||
|
@ -451,17 +452,18 @@ static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT3
|
|||
Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/
|
||||
|
||||
/* handle padding */
|
||||
pad = 8 - (length % 8);
|
||||
*pad = 8 - (length % 8);
|
||||
|
||||
if (pad == 8)
|
||||
if (*pad == 8)
|
||||
pad = 0;
|
||||
if (pad)
|
||||
memset(data+length, 0, pad);
|
||||
if (*pad)
|
||||
memset(data+length, 0, *pad);
|
||||
|
||||
Stream_Write_UINT8(s, pad);
|
||||
security_hmac_signature(data, length, Stream_Pointer(s), rdp);
|
||||
Stream_Write_UINT8(s, *pad);
|
||||
if (!security_hmac_signature(data, length, Stream_Pointer(s), rdp))
|
||||
return FALSE;
|
||||
Stream_Seek(s, 8);
|
||||
security_fips_encrypt(data, length + pad, rdp);
|
||||
security_fips_encrypt(data, length + *pad, rdp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -469,19 +471,24 @@ static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT3
|
|||
length = length - (data - Stream_Buffer(s));
|
||||
|
||||
if (sec_flags & SEC_SECURE_CHECKSUM)
|
||||
security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s));
|
||||
status = security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s));
|
||||
else
|
||||
security_mac_signature(rdp, data, length, Stream_Pointer(s));
|
||||
status = security_mac_signature(rdp, data, length, Stream_Pointer(s));
|
||||
|
||||
if (!status)
|
||||
return FALSE;
|
||||
|
||||
Stream_Seek(s, 8);
|
||||
security_encrypt(Stream_Pointer(s), length, rdp);
|
||||
|
||||
if (!security_encrypt(Stream_Pointer(s), length, rdp))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
rdp->sec_flags = 0;
|
||||
}
|
||||
|
||||
return pad;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static UINT32 rdp_get_sec_bytes(rdpRdp* rdp, UINT16 sec_flags)
|
||||
|
@ -516,11 +523,15 @@ static UINT32 rdp_get_sec_bytes(rdpRdp* rdp, UINT16 sec_flags)
|
|||
|
||||
BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channel_id)
|
||||
{
|
||||
UINT32 pad;
|
||||
UINT16 length;
|
||||
length = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
rdp_write_header(rdp, s, length, channel_id);
|
||||
length += rdp_security_stream_out(rdp, s, length, 0);
|
||||
|
||||
if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
|
||||
return FALSE;
|
||||
length += pad;
|
||||
Stream_SetPosition(s, length);
|
||||
Stream_SealLength(s);
|
||||
|
||||
|
@ -535,6 +546,8 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
|
|||
UINT16 length;
|
||||
UINT32 sec_bytes;
|
||||
int sec_hold;
|
||||
UINT32 pad;
|
||||
|
||||
length = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
|
||||
|
@ -543,7 +556,11 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
|
|||
Stream_Seek(s, sec_bytes);
|
||||
rdp_write_share_control_header(s, length - sec_bytes, type, channel_id);
|
||||
Stream_SetPosition(s, sec_hold);
|
||||
length += rdp_security_stream_out(rdp, s, length, 0);
|
||||
|
||||
if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
|
||||
return FALSE;
|
||||
|
||||
length += pad;
|
||||
Stream_SetPosition(s, length);
|
||||
Stream_SealLength(s);
|
||||
|
||||
|
@ -558,6 +575,8 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
|
|||
UINT16 length;
|
||||
UINT32 sec_bytes;
|
||||
int sec_hold;
|
||||
UINT32 pad;
|
||||
|
||||
length = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
|
||||
|
@ -567,7 +586,9 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
|
|||
rdp_write_share_control_header(s, length - sec_bytes, PDU_TYPE_DATA, channel_id);
|
||||
rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->ShareId);
|
||||
Stream_SetPosition(s, sec_hold);
|
||||
length += rdp_security_stream_out(rdp, s, length, 0);
|
||||
if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
|
||||
return FALSE;
|
||||
length += pad;
|
||||
Stream_SetPosition(s, length);
|
||||
Stream_SealLength(s);
|
||||
|
||||
|
@ -582,6 +603,8 @@ BOOL rdp_send_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 sec_flags)
|
|||
UINT16 length;
|
||||
UINT32 sec_bytes;
|
||||
int sec_hold;
|
||||
UINT32 pad;
|
||||
|
||||
length = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
rdp_write_header(rdp, s, length, rdp->mcs->messageChannelId);
|
||||
|
@ -589,7 +612,11 @@ BOOL rdp_send_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 sec_flags)
|
|||
sec_hold = Stream_GetPosition(s);
|
||||
Stream_Seek(s, sec_bytes);
|
||||
Stream_SetPosition(s, sec_hold);
|
||||
length += rdp_security_stream_out(rdp, s, length, sec_flags);
|
||||
|
||||
if (!rdp_security_stream_out(rdp, s, length, sec_flags, &pad))
|
||||
return FALSE;
|
||||
|
||||
length += pad;
|
||||
Stream_SetPosition(s, length);
|
||||
Stream_SealLength(s);
|
||||
|
||||
|
@ -956,6 +983,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
|
|||
{
|
||||
BYTE cmac[8];
|
||||
BYTE wmac[8];
|
||||
BOOL status;
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
|
@ -1001,9 +1029,12 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
|
|||
return FALSE;
|
||||
|
||||
if (securityFlags & SEC_SECURE_CHECKSUM)
|
||||
security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac);
|
||||
status = security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac);
|
||||
else
|
||||
security_mac_signature(rdp, Stream_Pointer(s), length, cmac);
|
||||
status = security_mac_signature(rdp, Stream_Pointer(s), length, cmac);
|
||||
|
||||
if (!status)
|
||||
return FALSE;
|
||||
|
||||
if (memcmp(wmac, cmac, sizeof(wmac)) != 0)
|
||||
{
|
||||
|
|
|
@ -123,7 +123,7 @@ fips_oddparity_table[256] =
|
|||
0xf8, 0xf8, 0xfb, 0xfb, 0xfd, 0xfd, 0xfe, 0xfe
|
||||
};
|
||||
|
||||
static void security_salted_hash(const BYTE* salt, const BYTE* input, int length,
|
||||
static BOOL security_salted_hash(const BYTE* salt, const BYTE* input, int length,
|
||||
const BYTE* salt1, const BYTE* salt2, BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
|
@ -137,7 +137,7 @@ static void security_salted_hash(const BYTE* salt, const BYTE* input, int length
|
|||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, input, length); /* Input */
|
||||
crypto_sha1_update(sha1, salt, 48); /* Salt (48 bytes) */
|
||||
|
@ -150,42 +150,44 @@ static void security_salted_hash(const BYTE* salt, const BYTE* input, int length
|
|||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */
|
||||
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
|
||||
crypto_md5_final(md5, output);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void security_premaster_hash(const char* input, int length, const BYTE* premaster_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output)
|
||||
static BOOL security_premaster_hash(const char* input, int length, const BYTE* premaster_secret,
|
||||
const BYTE* client_random, const BYTE* server_random, BYTE* output)
|
||||
{
|
||||
/* PremasterHash(Input) = SaltedHash(PremasterSecret, Input, ClientRandom, ServerRandom) */
|
||||
security_salted_hash(premaster_secret, (BYTE*)input, length, client_random, server_random, output);
|
||||
return security_salted_hash(premaster_secret, (BYTE*)input, length, client_random, server_random, output);
|
||||
}
|
||||
|
||||
void security_master_secret(const BYTE* premaster_secret, const BYTE* client_random,
|
||||
BOOL security_master_secret(const BYTE* premaster_secret, const BYTE* client_random,
|
||||
const BYTE* server_random, BYTE* output)
|
||||
{
|
||||
/* MasterSecret = PremasterHash('A') + PremasterHash('BB') + PremasterHash('CCC') */
|
||||
security_premaster_hash("A", 1, premaster_secret, client_random, server_random, &output[0]);
|
||||
security_premaster_hash("BB", 2, premaster_secret, client_random, server_random, &output[16]);
|
||||
security_premaster_hash("CCC", 3, premaster_secret, client_random, server_random, &output[32]);
|
||||
return security_premaster_hash("A", 1, premaster_secret, client_random, server_random, &output[0]) &&
|
||||
security_premaster_hash("BB", 2, premaster_secret, client_random, server_random, &output[16]) &&
|
||||
security_premaster_hash("CCC", 3, premaster_secret, client_random, server_random, &output[32]);
|
||||
}
|
||||
|
||||
static void security_master_hash(const char* input, int length, const BYTE* master_secret,
|
||||
static BOOL security_master_hash(const char* input, int length, const BYTE* master_secret,
|
||||
const BYTE* client_random, const BYTE* server_random, BYTE* output)
|
||||
{
|
||||
/* MasterHash(Input) = SaltedHash(MasterSecret, Input, ServerRandom, ClientRandom) */
|
||||
security_salted_hash(master_secret, (const BYTE*)input, length, server_random, client_random, output);
|
||||
return security_salted_hash(master_secret, (const BYTE*)input, length, server_random, client_random, output);
|
||||
}
|
||||
|
||||
void security_session_key_blob(const BYTE* master_secret, const BYTE* client_random,
|
||||
BOOL security_session_key_blob(const BYTE* master_secret, const BYTE* client_random,
|
||||
const BYTE* server_random, BYTE* output)
|
||||
{
|
||||
/* MasterHash = MasterHash('A') + MasterHash('BB') + MasterHash('CCC') */
|
||||
security_master_hash("A", 1, master_secret, client_random, server_random, &output[0]);
|
||||
security_master_hash("BB", 2, master_secret, client_random, server_random, &output[16]);
|
||||
security_master_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
|
||||
return security_master_hash("A", 1, master_secret, client_random, server_random, &output[0]) &&
|
||||
security_master_hash("BB", 2, master_secret, client_random, server_random, &output[16]) &&
|
||||
security_master_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
|
||||
}
|
||||
|
||||
void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_random,
|
||||
|
@ -195,7 +197,7 @@ void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_rand
|
|||
memcpy(output, session_key_blob, 16);
|
||||
}
|
||||
|
||||
void security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output)
|
||||
BOOL security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
|
||||
|
@ -203,19 +205,20 @@ void security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BY
|
|||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, in0, 16);
|
||||
crypto_md5_update(md5, in1, 32);
|
||||
crypto_md5_update(md5, in2, 32);
|
||||
crypto_md5_final(md5, output);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random,
|
||||
BOOL security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random,
|
||||
const BYTE* server_random, BYTE* output)
|
||||
{
|
||||
/* LicensingEncryptionKey = MD5(Second128Bits(SessionKeyBlob) + ClientRandom + ServerRandom)) */
|
||||
security_md5_16_32_32(&session_key_blob[16], client_random, server_random, output);
|
||||
return security_md5_16_32_32(&session_key_blob[16], client_random, server_random, output);
|
||||
}
|
||||
|
||||
void security_UINT32_le(BYTE* output, UINT32 value)
|
||||
|
@ -226,7 +229,7 @@ void security_UINT32_le(BYTE* output, UINT32 value)
|
|||
output[3] = (value >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length,
|
||||
BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length,
|
||||
BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
|
@ -242,8 +245,8 @@ void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length
|
|||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
return;
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, mac_salt_key, 16); /* MacSaltKey */
|
||||
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
|
||||
|
@ -255,16 +258,17 @@ void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length
|
|||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return;
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */
|
||||
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
|
||||
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
|
||||
crypto_md5_final(md5, output);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output)
|
||||
BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
|
@ -278,8 +282,8 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
|
|||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
return;
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
|
||||
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
|
||||
|
@ -291,8 +295,8 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
|
|||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return;
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
|
||||
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
|
||||
|
@ -300,9 +304,10 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
|
|||
crypto_md5_final(md5, md5_digest);
|
||||
|
||||
memcpy(output, md5_digest, 8);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
||||
BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
||||
BOOL encryption, BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
|
@ -331,8 +336,8 @@ void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
|||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
return;
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
|
||||
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
|
||||
|
@ -345,8 +350,8 @@ void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
|||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return;
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
|
||||
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
|
||||
|
@ -354,22 +359,25 @@ void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
|||
crypto_md5_final(md5, md5_digest);
|
||||
|
||||
memcpy(output, md5_digest, 8);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void security_A(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
|
||||
static BOOL security_A(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
|
||||
BYTE* output)
|
||||
{
|
||||
security_premaster_hash("A", 1, master_secret, client_random, server_random, &output[0]);
|
||||
security_premaster_hash("BB", 2, master_secret, client_random, server_random, &output[16]);
|
||||
security_premaster_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
|
||||
return
|
||||
security_premaster_hash("A", 1, master_secret, client_random, server_random, &output[0]) &&
|
||||
security_premaster_hash("BB", 2, master_secret, client_random, server_random, &output[16]) &&
|
||||
security_premaster_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
|
||||
}
|
||||
|
||||
static void security_X(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
|
||||
static BOOL security_X(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
|
||||
BYTE* output)
|
||||
{
|
||||
security_premaster_hash("X", 1, master_secret, client_random, server_random, &output[0]);
|
||||
security_premaster_hash("YY", 2, master_secret, client_random, server_random, &output[16]);
|
||||
security_premaster_hash("ZZZ", 3, master_secret, client_random, server_random, &output[32]);
|
||||
return
|
||||
security_premaster_hash("X", 1, master_secret, client_random, server_random, &output[0]) &&
|
||||
security_premaster_hash("YY", 2, master_secret, client_random, server_random, &output[16]) &&
|
||||
security_premaster_hash("ZZZ", 3, master_secret, client_random, server_random, &output[32]);
|
||||
}
|
||||
|
||||
static void fips_expand_key_bits(BYTE* in, BYTE* out)
|
||||
|
@ -413,6 +421,7 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
|
|||
BYTE* server_random;
|
||||
BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
|
||||
rdpSettings* settings;
|
||||
BOOL status;
|
||||
|
||||
settings = rdp->settings;
|
||||
server_random = settings->ServerRandom;
|
||||
|
@ -469,26 +478,29 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
|
|||
memcpy(pre_master_secret, client_random, 24);
|
||||
memcpy(pre_master_secret + 24, server_random, 24);
|
||||
|
||||
security_A(pre_master_secret, client_random, server_random, master_secret);
|
||||
security_X(master_secret, client_random, server_random, session_key_blob);
|
||||
if (!security_A(pre_master_secret, client_random, server_random, master_secret) ||
|
||||
!security_X(master_secret, client_random, server_random, session_key_blob))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(rdp->sign_key, session_key_blob, 16);
|
||||
|
||||
if (rdp->settings->ServerMode)
|
||||
{
|
||||
security_md5_16_32_32(&session_key_blob[16], client_random,
|
||||
server_random, rdp->encrypt_key);
|
||||
security_md5_16_32_32(&session_key_blob[32], client_random,
|
||||
server_random, rdp->decrypt_key);
|
||||
status = security_md5_16_32_32(&session_key_blob[16], client_random, server_random, rdp->encrypt_key);
|
||||
status &= security_md5_16_32_32(&session_key_blob[32], client_random, server_random, rdp->decrypt_key);
|
||||
}
|
||||
else
|
||||
{
|
||||
security_md5_16_32_32(&session_key_blob[16], client_random,
|
||||
server_random, rdp->decrypt_key);
|
||||
security_md5_16_32_32(&session_key_blob[32], client_random,
|
||||
server_random, rdp->encrypt_key);
|
||||
status = security_md5_16_32_32(&session_key_blob[16], client_random, server_random, rdp->decrypt_key);
|
||||
status &= security_md5_16_32_32(&session_key_blob[32], client_random, server_random, rdp->encrypt_key);
|
||||
}
|
||||
|
||||
if (!status)
|
||||
return FALSE;
|
||||
|
||||
|
||||
if (settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
|
||||
{
|
||||
memcpy(rdp->sign_key, salt, 3);
|
||||
|
@ -540,7 +552,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
|
|||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, update_key, key_len);
|
||||
|
@ -551,7 +563,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
|
|||
rc4 = crypto_rc4_init(key, key_len);
|
||||
if (!rc4)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a rc4");
|
||||
WLog_ERR(TAG, "unable to allocate a rc4");
|
||||
return FALSE;
|
||||
}
|
||||
crypto_rc4(rc4, key_len, key, key);
|
||||
|
@ -569,16 +581,19 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
|||
{
|
||||
if (rdp->encrypt_use_count >= 4096)
|
||||
{
|
||||
security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, rdp);
|
||||
if (!security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, rdp))
|
||||
return FALSE;
|
||||
|
||||
crypto_rc4_free(rdp->rc4_encrypt_key);
|
||||
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_encrypt_key)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
|
||||
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
|
||||
return FALSE;
|
||||
}
|
||||
rdp->encrypt_use_count = 0;
|
||||
}
|
||||
|
||||
crypto_rc4(rdp->rc4_encrypt_key, length, data, data);
|
||||
rdp->encrypt_use_count++;
|
||||
rdp->encrypt_checksum_use_count++;
|
||||
|
@ -589,9 +604,11 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
|||
{
|
||||
if (rdp->rc4_decrypt_key == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (rdp->decrypt_use_count >= 4096)
|
||||
{
|
||||
security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, rdp);
|
||||
if (!security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, rdp))
|
||||
return FALSE;
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_decrypt_key)
|
||||
|
@ -608,32 +625,35 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp)
|
||||
BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp)
|
||||
{
|
||||
BYTE buf[20];
|
||||
BYTE use_count_le[4];
|
||||
|
||||
security_UINT32_le(use_count_le, rdp->encrypt_use_count);
|
||||
|
||||
crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20);
|
||||
if (!crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20))
|
||||
return FALSE;
|
||||
|
||||
crypto_hmac_update(rdp->fips_hmac, data, length);
|
||||
crypto_hmac_update(rdp->fips_hmac, use_count_le, 4);
|
||||
crypto_hmac_final(rdp->fips_hmac, buf, 20);
|
||||
|
||||
memmove(output, buf, 8);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
crypto_des3_encrypt(rdp->fips_encrypt, length, data, data);
|
||||
if (!crypto_des3_encrypt(rdp->fips_encrypt, length, data, data))
|
||||
return FALSE;
|
||||
rdp->encrypt_use_count++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
crypto_des3_decrypt(rdp->fips_decrypt, length, data, data);
|
||||
return TRUE;
|
||||
return crypto_des3_decrypt(rdp->fips_decrypt, length, data, data);
|
||||
}
|
||||
|
||||
BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp)
|
||||
|
@ -643,7 +663,8 @@ BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig
|
|||
|
||||
security_UINT32_le(use_count_le, rdp->decrypt_use_count);
|
||||
|
||||
crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20);
|
||||
if (!crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20))
|
||||
return FALSE;
|
||||
crypto_hmac_update(rdp->fips_hmac, data, length);
|
||||
crypto_hmac_update(rdp->fips_hmac, use_count_le, 4);
|
||||
crypto_hmac_final(rdp->fips_hmac, buf, 20);
|
||||
|
|
|
@ -27,20 +27,20 @@
|
|||
|
||||
#include <winpr/stream.h>
|
||||
|
||||
void security_master_secret(const BYTE* premaster_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output);
|
||||
void security_session_key_blob(const BYTE* master_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output);
|
||||
BOOL security_master_secret(const BYTE* premaster_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output);
|
||||
BOOL security_session_key_blob(const BYTE* master_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output);
|
||||
void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_random, const BYTE* server_random, BYTE* output);
|
||||
void security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random, const BYTE* server_random, BYTE* output);
|
||||
void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length, BYTE* output);
|
||||
BOOL security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random, const BYTE* server_random, BYTE* output);
|
||||
BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length, BYTE* output);
|
||||
|
||||
void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output);
|
||||
void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BOOL encryption, BYTE* output);
|
||||
BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output);
|
||||
BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BOOL encryption, BYTE* output);
|
||||
BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp);
|
||||
|
||||
BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp);
|
||||
BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp);
|
||||
|
||||
void security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp);
|
||||
BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp);
|
||||
BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp);
|
||||
BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp);
|
||||
BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
TestCore.c
|
|
@ -112,19 +112,20 @@ CryptoDes3 crypto_des3_decrypt_init(const BYTE* key, const BYTE* ivec)
|
|||
return des3;
|
||||
}
|
||||
|
||||
void crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
|
||||
BOOL crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
|
||||
{
|
||||
int len;
|
||||
EVP_EncryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
|
||||
return EVP_EncryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length) == 1;
|
||||
}
|
||||
|
||||
void crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
|
||||
BOOL crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
|
||||
{
|
||||
int len;
|
||||
EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
|
||||
int ret = EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
|
||||
|
||||
if (length != len)
|
||||
abort(); /* TODO */
|
||||
return ret == 1;
|
||||
}
|
||||
|
||||
void crypto_des3_free(CryptoDes3 des3)
|
||||
|
@ -145,14 +146,24 @@ CryptoHmac crypto_hmac_new(void)
|
|||
return hmac;
|
||||
}
|
||||
|
||||
void crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
||||
BOOL crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x00909000)
|
||||
return HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL) == 1;
|
||||
#else
|
||||
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL);
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void crypto_hmac_md5_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
||||
BOOL crypto_hmac_md5_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x00909000)
|
||||
return HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL) == 1;
|
||||
#else
|
||||
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL);
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void crypto_hmac_update(CryptoHmac hmac, const BYTE* data, UINT32 length)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
version.h
|
Loading…
Reference in New Issue