/[rdesktop]/sourceforge.net/trunk/rdesktop/secure.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/secure.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 57 by matthewc, Sat Jul 13 02:30:49 2002 UTC revision 1374 by jsorg71, Tue Jan 9 07:24:44 2007 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP encryption and licensing     Protocol services - RDP encryption and licensing
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2007
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 19  Line 19 
19  */  */
20    
21  #include "rdesktop.h"  #include "rdesktop.h"
22    #include "ssl.h"
23    
24  #ifdef WITH_OPENSSL  extern char g_hostname[16];
25  #include <openssl/rc4.h>  extern int g_width;
26  #include <openssl/md5.h>  extern int g_height;
27  #include <openssl/sha.h>  extern unsigned int g_keylayout;
28  #include <openssl/bn.h>  extern int g_keyboard_type;
29  #else  extern int g_keyboard_subtype;
30  #include "crypto/rc4.h"  extern int g_keyboard_functionkeys;
31  #include "crypto/md5.h"  extern RD_BOOL g_encryption;
32  #include "crypto/sha.h"  extern RD_BOOL g_licence_issued;
33  #include "crypto/bn.h"  extern RD_BOOL g_use_rdp5;
34  #endif  extern RD_BOOL g_console_session;
35    extern int g_server_depth;
36  extern char hostname[16];  extern uint16 mcs_userid;
37  extern int width;  extern VCHANNEL g_channels[];
38  extern int height;  extern unsigned int g_num_channels;
 extern int keylayout;  
 extern BOOL encryption;  
 extern BOOL licence_issued;  
39    
40  static int rc4_key_len;  static int rc4_key_len;
41  static RC4_KEY rc4_decrypt_key;  static SSL_RC4 rc4_decrypt_key;
42  static RC4_KEY rc4_encrypt_key;  static SSL_RC4 rc4_encrypt_key;
43    static uint32 server_public_key_len;
44    
45  static uint8 sec_sign_key[16];  static uint8 sec_sign_key[16];
46  static uint8 sec_decrypt_key[16];  static uint8 sec_decrypt_key[16];
47  static uint8 sec_encrypt_key[16];  static uint8 sec_encrypt_key[16];
48  static uint8 sec_decrypt_update_key[16];  static uint8 sec_decrypt_update_key[16];
49  static uint8 sec_encrypt_update_key[16];  static uint8 sec_encrypt_update_key[16];
50  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];  static uint8 sec_crypted_random[SEC_MAX_MODULUS_SIZE];
51    
52    uint16 g_server_rdp_version = 0;
53    
54    /* These values must be available to reset state - Session Directory */
55    static int sec_encrypt_use_count = 0;
56    static int sec_decrypt_use_count = 0;
57    
58  /*  /*
59   * General purpose 48-byte transformation, using two 32-byte salts (generally,   * I believe this is based on SSLv3 with the following differences:
60   * a client and server salt) and a global salt value used for padding.   *  MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
61     *  MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
62     *  key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
63     *  key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
64     *  encryption/decryption keys updated every 4096 packets
65     * See http://wp.netscape.com/eng/ssl3/draft302.txt
66     */
67    
68    /*
69     * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
70   * Both SHA1 and MD5 algorithms are used.   * Both SHA1 and MD5 algorithms are used.
71   */   */
72  void  void
73  sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt)  sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
74  {  {
75          uint8 shasig[20];          uint8 shasig[20];
76          uint8 pad[4];          uint8 pad[4];
77          SHA_CTX sha;          SSL_SHA1 sha1;
78          MD5_CTX md5;          SSL_MD5 md5;
79          int i;          int i;
80    
81          for (i = 0; i < 3; i++)          for (i = 0; i < 3; i++)
82          {          {
83                  memset(pad, salt + i, i + 1);                  memset(pad, salt + i, i + 1);
84    
85                  SHA1_Init(&sha);                  ssl_sha1_init(&sha1);
86                  SHA1_Update(&sha, pad, i + 1);                  ssl_sha1_update(&sha1, pad, i + 1);
87                  SHA1_Update(&sha, in, 48);                  ssl_sha1_update(&sha1, in, 48);
88                  SHA1_Update(&sha, salt1, 32);                  ssl_sha1_update(&sha1, salt1, 32);
89                  SHA1_Update(&sha, salt2, 32);                  ssl_sha1_update(&sha1, salt2, 32);
90                  SHA1_Final(shasig, &sha);                  ssl_sha1_final(&sha1, shasig);
91    
92                  MD5_Init(&md5);                  ssl_md5_init(&md5);
93                  MD5_Update(&md5, in, 48);                  ssl_md5_update(&md5, in, 48);
94                  MD5_Update(&md5, shasig, 20);                  ssl_md5_update(&md5, shasig, 20);
95                  MD5_Final(&out[i * 16], &md5);                  ssl_md5_final(&md5, &out[i * 16]);
96          }          }
97  }  }
98    
99  /*  /*
100   * Weaker 16-byte transformation, also using two 32-byte salts, but   * 16-byte transformation used to generate export keys (6.2.2).
  * only using a single round of MD5.  
101   */   */
102  void  void
103  sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)  sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
104  {  {
105          MD5_CTX md5;          SSL_MD5 md5;
106    
107          MD5_Init(&md5);          ssl_md5_init(&md5);
108          MD5_Update(&md5, in, 16);          ssl_md5_update(&md5, in, 16);
109          MD5_Update(&md5, salt1, 32);          ssl_md5_update(&md5, salt1, 32);
110          MD5_Update(&md5, salt2, 32);          ssl_md5_update(&md5, salt2, 32);
111          MD5_Final(out, &md5);          ssl_md5_final(&md5, out);
112  }  }
113    
114  /* Reduce key entropy from 64 to 40 bits */  /* Reduce key entropy from 64 to 40 bits */
115  static void  static void
116  sec_make_40bit(uint8 *key)  sec_make_40bit(uint8 * key)
117  {  {
118          key[0] = 0xd1;          key[0] = 0xd1;
119          key[1] = 0x26;          key[1] = 0x26;
120          key[2] = 0x9e;          key[2] = 0x9e;
121  }  }
122    
123  /* Generate a session key and RC4 keys, given client and server randoms */  /* Generate encryption keys given client and server randoms */
124  static void  static void
125  sec_generate_keys(uint8 *client_key, uint8 *server_key, int rc4_key_size)  sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
126  {  {
127          uint8 session_key[48];          uint8 pre_master_secret[48];
128          uint8 temp_hash[48];          uint8 master_secret[48];
129          uint8 input[48];          uint8 key_block[48];
130    
131          /* Construct input data to hash */          /* Construct pre-master secret */
132          memcpy(input, client_key, 24);          memcpy(pre_master_secret, client_random, 24);
133          memcpy(input + 24, server_key, 24);          memcpy(pre_master_secret + 24, server_random, 24);
134    
135          /* Generate session key - two rounds of sec_hash_48 */          /* Generate master secret and then key material */
136          sec_hash_48(temp_hash, input, client_key, server_key, 65);          sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
137          sec_hash_48(session_key, temp_hash, client_key, server_key, 88);          sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
138    
139          /* Store first 16 bytes of session key, for generating signatures */          /* First 16 bytes of key material is MAC secret */
140          memcpy(sec_sign_key, session_key, 16);          memcpy(sec_sign_key, key_block, 16);
141    
142          /* Generate RC4 keys */          /* Generate export keys from next two blocks of 16 bytes */
143          sec_hash_16(sec_decrypt_key, &session_key[16], client_key,          sec_hash_16(sec_decrypt_key, &key_block[16], client_random, server_random);
144                      server_key);          sec_hash_16(sec_encrypt_key, &key_block[32], client_random, server_random);
         sec_hash_16(sec_encrypt_key, &session_key[32], client_key,  
                     server_key);  
145    
146          if (rc4_key_size == 1)          if (rc4_key_size == 1)
147          {          {
# Line 142  sec_generate_keys(uint8 *client_key, uin Line 153  sec_generate_keys(uint8 *client_key, uin
153          }          }
154          else          else
155          {          {
156                  DEBUG(("128-bit encryption enabled\n"));                  DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
157                  rc4_key_len = 16;                  rc4_key_len = 16;
158          }          }
159    
# Line 171  static uint8 pad_92[48] = { Line 182  static uint8 pad_92[48] = {
182    
183  /* Output a uint32 into a buffer (little-endian) */  /* Output a uint32 into a buffer (little-endian) */
184  void  void
185  buf_out_uint32(uint8 *buffer, uint32 value)  buf_out_uint32(uint8 * buffer, uint32 value)
186  {  {
187          buffer[0] = (value) & 0xff;          buffer[0] = (value) & 0xff;
188          buffer[1] = (value >> 8) & 0xff;          buffer[1] = (value >> 8) & 0xff;
# Line 179  buf_out_uint32(uint8 *buffer, uint32 val Line 190  buf_out_uint32(uint8 *buffer, uint32 val
190          buffer[3] = (value >> 24) & 0xff;          buffer[3] = (value >> 24) & 0xff;
191  }  }
192    
193  /* Generate a signature hash, using a combination of SHA1 and MD5 */  /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
194  void  void
195  sec_sign(uint8 *signature, uint8 *session_key, int length,  sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
          uint8 *data, int datalen)  
196  {  {
197          uint8 shasig[20];          uint8 shasig[20];
198          uint8 md5sig[16];          uint8 md5sig[16];
199          uint8 lenhdr[4];          uint8 lenhdr[4];
200          SHA_CTX sha;          SSL_SHA1 sha1;
201          MD5_CTX md5;          SSL_MD5 md5;
202    
203          buf_out_uint32(lenhdr, datalen);          buf_out_uint32(lenhdr, datalen);
204    
205          SHA1_Init(&sha);          ssl_sha1_init(&sha1);
206          SHA1_Update(&sha, session_key, rc4_key_len);          ssl_sha1_update(&sha1, session_key, keylen);
207          SHA1_Update(&sha, pad_54, 40);          ssl_sha1_update(&sha1, pad_54, 40);
208          SHA1_Update(&sha, lenhdr, 4);          ssl_sha1_update(&sha1, lenhdr, 4);
209          SHA1_Update(&sha, data, datalen);          ssl_sha1_update(&sha1, data, datalen);
210          SHA1_Final(shasig, &sha);          ssl_sha1_final(&sha1, shasig);
   
         MD5_Init(&md5);  
         MD5_Update(&md5, session_key, rc4_key_len);  
         MD5_Update(&md5, pad_92, 48);  
         MD5_Update(&md5, shasig, 20);  
         MD5_Final(md5sig, &md5);  
211    
212          memcpy(signature, md5sig, length);          ssl_md5_init(&md5);
213            ssl_md5_update(&md5, session_key, keylen);
214            ssl_md5_update(&md5, pad_92, 48);
215            ssl_md5_update(&md5, shasig, 20);
216            ssl_md5_final(&md5, md5sig);
217    
218            memcpy(signature, md5sig, siglen);
219  }  }
220    
221  /* Update an encryption key - similar to the signing process */  /* Update an encryption key */
222  static void  static void
223  sec_update(uint8 *key, uint8 *update_key)  sec_update(uint8 * key, uint8 * update_key)
224  {  {
225          uint8 shasig[20];          uint8 shasig[20];
226          SHA_CTX sha;          SSL_SHA1 sha1;
227          MD5_CTX md5;          SSL_MD5 md5;
228          RC4_KEY update;          SSL_RC4 update;
229    
230          SHA1_Init(&sha);          ssl_sha1_init(&sha1);
231          SHA1_Update(&sha, update_key, rc4_key_len);          ssl_sha1_update(&sha1, update_key, rc4_key_len);
232          SHA1_Update(&sha, pad_54, 40);          ssl_sha1_update(&sha1, pad_54, 40);
233          SHA1_Update(&sha, key, rc4_key_len);          ssl_sha1_update(&sha1, key, rc4_key_len);
234          SHA1_Final(shasig, &sha);          ssl_sha1_final(&sha1, shasig);
235    
236          MD5_Init(&md5);          ssl_md5_init(&md5);
237          MD5_Update(&md5, update_key, rc4_key_len);          ssl_md5_update(&md5, update_key, rc4_key_len);
238          MD5_Update(&md5, pad_92, 48);          ssl_md5_update(&md5, pad_92, 48);
239          MD5_Update(&md5, shasig, 20);          ssl_md5_update(&md5, shasig, 20);
240          MD5_Final(key, &md5);          ssl_md5_final(&md5, key);
241    
242          RC4_set_key(&update, rc4_key_len, key);          ssl_rc4_set_key(&update, key, rc4_key_len);
243          RC4(&update, rc4_key_len, key, key);          ssl_rc4_crypt(&update, key, key, rc4_key_len);
244    
245          if (rc4_key_len == 8)          if (rc4_key_len == 8)
246                  sec_make_40bit(key);                  sec_make_40bit(key);
# Line 238  sec_update(uint8 *key, uint8 *update_key Line 248  sec_update(uint8 *key, uint8 *update_key
248    
249  /* Encrypt data using RC4 */  /* Encrypt data using RC4 */
250  static void  static void
251  sec_encrypt(uint8 *data, int length)  sec_encrypt(uint8 * data, int length)
252  {  {
253          static int use_count;          if (sec_encrypt_use_count == 4096)
   
         if (use_count == 4096)  
254          {          {
255                  sec_update(sec_encrypt_key, sec_encrypt_update_key);                  sec_update(sec_encrypt_key, sec_encrypt_update_key);
256                  RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);                  ssl_rc4_set_key(&rc4_encrypt_key, sec_encrypt_key, rc4_key_len);
257                  use_count = 0;                  sec_encrypt_use_count = 0;
258          }          }
259    
260          RC4(&rc4_encrypt_key, length, data, data);          ssl_rc4_crypt(&rc4_encrypt_key, data, data, length);
261          use_count++;          sec_encrypt_use_count++;
262  }  }
263    
264  /* Decrypt data using RC4 */  /* Decrypt data using RC4 */
265  static void  void
266  sec_decrypt(uint8 *data, int length)  sec_decrypt(uint8 * data, int length)
267  {  {
268          static int use_count;          if (sec_decrypt_use_count == 4096)
   
         if (use_count == 4096)  
269          {          {
270                  sec_update(sec_decrypt_key, sec_decrypt_update_key);                  sec_update(sec_decrypt_key, sec_decrypt_update_key);
271                  RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);                  ssl_rc4_set_key(&rc4_decrypt_key, sec_decrypt_key, rc4_key_len);
272                  use_count = 0;                  sec_decrypt_use_count = 0;
273          }          }
274    
275          RC4(&rc4_decrypt_key, length, data, data);          ssl_rc4_crypt(&rc4_decrypt_key, data, data, length);
276          use_count++;          sec_decrypt_use_count++;
 }  
   
 static void  
 reverse(uint8 *p, int len)  
 {  
         int i, j;  
         uint8 temp;  
   
         for (i = 0, j = len-1; i < j; i++, j--)  
         {  
                 temp = p[i];  
                 p[i] = p[j];  
                 p[j] = temp;  
         }  
277  }  }
278    
279  /* Perform an RSA public key encryption operation */  /* Perform an RSA public key encryption operation */
280  static void  static void
281  sec_rsa_encrypt(uint8 *out, uint8 *in, int len,  sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
282                  uint8 *modulus, uint8 *exponent)                  uint8 * exponent)
283  {  {
284          BN_CTX ctx;          ssl_rsa_encrypt(out, in, len, modulus_size, modulus, exponent);
         BIGNUM mod, exp, x, y;  
         uint8 inr[SEC_MODULUS_SIZE];  
         int outlen;  
   
         reverse(modulus, SEC_MODULUS_SIZE);  
         reverse(exponent, SEC_EXPONENT_SIZE);  
         memcpy(inr, in, len);  
         reverse(inr, len);  
   
         BN_CTX_init(&ctx);  
         BN_init(&mod);  
         BN_init(&exp);  
         BN_init(&x);  
         BN_init(&y);  
   
         BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);  
         BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);  
         BN_bin2bn(inr, len, &x);  
         BN_mod_exp(&y, &x, &exp, &mod, &ctx);  
         outlen = BN_bn2bin(&y, out);  
         reverse(out, outlen);  
         if (outlen < SEC_MODULUS_SIZE)  
                 memset(out+outlen, 0, SEC_MODULUS_SIZE-outlen);  
   
         BN_free(&y);  
         BN_clear_free(&x);  
         BN_free(&exp);  
         BN_free(&mod);  
         BN_CTX_free(&ctx);  
285  }  }
286    
287  /* Initialise secure transport packet */  /* Initialise secure transport packet */
# Line 328  sec_init(uint32 flags, int maxlen) Line 291  sec_init(uint32 flags, int maxlen)
291          int hdrlen;          int hdrlen;
292          STREAM s;          STREAM s;
293    
294          if (!licence_issued)          if (!g_licence_issued)
295                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
296          else          else
297                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
# Line 338  sec_init(uint32 flags, int maxlen) Line 301  sec_init(uint32 flags, int maxlen)
301          return s;          return s;
302  }  }
303    
304  /* Transmit secure transport packet */  /* Transmit secure transport packet over specified channel */
305  void  void
306  sec_send(STREAM s, uint32 flags)  sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
307  {  {
308          int datalen;          int datalen;
309    
310    #ifdef WITH_SCARD
311            scard_lock(SCARD_LOCK_SEC);
312    #endif
313    
314          s_pop_layer(s, sec_hdr);          s_pop_layer(s, sec_hdr);
315          if (!licence_issued || (flags & SEC_ENCRYPT))          if (!g_licence_issued || (flags & SEC_ENCRYPT))
316                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
317    
318          if (flags & SEC_ENCRYPT)          if (flags & SEC_ENCRYPT)
# Line 358  sec_send(STREAM s, uint32 flags) Line 325  sec_send(STREAM s, uint32 flags)
325                  hexdump(s->p + 8, datalen);                  hexdump(s->p + 8, datalen);
326  #endif  #endif
327    
328                  sec_sign(s->p, sec_sign_key, 8, s->p + 8, datalen);                  sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, datalen);
329                  sec_encrypt(s->p + 8, datalen);                  sec_encrypt(s->p + 8, datalen);
330          }          }
331    
332          mcs_send(s);          mcs_send_to_channel(s, channel);
333    
334    #ifdef WITH_SCARD
335            scard_unlock(SCARD_LOCK_SEC);
336    #endif
337    }
338    
339    /* Transmit secure transport packet */
340    
341    void
342    sec_send(STREAM s, uint32 flags)
343    {
344            sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
345  }  }
346    
347    
348  /* Transfer the client random to the server */  /* Transfer the client random to the server */
349  static void  static void
350  sec_establish_key()  sec_establish_key(void)
351  {  {
352          uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;          uint32 length = server_public_key_len + SEC_PADDING_SIZE;
353          uint32 flags = SEC_CLIENT_RANDOM;          uint32 flags = SEC_CLIENT_RANDOM;
354          STREAM s;          STREAM s;
355    
356          s = sec_init(flags, 76);          s = sec_init(flags, length + 4);
357    
358          out_uint32_le(s, length);          out_uint32_le(s, length);
359          out_uint8p(s, sec_crypted_random, SEC_MODULUS_SIZE);          out_uint8p(s, sec_crypted_random, server_public_key_len);
360          out_uint8s(s, SEC_PADDING_SIZE);          out_uint8s(s, SEC_PADDING_SIZE);
361    
362          s_mark_end(s);          s_mark_end(s);
# Line 387  sec_establish_key() Line 367  sec_establish_key()
367  static void  static void
368  sec_out_mcs_data(STREAM s)  sec_out_mcs_data(STREAM s)
369  {  {
370          int hostlen = 2 * strlen(hostname);          int hostlen = 2 * strlen(g_hostname);
371            int length = 158 + 76 + 12 + 4;
372            unsigned int i;
373    
374            if (g_num_channels > 0)
375                    length += g_num_channels * 12 + 8;
376    
377            if (hostlen > 30)
378                    hostlen = 30;
379    
380          out_uint16_be(s, 5);    /* unknown */          /* Generic Conference Control (T.124) ConferenceCreateRequest */
381            out_uint16_be(s, 5);
382          out_uint16_be(s, 0x14);          out_uint16_be(s, 0x14);
383          out_uint8(s, 0x7c);          out_uint8(s, 0x7c);
384          out_uint16_be(s, 1);          out_uint16_be(s, 1);
385    
386          out_uint16_be(s, (158 | 0x8000));       /* remaining length */          out_uint16_be(s, (length | 0x8000));    /* remaining length */
387    
388          out_uint16_be(s, 8);    /* length? */          out_uint16_be(s, 8);    /* length? */
389          out_uint16_be(s, 16);          out_uint16_be(s, 16);
# Line 402  sec_out_mcs_data(STREAM s) Line 391  sec_out_mcs_data(STREAM s)
391          out_uint16_le(s, 0xc001);          out_uint16_le(s, 0xc001);
392          out_uint8(s, 0);          out_uint8(s, 0);
393    
394          out_uint32_le(s, 0x61637544);   /* "Duca" ?! */          out_uint32_le(s, 0x61637544);   /* OEM ID: "Duca", as in Ducati. */
395          out_uint16_be(s, (144 | 0x8000));       /* remaining length */          out_uint16_be(s, ((length - 14) | 0x8000));     /* remaining length */
396    
397          /* Client information */          /* Client information */
398          out_uint16_le(s, SEC_TAG_CLI_INFO);          out_uint16_le(s, SEC_TAG_CLI_INFO);
399          out_uint16_le(s, 136);  /* length */          out_uint16_le(s, 212);  /* length */
400          out_uint16_le(s, 1);          out_uint16_le(s, g_use_rdp5 ? 4 : 1);   /* RDP version. 1 == RDP4, 4 == RDP5. */
401          out_uint16_le(s, 8);          out_uint16_le(s, 8);
402          out_uint16_le(s, width);          out_uint16_le(s, g_width);
403          out_uint16_le(s, height);          out_uint16_le(s, g_height);
404          out_uint16_le(s, 0xca01);          out_uint16_le(s, 0xca01);
405          out_uint16_le(s, 0xaa03);          out_uint16_le(s, 0xaa03);
406          out_uint32_le(s, keylayout);          out_uint32_le(s, g_keylayout);
407          out_uint32_le(s, 419);  /* client build? we are 419 compatible :-) */          out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
408    
409          /* Unicode name of client, padded to 32 bytes */          /* Unicode name of client, padded to 32 bytes */
410          rdp_out_unistr(s, hostname, hostlen);          rdp_out_unistr(s, g_hostname, hostlen);
411          out_uint8s(s, 30 - hostlen);          out_uint8s(s, 30 - hostlen);
412    
413          out_uint32_le(s, 4);          /* See
414          out_uint32(s, 0);             http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
415          out_uint32_le(s, 12);          out_uint32_le(s, g_keyboard_type);
416            out_uint32_le(s, g_keyboard_subtype);
417            out_uint32_le(s, g_keyboard_functionkeys);
418          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */
419            out_uint16_le(s, 0xca01);       /* colour depth? */
420            out_uint16_le(s, 1);
421    
422            out_uint32(s, 0);
423            out_uint8(s, g_server_depth);
424            out_uint16_le(s, 0x0700);
425            out_uint8(s, 0);
426            out_uint32_le(s, 1);
427            out_uint8s(s, 64);      /* End of client info */
428    
429          out_uint16(s, 0xca01);          out_uint16_le(s, SEC_TAG_CLI_4);
430          out_uint16(s, 0);          out_uint16_le(s, 12);
431            out_uint32_le(s, g_console_session ? 0xb : 9);
432            out_uint32(s, 0);
433    
434          /* Client encryption settings */          /* Client encryption settings */
435          out_uint16_le(s, SEC_TAG_CLI_CRYPT);          out_uint16_le(s, SEC_TAG_CLI_CRYPT);
436          out_uint16(s, 8);       /* length */          out_uint16_le(s, 12);   /* length */
437          out_uint32_le(s, encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */          out_uint32_le(s, g_encryption ? 0x3 : 0);       /* encryption supported, 128-bit supported */
438            out_uint32(s, 0);       /* Unknown */
439    
440            DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
441            if (g_num_channels > 0)
442            {
443                    out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
444                    out_uint16_le(s, g_num_channels * 12 + 8);      /* length */
445                    out_uint32_le(s, g_num_channels);       /* number of virtual channels */
446                    for (i = 0; i < g_num_channels; i++)
447                    {
448                            DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
449                            out_uint8a(s, g_channels[i].name, 8);
450                            out_uint32_be(s, g_channels[i].flags);
451                    }
452            }
453    
454          s_mark_end(s);          s_mark_end(s);
455  }  }
456    
457  /* Parse a public key structure */  /* Parse a public key structure */
458  static BOOL  static RD_BOOL
459  sec_parse_public_key(STREAM s, uint8 **modulus, uint8 **exponent)  sec_parse_public_key(STREAM s, uint8 * modulus, uint8 * exponent)
460  {  {
461          uint32 magic, modulus_len;          uint32 magic, modulus_len;
462    
# Line 450  sec_parse_public_key(STREAM s, uint8 **m Line 468  sec_parse_public_key(STREAM s, uint8 **m
468          }          }
469    
470          in_uint32_le(s, modulus_len);          in_uint32_le(s, modulus_len);
471          if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)          modulus_len -= SEC_PADDING_SIZE;
472            if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE))
473          {          {
474                  error("modulus len 0x%x\n", modulus_len);                  error("Bad server public key size (%u bits)\n", modulus_len * 8);
475                  return False;                  return False;
476          }          }
477    
478          in_uint8s(s, 8);        /* modulus_bits, unknown */          in_uint8s(s, 8);        /* modulus_bits, unknown */
479          in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);          in_uint8a(s, exponent, SEC_EXPONENT_SIZE);
480          in_uint8p(s, *modulus, SEC_MODULUS_SIZE);          in_uint8a(s, modulus, modulus_len);
481          in_uint8s(s, SEC_PADDING_SIZE);          in_uint8s(s, SEC_PADDING_SIZE);
482            server_public_key_len = modulus_len;
483    
484          return s_check(s);          return s_check(s);
485  }  }
486    
487    /* Parse a public signature structure */
488    static RD_BOOL
489    sec_parse_public_sig(STREAM s, uint32 len, uint8 * modulus, uint8 * exponent)
490    {
491            uint8 signature[SEC_MAX_MODULUS_SIZE];
492            uint32 sig_len;
493    
494            if (len != 72)
495            {
496                    return True;
497            }
498            memset(signature, 0, sizeof(signature));
499            sig_len = len - 8;
500            in_uint8a(s, signature, sig_len);
501            return ssl_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, server_public_key_len,
502                              signature, sig_len);
503    }
504    
505  /* Parse a crypto information structure */  /* Parse a crypto information structure */
506  static BOOL  static RD_BOOL
507  sec_parse_crypt_info(STREAM s, uint32 *rc4_key_size,  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
508                       uint8 **server_random, uint8 **modulus, uint8 **exponent)                       uint8 ** server_random, uint8 * modulus, uint8 * exponent)
509  {  {
510          uint32 crypt_level, random_len, rsa_info_len;          uint32 crypt_level, random_len, rsa_info_len;
511            uint32 cacert_len, cert_len, flags;
512            SSL_CERT *cacert, *server_cert;
513            SSL_RKEY *server_public_key;
514          uint16 tag, length;          uint16 tag, length;
515          uint8 *next_tag, *end;          uint8 *next_tag, *end;
516    
517          in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */          in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
518          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */
519            if (crypt_level == 0)   /* no encryption */
520                    return False;
521          in_uint32_le(s, random_len);          in_uint32_le(s, random_len);
522          in_uint32_le(s, rsa_info_len);          in_uint32_le(s, rsa_info_len);
523    
524          if (random_len != SEC_RANDOM_SIZE)          if (random_len != SEC_RANDOM_SIZE)
525          {          {
526                  error("random len %d\n", random_len);                  error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
527                  return False;                  return False;
528          }          }
529    
# Line 491  sec_parse_crypt_info(STREAM s, uint32 *r Line 534  sec_parse_crypt_info(STREAM s, uint32 *r
534          if (end > s->end)          if (end > s->end)
535                  return False;                  return False;
536    
537          in_uint8s(s, 12);       /* unknown */          in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
538            if (flags & 1)
         while (s->p < end)  
539          {          {
540                  in_uint16_le(s, tag);                  DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
541                  in_uint16_le(s, length);                  in_uint8s(s, 8);        /* unknown */
   
                 next_tag = s->p + length;  
542    
543                  switch (tag)                  while (s->p < end)
544                  {                  {
545                          case SEC_TAG_PUBKEY:                          in_uint16_le(s, tag);
546                                  if (!sec_parse_public_key                          in_uint16_le(s, length);
                                     (s, modulus, exponent))  
                                         return False;  
547    
548                                  break;                          next_tag = s->p + length;
549    
550                          case SEC_TAG_KEYSIG:                          switch (tag)
551                                  /* Is this a Microsoft key that we just got? */                          {
552                                  /* Care factor: zero! */                                  case SEC_TAG_PUBKEY:
553                                  break;                                          if (!sec_parse_public_key(s, modulus, exponent))
554                                                    return False;
555                                            DEBUG_RDP5(("Got Public key, RDP4-style\n"));
556    
557                                            break;
558    
559                                    case SEC_TAG_KEYSIG:
560                                            if (!sec_parse_public_sig(s, length, modulus, exponent))
561                                                    return False;
562                                            break;
563    
564                          default:                                  default:
565                                  unimpl("crypt tag 0x%x\n", tag);                                          unimpl("crypt tag 0x%x\n", tag);
566                  }                          }
567    
568                  s->p = next_tag;                          s->p = next_tag;
569                    }
570          }          }
571            else
572            {
573                    uint32 certcount;
574    
575                    DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
576                    in_uint32_le(s, certcount);     /* Number of certificates */
577                    if (certcount < 2)
578                    {
579                            error("Server didn't send enough X509 certificates\n");
580                            return False;
581                    }
582                    for (; certcount > 2; certcount--)
583                    {               /* ignore all the certificates between the root and the signing CA */
584                            uint32 ignorelen;
585                            SSL_CERT *ignorecert;
586    
587                            DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
588                            in_uint32_le(s, ignorelen);
589                            DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
590                            ignorecert = ssl_cert_read(s->p, ignorelen);
591                            in_uint8s(s, ignorelen);
592                            if (ignorecert == NULL)
593                            {       /* XXX: error out? */
594                                    DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
595                            }
596    
597    #ifdef WITH_DEBUG_RDP5
598                            DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
599                            ssl_cert_print_fp(stdout, ignorecert);
600    #endif
601                    }
602                    /* Do da funky X.509 stuffy
603    
604                       "How did I find out about this?  I looked up and saw a
605                       bright light and when I came to I had a scar on my forehead
606                       and knew about X.500"
607                       - Peter Gutman in a early version of
608                       http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
609                     */
610                    in_uint32_le(s, cacert_len);
611                    DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
612                    cacert = ssl_cert_read(s->p, cacert_len);
613                    in_uint8s(s, cacert_len);
614                    if (NULL == cacert)
615                    {
616                            error("Couldn't load CA Certificate from server\n");
617                            return False;
618                    }
619                    in_uint32_le(s, cert_len);
620                    DEBUG_RDP5(("Certificate length is %d\n", cert_len));
621                    server_cert = ssl_cert_read(s->p, cert_len);
622                    in_uint8s(s, cert_len);
623                    if (NULL == server_cert)
624                    {
625                            ssl_cert_free(cacert);
626                            error("Couldn't load Certificate from server\n");
627                            return False;
628                    }
629                    if (!ssl_certs_ok(server_cert, cacert))
630                    {
631                            ssl_cert_free(server_cert);
632                            ssl_cert_free(cacert);
633                            error("Security error CA Certificate invalid\n");
634                            return False;
635                    }
636                    ssl_cert_free(cacert);
637                    in_uint8s(s, 16);       /* Padding */
638                    server_public_key = ssl_cert_to_rkey(server_cert, &server_public_key_len);
639                    if (NULL == server_public_key)
640                    {
641                            DEBUG_RDP5(("Didn't parse X509 correctly\n"));
642                            ssl_cert_free(server_cert);
643                            return False;
644                    }
645                    ssl_cert_free(server_cert);
646                    if ((server_public_key_len < SEC_MODULUS_SIZE) ||
647                        (server_public_key_len > SEC_MAX_MODULUS_SIZE))
648                    {
649                            error("Bad server public key size (%u bits)\n", server_public_key_len * 8);
650                            ssl_rkey_free(server_public_key);
651                            return False;
652                    }
653                    if (ssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
654                                             modulus, SEC_MAX_MODULUS_SIZE) != 0)
655                    {
656                            error("Problem extracting RSA exponent, modulus");
657                            ssl_rkey_free(server_public_key);
658                            return False;
659                    }
660                    ssl_rkey_free(server_public_key);
661                    return True;    /* There's some garbage here we don't care about */
662            }
663          return s_check_end(s);          return s_check_end(s);
664  }  }
665    
# Line 528  sec_parse_crypt_info(STREAM s, uint32 *r Line 667  sec_parse_crypt_info(STREAM s, uint32 *r
667  static void  static void
668  sec_process_crypt_info(STREAM s)  sec_process_crypt_info(STREAM s)
669  {  {
670          uint8 *server_random, *modulus, *exponent;          uint8 *server_random = NULL;
671          uint8 client_random[SEC_RANDOM_SIZE];          uint8 client_random[SEC_RANDOM_SIZE];
672            uint8 modulus[SEC_MAX_MODULUS_SIZE];
673            uint8 exponent[SEC_EXPONENT_SIZE];
674          uint32 rc4_key_size;          uint32 rc4_key_size;
675    
676          if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random,          memset(modulus, 0, sizeof(modulus));
677                                    &modulus, &exponent))          memset(exponent, 0, sizeof(exponent));
678            if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, modulus, exponent))
679            {
680                    DEBUG(("Failed to parse crypt info\n"));
681                  return;                  return;
682            }
683          /* Generate a client random, and hence determine encryption keys */          DEBUG(("Generating client random\n"));
684          generate_random(client_random);          generate_random(client_random);
685          sec_rsa_encrypt(sec_crypted_random, client_random,          sec_rsa_encrypt(sec_crypted_random, client_random, SEC_RANDOM_SIZE,
686                          SEC_RANDOM_SIZE, modulus, exponent);                          server_public_key_len, modulus, exponent);
687          sec_generate_keys(client_random, server_random, rc4_key_size);          sec_generate_keys(client_random, server_random, rc4_key_size);
688  }  }
689    
690  /* Process connect response data blob */  
691    /* Process SRV_INFO, find RDP version supported by server */
692  static void  static void
693    sec_process_srv_info(STREAM s)
694    {
695            in_uint16_le(s, g_server_rdp_version);
696            DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
697            if (1 == g_server_rdp_version)
698            {
699                    g_use_rdp5 = 0;
700                    g_server_depth = 8;
701            }
702    }
703    
704    
705    /* Process connect response data blob */
706    void
707  sec_process_mcs_data(STREAM s)  sec_process_mcs_data(STREAM s)
708  {  {
709          uint16 tag, length;          uint16 tag, length;
710          uint8 *next_tag;          uint8 *next_tag;
711            uint8 len;
712    
713          in_uint8s(s, 23);       /* header */          in_uint8s(s, 21);       /* header (T.124 ConferenceCreateResponse) */
714            in_uint8(s, len);
715            if (len & 0x80)
716                    in_uint8(s, len);
717    
718          while (s->p < s->end)          while (s->p < s->end)
719          {          {
# Line 565  sec_process_mcs_data(STREAM s) Line 728  sec_process_mcs_data(STREAM s)
728                  switch (tag)                  switch (tag)
729                  {                  {
730                          case SEC_TAG_SRV_INFO:                          case SEC_TAG_SRV_INFO:
731                          case SEC_TAG_SRV_3:                                  sec_process_srv_info(s);
732                                  break;                                  break;
733    
734                          case SEC_TAG_SRV_CRYPT:                          case SEC_TAG_SRV_CRYPT:
735                                  sec_process_crypt_info(s);                                  sec_process_crypt_info(s);
736                                  break;                                  break;
737    
738                            case SEC_TAG_SRV_CHANNELS:
739                                    /* FIXME: We should parse this information and
740                                       use it to map RDP5 channels to MCS
741                                       channels */
742                                    break;
743    
744                          default:                          default:
745                                  unimpl("response tag 0x%x\n", tag);                                  unimpl("response tag 0x%x\n", tag);
746                  }                  }
# Line 582  sec_process_mcs_data(STREAM s) Line 751  sec_process_mcs_data(STREAM s)
751    
752  /* Receive secure transport packet */  /* Receive secure transport packet */
753  STREAM  STREAM
754  sec_recv()  sec_recv(uint8 * rdpver)
755  {  {
756          uint32 sec_flags;          uint32 sec_flags;
757            uint16 channel;
758          STREAM s;          STREAM s;
759    
760          while ((s = mcs_recv()) != NULL)          while ((s = mcs_recv(&channel, rdpver)) != NULL)
761          {          {
762                  if (encryption || !licence_issued)                  if (rdpver != NULL)
763                    {
764                            if (*rdpver != 3)
765                            {
766                                    if (*rdpver & 0x80)
767                                    {
768                                            in_uint8s(s, 8);        /* signature */
769                                            sec_decrypt(s->p, s->end - s->p);
770                                    }
771                                    return s;
772                            }
773                    }
774                    if (g_encryption || !g_licence_issued)
775                  {                  {
776                          in_uint32_le(s, sec_flags);                          in_uint32_le(s, sec_flags);
777    
778                            if (sec_flags & SEC_ENCRYPT)
779                            {
780                                    in_uint8s(s, 8);        /* signature */
781                                    sec_decrypt(s->p, s->end - s->p);
782                            }
783    
784                          if (sec_flags & SEC_LICENCE_NEG)                          if (sec_flags & SEC_LICENCE_NEG)
785                          {                          {
786                                  licence_process(s);                                  licence_process(s);
787                                  continue;                                  continue;
788                          }                          }
789    
790                          if (sec_flags & SEC_ENCRYPT)                          if (sec_flags & 0x0400) /* SEC_REDIRECT_ENCRYPT */
791                          {                          {
792                                    uint8 swapbyte;
793    
794                                  in_uint8s(s, 8);        /* signature */                                  in_uint8s(s, 8);        /* signature */
795                                  sec_decrypt(s->p, s->end - s->p);                                  sec_decrypt(s->p, s->end - s->p);
796    
797                                    /* Check for a redirect packet, starts with 00 04 */
798                                    if (s->p[0] == 0 && s->p[1] == 4)
799                                    {
800                                            /* for some reason the PDU and the length seem to be swapped.
801                                               This isn't good, but we're going to do a byte for byte
802                                               swap.  So the first foure value appear as: 00 04 XX YY,
803                                               where XX YY is the little endian length. We're going to
804                                               use 04 00 as the PDU type, so after our swap this will look
805                                               like: XX YY 04 00 */
806                                            swapbyte = s->p[0];
807                                            s->p[0] = s->p[2];
808                                            s->p[2] = swapbyte;
809    
810                                            swapbyte = s->p[1];
811                                            s->p[1] = s->p[3];
812                                            s->p[3] = swapbyte;
813    
814                                            swapbyte = s->p[2];
815                                            s->p[2] = s->p[3];
816                                            s->p[3] = swapbyte;
817                                    }
818    #ifdef WITH_DEBUG
819                                    /* warning!  this debug statement will show passwords in the clear! */
820                                    hexdump(s->p, s->end - s->p);
821    #endif
822                          }                          }
823    
824                    }
825    
826                    if (channel != MCS_GLOBAL_CHANNEL)
827                    {
828                            channel_process(s, channel);
829                            *rdpver = 0xff;
830                            return s;
831                  }                  }
832    
833                  return s;                  return s;
# Line 613  sec_recv() Line 837  sec_recv()
837  }  }
838    
839  /* Establish a secure connection */  /* Establish a secure connection */
840  BOOL  RD_BOOL
841  sec_connect(char *server)  sec_connect(char *server, char *username)
842  {  {
843          struct stream mcs_data;          struct stream mcs_data;
844    
845          /* We exchange some RDP data during the MCS-Connect */          /* We exchange some RDP data during the MCS-Connect */
846          mcs_data.size = 512;          mcs_data.size = 512;
847          mcs_data.p = mcs_data.data = xmalloc(mcs_data.size);          mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
848          sec_out_mcs_data(&mcs_data);          sec_out_mcs_data(&mcs_data);
849    
850          if (!mcs_connect(server, &mcs_data))          if (!mcs_connect(server, &mcs_data, username))
851                  return False;                  return False;
852    
853          sec_process_mcs_data(&mcs_data);          /*      sec_process_mcs_data(&mcs_data); */
854          if (encryption)          if (g_encryption)
855                  sec_establish_key();                  sec_establish_key();
856            xfree(mcs_data.data);
857            return True;
858    }
859    
860    /* Establish a secure connection */
861    RD_BOOL
862    sec_reconnect(char *server)
863    {
864            struct stream mcs_data;
865    
866            /* We exchange some RDP data during the MCS-Connect */
867            mcs_data.size = 512;
868            mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
869            sec_out_mcs_data(&mcs_data);
870    
871            if (!mcs_reconnect(server, &mcs_data))
872                    return False;
873    
874            /*      sec_process_mcs_data(&mcs_data); */
875            if (g_encryption)
876                    sec_establish_key();
877            xfree(mcs_data.data);
878          return True;          return True;
879  }  }
880    
881  /* Disconnect a connection */  /* Disconnect a connection */
882  void  void
883  sec_disconnect()  sec_disconnect(void)
884  {  {
885          mcs_disconnect();          mcs_disconnect();
886  }  }
887    
888    /* reset the state of the sec layer */
889    void
890    sec_reset_state(void)
891    {
892            g_server_rdp_version = 0;
893            sec_encrypt_use_count = 0;
894            sec_decrypt_use_count = 0;
895            mcs_reset_state();
896    }

Legend:
Removed from v.57  
changed lines
  Added in v.1374

  ViewVC Help
Powered by ViewVC 1.1.26