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);
191 memcpy(signature, md5sig, siglen);
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);
290 BN_mod_exp(&
y, &
x, &
exp, &
mod, ctx);
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)
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++)
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;
#define out_uint16_le(s, v)
void buf_out_uint32(uint8 *buffer, uint32 value)
#define out_uint8p(s, v, n)
static void sec_update(RDPCLIENT *This, uint8 *key, uint8 *update_key)
#define SEC_TAG_CLI_CRYPT
static rfbScreenInfoPtr server
#define out_uint8a(s, v, n)
void mcs_send_to_channel(STREAM s, uint16 channel)
void sec_reset_state(void)
void sec_process_mcs_data(STREAM s)
static BOOL sec_parse_x509_key(RDPCLIENT *This, X509 *cert)
#define out_uint32_le(s, v)
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
#define SEC_MAX_MODULUS_SIZE
GLint GLint GLint GLint GLint x
void channel_process(STREAM s, uint16 mcs_channel)
BOOL sec_reconnect(RDPCLIENT *This, char *server, wchar_t *hostname, char *cookie)
static void sec_process_srv_info(RDPCLIENT *This, STREAM s)
int const JOCTET unsigned int datalen
#define in_uint8p(s, v, n)
void sec_decrypt(uint8 *data, int length)
#define SEC_TAG_CLI_CHANNELS
#define MCS_GLOBAL_CHANNEL
static BOOL sec_parse_crypt_info(RDPCLIENT *This, STREAM s, uint32 *rc4_key_size, uint8 **server_random, uint8 **modulus, uint8 **exponent)
static const uint8 pad_92[48]
static void reverse(uint8 *p, int len)
void mcs_reset_state(void)
static void sec_out_mcs_data(RDPCLIENT *This, STREAM s, wchar_t *hostname)
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
void sec_sign(uint8 *signature, int siglen, uint8 *session_key, int keylen, uint8 *data, int datalen)
void sec_send(STREAM s, uint32 flags)
static void sec_encrypt(RDPCLIENT *This, uint8 *data, int length)
#define s_pop_layer(s, h)
static void sec_establish_key(RDPCLIENT *This)
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
static void sec_rsa_encrypt(uint8 *out, uint8 *in, int len, uint32 modulus_size, uint8 *modulus, uint8 *exponent)
#define SEC_TAG_SRV_CHANNELS
static void sec_process_crypt_info(RDPCLIENT *This, STREAM s)
void MD5_Init(MD5_CTX *ctx)
#define SEC_EXPONENT_SIZE
GLenum GLuint GLenum GLsizei length
STREAM sec_recv(uint8 *rdpver)
static const uint8 pad_54[40]
static void sec_make_40bit(uint8 *key)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
RD_BOOL sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
STREAM mcs_init(int length)
STREAM mcs_recv(uint16 *channel, uint8 *rdpver)
#define memcpy(s1, s2, n)
GLsizei const GLfloat * value
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
#define out_uint32_be(s, v)
static BOOL sec_parse_public_key(RDPCLIENT *This, STREAM s, uint8 **modulus, uint8 **exponent)
#define s_push_layer(s, h, n)
void hexdump(unsigned char *p, unsigned int len)
static void sec_generate_keys(RDPCLIENT *This, uint8 *client_random, uint8 *server_random, int rc4_key_size)
#define SEC_TAG_SRV_CRYPT
void sec_disconnect(void)
void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)
void rdp_out_unistr(STREAM s, char *string, int len)
GLint GLint GLint GLint GLint GLint y
#define out_uint16_be(s, v)
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
void generate_random(uint8 *random)
void unimpl(char *format,...)
BOOL mcs_reconnect(RDPCLIENT *This, char *server, char *cookie, STREAM mcs_data)
STREAM sec_init(uint32 flags, int maxlen)
#define in_uint32_le(s, v)
void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt)
BOOL mcs_connect(RDPCLIENT *This, char *server, char *cookie, STREAM mcs_data)
void mcs_disconnect(void)
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define SEC_CLIENT_RANDOM
void licence_process(STREAM s)
#define in_uint16_le(s, v)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *