Commit 68c33cec authored by Bernhard Miklautz's avatar Bernhard Miklautz

add 0008-Fix-multiple-security-issues.patch

This adds a fix for:

* CVE-2017-2834
* CVE-2017-2835
* CVE-2017-2836
* CVE-2017-2837
* CVE-2017-2838
* CVE-2017-2839

Closes: #869880
parent c17307e8
freerdp (1.1.0~git20140921.1.440916e+dfsg1-14) UNRELEASED; urgency=high
[ Bernhard Miklautz ]
* debian/patches
+ Add fix for CVE-2017-2834, CVE-2017-2835, CVE-2017-2836,
CVE-2017-2837, CVE-2017-2838, CVE-2017-2839 (Closes: #869880)
-- Bernhard Miklautz <bernhard.miklautz@shacknet.at> Thu, 27 Jul 2017 13:47:59 +0200
freerdp (1.1.0~git20140921.1.440916e+dfsg1-13) unstable; urgency=medium
[ James Clarke ]
......
From 03ab68318966c3a22935a02838daaea7b7fbe96c Mon Sep 17 00:00:00 2001
From: Bernhard Miklautz <bernhard.miklautz@thincast.com>
Date: Thu, 27 Jul 2017 13:24:37 +0200
Subject: [PATCH] Fix multiple security issues
Fix the following issues identified by the CISCO TALOS project:
* TALOS-2017-0336 CVE-2017-2834
* TALOS-2017-0337 CVE-2017-2835
* TALOS-2017-0338 CVE-2017-2836
* TALOS-2017-0339 CVE-2017-2837
* TALOS-2017-0340 CVE-2017-2838
* TALOS-2017-0341 CVE-2017-2839
Backported based on commit 8292b4558f0684065ce1f58db7783cc426099223.
---
libfreerdp/core/capabilities.c | 4 +--
libfreerdp/core/certificate.c | 18 ++++++++-----
libfreerdp/core/certificate.h | 2 +-
libfreerdp/core/connection.c | 17 ++++++------
libfreerdp/core/gcc.c | 60 ++++++++++++++++++++++++------------------
libfreerdp/core/info.c | 4 +--
libfreerdp/core/license.c | 39 ++++++++++++++++++++-------
libfreerdp/core/mcs.c | 17 +++++++++---
libfreerdp/core/nego.c | 8 +++---
libfreerdp/core/peer.c | 4 +--
libfreerdp/core/rdp.c | 37 ++++++++++++++++++++------
libfreerdp/core/rdp.h | 4 +--
libfreerdp/core/security.c | 12 ++++-----
libfreerdp/core/security.h | 12 ++++-----
libfreerdp/core/surface.c | 2 +-
libfreerdp/core/tpkt.c | 22 ++++++++++++----
libfreerdp/core/tpkt.h | 2 +-
libfreerdp/core/transport.c | 6 ++++-
18 files changed, 174 insertions(+), 96 deletions(-)
diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c
index 4d69b4e..0e3b0de 100644
--- a/libfreerdp/core/capabilities.c
+++ b/libfreerdp/core/capabilities.c
@@ -3341,12 +3341,12 @@ BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId)
if (rdp->settings->DisableEncryption)
{
- 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))
{
fprintf(stderr, "rdp_decrypt failed\n");
return FALSE;
diff --git a/libfreerdp/core/certificate.c b/libfreerdp/core/certificate.c
index 6a28ab3..9a36abe 100644
--- a/libfreerdp/core/certificate.c
+++ b/libfreerdp/core/certificate.c
@@ -327,10 +327,10 @@ 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;
+
Stream_Read(s, magic, 4);
if (memcmp(magic, "RSA1", 4) != 0)
@@ -343,12 +343,16 @@ 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)
+ return FALSE;
+
Stream_Read(s, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength);
/* 8 bytes of zero padding */
Stream_Seek(s, 8);
@@ -500,7 +504,7 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate
BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s)
{
- int i;
+ UINT32 i;
UINT32 certLength;
UINT32 numCertBlobs;
BOOL ret;
@@ -513,7 +517,7 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs);
- for (i = 0; i < (int) numCertBlobs; i++)
+ for (i = 0; i < numCertBlobs; i++)
{
if (Stream_GetRemainingLength(s) < 4)
return FALSE;
@@ -562,7 +566,7 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
* @param length certificate length
*/
-int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length)
+int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, size_t length)
{
wStream* s;
UINT32 dwVersion;
diff --git a/libfreerdp/core/certificate.h b/libfreerdp/core/certificate.h
index 5008bb4..fb818f5 100644
--- a/libfreerdp/core/certificate.h
+++ b/libfreerdp/core/certificate.h
@@ -50,7 +50,7 @@ void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain);
BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate, wStream* s);
BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s);
-int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length);
+int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, size_t length);
rdpCertificate* certificate_new(void);
void certificate_free(rdpCertificate* certificate);
diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c
index 9c4c3d7..7e6b2bd 100644
--- a/libfreerdp/core/connection.c
+++ b/libfreerdp/core/connection.c
@@ -77,19 +77,18 @@ BOOL rdp_client_connect(rdpRdp* rdp)
if (settings->GatewayEnabled)
{
- char* user;
+ char* user = NULL;
char* domain;
char* cookie;
- int user_length = 0;
+ int user_length = 0;
int domain_length;
int cookie_length;
-
- if (settings->Username)
- {
- user = settings->Username;
- user_length = strlen(settings->Username);
- }
+ if (settings->Username)
+ {
+ user = settings->Username;
+ user_length = strlen(settings->Username);
+ }
if (settings->Domain)
domain = settings->Domain;
@@ -365,7 +364,7 @@ static 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))
return FALSE;
if ((sec_flags & SEC_EXCHANGE_PKT) == 0)
diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c
index 316f4f9..27def74 100644
--- a/libfreerdp/core/gcc.c
+++ b/libfreerdp/core/gcc.c
@@ -830,6 +830,7 @@ BOOL gcc_read_server_security_data(wStream* s, rdpSettings* settings)
if (Stream_GetRemainingLength(s) < 8)
return FALSE;
+
Stream_Read_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */
Stream_Read_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */
@@ -844,43 +845,50 @@ BOOL gcc_read_server_security_data(wStream* s, rdpSettings* settings)
if (Stream_GetRemainingLength(s) < 8)
return FALSE;
+
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)
- {
- /* serverRandom */
- settings->ServerRandom = (BYTE*) malloc(settings->ServerRandomLength);
- Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength);
- }
- else
- {
+ if (Stream_GetRemainingLength(s) < settings->ServerRandomLength)
return FALSE;
- }
- if (settings->ServerCertificateLength > 0)
- {
- /* serverCertificate */
- settings->ServerCertificate = (BYTE*) malloc(settings->ServerCertificateLength);
- Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength);
+ /* serverRandom */
+ settings->ServerRandom = (BYTE*) malloc(settings->ServerRandomLength);
+ if (!settings->ServerRandom)
+ return FALSE;
+ Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength);
- certificate_free(settings->RdpServerCertificate);
- settings->RdpServerCertificate = certificate_new();
- data = settings->ServerCertificate;
- length = settings->ServerCertificateLength;
+ /* serverCertificate */
+ if(Stream_GetRemainingLength(s) < settings->ServerCertificateLength)
+ goto out_fail1;
+ settings->ServerCertificate = (BYTE*) malloc(settings->ServerCertificateLength);
+ if (!settings->ServerCertificate)
+ goto out_fail1;
- if (certificate_read_server_certificate(settings->RdpServerCertificate, data, length) < 1)
- return FALSE;
- }
- else
- {
- return FALSE;
- }
+ Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength);
+ certificate_free(settings->RdpServerCertificate);
+ settings->RdpServerCertificate = certificate_new();
+ if (!settings->RdpServerCertificate)
+ goto out_fail2;
+
+ data = settings->ServerCertificate;
+ length = settings->ServerCertificateLength;
+
+ if (certificate_read_server_certificate(settings->RdpServerCertificate, data, length) < 1)
+ goto out_fail2;
return TRUE;
+
+ out_fail2:
+ free(settings->ServerCertificate);
+ settings->ServerCertificate = NULL;
+ out_fail1:
+ free(settings->ServerRandom);
+ settings->ServerRandom = NULL;
+ return FALSE;
}
static const BYTE initial_signature[] =
diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c
index 11435ef..7717731 100644
--- a/libfreerdp/core/info.c
+++ b/libfreerdp/core/info.c
@@ -441,7 +441,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)
@@ -457,7 +457,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))
{
fprintf(stderr, "rdp_decrypt failed\n");
return FALSE;
diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c
index 88d039e..40bb150 100644
--- a/libfreerdp/core/license.c
+++ b/libfreerdp/core/license.c
@@ -240,12 +240,12 @@ BOOL license_recv(rdpLicense* license, wStream* s)
return FALSE;
}
- if (!rdp_read_security_header(s, &securityFlags))
+ if (!rdp_read_security_header(s, &securityFlags, &length))
return FALSE;
if (securityFlags & SEC_ENCRYPT)
{
- if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags))
+ if (!rdp_decrypt(license->rdp, s, length, securityFlags))
{
fprintf(stderr, "rdp_decrypt failed\n");
return FALSE;
@@ -474,25 +474,41 @@ BOOL license_read_product_info(wStream* s, PRODUCT_INFO* productInfo)
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->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)
- {
- free(productInfo->pbCompanyName);
- productInfo->pbCompanyName = NULL;
- return FALSE;
- }
+ goto out_fail;
productInfo->pbProductId = (BYTE*) malloc(productInfo->cbProductId);
- Stream_Read(s, productInfo->pbProductId, productInfo->cbProductId);
+ if (!productInfo->pbProductId)
+ goto out_fail;
+ Stream_Read(s, productInfo->pbProductId, productInfo->cbProductId);
return TRUE;
+
+ out_fail:
+ free(productInfo->pbCompanyName);
+ productInfo->pbCompanyName = NULL;
+ return FALSE;
+
}
/**
@@ -796,7 +812,10 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
/* 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)
diff --git a/libfreerdp/core/mcs.c b/libfreerdp/core/mcs.c
index d5ea089..16cf88e 100644
--- a/libfreerdp/core/mcs.c
+++ b/libfreerdp/core/mcs.c
@@ -197,7 +197,8 @@ BOOL mcs_read_domain_mcspdu_header(wStream* s, enum DomainMCSPDU* domainMCSPDU,
BYTE choice;
enum DomainMCSPDU MCSPDU;
- *length = tpkt_read_header(s);
+ if (!tpkt_read_header(s, length))
+ return FALSE;
if (!tpdu_read_data(s, &li))
return FALSE;
@@ -332,8 +333,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;
@@ -504,8 +510,13 @@ BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s)
BYTE result;
UINT16 li;
UINT32 calledConnectId;
+ UINT16 tlength;
- tpkt_read_header(s);
+ if (!mcs || !s)
+ return FALSE;
+
+ if (!tpkt_read_header(s, &tlength))
+ return FALSE;
if (!tpdu_read_data(s, &li))
return FALSE;
diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c
index 6148e86..bc77eb3 100644
--- a/libfreerdp/core/nego.c
+++ b/libfreerdp/core/nego.c
@@ -506,9 +506,7 @@ int nego_recv(rdpTransport* transport, wStream* s, void* extra)
UINT16 length;
rdpNego* nego = (rdpNego*) extra;
- length = tpkt_read_header(s);
-
- if (length == 0)
+ if (!tpkt_read_header(s, &length) || length == 0)
return -1;
if (!tpdu_read_connection_confirm(s, &li))
@@ -582,8 +580,10 @@ BOOL nego_read_request(rdpNego* nego, wStream* s)
BYTE li;
BYTE c;
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;
diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c
index eb4ad60..b9bad7e 100644
--- a/libfreerdp/core/peer.c
+++ b/libfreerdp/core/peer.c
@@ -179,12 +179,12 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
if (rdp->settings->DisableEncryption)
{
- 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))
{
fprintf(stderr, "rdp_decrypt failed\n");
return -1;
diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c
index 1a4704d..bb35bd9 100644
--- a/libfreerdp/core/rdp.c
+++ b/libfreerdp/core/rdp.c
@@ -77,13 +77,17 @@ static const char* const DATA_PDU_TYPE_STRINGS[] =
* @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;
}
@@ -249,6 +253,9 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id
return FALSE;
}
+ if (*length < 8)
+ return FALSE;
+
if (*length - 8 > Stream_GetRemainingLength(s))
return FALSE;
@@ -273,8 +280,12 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id
if (Stream_GetRemainingLength(s) < 5)
return FALSE;
- per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
- per_read_integer16(s, channel_id, 0); /* channelId */
+ if (!per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID)) /* initiator (UserId) */
+ return FALSE;
+
+ if (!per_read_integer16(s, channel_id, 0)) /* channelId */
+ return FALSE;
+
Stream_Seek(s, 1); /* dataPriority + Segmentation (0x70) */
if (!per_read_length(s, length)) /* userData (OCTET_STRING) */
@@ -701,16 +712,20 @@ BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s)
* @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];
+ 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;
@@ -723,6 +738,10 @@ 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))
{
@@ -741,11 +760,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;
@@ -795,12 +816,12 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
if (rdp->settings->DisableEncryption)
{
- if (!rdp_read_security_header(s, &securityFlags))
+ if (!rdp_read_security_header(s, &securityFlags, &length))
return -1;
if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
{
- if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
+ if (!rdp_decrypt(rdp, s, length, securityFlags))
{
fprintf(stderr, "rdp_decrypt failed\n");
return -1;
diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h
index fc73026..7bcfc27 100644
--- a/libfreerdp/core/rdp.h
+++ b/libfreerdp/core/rdp.h
@@ -160,7 +160,7 @@ struct rdp_rdp
BOOL deactivation_reactivation;
};
-BOOL rdp_read_security_header(wStream* s, UINT16* flags);
+BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length);
void rdp_write_security_header(wStream* s, UINT16 flags);
BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UINT16* channel_id);
@@ -202,6 +202,6 @@ void rdp_free(rdpRdp* rdp);
#define DEBUG_RDP(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
-BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags);
+BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags);
#endif /* __RDP_H */
diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c
index 5684528..dc9b2fc 100644
--- a/libfreerdp/core/security.c
+++ b/libfreerdp/core/security.c
@@ -475,7 +475,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len)
return TRUE;
}
-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)
{
@@ -490,7 +490,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;
@@ -507,7 +507,7 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
return TRUE;
}
-void security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp)
+void security_hmac_signature(const BYTE* data, size_t length, BYTE* output, rdpRdp* rdp)
{
BYTE buf[20];
BYTE use_count_le[4];
@@ -522,20 +522,20 @@ void security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp*
memmove(output, buf, 8);
}
-BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
+BOOL security_fips_encrypt(BYTE* data, size_t length, rdpRdp* rdp)
{
crypto_des3_encrypt(rdp->fips_encrypt, length, data, data);
rdp->encrypt_use_count++;
return TRUE;
}
-BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
+BOOL security_fips_decrypt(BYTE* data, size_t length, rdpRdp* rdp)
{
crypto_des3_decrypt(rdp->fips_decrypt, length, data, data);
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[20];
BYTE use_count_le[4];
diff --git a/libfreerdp/core/security.h b/libfreerdp/core/security.h
index ffcebdf..c6b6038 100644
--- a/libfreerdp/core/security.h
+++ b/libfreerdp/core/security.h
@@ -37,12 +37,12 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
void 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);
+BOOL security_encrypt(BYTE* data, size_t length, rdpRdp* rdp);
+BOOL security_decrypt(BYTE* data, size_t length, rdpRdp* rdp);
-void 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);
+void security_hmac_signature(const BYTE* data, size_t length, BYTE* output, rdpRdp* rdp);
+BOOL security_fips_encrypt(BYTE* data, size_t length, rdpRdp* rdp);
+BOOL security_fips_decrypt(BYTE* data, size_t length, rdpRdp* rdp);
+BOOL security_fips_check_signature(const BYTE* data, size_t length, const BYTE* sig, rdpRdp* rdp);
#endif /* __SECURITY_H */
diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c
index 992a3dd..15b2257 100644
--- a/libfreerdp/core/surface.c
+++ b/libfreerdp/core/surface.c
@@ -85,7 +85,7 @@ int update_recv_surfcmds(rdpUpdate* update, UINT32 size, wStream* s)
{
BYTE* mark;
UINT16 cmdType;
- UINT32 cmdLength;
+ UINT32 cmdLength = 0;
while (size > 2)
{
diff --git a/libfreerdp/core/tpkt.c b/libfreerdp/core/tpkt.c
index 5689d62..900e288 100644
--- a/libfreerdp/core/tpkt.c
+++ b/libfreerdp/core/tpkt.c
@@ -81,25 +81,37 @@ BOOL tpkt_verify_header(wStream* s)
* @return length
*/
-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;
}
/**
diff --git a/libfreerdp/core/tpkt.h b/libfreerdp/core/tpkt.h
index af984c1..9b51749 100644
--- a/libfreerdp/core/tpkt.h
+++ b/libfreerdp/core/tpkt.h
@@ -28,7 +28,7 @@
#define TPKT_HEADER_LENGTH 4
BOOL tpkt_verify_header(wStream* s);
-UINT16 tpkt_read_header(wStream* s);
+BOOL tpkt_read_header(wStream* s, UINT16* length);
void tpkt_write_header(wStream* s, UINT16 length);
#endif /* __TPKT_H */