boolean license_send(rdpLicense* license, STREAM* s, uint8 type) { int length; uint8 flags; uint16 wMsgSize; uint16 sec_flags; DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]); length = stream_get_length(s); stream_set_pos(s, 0); sec_flags = SEC_LICENSE_PKT; wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4; /** * Using EXTENDED_ERROR_MSG_SUPPORTED here would cause mstsc to crash when * running in server mode! This flag seems to be incorrectly documented. */ flags = PREAMBLE_VERSION_3_0; rdp_write_header(license->rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, sec_flags); license_write_preamble(s, type, flags, wMsgSize); #ifdef WITH_DEBUG_LICENSE printf("Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize); freerdp_hexdump(s->p - 4, wMsgSize); #endif stream_set_pos(s, length); if (transport_write(license->rdp->transport, s) < 0) return false; return true; }
static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length) { BYTE* data; UINT32 sec_flags; UINT32 pad = 0; sec_flags = rdp->sec_flags; if (sec_flags != 0) { rdp_write_security_header(s, sec_flags); if (sec_flags & SEC_ENCRYPT) { if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { data = Stream_Pointer(s) + 12; length = length - (data - Stream_Buffer(s)); Stream_Write_UINT16(s, 0x10); /* length */ Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/ /* handle padding */ pad = 8 - (length % 8); if (pad == 8) pad = 0; if (pad) memset(data+length, 0, pad); Stream_Write_UINT8(s, pad); security_hmac_signature(data, length, Stream_Pointer(s), rdp); Stream_Seek(s, 8); security_fips_encrypt(data, length + pad, rdp); } else { data = Stream_Pointer(s) + 8; length = length - (data - Stream_Buffer(s)); if (sec_flags & SEC_SECURE_CHECKSUM) security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s)); else security_mac_signature(rdp, data, length, Stream_Pointer(s)); Stream_Seek(s, 8); security_encrypt(Stream_Pointer(s), length, rdp); } } rdp->sec_flags = 0; } return pad; }
static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) { uint32 ml; uint8* mk; uint8* data; uint32 sec_flags; uint32 pad = 0; sec_flags = rdp->sec_flags; if (sec_flags != 0) { rdp_write_security_header(s, sec_flags); if (sec_flags & SEC_ENCRYPT) { if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { data = s->p + 12; length = length - (data - s->data); stream_write_uint16(s, 0x10); /* length */ stream_write_uint8(s, 0x1); /* TSFIPS_VERSION 1*/ /* handle padding */ pad = 8 - (length % 8); if (pad == 8) pad = 0; if (pad) memset(data+length, 0, pad); stream_write_uint8(s, pad); security_hmac_signature(data, length, s->p, rdp); stream_seek(s, 8); security_fips_encrypt(data, length + pad, rdp); } else { data = s->p + 8; length = length - (data - s->data); mk = rdp->sign_key; ml = rdp->rc4_key_len; security_mac_signature(mk, ml, data, length, s->p); stream_seek(s, 8); security_encrypt(s->p, length, rdp); } } rdp->sec_flags = 0; } return pad; }
void rdp_send_client_info(rdpRdp* rdp) { STREAM* s; s = rdp_send_stream_init(rdp); rdp_write_security_header(s, SEC_INFO_PKT); rdp_write_info_packet(s, rdp->settings); rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID); }
static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) { uint8* data; uint32 sec_flags; uint32 pad = 0; sec_flags = rdp->sec_flags; if (sec_flags != 0) { rdp_write_security_header(s, sec_flags); if (sec_flags & SEC_ENCRYPT) { if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { data = s->p + 12; length = length - (data - s->data); stream_write_uint16(s, 0x10); /* length */ stream_write_uint8(s, 0x1); /* TSFIPS_VERSION 1*/ /* handle padding */ pad = (8 - (length % 8)) & 7; memset(data+length, 0, pad); stream_write_uint8(s, pad); security_hmac_signature(data, length, s->p, rdp); stream_seek(s, 8); security_fips_encrypt(data, length + pad, rdp); } else { data = s->p + 8; length = length - (data - s->data); if (sec_flags & SEC_SECURE_CHECKSUM) security_salted_mac_signature(rdp, data, length, true, s->p); else security_mac_signature(rdp, data, length, s->p); stream_seek(s, 8); security_encrypt(s->p, length, rdp); } } rdp->sec_flags = 0; } return pad; }
BOOL license_send(rdpLicense* license, wStream* s, BYTE type) { int length; BYTE flags; UINT16 wMsgSize; UINT16 sec_flags; DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]); length = Stream_GetPosition(s); Stream_SetPosition(s, 0); sec_flags = SEC_LICENSE_PKT; wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4; /** * Using EXTENDED_ERROR_MSG_SUPPORTED here would cause mstsc to crash when * running in server mode! This flag seems to be incorrectly documented. */ flags = PREAMBLE_VERSION_3_0; rdp_write_header(license->rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, sec_flags); license_write_preamble(s, type, flags, wMsgSize); #ifdef WITH_DEBUG_LICENSE fprintf(stderr, "Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize); winpr_HexDump(Stream_Pointer(s) - 4, wMsgSize); #endif Stream_SetPosition(s, length); Stream_SealLength(s); if (transport_write(license->rdp->transport, s) < 0) return FALSE; Stream_Free(s, TRUE); return TRUE; }
static BOOL rdp_client_establish_keys(rdpRdp* rdp) { BYTE* mod; BYTE* exp; wStream* s; UINT32 length; UINT32 key_len; BYTE crypt_client_random[256 + 8]; if (!rdp->settings->DisableEncryption) { /* no RDP encryption */ return TRUE; } /* encrypt client random */ if (rdp->settings->ClientRandom) free(rdp->settings->ClientRandom); rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH); if (!rdp->settings->ClientRandom) return FALSE; ZeroMemory(crypt_client_random, sizeof(crypt_client_random)); 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; crypto_rsa_public_encrypt(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH, 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; s = Stream_New(NULL, length); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT); length = key_len + 8; Stream_Write_UINT32(s, length); Stream_Write(s, crypt_client_random, length); Stream_SealLength(s); if (transport_write(rdp->mcs->transport, s) < 0) { return FALSE; } Stream_Free(s, TRUE); /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(rdp->settings->ClientRandom, rdp)) { return FALSE; } rdp->do_crypt = TRUE; if (rdp->settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_hmac = crypto_hmac_new(); return TRUE; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); return TRUE; }
static boolean rdp_client_establish_keys(rdpRdp* rdp) { uint8 client_random[CLIENT_RANDOM_LENGTH]; uint8 crypt_client_random[256 + 8]; uint32 key_len; uint8* mod; uint8* exp; uint32 length; STREAM* s; if (rdp->settings->encryption == false) { /* no RDP encryption */ return true; } /* encrypt client random */ memset(crypt_client_random, 0, sizeof(crypt_client_random)); crypto_nonce(client_random, sizeof(client_random)); key_len = rdp->settings->server_cert->cert_info.modulus.length; mod = rdp->settings->server_cert->cert_info.modulus.data; exp = rdp->settings->server_cert->cert_info.exponent; crypto_rsa_public_encrypt(client_random, sizeof(client_random), 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; s = transport_send_stream_init(rdp->mcs->transport, length); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT); length = key_len + 8; stream_write_uint32(s, length); stream_write(s, crypt_client_random, length); if (transport_write(rdp->mcs->transport, s) < 0) { return false; } /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) { return false; } rdp->do_crypt = true; if (rdp->settings->salted_checksum) rdp->do_secure_checksum = true; if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_hmac = crypto_hmac_new(); return true; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); return true; }
static BOOL rdp_client_establish_keys(rdpRdp* rdp) { BYTE* mod; BYTE* exp; wStream* s; UINT32 length; UINT32 key_len; int status = 0; BOOL ret = FALSE; rdpSettings* settings; BYTE* crypt_client_random = NULL; settings = rdp->settings; if (!settings->DisableEncryption) { /* no RDP encryption */ return TRUE; } /* encrypt client random */ if (settings->ClientRandom) free(settings->ClientRandom); settings->ClientRandomLength = CLIENT_RANDOM_LENGTH; settings->ClientRandom = malloc(settings->ClientRandomLength); 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; /* * client random must be (bitlen / 8) + 8 - see [MS-RDPBCGR] 5.3.4.1 * for details */ crypt_client_random = calloc(1, key_len + 8); if (!crypt_client_random) return FALSE; 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; s = Stream_New(NULL, length); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT | SEC_LICENSE_ENCRYPT_SC); length = key_len + 8; Stream_Write_UINT32(s, length); Stream_Write(s, crypt_client_random, length); Stream_SealLength(s); status = transport_write(rdp->mcs->transport, s); Stream_Free(s, TRUE); if (status < 0) goto end; rdp->do_crypt_license = TRUE; /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(settings->ClientRandom, rdp)) goto end; rdp->do_crypt = TRUE; if (settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); if (!rdp->fips_encrypt) { WLog_ERR(TAG, "unable to allocate des3 encrypt key"); goto end; } rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); if (!rdp->fips_decrypt) { WLog_ERR(TAG, "unable to allocate des3 decrypt key"); goto end; } rdp->fips_hmac = crypto_hmac_new(); if (!rdp->fips_hmac) { WLog_ERR(TAG, "unable to allocate fips hmac"); goto end; } ret = TRUE; goto end; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key) { WLog_ERR(TAG, "unable to allocate rc4 decrypt key"); goto end; } rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_encrypt_key) { WLog_ERR(TAG, "unable to allocate rc4 encrypt key"); goto end; } ret = TRUE; end: if (crypt_client_random) free(crypt_client_random); return ret; }