New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security fixes and code cleanups #4055

Merged
merged 9 commits into from Jul 24, 2017
Next

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
  • Loading branch information...
akallabeth committed May 29, 2017
commit 8292b4558f0684065ce1f58db7783cc426099223
@@ -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;
View
@@ -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
@@ -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
@@ -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
@@ -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);
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.