25#include <openssl/rc4.h>
26#include <openssl/md5.h>
27#include <openssl/sha.h>
28#include <openssl/bn.h>
29#include <openssl/x509v3.h>
54 for (
i = 0;
i < 3;
i++)
59 SHA1_Update(&
sha, pad,
i + 1);
60 SHA1_Update(&
sha,
in, 48);
61 SHA1_Update(&
sha, salt1, 32);
62 SHA1_Update(&
sha, salt2, 32);
63 SHA1_Final(shasig, &
sha);
100 uint8 pre_master_secret[48];
101 uint8 master_secret[48];
105 memcpy(pre_master_secret, client_random, 24);
106 memcpy(pre_master_secret + 24, server_random, 24);
109 sec_hash_48(master_secret, pre_master_secret, client_random, server_random,
'A');
110 sec_hash_48(key_block, master_secret, client_random, server_random,
'X');
116 sec_hash_16(
This->secure.decrypt_key, &key_block[16], client_random, server_random);
117 sec_hash_16(
This->secure.encrypt_key, &key_block[32], client_random, server_random);
119 if (rc4_key_size == 1)
121 DEBUG((
"40-bit encryption enabled\n"));
125 This->secure.rc4_key_len = 8;
129 DEBUG((
"rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
130 This->secure.rc4_key_len = 16;
134 memcpy(
This->secure.decrypt_update_key,
This->secure.decrypt_key, 16);
135 memcpy(
This->secure.encrypt_update_key,
This->secure.encrypt_key, 16);
138 RC4_set_key(&
This->secure.rc4_decrypt_key,
This->secure.rc4_key_len,
This->secure.decrypt_key);
139 RC4_set_key(&
This->secure.rc4_encrypt_key,
This->secure.rc4_key_len,
This->secure.encrypt_key);
143 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
145 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
150 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
151 92, 92, 92, 92, 92, 92, 92,
152 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
153 92, 92, 92, 92, 92, 92, 92
179 SHA1_Update(&
sha, session_key, keylen);
181 SHA1_Update(&
sha, lenhdr, 4);
183 SHA1_Final(shasig, &
sha);
204 SHA1_Update(&
sha, update_key,
This->secure.rc4_key_len);
206 SHA1_Update(&
sha,
key,
This->secure.rc4_key_len);
207 SHA1_Final(shasig, &
sha);
215 RC4_set_key(&update,
This->secure.rc4_key_len,
key);
216 RC4(&update,
This->secure.rc4_key_len,
key,
key);
218 if (
This->secure.rc4_key_len == 8)
226 if (
This->secure.encrypt_use_count == 4096)
229 RC4_set_key(&
This->secure.rc4_encrypt_key,
This->secure.rc4_key_len,
This->secure.encrypt_key);
230 This->secure.encrypt_use_count = 0;
234 This->secure.encrypt_use_count++;
241 if (
This->secure.decrypt_use_count == 4096)
244 RC4_set_key(&
This->secure.rc4_decrypt_key,
This->secure.rc4_key_len,
This->secure.decrypt_key);
245 This->secure.decrypt_use_count = 0;
249 This->secure.decrypt_use_count++;
258 for (
i = 0,
j =
len - 1;
i <
j;
i++,
j--)
289 BN_bin2bn(inr,
len, &
x);
291 outlen = BN_bn2bin(&
y,
out);
293 if ((
uint32)outlen < modulus_size)
294 memset(
out + outlen, 0, modulus_size - outlen);
310 if (!
This->licence_issued)
338 flags &= ~SEC_ENCRYPT;
342 DEBUG((
"Sending encrypted packet:\n"));
385 int length = 158 + 76 + 12 + 4;
388 if (
This->num_channels > 0)
455 if (
This->num_channels > 0)
460 for (
i = 0;
i <
This->num_channels;
i++)
475 uint32 magic, modulus_len;
480 error(
"RSA magic 0x%x\n", magic);
488 error(
"Bad server public key size (%u bits)\n", modulus_len * 8);
496 This->secure.server_public_key_len = modulus_len;
504 EVP_PKEY *epk =
NULL;
510 if (OBJ_obj2nid(
cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
512 DEBUG_RDP5((
"Re-setting algorithm type to RSA in server certificate\n"));
513 ASN1_OBJECT_free(
cert->cert_info->key->algor->algorithm);
514 cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
516 epk = X509_get_pubkey(
cert);
519 error(
"Failed to extract public key from certificate\n");
523 This->secure.server_public_key = RSAPublicKey_dup((
RSA *) epk->pkey.ptr);
526 This->secure.server_public_key_len = RSA_size(
This->secure.server_public_key);
529 error(
"Bad server public key size (%u bits)\n",
This->secure.server_public_key_len * 8);
542 uint32 crypt_level, random_len, rsa_info_len;
544 X509 *cacert, *server_cert;
550 if (crypt_level == 0)
564 end =
s->p + rsa_info_len;
571 DEBUG_RDP5((
"We're going for the RDP4-style encryption\n"));
608 DEBUG_RDP5((
"We're going for the RDP5-style encryption\n"));
613 error(
"Server didn't send enough X509 certificates\n");
614 This->disconnect_reason = 1798;
618 for (; certcount > 2; certcount--)
623 DEBUG_RDP5((
"Ignored certs left: %d\n", certcount));
626 DEBUG_RDP5((
"Ignored Certificate length is %d\n", ignorelen));
627 ignorecert = d2i_X509(
NULL, &(
s->p), ignorelen);
629 if (ignorecert ==
NULL)
631 DEBUG_RDP5((
"got a bad cert: this will probably screw up the rest of the communication\n"));
634#ifdef WITH_DEBUG_RDP5
635 DEBUG_RDP5((
"cert #%d (ignored):\n", certcount));
636 X509_print_fp(
stdout, ignorecert);
650 DEBUG_RDP5((
"CA Certificate length is %d\n", cacert_len));
651 cacert = d2i_X509(
NULL, &(
s->p), cacert_len);
656 error(
"Couldn't load CA Certificate from server\n");
657 This->disconnect_reason = 1798;
674 DEBUG_RDP5((
"Certificate length is %d\n", cert_len));
675 server_cert = d2i_X509(
NULL, &(
s->p), cert_len);
676 if (
NULL == server_cert)
678 error(
"Couldn't load Certificate from server\n");
679 This->disconnect_reason = 1798;
691 DEBUG_RDP5((
"Didn't parse X509 correctly\n"));
692 X509_free(server_cert);
693 This->disconnect_reason = 1798;
696 X509_free(server_cert);
712 DEBUG((
"Failed to parse crypt info\n"));
716 DEBUG((
"Generating client random\n"));
719 if (
NULL !=
This->secure.server_public_key)
726 memset(inr, 0, padding_len);
737 RSA_public_encrypt(
This->secure.server_public_key_len,
738 inr,
This->secure.crypted_random,
This->secure.server_public_key, RSA_NO_PADDING);
740 reverse(
This->secure.crypted_random,
This->secure.server_public_key_len);
742 RSA_free(
This->secure.server_public_key);
743 This->secure.server_public_key =
NULL;
760 DEBUG_RDP5((
"Server RDP version is %d\n",
This->server_rdp_version));
761 if (1 ==
This->server_rdp_version)
764 This->server_depth = 8;
782 while (
s->p <
s->end)
838 if (
This->encryption || !
This->licence_issued)
854 if (sec_flags & 0x0400)
862 if (
s->p[0] == 0 &&
s->p[1] == 4)
912 This->disconnect_reason = 262;
925 if (
This->encryption)
940 This->disconnect_reason = 262;
953 if (
This->encryption)
970 This->server_rdp_version = 0;
971 This->secure.encrypt_use_count = 0;
972 This->secure.decrypt_use_count = 0;
std::map< E_MODULE, HMODULE > mod
void channel_process(STREAM s, uint16 mcs_channel)
#define SEC_EXPONENT_SIZE
#define SEC_TAG_CLI_CRYPT
#define SEC_TAG_SRV_CRYPT
#define SEC_TAG_SRV_CHANNELS
#define SEC_TAG_CLI_CHANNELS
#define SEC_MAX_MODULUS_SIZE
#define MCS_GLOBAL_CHANNEL
void licence_process(STREAM s)
STREAM mcs_init(int length)
void mcs_reset_state(void)
STREAM mcs_recv(uint16 *channel, uint8 *rdpver)
void mcs_disconnect(void)
void mcs_send_to_channel(STREAM s, uint16 channel)
#define out_uint32_le(s, v)
#define out_uint32_be(s, v)
#define s_pop_layer(s, h)
#define s_push_layer(s, h, n)
#define in_uint16_le(s, v)
#define out_uint16_be(s, v)
#define in_uint8p(s, v, n)
#define out_uint16_le(s, v)
#define out_uint8p(s, v, n)
#define in_uint32_le(s, v)
#define out_uint8a(s, v, n)
void unimpl(char *format,...)
void hexdump(unsigned char *p, unsigned int len)
void rdp_out_unistr(STREAM s, char *string, int len)
void generate_random(uint8 *random)
void sec_process_mcs_data(STREAM s)
static void sec_generate_keys(uint8 *client_random, uint8 *server_random, int rc4_key_size)
void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt)
static void sec_make_40bit(uint8 *key)
void buf_out_uint32(uint8 *buffer, uint32 value)
static RD_BOOL sec_parse_public_key(STREAM s, uint8 *modulus, uint8 *exponent)
static void sec_out_mcs_data(STREAM s, uint32 selected_protocol)
void sec_send(STREAM s, uint32 flags)
static RD_BOOL sec_parse_crypt_info(STREAM s, uint32 *rc4_key_size, uint8 **server_random, uint8 *modulus, uint8 *exponent)
RD_BOOL sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
void sec_reset_state(void)
void sec_disconnect(void)
static void sec_update(uint8 *key, uint8 *update_key)
static void sec_establish_key(void)
static void sec_rsa_encrypt(uint8 *out, uint8 *in, int len, uint32 modulus_size, uint8 *modulus, uint8 *exponent)
void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)
STREAM sec_recv(uint8 *rdpver)
static void sec_process_srv_info(STREAM s)
STREAM sec_init(uint32 flags, int maxlen)
static void sec_process_crypt_info(STREAM s)
static void sec_encrypt(uint8 *data, int length)
void sec_sign(uint8 *signature, int siglen, uint8 *session_key, int keylen, uint8 *data, int datalen)
void sec_decrypt(uint8 *data, int length)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
GLint GLint GLint GLint GLint x
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLuint GLsizei GLsizei * length
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
int const JOCTET unsigned int datalen
#define memcpy(s1, s2, n)
#define SEC_CLIENT_RANDOM
BOOL mcs_connect(RDPCLIENT *This, char *server, char *cookie, STREAM mcs_data)
BOOL mcs_reconnect(RDPCLIENT *This, char *server, char *cookie, STREAM mcs_data)
BOOL sec_reconnect(RDPCLIENT *This, char *server, wchar_t *hostname, char *cookie)
static BOOL sec_parse_x509_key(RDPCLIENT *This, X509 *cert)
static void reverse(uint8 *p, int len)
void MD5_Init(MD5_CTX *ctx)
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
static rfbScreenInfoPtr server