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:
Armin Novak 2017-05-29 10:50:22 +02:00
parent 72cd36c112
commit 8292b4558f
17 changed files with 181 additions and 116 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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[] =

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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];

View File

@ -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 */

View File

@ -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;
}
/**

View File

@ -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 */