ReactOS  0.4.14-dev-115-g4576127
secure.c File Reference
#include "rdesktop.h"
#include <string.h>
#include <openssl/rc4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
Include dependency graph for secure.c:

Go to the source code of this file.

Functions

void sec_hash_48 (uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt)
 
void sec_hash_16 (uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)
 
static void sec_make_40bit (uint8 *key)
 
static void sec_generate_keys (RDPCLIENT *This, uint8 *client_random, uint8 *server_random, int rc4_key_size)
 
void buf_out_uint32 (uint8 *buffer, uint32 value)
 
void sec_sign (uint8 *signature, int siglen, uint8 *session_key, int keylen, uint8 *data, int datalen)
 
static void sec_update (RDPCLIENT *This, uint8 *key, uint8 *update_key)
 
static void sec_encrypt (RDPCLIENT *This, uint8 *data, int length)
 
void sec_decrypt (RDPCLIENT *This, uint8 *data, int length)
 
static void reverse (uint8 *p, int len)
 
static void sec_rsa_encrypt (uint8 *out, uint8 *in, int len, uint32 modulus_size, uint8 *modulus, uint8 *exponent)
 
STREAM sec_init (RDPCLIENT *This, uint32 flags, int maxlen)
 
BOOL sec_send_to_channel (RDPCLIENT *This, STREAM s, uint32 flags, uint16 channel)
 
BOOL sec_send (RDPCLIENT *This, STREAM s, uint32 flags)
 
static void sec_establish_key (RDPCLIENT *This)
 
static void sec_out_mcs_data (RDPCLIENT *This, STREAM s, wchar_t *hostname)
 
static BOOL sec_parse_public_key (RDPCLIENT *This, STREAM s, uint8 **modulus, uint8 **exponent)
 
static BOOL sec_parse_x509_key (RDPCLIENT *This, X509 *cert)
 
static BOOL sec_parse_crypt_info (RDPCLIENT *This, STREAM s, uint32 *rc4_key_size, uint8 **server_random, uint8 **modulus, uint8 **exponent)
 
static void sec_process_crypt_info (RDPCLIENT *This, STREAM s)
 
static void sec_process_srv_info (RDPCLIENT *This, STREAM s)
 
void sec_process_mcs_data (RDPCLIENT *This, STREAM s)
 
STREAM sec_recv (RDPCLIENT *This, uint8 *rdpver)
 
BOOL sec_connect (RDPCLIENT *This, char *server, wchar_t *hostname, char *cookie)
 
BOOL sec_reconnect (RDPCLIENT *This, char *server, wchar_t *hostname, char *cookie)
 
void sec_disconnect (RDPCLIENT *This)
 
void sec_reset_state (RDPCLIENT *This)
 

Variables

static const uint8 pad_54 [40]
 
static const uint8 pad_92 [48]
 

Function Documentation

◆ buf_out_uint32()

void buf_out_uint32 ( uint8 buffer,
uint32  value 
)

Definition at line 158 of file secure.c.

159 {
160  buffer[0] = (value) & 0xff;
161  buffer[1] = (value >> 8) & 0xff;
162  buffer[2] = (value >> 16) & 0xff;
163  buffer[3] = (value >> 24) & 0xff;
164 }
GLuint buffer
Definition: glext.h:5915
GLsizei const GLfloat * value
Definition: glext.h:6069

Referenced by cliprdr_send_data_request(), cliprdr_send_simple_native_format_announce(), and licence_generate_hwid().

◆ reverse()

static void reverse ( uint8 p,
int  len 
)
static

Definition at line 253 of file secure.c.

254 {
255  int i, j;
256  uint8 temp;
257 
258  for (i = 0, j = len - 1; i < j; i++, j--)
259  {
260  temp = p[i];
261  p[i] = p[j];
262  p[j] = temp;
263  }
264 }
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
Definition: glfuncs.h:248
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
Definition: glfuncs.h:250
unsigned char uint8
Definition: types.h:28
GLenum GLsizei len
Definition: glext.h:6722
static calc_node_t temp
Definition: rpn_ieee.c:38
GLfloat GLfloat p
Definition: glext.h:8902

Referenced by sec_process_crypt_info(), and sec_rsa_encrypt().

◆ sec_connect()

BOOL sec_connect ( RDPCLIENT This,
char server,
wchar_t hostname,
char cookie 
)

Definition at line 905 of file secure.c.

906 {
907  struct stream mcs_data;
908  void * p = malloc(512);
909 
910  if(p == NULL)
911  {
912  This->disconnect_reason = 262;
913  return False;
914  }
915 
916  /* We exchange some RDP data during the MCS-Connect */
917  mcs_data.size = 512;
918  mcs_data.p = mcs_data.data = (uint8 *) p;
919  sec_out_mcs_data(This, &mcs_data, hostname);
920 
921  if (!mcs_connect(This, server, cookie, &mcs_data))
922  return False;
923 
924  /* sec_process_mcs_data(&mcs_data); */
925  if (This->encryption)
927  free(mcs_data.data);
928  return True;
929 }
static rfbScreenInfoPtr server
Definition: vnc.c:74
#define free
Definition: debug_ros.c:5
char * hostname
Definition: ftp.c:88
static void sec_out_mcs_data(RDPCLIENT *This, STREAM s, wchar_t *hostname)
Definition: secure.c:382
smooth NULL
Definition: ftsmooth.c:416
static void sec_establish_key(RDPCLIENT *This)
Definition: secure.c:364
#define True
Definition: types.h:24
#define False
Definition: types.h:25
unsigned char uint8
Definition: types.h:28
Definition: parse.h:22
#define malloc
Definition: debug_ros.c:4
GLfloat GLfloat p
Definition: glext.h:8902
BOOL mcs_connect(RDPCLIENT *This, char *server, char *cookie, STREAM mcs_data)
Definition: mcs.c:388

◆ sec_decrypt()

void sec_decrypt ( RDPCLIENT This,
uint8 data,
int  length 
)

Definition at line 239 of file secure.c.

240 {
241  if (This->secure.decrypt_use_count == 4096)
242  {
243  sec_update(This, This->secure.decrypt_key, This->secure.decrypt_update_key);
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;
246  }
247 
248  RC4(&This->secure.rc4_decrypt_key, length, data, data);
249  This->secure.decrypt_use_count++;
250 }
static void sec_update(RDPCLIENT *This, uint8 *key, uint8 *update_key)
Definition: secure.c:196
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

◆ sec_disconnect()

void sec_disconnect ( RDPCLIENT This)

Definition at line 961 of file secure.c.

962 {
964 }
void mcs_disconnect(void)
Definition: mcs.c:356

◆ sec_encrypt()

static void sec_encrypt ( RDPCLIENT This,
uint8 data,
int  length 
)
static

Definition at line 224 of file secure.c.

225 {
226  if (This->secure.encrypt_use_count == 4096)
227  {
228  sec_update(This, This->secure.encrypt_key, This->secure.encrypt_update_key);
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;
231  }
232 
233  RC4(&This->secure.rc4_encrypt_key, length, data, data);
234  This->secure.encrypt_use_count++;
235 }
static void sec_update(RDPCLIENT *This, uint8 *key, uint8 *update_key)
Definition: secure.c:196
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by sec_send_to_channel().

◆ sec_establish_key()

static void sec_establish_key ( RDPCLIENT This)
static

Definition at line 364 of file secure.c.

365 {
366  uint32 length = This->secure.server_public_key_len + SEC_PADDING_SIZE;
368  STREAM s;
369 
370  s = sec_init(This, flags, length + 4);
371 
373  out_uint8p(s, This->secure.crypted_random, This->secure.server_public_key_len);
375 
376  s_mark_end(s);
377  sec_send(This, s, flags);
378 }
#define out_uint8p(s, v, n)
Definition: parse.h:93
unsigned int uint32
Definition: types.h:32
#define out_uint32_le(s, v)
Definition: parse.h:59
void sec_send(STREAM s, uint32 flags)
Definition: secure.c:472
#define out_uint8s(s, n)
Definition: parse.h:95
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
GLbitfield flags
Definition: glext.h:7161
Definition: parse.h:22
#define SEC_PADDING_SIZE
Definition: constants.h:94
GLdouble s
Definition: gl.h:2039
#define s_mark_end(s)
Definition: parse.h:41
STREAM sec_init(uint32 flags, int maxlen)
Definition: secure.c:419
#define SEC_CLIENT_RANDOM
Definition: constants.h:69

Referenced by sec_connect(), and sec_reconnect().

◆ sec_generate_keys()

static void sec_generate_keys ( RDPCLIENT This,
uint8 client_random,
uint8 server_random,
int  rc4_key_size 
)
static

Definition at line 98 of file secure.c.

99 {
100  uint8 pre_master_secret[48];
101  uint8 master_secret[48];
102  uint8 key_block[48];
103 
104  /* Construct pre-master secret */
105  memcpy(pre_master_secret, client_random, 24);
106  memcpy(pre_master_secret + 24, server_random, 24);
107 
108  /* Generate master secret and then key material */
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');
111 
112  /* First 16 bytes of key material is MAC secret */
113  memcpy(This->secure.sign_key, key_block, 16);
114 
115  /* Generate export keys from next two blocks of 16 bytes */
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);
118 
119  if (rc4_key_size == 1)
120  {
121  DEBUG(("40-bit encryption enabled\n"));
122  sec_make_40bit(This->secure.sign_key);
123  sec_make_40bit(This->secure.decrypt_key);
124  sec_make_40bit(This->secure.encrypt_key);
125  This->secure.rc4_key_len = 8;
126  }
127  else
128  {
129  DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
130  This->secure.rc4_key_len = 16;
131  }
132 
133  /* Save initial RC4 keys as update keys */
134  memcpy(This->secure.decrypt_update_key, This->secure.decrypt_key, 16);
135  memcpy(This->secure.encrypt_update_key, This->secure.encrypt_key, 16);
136 
137  /* Initialise RC4 state arrays */
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);
140 }
unsigned char uint8
Definition: types.h:28
static void sec_make_40bit(uint8 *key)
Definition: secure.c:89
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)
Definition: secure.c:187
#define DEBUG(args)
Definition: rdesktop.h:129
void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt)
Definition: secure.c:155

Referenced by sec_process_crypt_info().

◆ sec_hash_16()

void sec_hash_16 ( uint8 out,
uint8 in,
uint8 salt1,
uint8 salt2 
)

Definition at line 76 of file secure.c.

77 {
78  MD5_CTX md5;
79 
80  MD5_Init(&md5);
81  MD5_Update(&md5, in, 16);
82  MD5_Update(&md5, salt1, 32);
83  MD5_Update(&md5, salt2, 32);
84  MD5_Final(out, &md5);
85 }
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
Definition: md5.c:258
void MD5_Init(MD5_CTX *ctx)
Definition: md5.c:207
static FILE * out
Definition: regtests2xml.c:44
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:218
GLuint in
Definition: glext.h:9616
#define md5
Definition: compat-1.3.h:2010
Definition: msi.c:4078

Referenced by licence_generate_keys().

◆ sec_hash_48()

void sec_hash_48 ( uint8 out,
uint8 in,
uint8 salt1,
uint8 salt2,
uint8  salt 
)

Definition at line 46 of file secure.c.

47 {
48  uint8 shasig[20];
49  uint8 pad[4];
50  SHA_CTX sha;
51  MD5_CTX md5;
52  int i;
53 
54  for (i = 0; i < 3; i++)
55  {
56  memset(pad, salt + i, i + 1);
57 
58  SHA1_Init(&sha);
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);
64 
65  MD5_Init(&md5);
66  MD5_Update(&md5, in, 48);
67  MD5_Update(&md5, shasig, 20);
68  MD5_Final(&out[i * 16], &md5);
69  }
70 }
static const WCHAR sha[]
Definition: oid.c:1218
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
Definition: md5.c:258
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
Definition: glfuncs.h:248
Definition: addons.c:68
void MD5_Init(MD5_CTX *ctx)
Definition: md5.c:207
static FILE * out
Definition: regtests2xml.c:44
unsigned char uint8
Definition: types.h:28
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:218
GLuint in
Definition: glext.h:9616
#define md5
Definition: compat-1.3.h:2010
Definition: msi.c:4078
#define memset(x, y, z)
Definition: compat.h:39

Referenced by licence_generate_keys().

◆ sec_init()

STREAM sec_init ( RDPCLIENT This,
uint32  flags,
int  maxlen 
)

Definition at line 305 of file secure.c.

306 {
307  int hdrlen;
308  STREAM s;
309 
310  if (!This->licence_issued)
311  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
312  else
313  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
314  s = mcs_init(This, maxlen + hdrlen);
315 
316  if(s == NULL)
317  return s;
318 
319  s_push_layer(s, sec_hdr, hdrlen);
320 
321  return s;
322 }
smooth NULL
Definition: ftsmooth.c:416
#define SEC_ENCRYPT
Definition: constants.h:101
GLbitfield flags
Definition: glext.h:7161
STREAM mcs_init(int length)
Definition: mcs.c:242
Definition: parse.h:22
GLdouble s
Definition: gl.h:2039
#define s_push_layer(s, h, n)
Definition: parse.h:39
unsigned char * sec_hdr
Definition: parse.h:32

◆ sec_make_40bit()

static void sec_make_40bit ( uint8 key)
static

Definition at line 89 of file secure.c.

90 {
91  key[0] = 0xd1;
92  key[1] = 0x26;
93  key[2] = 0x9e;
94 }
Definition: path.c:42

Referenced by sec_generate_keys(), and sec_update().

◆ sec_out_mcs_data()

static void sec_out_mcs_data ( RDPCLIENT This,
STREAM  s,
wchar_t hostname 
)
static

Definition at line 382 of file secure.c.

383 {
384  int hostlen = 2 * (int)wcslen(hostname);
385  int length = 158 + 76 + 12 + 4;
386  unsigned int i;
387 
388  if (This->num_channels > 0)
389  length += This->num_channels * 12 + 8;
390 
391  if (hostlen > 30)
392  hostlen = 30;
393 
394  /* Generic Conference Control (T.124) ConferenceCreateRequest */
395  out_uint16_be(s, 5);
396  out_uint16_be(s, 0x14);
397  out_uint8(s, 0x7c);
398  out_uint16_be(s, 1);
399 
400  out_uint16_be(s, (length | 0x8000)); /* remaining length */
401 
402  out_uint16_be(s, 8); /* length? */
403  out_uint16_be(s, 16);
404  out_uint8(s, 0);
405  out_uint16_le(s, 0xc001);
406  out_uint8(s, 0);
407 
408  out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
409  out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
410 
411  /* Client information */
413  out_uint16_le(s, 212); /* length */
414  out_uint16_le(s, This->use_rdp5 ? 4 : 1); /* RDP version. 1 == RDP4, 4 == RDP5. */
415  out_uint16_le(s, 8);
416  out_uint16_le(s, This->width);
417  out_uint16_le(s, This->height);
418  out_uint16_le(s, 0xca01);
419  out_uint16_le(s, 0xaa03);
420  out_uint32_le(s, This->keylayout);
421  out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
422 
423  /* Unicode name of client, padded to 32 bytes */
424  rdp_out_unistr(This, s, hostname, hostlen);
425  out_uint8s(s, 30 - hostlen);
426 
427  /* See
428  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
429  out_uint32_le(s, This->keyboard_type);
430  out_uint32_le(s, This->keyboard_subtype);
431  out_uint32_le(s, This->keyboard_functionkeys);
432  out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
433  out_uint16_le(s, 0xca01); /* colour depth? */
434  out_uint16_le(s, 1);
435 
436  out_uint32(s, 0);
437  out_uint8(s, This->server_depth);
438  out_uint16_le(s, 0x0700);
439  out_uint8(s, 0);
440  out_uint32_le(s, 1);
441  out_uint8s(s, 64); /* End of client info */
442 
444  out_uint16_le(s, 12);
445  out_uint32_le(s, This->console_session ? 0xb : 9);
446  out_uint32(s, 0);
447 
448  /* Client encryption settings */
450  out_uint16_le(s, 12); /* length */
451  out_uint32_le(s, This->encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
452  out_uint32(s, 0); /* Unknown */
453 
454  DEBUG_RDP5(("This->num_channels is %d\n", This->num_channels));
455  if (This->num_channels > 0)
456  {
458  out_uint16_le(s, This->num_channels * 12 + 8); /* length */
459  out_uint32_le(s, This->num_channels); /* number of virtual channels */
460  for (i = 0; i < This->num_channels; i++)
461  {
462  DEBUG_RDP5(("Requesting channel %s\n", This->channels[i].name));
463  out_uint8a(s, This->channel_defs[i].name, 8);
464  out_uint32_be(s, This->channel_defs[i].options);
465  }
466  }
467 
468  s_mark_end(s);
469 }
#define out_uint16_le(s, v)
Definition: parse.h:58
#define SEC_TAG_CLI_INFO
Definition: constants.h:119
#define SEC_TAG_CLI_CRYPT
Definition: constants.h:120
#define out_uint8a(s, v, n)
Definition: parse.h:94
#define out_uint32_le(s, v)
Definition: parse.h:59
char * hostname
Definition: ftp.c:88
#define SEC_TAG_CLI_CHANNELS
Definition: constants.h:121
#define out_uint8(s, v)
Definition: parse.h:92
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
Definition: glfuncs.h:248
#define SEC_TAG_CLI_4
Definition: constants.h:82
#define out_uint8s(s, n)
Definition: parse.h:95
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
GLdouble s
Definition: gl.h:2039
#define out_uint32_be(s, v)
Definition: parse.h:78
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
void rdp_out_unistr(STREAM s, char *string, int len)
Definition: rdp.c:188
#define out_uint16_be(s, v)
Definition: parse.h:77
#define out_uint32(s, v)
Definition: parse.h:85
#define s_mark_end(s)
Definition: parse.h:41
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

Referenced by sec_connect(), and sec_reconnect().

◆ sec_parse_crypt_info()

static BOOL sec_parse_crypt_info ( RDPCLIENT This,
STREAM  s,
uint32 rc4_key_size,
uint8 **  server_random,
uint8 **  modulus,
uint8 **  exponent 
)
static

Definition at line 539 of file secure.c.

541 {
542  uint32 crypt_level, random_len, rsa_info_len;
543  uint32 cacert_len, cert_len, flags;
544  X509 *cacert, *server_cert;
545  uint16 tag, length;
546  uint8 *next_tag, *end;
547 
548  in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
549  in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
550  if (crypt_level == 0) /* no encryption */
551  return False;
552  in_uint32_le(s, random_len);
553  in_uint32_le(s, rsa_info_len);
554 
555  if (random_len != SEC_RANDOM_SIZE)
556  {
557  error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
558  return False;
559  }
560 
561  in_uint8p(s, *server_random, random_len);
562 
563  /* RSA info */
564  end = s->p + rsa_info_len;
565  if (end > s->end)
566  return False;
567 
568  in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
569  if (flags & 1)
570  {
571  DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
572  in_uint8s(s, 8); /* unknown */
573 
574  while (s->p < end)
575  {
576  in_uint16_le(s, tag);
578 
579  next_tag = s->p + length;
580 
581  switch (tag)
582  {
583  case SEC_TAG_PUBKEY:
584  if (!sec_parse_public_key(This, s, modulus, exponent))
585  return False;
586  DEBUG_RDP5(("Got Public key, RDP4-style\n"));
587 
588  break;
589 
590  case SEC_TAG_KEYSIG:
591  /* Is this a Microsoft key that we just got? */
592  /* Care factor: zero! */
593  /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
594  key as a known key of the hostname. This would prevent some MITM-attacks. */
595  break;
596 
597  default:
598  unimpl("crypt tag 0x%x\n", tag);
599  }
600 
601  s->p = next_tag;
602  }
603  }
604  else
605  {
606  uint32 certcount;
607 
608  DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
609  in_uint32_le(s, certcount); /* Number of certificates */
610 
611  if (certcount < 2)
612  {
613  error("Server didn't send enough X509 certificates\n");
614  This->disconnect_reason = 1798;
615  return False;
616  }
617 
618  for (; certcount > 2; certcount--)
619  { /* ignore all the certificates between the root and the signing CA */
620  uint32 ignorelen;
621  X509 *ignorecert;
622 
623  DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
624 
625  in_uint32_le(s, ignorelen);
626  DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
627  ignorecert = d2i_X509(NULL, &(s->p), ignorelen);
628 
629  if (ignorecert == NULL)
630  { /* XXX: error out? */
631  DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
632  }
633 
634 #ifdef WITH_DEBUG_RDP5
635  DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
636  X509_print_fp(stdout, ignorecert);
637 #endif
638  }
639 
640  /* Do da funky X.509 stuffy
641 
642  "How did I find out about this? I looked up and saw a
643  bright light and when I came to I had a scar on my forehead
644  and knew about X.500"
645  - Peter Gutman in a early version of
646  http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
647  */
648 
649  in_uint32_le(s, cacert_len);
650  DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
651  cacert = d2i_X509(NULL, &(s->p), cacert_len);
652  /* Note: We don't need to move s->p here - d2i_X509 is
653  "kind" enough to do it for us */
654  if (NULL == cacert)
655  {
656  error("Couldn't load CA Certificate from server\n");
657  This->disconnect_reason = 1798;
658  return False;
659  }
660 
661  /* Currently, we don't use the CA Certificate.
662  FIXME:
663  *) Verify the server certificate (server_cert) with the
664  CA certificate.
665  *) Store the CA Certificate with the hostname of the
666  server we are connecting to as key, and compare it
667  when we connect the next time, in order to prevent
668  MITM-attacks.
669  */
670 
671  X509_free(cacert);
672 
673  in_uint32_le(s, cert_len);
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)
677  {
678  error("Couldn't load Certificate from server\n");
679  This->disconnect_reason = 1798;
680  return False;
681  }
682 
683  in_uint8s(s, 16); /* Padding */
684 
685  /* Note: Verifying the server certificate must be done here,
686  before sec_parse_public_key since we'll have to apply
687  serious violence to the key after this */
688 
689  if (!sec_parse_x509_key(This, server_cert))
690  {
691  DEBUG_RDP5(("Didn't parse X509 correctly\n"));
692  X509_free(server_cert);
693  This->disconnect_reason = 1798;
694  return False;
695  }
696  X509_free(server_cert);
697  return True; /* There's some garbage here we don't care about */
698  }
699  return s_check_end(s);
700 }
#define error(str)
Definition: mkdosfs.c:1605
unsigned int uint32
Definition: types.h:32
#define SEC_TAG_PUBKEY
Definition: constants.h:124
static BOOL sec_parse_x509_key(RDPCLIENT *This, X509 *cert)
Definition: secure.c:502
Definition: ecma_167.h:138
GLuint GLuint end
Definition: gl.h:1545
#define in_uint8p(s, v, n)
Definition: parse.h:89
FILE * stdout
smooth NULL
Definition: ftsmooth.c:416
#define in_uint8s(s, n)
Definition: parse.h:91
#define s_check_end(s)
Definition: parse.h:44
#define True
Definition: types.h:24
#define False
Definition: types.h:25
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define SEC_RANDOM_SIZE
Definition: constants.h:91
unsigned char uint8
Definition: types.h:28
GLbitfield flags
Definition: glext.h:7161
GLdouble s
Definition: gl.h:2039
#define SEC_TAG_KEYSIG
Definition: constants.h:125
static BOOL sec_parse_public_key(RDPCLIENT *This, STREAM s, uint8 **modulus, uint8 **exponent)
Definition: secure.c:473
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
unsigned short uint16
Definition: types.h:30
void unimpl(char *format,...)
Definition: uimain.c:801
#define in_uint32_le(s, v)
Definition: parse.h:56
#define in_uint16_le(s, v)
Definition: parse.h:55
char * tag
Definition: main.c:59

Referenced by sec_process_crypt_info().

◆ sec_parse_public_key()

static BOOL sec_parse_public_key ( RDPCLIENT This,
STREAM  s,
uint8 **  modulus,
uint8 **  exponent 
)
static

Definition at line 473 of file secure.c.

474 {
475  uint32 magic, modulus_len;
476 
477  in_uint32_le(s, magic);
478  if (magic != SEC_RSA_MAGIC)
479  {
480  error("RSA magic 0x%x\n", magic);
481  return False;
482  }
483 
484  in_uint32_le(s, modulus_len);
485  modulus_len -= SEC_PADDING_SIZE;
486  if ((modulus_len < 64) || (modulus_len > SEC_MAX_MODULUS_SIZE))
487  {
488  error("Bad server public key size (%u bits)\n", modulus_len * 8);
489  return False;
490  }
491 
492  in_uint8s(s, 8); /* modulus_bits, unknown */
493  in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);
494  in_uint8p(s, *modulus, modulus_len);
496  This->secure.server_public_key_len = modulus_len;
497 
498  return s_check(s);
499 }
#define SEC_RSA_MAGIC
Definition: constants.h:127
#define error(str)
Definition: mkdosfs.c:1605
unsigned int uint32
Definition: types.h:32
u32_t magic(void)
#define SEC_MAX_MODULUS_SIZE
Definition: constants.h:93
#define in_uint8p(s, v, n)
Definition: parse.h:89
#define s_check(s)
Definition: parse.h:42
#define in_uint8s(s, n)
Definition: parse.h:91
#define False
Definition: types.h:25
#define SEC_EXPONENT_SIZE
Definition: constants.h:95
#define SEC_PADDING_SIZE
Definition: constants.h:94
GLdouble s
Definition: gl.h:2039
#define in_uint32_le(s, v)
Definition: parse.h:56

Referenced by sec_parse_crypt_info().

◆ sec_parse_x509_key()

static BOOL sec_parse_x509_key ( RDPCLIENT This,
X509 *  cert 
)
static

Definition at line 502 of file secure.c.

503 {
504  EVP_PKEY *epk = NULL;
505  /* By some reason, Microsoft sets the OID of the Public RSA key to
506  the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
507 
508  Kudos to Richard Levitte for the following (. intiutive .)
509  lines of code that resets the OID and let's us extract the key. */
510  if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
511  {
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);
515  }
516  epk = X509_get_pubkey(cert);
517  if (NULL == epk)
518  {
519  error("Failed to extract public key from certificate\n");
520  return False;
521  }
522 
523  This->secure.server_public_key = RSAPublicKey_dup((RSA *) epk->pkey.ptr);
524  EVP_PKEY_free(epk);
525 
526  This->secure.server_public_key_len = RSA_size(This->secure.server_public_key);
527  if ((This->secure.server_public_key_len < 64) || (This->secure.server_public_key_len > SEC_MAX_MODULUS_SIZE))
528  {
529  error("Bad server public key size (%u bits)\n", This->secure.server_public_key_len * 8);
530  return False;
531  }
532 
533  return True;
534 }
#define error(str)
Definition: mkdosfs.c:1605
#define SEC_MAX_MODULUS_SIZE
Definition: constants.h:93
static const WCHAR RSA[]
Definition: oid.c:1223
smooth NULL
Definition: ftsmooth.c:416
static BYTE cert[]
Definition: msg.c:1437
#define True
Definition: types.h:24
#define False
Definition: types.h:25
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141

Referenced by sec_parse_crypt_info().

◆ sec_process_crypt_info()

static void sec_process_crypt_info ( RDPCLIENT This,
STREAM  s 
)
static

Definition at line 704 of file secure.c.

705 {
706  uint8 *server_random, *modulus, *exponent;
707  uint8 client_random[SEC_RANDOM_SIZE];
708  uint32 rc4_key_size;
709 
710  if (!sec_parse_crypt_info(This, s, &rc4_key_size, &server_random, &modulus, &exponent))
711  {
712  DEBUG(("Failed to parse crypt info\n"));
713  return;
714  }
715 
716  DEBUG(("Generating client random\n"));
717  generate_random(client_random);
718 
719  if (NULL != This->secure.server_public_key)
720  { /* Which means we should use
721  RDP5-style encryption */
723  uint32 padding_len = This->secure.server_public_key_len - SEC_RANDOM_SIZE;
724 
725  /* This is what the MS client do: */
726  memset(inr, 0, padding_len);
727  /* *ARIGL!* Plaintext attack, anyone?
728  I tried doing:
729  generate_random(inr);
730  ..but that generates connection errors now and then (yes,
731  "now and then". Something like 0 to 3 attempts needed before a
732  successful connection. Nice. Not!
733  */
734  memcpy(inr + padding_len, client_random, SEC_RANDOM_SIZE);
735  reverse(inr + padding_len, SEC_RANDOM_SIZE);
736 
737  RSA_public_encrypt(This->secure.server_public_key_len,
738  inr, This->secure.crypted_random, This->secure.server_public_key, RSA_NO_PADDING);
739 
740  reverse(This->secure.crypted_random, This->secure.server_public_key_len);
741 
742  RSA_free(This->secure.server_public_key);
743  This->secure.server_public_key = NULL;
744  }
745  else
746  { /* RDP4-style encryption */
747  sec_rsa_encrypt(This->secure.crypted_random,
748  client_random, SEC_RANDOM_SIZE, This->secure.server_public_key_len, modulus,
749  exponent);
750  }
751  sec_generate_keys(This, client_random, server_random, rc4_key_size);
752 }
unsigned int uint32
Definition: types.h:32
#define SEC_MAX_MODULUS_SIZE
Definition: constants.h:93
static BOOL sec_parse_crypt_info(RDPCLIENT *This, STREAM s, uint32 *rc4_key_size, uint8 **server_random, uint8 **modulus, uint8 **exponent)
Definition: secure.c:539
static void reverse(uint8 *p, int len)
Definition: secure.c:253
smooth NULL
Definition: ftsmooth.c:416
static void sec_rsa_encrypt(uint8 *out, uint8 *in, int len, uint32 modulus_size, uint8 *modulus, uint8 *exponent)
Definition: secure.c:268
#define SEC_RANDOM_SIZE
Definition: constants.h:91
unsigned char uint8
Definition: types.h:28
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLdouble s
Definition: gl.h:2039
static void sec_generate_keys(RDPCLIENT *This, uint8 *client_random, uint8 *server_random, int rc4_key_size)
Definition: secure.c:98
void generate_random(uint8 *random)
Definition: uimain.c:709
#define DEBUG(args)
Definition: rdesktop.h:129
#define memset(x, y, z)
Definition: compat.h:39

Referenced by sec_process_mcs_data().

◆ sec_process_mcs_data()

void sec_process_mcs_data ( RDPCLIENT This,
STREAM  s 
)

Definition at line 771 of file secure.c.

772 {
773  uint16 tag, length;
774  uint8 *next_tag;
775  uint8 len;
776 
777  in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */
778  in_uint8(s, len);
779  if (len & 0x80)
780  in_uint8(s, len);
781 
782  while (s->p < s->end)
783  {
784  in_uint16_le(s, tag);
786 
787  if (length <= 4)
788  return;
789 
790  next_tag = s->p + length - 4;
791 
792  switch (tag)
793  {
794  case SEC_TAG_SRV_INFO:
796  break;
797 
798  case SEC_TAG_SRV_CRYPT:
800  break;
801 
803  /* FIXME: We should parse this information and
804  use it to map RDP5 channels to MCS
805  channels */
806  break;
807 
808  default:
809  unimpl("response tag 0x%x\n", tag);
810  }
811 
812  s->p = next_tag;
813  }
814 }
Definition: ecma_167.h:138
static void sec_process_srv_info(RDPCLIENT *This, STREAM s)
Definition: secure.c:757
#define in_uint8s(s, n)
Definition: parse.h:91
#define SEC_TAG_SRV_CHANNELS
Definition: constants.h:117
static void sec_process_crypt_info(RDPCLIENT *This, STREAM s)
Definition: secure.c:704
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned char uint8
Definition: types.h:28
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
#define SEC_TAG_SRV_CRYPT
Definition: constants.h:116
unsigned short uint16
Definition: types.h:30
#define in_uint8(s, v)
Definition: parse.h:88
void unimpl(char *format,...)
Definition: uimain.c:801
#define SEC_TAG_SRV_INFO
Definition: constants.h:115
#define in_uint16_le(s, v)
Definition: parse.h:55
char * tag
Definition: main.c:59

◆ sec_process_srv_info()

static void sec_process_srv_info ( RDPCLIENT This,
STREAM  s 
)
static

Definition at line 757 of file secure.c.

758 {
759  in_uint16_le(s, This->server_rdp_version);
760  DEBUG_RDP5(("Server RDP version is %d\n", This->server_rdp_version));
761  if (1 == This->server_rdp_version)
762  {
763  This->use_rdp5 = 0;
764  This->server_depth = 8;
765  }
766 }
GLdouble s
Definition: gl.h:2039
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
#define in_uint16_le(s, v)
Definition: parse.h:55

Referenced by sec_process_mcs_data().

◆ sec_reconnect()

BOOL sec_reconnect ( RDPCLIENT This,
char server,
wchar_t hostname,
char cookie 
)

Definition at line 933 of file secure.c.

934 {
935  struct stream mcs_data;
936  void * p = malloc(512);
937 
938  if(p == NULL)
939  {
940  This->disconnect_reason = 262;
941  return False;
942  }
943 
944  /* We exchange some RDP data during the MCS-Connect */
945  mcs_data.size = 512;
946  mcs_data.p = mcs_data.data = (uint8 *) p;
947  sec_out_mcs_data(This, &mcs_data, hostname);
948 
949  if (!mcs_reconnect(This, server, cookie, &mcs_data))
950  return False;
951 
952  /* sec_process_mcs_data(&mcs_data); */
953  if (This->encryption)
955  free(mcs_data.data);
956  return True;
957 }
static rfbScreenInfoPtr server
Definition: vnc.c:74
#define free
Definition: debug_ros.c:5
char * hostname
Definition: ftp.c:88
static void sec_out_mcs_data(RDPCLIENT *This, STREAM s, wchar_t *hostname)
Definition: secure.c:382
smooth NULL
Definition: ftsmooth.c:416
static void sec_establish_key(RDPCLIENT *This)
Definition: secure.c:364
#define True
Definition: types.h:24
#define False
Definition: types.h:25
unsigned char uint8
Definition: types.h:28
Definition: parse.h:22
#define malloc
Definition: debug_ros.c:4
BOOL mcs_reconnect(RDPCLIENT *This, char *server, char *cookie, STREAM mcs_data)
Definition: mcs.c:424
GLfloat GLfloat p
Definition: glext.h:8902

Referenced by rdp_reconnect().

◆ sec_recv()

STREAM sec_recv ( RDPCLIENT This,
uint8 rdpver 
)

Definition at line 818 of file secure.c.

819 {
820  uint32 sec_flags;
821  uint16 channel;
822  STREAM s;
823 
824  while ((s = mcs_recv(This, &channel, rdpver)) != NULL)
825  {
826  if (rdpver != NULL)
827  {
828  if (*rdpver != 3)
829  {
830  if (*rdpver & 0x80)
831  {
832  in_uint8s(s, 8); /* signature */
833  sec_decrypt(This, s->p, (int)(s->end - s->p));
834  }
835  return s;
836  }
837  }
838  if (This->encryption || !This->licence_issued)
839  {
840  in_uint32_le(s, sec_flags);
841 
842  if (sec_flags & SEC_ENCRYPT)
843  {
844  in_uint8s(s, 8); /* signature */
845  sec_decrypt(This, s->p, (int)(s->end - s->p));
846  }
847 
848  if (sec_flags & SEC_LICENCE_NEG)
849  {
851  continue;
852  }
853 
854  if (sec_flags & 0x0400) /* SEC_REDIRECT_ENCRYPT */
855  {
856  uint8 swapbyte;
857 
858  in_uint8s(s, 8); /* signature */
859  sec_decrypt(This, s->p, (int)(s->end - s->p));
860 
861  /* Check for a redirect packet, starts with 00 04 */
862  if (s->p[0] == 0 && s->p[1] == 4)
863  {
864  /* for some reason the PDU and the length seem to be swapped.
865  This isn't good, but we're going to do a byte for byte
866  swap. So the first foure value appear as: 00 04 XX YY,
867  where XX YY is the little endian length. We're going to
868  use 04 00 as the PDU type, so after our swap this will look
869  like: XX YY 04 00 */
870  swapbyte = s->p[0];
871  s->p[0] = s->p[2];
872  s->p[2] = swapbyte;
873 
874  swapbyte = s->p[1];
875  s->p[1] = s->p[3];
876  s->p[3] = swapbyte;
877 
878  swapbyte = s->p[2];
879  s->p[2] = s->p[3];
880  s->p[3] = swapbyte;
881  }
882 #ifdef WITH_DEBUG
883  /* warning! this debug statement will show passwords in the clear! */
884  hexdump(s->p, s->end - s->p);
885 #endif
886  }
887 
888  }
889 
890  if (channel != MCS_GLOBAL_CHANNEL)
891  {
892  channel_process(This, s, channel);
893  *rdpver = 0xff;
894  return s;
895  }
896 
897  return s;
898  }
899 
900  return NULL;
901 }
unsigned int uint32
Definition: types.h:32
void channel_process(STREAM s, uint16 mcs_channel)
Definition: channels.c:138
void sec_decrypt(uint8 *data, int length)
Definition: secure.c:396
#define MCS_GLOBAL_CHANNEL
Definition: constants.h:87
smooth NULL
Definition: ftsmooth.c:416
#define in_uint8s(s, n)
Definition: parse.h:91
#define SEC_ENCRYPT
Definition: constants.h:101
unsigned char uint8
Definition: types.h:28
Definition: parse.h:22
STREAM mcs_recv(uint16 *channel, uint8 *rdpver)
Definition: mcs.c:280
GLdouble s
Definition: gl.h:2039
void hexdump(unsigned char *p, unsigned int len)
Definition: shimdbg.c:234
unsigned short uint16
Definition: types.h:30
#define in_uint32_le(s, v)
Definition: parse.h:56
#define SEC_LICENCE_NEG
Definition: constants.h:72
void licence_process(STREAM s)
Definition: licence.c:378

◆ sec_reset_state()

void sec_reset_state ( RDPCLIENT This)

Definition at line 968 of file secure.c.

969 {
970  This->server_rdp_version = 0;
971  This->secure.encrypt_use_count = 0;
972  This->secure.decrypt_use_count = 0;
974 }
void mcs_reset_state(void)
Definition: mcs.c:363

◆ sec_rsa_encrypt()

static void sec_rsa_encrypt ( uint8 out,
uint8 in,
int  len,
uint32  modulus_size,
uint8 modulus,
uint8 exponent 
)
static

Definition at line 268 of file secure.c.

270 {
271  BN_CTX *ctx;
272  BIGNUM mod, exp, x, y;
274  int outlen;
275 
276  reverse(modulus, modulus_size);
277  reverse(exponent, SEC_EXPONENT_SIZE);
278  memcpy(inr, in, len);
279  reverse(inr, len);
280 
281  ctx = BN_CTX_new();
282  BN_init(&mod);
283  BN_init(&exp);
284  BN_init(&x);
285  BN_init(&y);
286 
287  BN_bin2bn(modulus, modulus_size, &mod);
288  BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
289  BN_bin2bn(inr, len, &x);
290  BN_mod_exp(&y, &x, &exp, &mod, ctx);
291  outlen = BN_bn2bin(&y, out);
292  reverse(out, outlen);
293  if ((uint32)outlen < modulus_size)
294  memset(out + outlen, 0, modulus_size - outlen);
295 
296  BN_free(&y);
297  BN_clear_free(&x);
298  BN_free(&exp);
299  BN_free(&mod);
300  BN_CTX_free(ctx);
301 }
unsigned int uint32
Definition: types.h:32
#define SEC_MAX_MODULUS_SIZE
Definition: constants.h:93
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static void reverse(uint8 *p, int len)
Definition: secure.c:253
#define SEC_EXPONENT_SIZE
Definition: constants.h:95
static FILE * out
Definition: regtests2xml.c:44
unsigned char uint8
Definition: types.h:28
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLuint in
Definition: glext.h:9616
DWORD exp
Definition: msg.c:15681
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define memset(x, y, z)
Definition: compat.h:39
static int mod
Definition: i386-dis.c:1273

Referenced by sec_process_crypt_info().

◆ sec_send()

BOOL sec_send ( RDPCLIENT This,
STREAM  s,
uint32  flags 
)

Definition at line 356 of file secure.c.

357 {
359 }
#define MCS_GLOBAL_CHANNEL
Definition: constants.h:87
GLbitfield flags
Definition: glext.h:7161
GLdouble s
Definition: gl.h:2039
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
Definition: secure.c:436

◆ sec_send_to_channel()

BOOL sec_send_to_channel ( RDPCLIENT This,
STREAM  s,
uint32  flags,
uint16  channel 
)

Definition at line 328 of file secure.c.

329 {
330  int datalen;
331 
333  if (!This->licence_issued || (flags & SEC_ENCRYPT))
335 
336  if (flags & SEC_ENCRYPT)
337  {
338  flags &= ~SEC_ENCRYPT;
339  datalen = (int)(s->end - s->p - 8);
340 
341 #if WITH_DEBUG
342  DEBUG(("Sending encrypted packet:\n"));
343  hexdump(s->p + 8, datalen);
344 #endif
345 
346  sec_sign(s->p, 8, This->secure.sign_key, This->secure.rc4_key_len, s->p + 8, datalen);
347  sec_encrypt(This, s->p + 8, datalen);
348  }
349 
350  return mcs_send_to_channel(This, s, channel);
351 }
void mcs_send_to_channel(STREAM s, uint16 channel)
Definition: mcs.c:254
#define out_uint32_le(s, v)
Definition: parse.h:59
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1027
void sec_sign(uint8 *signature, int siglen, uint8 *session_key, int keylen, uint8 *data, int datalen)
Definition: secure.c:314
static void sec_encrypt(RDPCLIENT *This, uint8 *data, int length)
Definition: secure.c:224
#define s_pop_layer(s, h)
Definition: parse.h:40
#define SEC_ENCRYPT
Definition: constants.h:101
GLbitfield flags
Definition: glext.h:7161
GLdouble s
Definition: gl.h:2039
void hexdump(unsigned char *p, unsigned int len)
Definition: shimdbg.c:234
unsigned char * sec_hdr
Definition: parse.h:32
#define DEBUG(args)
Definition: rdesktop.h:129
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

◆ sec_sign()

void sec_sign ( uint8 signature,
int  siglen,
uint8 session_key,
int  keylen,
uint8 data,
int  datalen 
)

Definition at line 168 of file secure.c.

169 {
170  uint8 shasig[20];
171  uint8 md5sig[16];
172  uint8 lenhdr[4];
173  SHA_CTX sha;
174  MD5_CTX md5;
175 
176  buf_out_uint32(lenhdr, datalen);
177 
178  SHA1_Init(&sha);
179  SHA1_Update(&sha, session_key, keylen);
180  SHA1_Update(&sha, pad_54, 40);
181  SHA1_Update(&sha, lenhdr, 4);
182  SHA1_Update(&sha, data, datalen);
183  SHA1_Final(shasig, &sha);
184 
185  MD5_Init(&md5);
186  MD5_Update(&md5, session_key, keylen);
187  MD5_Update(&md5, pad_92, 48);
188  MD5_Update(&md5, shasig, 20);
189  MD5_Final(md5sig, &md5);
190 
191  memcpy(signature, md5sig, siglen);
192 }
static const WCHAR sha[]
Definition: oid.c:1218
void buf_out_uint32(uint8 *buffer, uint32 value)
Definition: secure.c:304
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
Definition: md5.c:258
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1027
static const uint8 pad_92[48]
Definition: secure.c:149
Definition: addons.c:68
void MD5_Init(MD5_CTX *ctx)
Definition: md5.c:207
unsigned char uint8
Definition: types.h:28
static const uint8 pad_54[40]
Definition: secure.c:142
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:218
#define md5
Definition: compat-1.3.h:2010
Definition: msi.c:4078

Referenced by licence_process_authreq(), licence_process_demand(), licence_process_platform_challenge(), and licence_process_request().

◆ sec_update()

static void sec_update ( RDPCLIENT This,
uint8 key,
uint8 update_key 
)
static

Definition at line 196 of file secure.c.

197 {
198  uint8 shasig[20];
199  SHA_CTX sha;
200  MD5_CTX md5;
201  RC4_KEY update;
202 
203  SHA1_Init(&sha);
204  SHA1_Update(&sha, update_key, This->secure.rc4_key_len);
205  SHA1_Update(&sha, pad_54, 40);
206  SHA1_Update(&sha, key, This->secure.rc4_key_len);
207  SHA1_Final(shasig, &sha);
208 
209  MD5_Init(&md5);
210  MD5_Update(&md5, update_key, This->secure.rc4_key_len);
211  MD5_Update(&md5, pad_92, 48);
212  MD5_Update(&md5, shasig, 20);
213  MD5_Final(key, &md5);
214 
215  RC4_set_key(&update, This->secure.rc4_key_len, key);
216  RC4(&update, This->secure.rc4_key_len, key, key);
217 
218  if (This->secure.rc4_key_len == 8)
220 }
static const WCHAR sha[]
Definition: oid.c:1218
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
Definition: md5.c:258
static const uint8 pad_92[48]
Definition: secure.c:149
Definition: addons.c:68
void MD5_Init(MD5_CTX *ctx)
Definition: md5.c:207
unsigned char uint8
Definition: types.h:28
static const uint8 pad_54[40]
Definition: secure.c:142
static void sec_make_40bit(uint8 *key)
Definition: secure.c:89
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:218
#define md5
Definition: compat-1.3.h:2010
Definition: msi.c:4078
Definition: path.c:42

Referenced by sec_decrypt(), and sec_encrypt().

Variable Documentation

◆ pad_54

const uint8 pad_54[40]
static
Initial value:
= {
54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
54, 54, 54
}

Definition at line 142 of file secure.c.

Referenced by sec_sign(), and sec_update().

◆ pad_92

const uint8 pad_92[48]
static
Initial value:
= {
92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 92, 92
}

Definition at line 149 of file secure.c.

Referenced by sec_sign(), and sec_update().