Fix TALOS issues
Fix the following issues identified by the CISCO TALOS project: * TALOS-2017-0336 CVE-2017-2834 * TALOS-2017-0337 CVE-2017-2834 * TALOS-2017-0338 CVE-2017-2836 * TALOS-2017-0339 CVE-2017-2837 * TALOS-2017-0340 CVE-2017-2838 * TALOS-2017-0341 CVE-2017-2839
This commit is contained in:
parent
72cd36c112
commit
8292b4558f
@ -3769,12 +3769,12 @@ BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId)
|
||||
|
||||
if (rdp->settings->UseRdpSecurityLayer)
|
||||
{
|
||||
if (!rdp_read_security_header(s, &securityFlags))
|
||||
if (!rdp_read_security_header(s, &securityFlags, &length))
|
||||
return FALSE;
|
||||
|
||||
if (securityFlags & SEC_ENCRYPT)
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
if (!rdp_decrypt(rdp, s, length, securityFlags))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_decrypt failed");
|
||||
return FALSE;
|
||||
|
@ -362,7 +362,6 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w
|
||||
UINT32 keylen;
|
||||
UINT32 bitlen;
|
||||
UINT32 datalen;
|
||||
UINT32 modlen;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 20)
|
||||
return FALSE;
|
||||
@ -379,12 +378,11 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w
|
||||
Stream_Read_UINT32(s, bitlen);
|
||||
Stream_Read_UINT32(s, datalen);
|
||||
Stream_Read(s, certificate->cert_info.exponent, 4);
|
||||
modlen = keylen - 8;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < modlen + 8) // count padding
|
||||
if ((keylen <= 8) || (Stream_GetRemainingLength(s) < keylen))
|
||||
return FALSE;
|
||||
|
||||
certificate->cert_info.ModulusLength = modlen;
|
||||
certificate->cert_info.ModulusLength = keylen - 8;
|
||||
certificate->cert_info.Modulus = malloc(certificate->cert_info.ModulusLength);
|
||||
|
||||
if (!certificate->cert_info.Modulus)
|
||||
@ -405,7 +403,7 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific
|
||||
BYTE md5hash[WINPR_MD5_DIGEST_LENGTH];
|
||||
|
||||
if (!winpr_Digest(WINPR_MD_MD5, sigdata, sigdatalen, md5hash, sizeof(md5hash)))
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
Stream_Read(s, encsig, siglen);
|
||||
|
||||
/* Last 8 bytes shall be all zero. */
|
||||
@ -546,7 +544,7 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate
|
||||
|
||||
BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s)
|
||||
{
|
||||
int i;
|
||||
UINT32 i;
|
||||
BOOL ret;
|
||||
UINT32 certLength;
|
||||
UINT32 numCertBlobs;
|
||||
@ -562,7 +560,7 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
|
||||
if (!certificate->x509_cert_chain)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < (int) numCertBlobs; i++)
|
||||
for (i = 0; i < numCertBlobs; i++)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
@ -621,7 +619,7 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
|
||||
* @param length certificate length
|
||||
*/
|
||||
|
||||
BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length)
|
||||
BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, size_t length)
|
||||
{
|
||||
BOOL ret;
|
||||
wStream* s;
|
||||
|
@ -58,7 +58,7 @@ FREERDP_LOCAL BOOL certificate_read_server_proprietary_certificate(
|
||||
FREERDP_LOCAL BOOL certificate_read_server_x509_certificate_chain(
|
||||
rdpCertificate* certificate, wStream* s);
|
||||
FREERDP_LOCAL BOOL certificate_read_server_certificate(rdpCertificate*
|
||||
certificate, BYTE* server_cert, int length);
|
||||
certificate, BYTE* server_cert, size_t length);
|
||||
|
||||
FREERDP_LOCAL rdpCertificate* certificate_clone(rdpCertificate* certificate);
|
||||
|
||||
|
@ -542,7 +542,7 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!rdp_read_security_header(s, &sec_flags))
|
||||
if (!rdp_read_security_header(s, &sec_flags, NULL))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid security header");
|
||||
return FALSE;
|
||||
@ -769,12 +769,12 @@ BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
UINT16 securityFlags = 0;
|
||||
|
||||
if (!rdp_read_security_header(s, &securityFlags))
|
||||
if (!rdp_read_security_header(s, &securityFlags, &length))
|
||||
return FALSE;
|
||||
|
||||
if (securityFlags & SEC_ENCRYPT)
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
if (!rdp_decrypt(rdp, s, length, securityFlags))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_decrypt failed");
|
||||
return FALSE;
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#define TAG FREERDP_TAG("core.gcc")
|
||||
|
||||
|
||||
/**
|
||||
* T.124 GCC is defined in:
|
||||
*
|
||||
@ -1188,38 +1189,50 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs)
|
||||
Stream_Read_UINT32(s, settings->ServerRandomLength); /* serverRandomLen */
|
||||
Stream_Read_UINT32(s, settings->ServerCertificateLength); /* serverCertLen */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < settings->ServerRandomLength +
|
||||
settings->ServerCertificateLength)
|
||||
if ((settings->ServerRandomLength == 0) || (settings->ServerCertificateLength == 0))
|
||||
return FALSE;
|
||||
|
||||
if ((settings->ServerRandomLength <= 0)
|
||||
|| (settings->ServerCertificateLength <= 0))
|
||||
if (Stream_GetRemainingLength(s) < settings->ServerRandomLength)
|
||||
return FALSE;
|
||||
|
||||
/* serverRandom */
|
||||
settings->ServerRandom = (BYTE*) malloc(settings->ServerRandomLength);
|
||||
|
||||
if (!settings->ServerRandom)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < settings->ServerCertificateLength)
|
||||
goto fail;
|
||||
|
||||
/* serverCertificate */
|
||||
settings->ServerCertificate = (BYTE*) malloc(settings->ServerCertificateLength);
|
||||
|
||||
if (!settings->ServerCertificate)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength);
|
||||
certificate_free(settings->RdpServerCertificate);
|
||||
settings->RdpServerCertificate = certificate_new();
|
||||
|
||||
if (!settings->RdpServerCertificate)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
data = settings->ServerCertificate;
|
||||
length = settings->ServerCertificateLength;
|
||||
return certificate_read_server_certificate(settings->RdpServerCertificate, data,
|
||||
length);
|
||||
if (!certificate_read_server_certificate(settings->RdpServerCertificate, data,
|
||||
length))
|
||||
goto fail;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
free (settings->ServerRandom);
|
||||
free (settings->ServerCertificate);
|
||||
settings->ServerRandom = NULL;
|
||||
settings->ServerCertificate = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const BYTE initial_signature[] =
|
||||
|
@ -806,7 +806,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
|
||||
if (!rdp_read_header(rdp, s, &length, &channelId))
|
||||
return FALSE;
|
||||
|
||||
if (!rdp_read_security_header(s, &securityFlags))
|
||||
if (!rdp_read_security_header(s, &securityFlags, &length))
|
||||
return FALSE;
|
||||
|
||||
if ((securityFlags & SEC_INFO_PKT) == 0)
|
||||
@ -822,7 +822,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if (securityFlags & SEC_ENCRYPT)
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
if (!rdp_decrypt(rdp, s, length, securityFlags))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_decrypt failed");
|
||||
return FALSE;
|
||||
|
@ -36,6 +36,40 @@
|
||||
/* #define LICENSE_NULL_CLIENT_RANDOM 1 */
|
||||
/* #define LICENSE_NULL_PREMASTER_SECRET 1 */
|
||||
|
||||
static wStream* license_send_stream_init(rdpLicense* license);
|
||||
|
||||
static void license_generate_randoms(rdpLicense* license);
|
||||
static BOOL license_generate_keys(rdpLicense* license);
|
||||
static BOOL license_generate_hwid(rdpLicense* license);
|
||||
static BOOL license_encrypt_premaster_secret(rdpLicense* license);
|
||||
static BOOL license_decrypt_platform_challenge(rdpLicense* license);
|
||||
|
||||
static LICENSE_PRODUCT_INFO* license_new_product_info(void);
|
||||
static void license_free_product_info(LICENSE_PRODUCT_INFO* productInfo);
|
||||
static BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo);
|
||||
|
||||
static LICENSE_BLOB* license_new_binary_blob(UINT16 type);
|
||||
static void license_free_binary_blob(LICENSE_BLOB* blob);
|
||||
static BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob);
|
||||
static BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob);
|
||||
|
||||
static SCOPE_LIST* license_new_scope_list(void);
|
||||
static void license_free_scope_list(SCOPE_LIST* scopeList);
|
||||
static BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList);
|
||||
|
||||
static BOOL license_read_license_request_packet(rdpLicense* license, wStream* s);
|
||||
static BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s);
|
||||
static void license_read_new_license_packet(rdpLicense* license, wStream* s);
|
||||
static void license_read_upgrade_license_packet(rdpLicense* license, wStream* s);
|
||||
static BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s);
|
||||
|
||||
static BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s);
|
||||
static BOOL license_send_new_license_request_packet(rdpLicense* license);
|
||||
|
||||
static BOOL license_write_platform_challenge_response_packet(
|
||||
rdpLicense* license, wStream* s, BYTE* mac_data);
|
||||
static BOOL license_send_platform_challenge_response_packet(rdpLicense* license);
|
||||
|
||||
#ifdef WITH_DEBUG_LICENSE
|
||||
|
||||
static const char* const LICENSE_MESSAGE_STRINGS[] =
|
||||
@ -82,7 +116,7 @@ static const char* const state_transitions[] =
|
||||
"ST_RESEND_LAST_MESSAGE"
|
||||
};
|
||||
|
||||
void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo)
|
||||
static void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo)
|
||||
{
|
||||
char* CompanyName = NULL;
|
||||
char* ProductId = NULL;
|
||||
@ -98,7 +132,7 @@ void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo)
|
||||
free(ProductId);
|
||||
}
|
||||
|
||||
void license_print_scope_list(SCOPE_LIST* scopeList)
|
||||
static void license_print_scope_list(SCOPE_LIST* scopeList)
|
||||
{
|
||||
int index;
|
||||
LICENSE_BLOB* scope;
|
||||
@ -251,12 +285,12 @@ int license_recv(rdpLicense* license, wStream* s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!rdp_read_security_header(s, &securityFlags))
|
||||
if (!rdp_read_security_header(s, &securityFlags, &length))
|
||||
return -1;
|
||||
|
||||
if (securityFlags & SEC_ENCRYPT)
|
||||
{
|
||||
if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags))
|
||||
if (!rdp_decrypt(license->rdp, s, length, securityFlags))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_decrypt failed");
|
||||
return -1;
|
||||
@ -463,7 +497,12 @@ BOOL license_decrypt_platform_challenge(rdpLicense* license)
|
||||
|
||||
if ((rc4 = winpr_RC4_New(license->LicensingEncryptionKey,
|
||||
LICENSING_ENCRYPTION_KEY_LENGTH)) == NULL)
|
||||
{
|
||||
free(license->PlatformChallenge->data);
|
||||
license->PlatformChallenge->data = NULL;
|
||||
license->PlatformChallenge->length = 0;
|
||||
return FALSE;
|
||||
}
|
||||
rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
|
||||
license->EncryptedPlatformChallenge->data,
|
||||
license->PlatformChallenge->data);
|
||||
@ -487,15 +526,27 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
|
||||
Stream_Read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */
|
||||
Stream_Read_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < productInfo->cbCompanyName + 4)
|
||||
/* Name must be >0, but there is no upper limit defined, use UINT32_MAX */
|
||||
if ((productInfo->cbCompanyName < 2) || (productInfo->cbCompanyName % 2 != 0))
|
||||
return FALSE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < productInfo->cbCompanyName)
|
||||
return FALSE;
|
||||
|
||||
productInfo->pbProductId = NULL;
|
||||
productInfo->pbCompanyName = (BYTE*) malloc(productInfo->cbCompanyName);
|
||||
if (!productInfo->pbCompanyName)
|
||||
return FALSE;
|
||||
Stream_Read(s, productInfo->pbCompanyName, productInfo->cbCompanyName);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
goto out_fail;
|
||||
|
||||
Stream_Read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */
|
||||
|
||||
if ((productInfo->cbProductId < 2) || (productInfo->cbProductId % 2 != 0))
|
||||
goto out_fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < productInfo->cbProductId)
|
||||
goto out_fail;
|
||||
|
||||
@ -507,7 +558,9 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
|
||||
|
||||
out_fail:
|
||||
free(productInfo->pbCompanyName);
|
||||
free(productInfo->pbProductId);
|
||||
productInfo->pbCompanyName = NULL;
|
||||
productInfo->pbProductId = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -806,7 +859,9 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
|
||||
Stream_Read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */
|
||||
/* EncryptedPlatformChallenge */
|
||||
license->EncryptedPlatformChallenge->type = BB_ANY_BLOB;
|
||||
license_read_binary_blob(s, license->EncryptedPlatformChallenge);
|
||||
if (!license_read_binary_blob(s, license->EncryptedPlatformChallenge))
|
||||
return FALSE;
|
||||
|
||||
license->EncryptedPlatformChallenge->type = BB_ENCRYPTED_DATA_BLOB;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 16)
|
||||
|
@ -17,8 +17,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __LICENSE_H
|
||||
#define __LICENSE_H
|
||||
#ifndef FREERDP_LICENSE_H
|
||||
#define FREERDP_LICENSE_H
|
||||
|
||||
typedef struct rdp_license rdpLicense;
|
||||
|
||||
@ -203,47 +203,6 @@ struct rdp_license
|
||||
|
||||
FREERDP_LOCAL int license_recv(rdpLicense* license, wStream* s);
|
||||
FREERDP_LOCAL BOOL license_send(rdpLicense* license, wStream* s, BYTE type);
|
||||
FREERDP_LOCAL wStream* license_send_stream_init(rdpLicense* license);
|
||||
|
||||
FREERDP_LOCAL void license_generate_randoms(rdpLicense* license);
|
||||
FREERDP_LOCAL BOOL license_generate_keys(rdpLicense* license);
|
||||
FREERDP_LOCAL BOOL license_generate_hwid(rdpLicense* license);
|
||||
FREERDP_LOCAL BOOL license_encrypt_premaster_secret(rdpLicense* license);
|
||||
FREERDP_LOCAL BOOL license_decrypt_platform_challenge(rdpLicense* license);
|
||||
|
||||
FREERDP_LOCAL LICENSE_PRODUCT_INFO* license_new_product_info(void);
|
||||
FREERDP_LOCAL void license_free_product_info(LICENSE_PRODUCT_INFO* productInfo);
|
||||
FREERDP_LOCAL BOOL license_read_product_info(wStream* s,
|
||||
LICENSE_PRODUCT_INFO* productInfo);
|
||||
|
||||
FREERDP_LOCAL LICENSE_BLOB* license_new_binary_blob(UINT16 type);
|
||||
FREERDP_LOCAL void license_free_binary_blob(LICENSE_BLOB* blob);
|
||||
FREERDP_LOCAL BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob);
|
||||
FREERDP_LOCAL BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob);
|
||||
|
||||
FREERDP_LOCAL SCOPE_LIST* license_new_scope_list(void);
|
||||
FREERDP_LOCAL void license_free_scope_list(SCOPE_LIST* scopeList);
|
||||
FREERDP_LOCAL BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList);
|
||||
|
||||
FREERDP_LOCAL BOOL license_read_license_request_packet(rdpLicense* license,
|
||||
wStream* s);
|
||||
FREERDP_LOCAL BOOL license_read_platform_challenge_packet(rdpLicense* license,
|
||||
wStream* s);
|
||||
FREERDP_LOCAL void license_read_new_license_packet(rdpLicense* license,
|
||||
wStream* s);
|
||||
FREERDP_LOCAL void license_read_upgrade_license_packet(rdpLicense* license,
|
||||
wStream* s);
|
||||
FREERDP_LOCAL BOOL license_read_error_alert_packet(rdpLicense* license,
|
||||
wStream* s);
|
||||
|
||||
FREERDP_LOCAL BOOL license_write_new_license_request_packet(rdpLicense* license,
|
||||
wStream* s);
|
||||
FREERDP_LOCAL BOOL license_send_new_license_request_packet(rdpLicense* license);
|
||||
|
||||
FREERDP_LOCAL BOOL license_write_platform_challenge_response_packet(
|
||||
rdpLicense* license, wStream* s, BYTE* mac_data);
|
||||
FREERDP_LOCAL BOOL license_send_platform_challenge_response_packet(
|
||||
rdpLicense* license);
|
||||
|
||||
FREERDP_LOCAL BOOL license_send_valid_client_error_packet(rdpLicense* license);
|
||||
|
||||
|
@ -232,7 +232,8 @@ BOOL mcs_read_domain_mcspdu_header(wStream* s, enum DomainMCSPDU* domainMCSPDU,
|
||||
if (!s || !domainMCSPDU || !length)
|
||||
return FALSE;
|
||||
|
||||
*length = tpkt_read_header(s);
|
||||
if (!tpkt_read_header(s, length))
|
||||
return FALSE;
|
||||
|
||||
if (!tpdu_read_data(s, &li))
|
||||
return FALSE;
|
||||
@ -509,11 +510,13 @@ BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s)
|
||||
UINT16 li;
|
||||
int length;
|
||||
BOOL upwardFlag;
|
||||
UINT16 tlength;
|
||||
|
||||
if (!mcs || !s)
|
||||
return FALSE;
|
||||
|
||||
tpkt_read_header(s);
|
||||
if (!tpkt_read_header(s, &tlength))
|
||||
return FALSE;
|
||||
|
||||
if (!tpdu_read_data(s, &li))
|
||||
return FALSE;
|
||||
@ -739,6 +742,7 @@ out:
|
||||
BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s)
|
||||
{
|
||||
int length;
|
||||
UINT16 tlength;
|
||||
BYTE result;
|
||||
UINT16 li;
|
||||
UINT32 calledConnectId;
|
||||
@ -746,7 +750,8 @@ BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s)
|
||||
if (!mcs || !s)
|
||||
return FALSE;
|
||||
|
||||
tpkt_read_header(s);
|
||||
if (!tpkt_read_header(s, &tlength))
|
||||
return FALSE;
|
||||
|
||||
if (!tpdu_read_data(s, &li))
|
||||
return FALSE;
|
||||
|
@ -575,7 +575,8 @@ int nego_recv(rdpTransport* transport, wStream* s, void* extra)
|
||||
UINT16 length;
|
||||
rdpNego* nego = (rdpNego*) extra;
|
||||
|
||||
length = tpkt_read_header(s);
|
||||
if (!tpkt_read_header(s, &length))
|
||||
return -1;
|
||||
|
||||
if (length == 0)
|
||||
return -1;
|
||||
@ -739,8 +740,10 @@ BOOL nego_read_request(rdpNego* nego, wStream* s)
|
||||
{
|
||||
BYTE li;
|
||||
BYTE type;
|
||||
UINT16 length;
|
||||
|
||||
tpkt_read_header(s);
|
||||
if (!tpkt_read_header(s, &length))
|
||||
return FALSE;
|
||||
|
||||
if (!tpdu_read_connection_request(s, &li))
|
||||
return FALSE;
|
||||
|
@ -371,12 +371,12 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
|
||||
|
||||
if (rdp->settings->UseRdpSecurityLayer)
|
||||
{
|
||||
if (!rdp_read_security_header(s, &securityFlags))
|
||||
if (!rdp_read_security_header(s, &securityFlags, &length))
|
||||
return -1;
|
||||
|
||||
if (securityFlags & SEC_ENCRYPT)
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
if (!rdp_decrypt(rdp, s, length, securityFlags))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_decrypt failed");
|
||||
return -1;
|
||||
@ -418,7 +418,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
|
||||
else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId)
|
||||
{
|
||||
if (!rdp->settings->UseRdpSecurityLayer)
|
||||
if (!rdp_read_security_header(s, &securityFlags))
|
||||
if (!rdp_read_security_header(s, &securityFlags, NULL))
|
||||
return -1;
|
||||
|
||||
return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
|
||||
|
@ -79,13 +79,17 @@ const char* DATA_PDU_TYPE_STRINGS[80] =
|
||||
* @param flags security flags
|
||||
*/
|
||||
|
||||
BOOL rdp_read_security_header(wStream* s, UINT16* flags)
|
||||
BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length)
|
||||
{
|
||||
/* Basic Security Header */
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
if ((Stream_GetRemainingLength(s) < 4) || (length && (*length < 4)))
|
||||
return FALSE;
|
||||
Stream_Read_UINT16(s, *flags); /* flags */
|
||||
Stream_Seek(s, 2); /* flagsHi (unused) */
|
||||
|
||||
if (length)
|
||||
*length -= 4;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -301,7 +305,8 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
|
||||
|
||||
MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication;
|
||||
|
||||
*length = tpkt_read_header(s);
|
||||
if (!tpkt_read_header(s, length))
|
||||
return FALSE;
|
||||
|
||||
if (!tpdu_read_header(s, &code, &li))
|
||||
return FALSE;
|
||||
@ -330,7 +335,10 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
|
||||
|
||||
MCSPDU = domainMCSPDU;
|
||||
|
||||
if ((size_t) (*length - 8) > Stream_GetRemainingLength(s))
|
||||
if (*length < 8)
|
||||
return FALSE;
|
||||
|
||||
if ((*length - 8) > Stream_GetRemainingLength(s))
|
||||
return FALSE;
|
||||
|
||||
if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum)
|
||||
@ -376,8 +384,12 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
|
||||
if (Stream_GetRemainingLength(s) < 5)
|
||||
return FALSE;
|
||||
|
||||
per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
|
||||
per_read_integer16(s, channelId, 0); /* channelId */
|
||||
if (!per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID)) /* initiator (UserId) */
|
||||
return FALSE;
|
||||
|
||||
if (!per_read_integer16(s, channelId, 0)) /* channelId */
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(s, byte); /* dataPriority + Segmentation (0x70) */
|
||||
|
||||
if (!per_read_length(s, length)) /* userData (OCTET_STRING) */
|
||||
@ -1030,17 +1042,21 @@ void rdp_read_flow_control_pdu(wStream* s, UINT16* type)
|
||||
* @param length int
|
||||
*/
|
||||
|
||||
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
|
||||
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags)
|
||||
{
|
||||
BYTE cmac[8];
|
||||
BYTE wmac[8];
|
||||
BOOL status;
|
||||
|
||||
if (!rdp || !s || (length < 0))
|
||||
return FALSE;
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
UINT16 len;
|
||||
BYTE version, pad;
|
||||
BYTE* sig;
|
||||
INT64 padLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 12)
|
||||
return FALSE;
|
||||
@ -1053,6 +1069,9 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
|
||||
Stream_Seek(s, 8); /* signature */
|
||||
|
||||
length -= 12;
|
||||
padLength = length - pad;
|
||||
if ((length <= 0) || (padLength <= 0))
|
||||
return FALSE;
|
||||
|
||||
if (!security_fips_decrypt(Stream_Pointer(s), length, rdp))
|
||||
{
|
||||
@ -1070,11 +1089,13 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
if (Stream_GetRemainingLength(s) < sizeof(wmac))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read(s, wmac, sizeof(wmac));
|
||||
length -= sizeof(wmac);
|
||||
if (length <= 0)
|
||||
return FALSE;
|
||||
|
||||
if (!security_decrypt(Stream_Pointer(s), length, rdp))
|
||||
return FALSE;
|
||||
@ -1135,7 +1156,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if (rdp->settings->UseRdpSecurityLayer)
|
||||
{
|
||||
if (!rdp_read_security_header(s, &securityFlags))
|
||||
if (!rdp_read_security_header(s, &securityFlags, &length))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_recv_tpkt_pdu: rdp_read_security_header() fail");
|
||||
return -1;
|
||||
@ -1143,7 +1164,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
if (!rdp_decrypt(rdp, s, length, securityFlags))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_decrypt failed");
|
||||
return -1;
|
||||
@ -1216,7 +1237,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
|
||||
else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId)
|
||||
{
|
||||
if (!rdp->settings->UseRdpSecurityLayer)
|
||||
if (!rdp_read_security_header(s, &securityFlags))
|
||||
if (!rdp_read_security_header(s, &securityFlags, NULL))
|
||||
return -1;
|
||||
|
||||
return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
|
||||
|
@ -177,7 +177,7 @@ struct rdp_rdp
|
||||
BOOL AwaitCapabilities;
|
||||
};
|
||||
|
||||
FREERDP_LOCAL BOOL rdp_read_security_header(wStream* s, UINT16* flags);
|
||||
FREERDP_LOCAL BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length);
|
||||
FREERDP_LOCAL void rdp_write_security_header(wStream* s, UINT16 flags);
|
||||
|
||||
FREERDP_LOCAL BOOL rdp_read_share_control_header(wStream* s, UINT16* length,
|
||||
@ -245,7 +245,7 @@ extern const char* DATA_PDU_TYPE_STRINGS[80];
|
||||
#define DEBUG_RDP(...) do { } while (0)
|
||||
#endif
|
||||
|
||||
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags);
|
||||
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags);
|
||||
|
||||
BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo);
|
||||
BOOL rdp_send_error_info(rdpRdp* rdp);
|
||||
|
@ -637,7 +637,7 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
BOOL security_encrypt(BYTE* data, size_t length, rdpRdp* rdp)
|
||||
{
|
||||
if (rdp->encrypt_use_count >= 4096)
|
||||
{
|
||||
@ -659,7 +659,7 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
BOOL security_decrypt(BYTE* data, size_t length, rdpRdp* rdp)
|
||||
{
|
||||
if (rdp->rc4_decrypt_key == NULL)
|
||||
return FALSE;
|
||||
@ -683,7 +683,7 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp)
|
||||
BOOL security_hmac_signature(const BYTE* data, size_t length, BYTE* output, rdpRdp* rdp)
|
||||
{
|
||||
BYTE buf[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BYTE use_count_le[4];
|
||||
@ -710,7 +710,7 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
BOOL security_fips_encrypt(BYTE* data, size_t length, rdpRdp* rdp)
|
||||
{
|
||||
size_t olen;
|
||||
|
||||
@ -720,7 +720,7 @@ BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
BOOL security_fips_decrypt(BYTE* data, size_t length, rdpRdp* rdp)
|
||||
{
|
||||
size_t olen;
|
||||
|
||||
@ -729,7 +729,7 @@ BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp)
|
||||
BOOL security_fips_check_signature(const BYTE* data, size_t length, const BYTE* sig, rdpRdp* rdp)
|
||||
{
|
||||
BYTE buf[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BYTE use_count_le[4];
|
||||
|
@ -17,8 +17,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __SECURITY_H
|
||||
#define __SECURITY_H
|
||||
#ifndef FREERDP_SECURITY_H
|
||||
#define FREERDP_SECURITY_H
|
||||
|
||||
#include "rdp.h"
|
||||
#include <freerdp/crypto/crypto.h>
|
||||
@ -45,13 +45,13 @@ FREERDP_LOCAL BOOL security_salted_mac_signature(rdpRdp* rdp, const BYTE* data,
|
||||
UINT32 length, BOOL encryption, BYTE* output);
|
||||
FREERDP_LOCAL BOOL security_establish_keys(const BYTE* client_random,
|
||||
rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_hmac_signature(const BYTE* data, int length,
|
||||
FREERDP_LOCAL BOOL security_encrypt(BYTE* data, size_t length, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_decrypt(BYTE* data, size_t length, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_hmac_signature(const BYTE* data, size_t length,
|
||||
BYTE* output, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_fips_check_signature(const BYTE* data, int length,
|
||||
FREERDP_LOCAL BOOL security_fips_encrypt(BYTE* data, size_t length, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_fips_decrypt(BYTE* data, size_t length, rdpRdp* rdp);
|
||||
FREERDP_LOCAL BOOL security_fips_check_signature(const BYTE* data, size_t length,
|
||||
const BYTE* sig, rdpRdp* rdp);
|
||||
|
||||
#endif /* __SECURITY_H */
|
||||
|
@ -78,28 +78,39 @@ BOOL tpkt_verify_header(wStream* s)
|
||||
/**
|
||||
* Read a TPKT header.\n
|
||||
* @param s
|
||||
* @return length
|
||||
* @param length
|
||||
* @return success
|
||||
*/
|
||||
|
||||
UINT16 tpkt_read_header(wStream* s)
|
||||
BOOL tpkt_read_header(wStream* s, UINT16* length)
|
||||
{
|
||||
BYTE version;
|
||||
UINT16 length;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
|
||||
Stream_Peek_UINT8(s, version);
|
||||
|
||||
if (version == 3)
|
||||
{
|
||||
UINT16 len;
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
Stream_Seek(s, 2);
|
||||
Stream_Read_UINT16_BE(s, length);
|
||||
Stream_Read_UINT16_BE(s, len);
|
||||
if (len < 4)
|
||||
return FALSE;
|
||||
|
||||
*length = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* not a TPKT header */
|
||||
length = 0;
|
||||
*length = 0;
|
||||
}
|
||||
|
||||
return length;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,7 +29,7 @@
|
||||
#define TPKT_HEADER_LENGTH 4
|
||||
|
||||
FREERDP_LOCAL BOOL tpkt_verify_header(wStream* s);
|
||||
FREERDP_LOCAL UINT16 tpkt_read_header(wStream* s);
|
||||
FREERDP_LOCAL BOOL tpkt_read_header(wStream* s, UINT16* length);
|
||||
FREERDP_LOCAL void tpkt_write_header(wStream* s, UINT16 length);
|
||||
|
||||
#endif /* __TPKT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user