libfreerdp-core: fix reconnection using client random
This commit is contained in:
parent
cff9c16c1e
commit
7171a0b5c1
@ -536,6 +536,8 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_ServerRandomLength 197
|
||||
#define FreeRDP_ServerCertificate 198
|
||||
#define FreeRDP_ServerCertificateLength 199
|
||||
#define FreeRDP_ClientRandom 200
|
||||
#define FreeRDP_ClientRandomLength 201
|
||||
#define FreeRDP_ChannelCount 256
|
||||
#define FreeRDP_ChannelDefArraySize 257
|
||||
#define FreeRDP_ChannelDefArray 258
|
||||
@ -851,11 +853,12 @@ struct rdp_settings
|
||||
ALIGN64 UINT32 ExtEncryptionMethods; /* 194 */
|
||||
ALIGN64 UINT32 EncryptionLevel; /* 195 */
|
||||
ALIGN64 BYTE* ServerRandom; /* 196 */
|
||||
ALIGN64 DWORD ServerRandomLength; /* 197 */
|
||||
ALIGN64 UINT32 ServerRandomLength; /* 197 */
|
||||
ALIGN64 BYTE* ServerCertificate; /* 198 */
|
||||
ALIGN64 DWORD ServerCertificateLength; /* 199 */
|
||||
ALIGN64 UINT32 ServerCertificateLength; /* 199 */
|
||||
ALIGN64 BYTE* ClientRandom; /* 200 */
|
||||
UINT64 padding0256[256 - 201]; /* 201 */
|
||||
ALIGN64 UINT32 ClientRandomLength; /* 201 */
|
||||
UINT64 padding0256[256 - 202]; /* 202 */
|
||||
|
||||
/* Client Network Data */
|
||||
ALIGN64 UINT32 ChannelCount; /* 256 */
|
||||
@ -1014,7 +1017,7 @@ struct rdp_settings
|
||||
|
||||
/* Credentials Cache */
|
||||
ALIGN64 BYTE* Password51; /* 1280 */
|
||||
ALIGN64 DWORD Password51Length; /* 1281 */
|
||||
ALIGN64 UINT32 Password51Length; /* 1281 */
|
||||
UINT64 padding1344[1344 - 1282]; /* 1282 */
|
||||
|
||||
/* Kerberos Authentication */
|
||||
@ -1120,8 +1123,8 @@ struct rdp_settings
|
||||
ALIGN64 char* RemoteApplicationFile; /* 2116 */
|
||||
ALIGN64 char* RemoteApplicationGuid; /* 2117 */
|
||||
ALIGN64 char* RemoteApplicationCmdLine; /* 2118 */
|
||||
ALIGN64 DWORD RemoteApplicationExpandCmdLine; /* 2119 */
|
||||
ALIGN64 DWORD RemoteApplicationExpandWorkingDir; /* 2120 */
|
||||
ALIGN64 UINT32 RemoteApplicationExpandCmdLine; /* 2119 */
|
||||
ALIGN64 UINT32 RemoteApplicationExpandWorkingDir; /* 2120 */
|
||||
ALIGN64 BOOL DisableRemoteAppCapsCheck; /* 2121 */
|
||||
ALIGN64 UINT32 RemoteAppNumIconCaches; /* 2122 */
|
||||
ALIGN64 UINT32 RemoteAppNumIconCacheEntries; /* 2123 */
|
||||
|
@ -1626,6 +1626,12 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id)
|
||||
case FreeRDP_EncryptionLevel:
|
||||
return settings->EncryptionLevel;
|
||||
|
||||
case FreeRDP_ServerRandomLength:
|
||||
return settings->ServerRandomLength;
|
||||
|
||||
case FreeRDP_ClientRandomLength:
|
||||
return settings->ClientRandomLength;
|
||||
|
||||
case FreeRDP_ChannelCount:
|
||||
return settings->ChannelCount;
|
||||
|
||||
@ -1875,6 +1881,14 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
|
||||
settings->EncryptionLevel = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_ServerRandomLength:
|
||||
settings->ServerRandomLength = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_ClientRandomLength:
|
||||
settings->ClientRandomLength = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_ChannelCount:
|
||||
settings->ChannelCount = param;
|
||||
break;
|
||||
|
@ -388,11 +388,14 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
||||
wStream* s;
|
||||
UINT32 length;
|
||||
UINT32 key_len;
|
||||
BYTE *crypt_client_random = NULL;
|
||||
BOOL ret = FALSE;
|
||||
int status = 0;
|
||||
BOOL ret = FALSE;
|
||||
rdpSettings* settings;
|
||||
BYTE* crypt_client_random = NULL;
|
||||
|
||||
if (!rdp->settings->DisableEncryption)
|
||||
settings = rdp->settings;
|
||||
|
||||
if (!settings->DisableEncryption)
|
||||
{
|
||||
/* no RDP encryption */
|
||||
return TRUE;
|
||||
@ -400,27 +403,30 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
||||
|
||||
/* encrypt client random */
|
||||
|
||||
if (rdp->settings->ClientRandom)
|
||||
free(rdp->settings->ClientRandom);
|
||||
if (settings->ClientRandom)
|
||||
free(settings->ClientRandom);
|
||||
|
||||
rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH);
|
||||
settings->ClientRandomLength = CLIENT_RANDOM_LENGTH;
|
||||
settings->ClientRandom = malloc(settings->ClientRandomLength);
|
||||
|
||||
if (!rdp->settings->ClientRandom)
|
||||
if (!settings->ClientRandom)
|
||||
return FALSE;
|
||||
|
||||
crypto_nonce(settings->ClientRandom, settings->ClientRandomLength);
|
||||
key_len = settings->RdpServerCertificate->cert_info.ModulusLength;
|
||||
mod = settings->RdpServerCertificate->cert_info.Modulus;
|
||||
exp = settings->RdpServerCertificate->cert_info.exponent;
|
||||
|
||||
crypto_nonce(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH);
|
||||
key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength;
|
||||
mod = rdp->settings->RdpServerCertificate->cert_info.Modulus;
|
||||
exp = rdp->settings->RdpServerCertificate->cert_info.exponent;
|
||||
/*
|
||||
* client random must be (bitlen / 8) + 8 - see [MS-RDPBCGR] 5.3.4.1
|
||||
* for details
|
||||
*/
|
||||
crypt_client_random = calloc(1,key_len+8);
|
||||
crypt_client_random = calloc(1, key_len + 8);
|
||||
|
||||
if (!crypt_client_random)
|
||||
return FALSE;
|
||||
crypto_rsa_public_encrypt(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH, key_len, mod, exp, crypt_client_random);
|
||||
|
||||
crypto_rsa_public_encrypt(settings->ClientRandom, settings->ClientRandomLength, key_len, mod, exp, crypt_client_random);
|
||||
|
||||
/* send crypt client random to server */
|
||||
length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8;
|
||||
@ -441,15 +447,15 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
||||
goto end;
|
||||
|
||||
/* now calculate encrypt / decrypt and update keys */
|
||||
if (!security_establish_keys(rdp->settings->ClientRandom, rdp))
|
||||
if (!security_establish_keys(settings->ClientRandom, rdp))
|
||||
goto end;
|
||||
|
||||
rdp->do_crypt = TRUE;
|
||||
|
||||
if (rdp->settings->SaltedChecksum)
|
||||
if (settings->SaltedChecksum)
|
||||
rdp->do_secure_checksum = TRUE;
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
|
||||
if (!rdp->fips_encrypt)
|
||||
|
@ -105,13 +105,31 @@ BOOL rdp_read_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings)
|
||||
|
||||
void rdp_write_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings)
|
||||
{
|
||||
CryptoHmac hmac;
|
||||
BYTE nullRandom[32];
|
||||
BYTE cryptSecurityVerifier[16];
|
||||
ARC_CS_PRIVATE_PACKET* autoReconnectCookie;
|
||||
autoReconnectCookie = settings->ClientAutoReconnectCookie;
|
||||
|
||||
/* SecurityVerifier = HMAC(AutoReconnectRandom, ClientRandom) */
|
||||
|
||||
hmac = crypto_hmac_new();
|
||||
ZeroMemory(nullRandom, sizeof(nullRandom));
|
||||
|
||||
crypto_hmac_md5_init(hmac, autoReconnectCookie->securityVerifier, 16);
|
||||
|
||||
if (settings->ClientRandomLength > 0)
|
||||
crypto_hmac_update(hmac, settings->ClientRandom, settings->ClientRandomLength);
|
||||
else
|
||||
crypto_hmac_update(hmac, nullRandom, sizeof(nullRandom));
|
||||
|
||||
crypto_hmac_final(hmac, cryptSecurityVerifier, 16);
|
||||
crypto_hmac_free(hmac);
|
||||
|
||||
Stream_Write_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
|
||||
Stream_Write_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */
|
||||
Stream_Write_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
|
||||
Stream_Write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */
|
||||
Stream_Write(s, cryptSecurityVerifier, 16); /* SecurityVerifier */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -522,6 +522,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
_settings->EncryptionLevel = settings->EncryptionLevel; /* 195 */
|
||||
_settings->ServerRandomLength = settings->ServerRandomLength; /* 197 */
|
||||
_settings->ServerCertificateLength = settings->ServerCertificateLength; /* 199 */
|
||||
_settings->ClientRandomLength = settings->ClientRandomLength; /* 201 */
|
||||
_settings->ChannelCount = settings->ChannelCount; /* 256 */
|
||||
_settings->ChannelDefArraySize = settings->ChannelDefArraySize; /* 257 */
|
||||
_settings->ClusterInfoFlags = settings->ClusterInfoFlags; /* 320 */
|
||||
@ -725,6 +726,18 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
* Manual Code
|
||||
*/
|
||||
|
||||
if (_settings->ServerRandomLength)
|
||||
{
|
||||
_settings->ServerRandom = (BYTE*) malloc(_settings->ServerRandomLength);
|
||||
CopyMemory(_settings->ServerRandom, settings->ServerRandom, _settings->ServerRandomLength);
|
||||
}
|
||||
|
||||
if (_settings->ClientRandomLength)
|
||||
{
|
||||
_settings->ClientRandom = (BYTE*) malloc(_settings->ClientRandomLength);
|
||||
CopyMemory(_settings->ClientRandom, settings->ClientRandom, _settings->ClientRandomLength);
|
||||
}
|
||||
|
||||
_settings->ChannelCount = settings->ChannelCount;
|
||||
_settings->ChannelDefArraySize = settings->ChannelDefArraySize;
|
||||
_settings->ChannelDefArray = (CHANNEL_DEF*) malloc(sizeof(CHANNEL_DEF) * settings->ChannelDefArraySize);
|
||||
@ -836,7 +849,7 @@ void freerdp_settings_free(rdpSettings* settings)
|
||||
free(settings->ClientHostname);
|
||||
free(settings->ClientProductId);
|
||||
free(settings->ServerRandom);
|
||||
if (settings->ClientRandom) free(settings->ClientRandom);
|
||||
free(settings->ClientRandom);
|
||||
free(settings->ServerCertificate);
|
||||
free(settings->RdpKeyFile);
|
||||
certificate_free(settings->RdpServerCertificate);
|
||||
|
Loading…
Reference in New Issue
Block a user