/[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 24 by matty, Sat Jan 6 03:12:10 2001 UTC revision 966 by astrand, Wed Aug 3 11:48:22 2005 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-2000     Copyright (C) Matthew Chapman 1999-2005
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 "crypto/rc4.h"  
23  #include "crypto/md5.h"  #include <openssl/rc4.h>
24  #include "crypto/sha.h"  #include <openssl/md5.h>
25  #include "crypto/arith.h"  #include <openssl/sha.h>
26    #include <openssl/bn.h>
27  extern char hostname[16];  #include <openssl/x509v3.h>
28  extern int width;  
29  extern int height;  extern char g_hostname[16];
30  extern int keylayout;  extern int g_width;
31    extern int g_height;
32    extern int g_keylayout;
33    extern int g_keyboard_type;
34    extern int g_keyboard_subtype;
35    extern int g_keyboard_functionkeys;
36    extern BOOL g_encryption;
37    extern BOOL g_licence_issued;
38    extern BOOL g_use_rdp5;
39    extern BOOL g_console_session;
40    extern int g_server_bpp;
41    extern uint16 mcs_userid;
42    extern VCHANNEL g_channels[];
43    extern unsigned int g_num_channels;
44    
45  static int rc4_key_len;  static int rc4_key_len;
46  static RC4_KEY rc4_decrypt_key;  static RC4_KEY rc4_decrypt_key;
47  static RC4_KEY rc4_encrypt_key;  static RC4_KEY rc4_encrypt_key;
48    static RSA *server_public_key;
49    
50  static uint8 sec_sign_key[8];  static uint8 sec_sign_key[16];
51  static uint8 sec_decrypt_key[16];  static uint8 sec_decrypt_key[16];
52  static uint8 sec_encrypt_key[16];  static uint8 sec_encrypt_key[16];
53  static uint8 sec_decrypt_update_key[8];  static uint8 sec_decrypt_update_key[16];
54  static uint8 sec_encrypt_update_key[8];  static uint8 sec_encrypt_update_key[16];
55  static uint8 sec_crypted_random[64];  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
56    
57    uint16 g_server_rdp_version = 0;
58    
59  /*  /*
60   * General purpose 48-byte transformation, using two 32-byte salts (generally,   * I believe this is based on SSLv3 with the following differences:
61   * 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
62     *  MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
63     *  key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
64     *  key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
65     *  encryption/decryption keys updated every 4096 packets
66     * See http://wp.netscape.com/eng/ssl3/draft302.txt
67     */
68    
69    /*
70     * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
71   * Both SHA1 and MD5 algorithms are used.   * Both SHA1 and MD5 algorithms are used.
72   */   */
73  void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2,  void
74                   uint8 salt)  sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
75  {  {
76          uint8 shasig[20];          uint8 shasig[20];
77          uint8 pad[4];          uint8 pad[4];
# Line 73  void sec_hash_48(uint8 *out, uint8 *in, Line 98  void sec_hash_48(uint8 *out, uint8 *in,
98  }  }
99    
100  /*  /*
101   * 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.  
102   */   */
103  void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)  void
104    sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
105  {  {
106          MD5_CTX md5;          MD5_CTX md5;
107    
# Line 88  void sec_hash_16(uint8 *out, uint8 *in, Line 113  void sec_hash_16(uint8 *out, uint8 *in,
113  }  }
114    
115  /* Reduce key entropy from 64 to 40 bits */  /* Reduce key entropy from 64 to 40 bits */
116  static void sec_make_40bit(uint8 *key)  static void
117    sec_make_40bit(uint8 * key)
118  {  {
119          key[0] = 0xd1;          key[0] = 0xd1;
120          key[1] = 0x26;          key[1] = 0x26;
121          key[2] = 0x9e;          key[2] = 0x9e;
122  }  }
123    
124  /* Generate a session key and RC4 keys, given client and server randoms */  /* Generate encryption keys given client and server randoms */
125  static void sec_generate_keys(uint8 *client_key, uint8 *server_key,  static void
126                                int rc4_key_size)  sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
127  {  {
128          uint8 session_key[48];          uint8 pre_master_secret[48];
129          uint8 temp_hash[48];          uint8 master_secret[48];
130          uint8 input[48];          uint8 key_block[48];
131    
132          /* Construct input data to hash */          /* Construct pre-master secret */
133          memcpy(input, client_key, 24);          memcpy(pre_master_secret, client_random, 24);
134          memcpy(input + 24, server_key, 24);          memcpy(pre_master_secret + 24, server_random, 24);
135    
136          /* Generate session key - two rounds of sec_hash_48 */          /* Generate master secret and then key material */
137          sec_hash_48(temp_hash, input, client_key, server_key, 65);          sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
138          sec_hash_48(session_key, temp_hash, client_key, server_key, 88);          sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
139    
140          /* Store first 8 bytes of session key, for generating signatures */          /* First 16 bytes of key material is MAC secret */
141          memcpy(sec_sign_key, session_key, 8);          memcpy(sec_sign_key, key_block, 16);
142    
143          /* Generate RC4 keys */          /* Generate export keys from next two blocks of 16 bytes */
144          sec_hash_16(sec_decrypt_key, &session_key[16], client_key,          sec_hash_16(sec_decrypt_key, &key_block[16], client_random, server_random);
145                      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);  
146    
147          if (rc4_key_size == 1)          if (rc4_key_size == 1)
148          {          {
149                  DEBUG("40-bit encryption enabled\n");                  DEBUG(("40-bit encryption enabled\n"));
150                  sec_make_40bit(sec_sign_key);                  sec_make_40bit(sec_sign_key);
151                  sec_make_40bit(sec_decrypt_key);                  sec_make_40bit(sec_decrypt_key);
152                  sec_make_40bit(sec_encrypt_key);                  sec_make_40bit(sec_encrypt_key);
# Line 130  static void sec_generate_keys(uint8 *cli Line 154  static void sec_generate_keys(uint8 *cli
154          }          }
155          else          else
156          {          {
157                  DEBUG("128-bit encryption enabled\n");                  DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
158                  rc4_key_len = 16;                  rc4_key_len = 16;
159          }          }
160    
161          /* Store first 8 bytes of RC4 keys as update keys */          /* Save initial RC4 keys as update keys */
162          memcpy(sec_decrypt_update_key, sec_decrypt_key, 8);          memcpy(sec_decrypt_update_key, sec_decrypt_key, 16);
163          memcpy(sec_encrypt_update_key, sec_encrypt_key, 8);          memcpy(sec_encrypt_update_key, sec_encrypt_key, 16);
164    
165          /* Initialise RC4 state arrays */          /* Initialise RC4 state arrays */
166          RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);          RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
# Line 145  static void sec_generate_keys(uint8 *cli Line 169  static void sec_generate_keys(uint8 *cli
169    
170  static uint8 pad_54[40] = {  static uint8 pad_54[40] = {
171          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,
172                  54, 54, 54,          54, 54, 54,
173          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,
174                  54, 54, 54          54, 54, 54
175  };  };
176    
177  static uint8 pad_92[48] = {  static uint8 pad_92[48] = {
178          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,
179                  92, 92, 92, 92, 92, 92, 92,          92, 92, 92, 92, 92, 92, 92,
180          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,
181                  92, 92, 92, 92, 92, 92, 92          92, 92, 92, 92, 92, 92, 92
182  };  };
183    
184  /* Output a uint32 into a buffer (little-endian) */  /* Output a uint32 into a buffer (little-endian) */
185  void buf_out_uint32(uint8 *buffer, uint32 value)  void
186    buf_out_uint32(uint8 * buffer, uint32 value)
187  {  {
188          buffer[0] = (value) & 0xff;          buffer[0] = (value) & 0xff;
189          buffer[1] = (value >> 8) & 0xff;          buffer[1] = (value >> 8) & 0xff;
# Line 166  void buf_out_uint32(uint8 *buffer, uint3 Line 191  void buf_out_uint32(uint8 *buffer, uint3
191          buffer[3] = (value >> 24) & 0xff;          buffer[3] = (value >> 24) & 0xff;
192  }  }
193    
194  /* 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 */
195  void sec_sign(uint8 *signature, uint8 *session_key, int length,  void
196                uint8 *data, int datalen)  sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
197  {  {
198          uint8 shasig[20];          uint8 shasig[20];
199          uint8 md5sig[16];          uint8 md5sig[16];
# Line 179  void sec_sign(uint8 *signature, uint8 *s Line 204  void sec_sign(uint8 *signature, uint8 *s
204          buf_out_uint32(lenhdr, datalen);          buf_out_uint32(lenhdr, datalen);
205    
206          SHA1_Init(&sha);          SHA1_Init(&sha);
207          SHA1_Update(&sha, session_key, length);          SHA1_Update(&sha, session_key, keylen);
208          SHA1_Update(&sha, pad_54, 40);          SHA1_Update(&sha, pad_54, 40);
209          SHA1_Update(&sha, lenhdr, 4);          SHA1_Update(&sha, lenhdr, 4);
210          SHA1_Update(&sha, data, datalen);          SHA1_Update(&sha, data, datalen);
211          SHA1_Final(shasig, &sha);          SHA1_Final(shasig, &sha);
212    
213          MD5_Init(&md5);          MD5_Init(&md5);
214          MD5_Update(&md5, session_key, length);          MD5_Update(&md5, session_key, keylen);
215          MD5_Update(&md5, pad_92, 48);          MD5_Update(&md5, pad_92, 48);
216          MD5_Update(&md5, shasig, 20);          MD5_Update(&md5, shasig, 20);
217          MD5_Final(md5sig, &md5);          MD5_Final(md5sig, &md5);
218    
219          memcpy(signature, md5sig, length);          memcpy(signature, md5sig, siglen);
220  }  }
221    
222  /* Update an encryption key - similar to the signing process */  /* Update an encryption key */
223  static void sec_update(uint8 *key, uint8 *update_key)  static void
224    sec_update(uint8 * key, uint8 * update_key)
225  {  {
226          uint8 shasig[20];          uint8 shasig[20];
227          SHA_CTX sha;          SHA_CTX sha;
# Line 203  static void sec_update(uint8 *key, uint8 Line 229  static void sec_update(uint8 *key, uint8
229          RC4_KEY update;          RC4_KEY update;
230    
231          SHA1_Init(&sha);          SHA1_Init(&sha);
232          SHA1_Update(&sha, update_key, 8);          SHA1_Update(&sha, update_key, rc4_key_len);
233          SHA1_Update(&sha, pad_54, 40);          SHA1_Update(&sha, pad_54, 40);
234          SHA1_Update(&sha, key, 8);          SHA1_Update(&sha, key, rc4_key_len);
235          SHA1_Final(shasig, &sha);          SHA1_Final(shasig, &sha);
236    
237          MD5_Init(&md5);          MD5_Init(&md5);
238          MD5_Update(&md5, update_key, 8);          MD5_Update(&md5, update_key, rc4_key_len);
239          MD5_Update(&md5, pad_92, 48);          MD5_Update(&md5, pad_92, 48);
240          MD5_Update(&md5, shasig, 20);          MD5_Update(&md5, shasig, 20);
241          MD5_Final(key, &md5);          MD5_Final(key, &md5);
# Line 222  static void sec_update(uint8 *key, uint8 Line 248  static void sec_update(uint8 *key, uint8
248  }  }
249    
250  /* Encrypt data using RC4 */  /* Encrypt data using RC4 */
251  static void sec_encrypt(uint8 *data, int length)  static void
252    sec_encrypt(uint8 * data, int length)
253  {  {
254          static int use_count;          static int use_count;
255    
# Line 238  static void sec_encrypt(uint8 *data, int Line 265  static void sec_encrypt(uint8 *data, int
265  }  }
266    
267  /* Decrypt data using RC4 */  /* Decrypt data using RC4 */
268  static void sec_decrypt(uint8 *data, int length)  void
269    sec_decrypt(uint8 * data, int length)
270  {  {
271          static int use_count;          static int use_count;
272    
# Line 253  static void sec_decrypt(uint8 *data, int Line 281  static void sec_decrypt(uint8 *data, int
281          use_count++;          use_count++;
282  }  }
283    
284  /* Read in a NUMBER from a buffer */  static void
285  static void sec_read_number(NUMBER * num, uint8 *buffer, int len)  reverse(uint8 * p, int len)
286  {  {
         INT *data = num->n_part;  
287          int i, j;          int i, j;
288            uint8 temp;
289    
290          for (i = 0, j = 0; j < len; i++, j += 2)          for (i = 0, j = len - 1; i < j; i++, j--)
                 data[i] = buffer[j] | (buffer[j + 1] << 8);  
   
         num->n_len = i;  
 }  
   
 /* Write a NUMBER to a buffer */  
 static void sec_write_number(NUMBER * num, uint8 *buffer, int len)  
 {  
         INT *data = num->n_part;  
         int i, j;  
   
         for (i = 0, j = 0; j < len; i++, j += 2)  
291          {          {
292                  buffer[j] = data[i] & 0xff;                  temp = p[i];
293                  buffer[j + 1] = data[i] >> 8;                  p[i] = p[j];
294                    p[j] = temp;
295          }          }
296  }  }
297    
298  /* Perform an RSA public key encryption operation */  /* Perform an RSA public key encryption operation */
299  static void sec_rsa_encrypt(uint8 *out, uint8 *in, int len,  static void
300                              uint8 *modulus, uint8 *exponent)  sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
301  {  {
302          NUMBER data, key;          BN_CTX *ctx;
303            BIGNUM mod, exp, x, y;
304          /* Set modulus for arithmetic */          uint8 inr[SEC_MODULUS_SIZE];
305          sec_read_number(&key, modulus, SEC_MODULUS_SIZE);          int outlen;
306          m_init(&key, NULL);  
307            reverse(modulus, SEC_MODULUS_SIZE);
308          /* Exponentiate */          reverse(exponent, SEC_EXPONENT_SIZE);
309          sec_read_number(&data, in, len);          memcpy(inr, in, len);
310          sec_read_number(&key, exponent, SEC_EXPONENT_SIZE);          reverse(inr, len);
311          m_exp(&data, &key, &data);  
312          sec_write_number(&data, out, SEC_MODULUS_SIZE);          ctx = BN_CTX_new();
313            BN_init(&mod);
314            BN_init(&exp);
315            BN_init(&x);
316            BN_init(&y);
317    
318            BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
319            BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
320            BN_bin2bn(inr, len, &x);
321            BN_mod_exp(&y, &x, &exp, &mod, ctx);
322            outlen = BN_bn2bin(&y, out);
323            reverse(out, outlen);
324            if (outlen < SEC_MODULUS_SIZE)
325                    memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
326    
327            BN_free(&y);
328            BN_clear_free(&x);
329            BN_free(&exp);
330            BN_free(&mod);
331            BN_CTX_free(ctx);
332  }  }
333    
334  /* Initialise secure transport packet */  /* Initialise secure transport packet */
335  STREAM sec_init(uint32 flags, int maxlen)  STREAM
336    sec_init(uint32 flags, int maxlen)
337  {  {
338          int hdrlen;          int hdrlen;
339          STREAM s;          STREAM s;
340    
341          hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;          if (!g_licence_issued)
342                    hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
343            else
344                    hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
345          s = mcs_init(maxlen + hdrlen);          s = mcs_init(maxlen + hdrlen);
346          s_push_layer(s, sec_hdr, hdrlen);          s_push_layer(s, sec_hdr, hdrlen);
347    
348          return s;          return s;
349  }  }
350    
351  /* Transmit secure transport packet */  /* Transmit secure transport packet over specified channel */
352  void sec_send(STREAM s, uint32 flags)  void
353    sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
354  {  {
355          int datalen;          int datalen;
356    
357          s_pop_layer(s, sec_hdr);          s_pop_layer(s, sec_hdr);
358          out_uint32_le(s, flags);          if (!g_licence_issued || (flags & SEC_ENCRYPT))
359                    out_uint32_le(s, flags);
360    
361          if (flags & SEC_ENCRYPT)          if (flags & SEC_ENCRYPT)
362          {          {
363                  flags &= ~SEC_ENCRYPT;                  flags &= ~SEC_ENCRYPT;
364                  datalen = s->end - s->p - 8;                  datalen = s->end - s->p - 8;
365    
366  #if RDP_DEBUG  #if WITH_DEBUG
367                  DEBUG("Sending encrypted packet:\n");                  DEBUG(("Sending encrypted packet:\n"));
368                  hexdump(s->p + 8, datalen);                  hexdump(s->p + 8, datalen);
369  #endif  #endif
370    
371                  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);
372                  sec_encrypt(s->p + 8, datalen);                  sec_encrypt(s->p + 8, datalen);
373          }          }
374    
375          mcs_send(s);          mcs_send_to_channel(s, channel);
376    }
377    
378    /* Transmit secure transport packet */
379    
380    void
381    sec_send(STREAM s, uint32 flags)
382    {
383            sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
384  }  }
385    
386    
387  /* Transfer the client random to the server */  /* Transfer the client random to the server */
388  static void sec_establish_key()  static void
389    sec_establish_key(void)
390  {  {
391          uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;          uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
392          uint32 flags = SEC_CLIENT_RANDOM;          uint32 flags = SEC_CLIENT_RANDOM;
# Line 351  static void sec_establish_key() Line 403  static void sec_establish_key()
403  }  }
404    
405  /* Output connect initial data blob */  /* Output connect initial data blob */
406  static void sec_out_mcs_data(STREAM s)  static void
407    sec_out_mcs_data(STREAM s)
408  {  {
409          int hostlen = 2 * strlen(hostname);          int hostlen = 2 * strlen(g_hostname);
410            int length = 158 + 76 + 12 + 4;
411            unsigned int i;
412    
413            if (g_num_channels > 0)
414                    length += g_num_channels * 12 + 8;
415    
416          out_uint16_be(s, 5);    /* unknown */          if (hostlen > 30)
417                    hostlen = 30;
418    
419            /* Generic Conference Control (T.124) ConferenceCreateRequest */
420            out_uint16_be(s, 5);
421          out_uint16_be(s, 0x14);          out_uint16_be(s, 0x14);
422          out_uint8(s, 0x7c);          out_uint8(s, 0x7c);
423          out_uint16_be(s, 1);          out_uint16_be(s, 1);
424    
425          out_uint16_be(s, (158 | 0x8000));       /* remaining length */          out_uint16_be(s, (length | 0x8000));    /* remaining length */
426    
427          out_uint16_be(s, 8);    /* length? */          out_uint16_be(s, 8);    /* length? */
428          out_uint16_be(s, 16);          out_uint16_be(s, 16);
# Line 368  static void sec_out_mcs_data(STREAM s) Line 430  static void sec_out_mcs_data(STREAM s)
430          out_uint16_le(s, 0xc001);          out_uint16_le(s, 0xc001);
431          out_uint8(s, 0);          out_uint8(s, 0);
432    
433          out_uint32_le(s, 0x61637544);   /* "Duca" ?! */          out_uint32_le(s, 0x61637544);   /* OEM ID: "Duca", as in Ducati. */
434          out_uint16_be(s, (144 | 0x8000));       /* remaining length */          out_uint16_be(s, ((length - 14) | 0x8000));     /* remaining length */
435    
436          /* Client information */          /* Client information */
437          out_uint16_le(s, SEC_TAG_CLI_INFO);          out_uint16_le(s, SEC_TAG_CLI_INFO);
438          out_uint16_le(s, 136);  /* length */          out_uint16_le(s, 212);  /* length */
439          out_uint16_le(s, 1);          out_uint16_le(s, g_use_rdp5 ? 4 : 1);   /* RDP version. 1 == RDP4, 4 == RDP5. */
440          out_uint16_le(s, 8);          out_uint16_le(s, 8);
441          out_uint16_le(s, width);          out_uint16_le(s, g_width);
442          out_uint16_le(s, height);          out_uint16_le(s, g_height);
443          out_uint16_le(s, 0xca01);          out_uint16_le(s, 0xca01);
444          out_uint16_le(s, 0xaa03);          out_uint16_le(s, 0xaa03);
445          out_uint32_le(s, keylayout);          out_uint32_le(s, g_keylayout);
446          out_uint32_le(s, 419);  /* client build? we are 419 compatible :-) */          out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
447    
448          /* Unicode name of client, padded to 32 bytes */          /* Unicode name of client, padded to 32 bytes */
449          rdp_out_unistr(s, hostname, hostlen);          rdp_out_unistr(s, g_hostname, hostlen);
450          out_uint8s(s, 30 - hostlen);          out_uint8s(s, 30 - hostlen);
451    
452          out_uint32_le(s, 4);          /* See
453          out_uint32(s, 0);             http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
454          out_uint32_le(s, 12);          out_uint32_le(s, g_keyboard_type);
455            out_uint32_le(s, g_keyboard_subtype);
456            out_uint32_le(s, g_keyboard_functionkeys);
457          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */
458            out_uint16_le(s, 0xca01);       /* colour depth? */
459            out_uint16_le(s, 1);
460    
461            out_uint32(s, 0);
462            out_uint8(s, g_server_bpp);
463            out_uint16_le(s, 0x0700);
464            out_uint8(s, 0);
465            out_uint32_le(s, 1);
466            out_uint8s(s, 64);      /* End of client info */
467    
468          out_uint16(s, 0xca01);          out_uint16_le(s, SEC_TAG_CLI_4);
469          out_uint16(s, 0);          out_uint16_le(s, 12);
470            out_uint32_le(s, g_console_session ? 0xb : 9);
471            out_uint32(s, 0);
472    
473          /* Client encryption settings */          /* Client encryption settings */
474          out_uint16_le(s, SEC_TAG_CLI_CRYPT);          out_uint16_le(s, SEC_TAG_CLI_CRYPT);
475          out_uint16(s, 8);       /* length */          out_uint16_le(s, 12);   /* length */
476          out_uint32_le(s, 1);    /* encryption enabled */          out_uint32_le(s, g_encryption ? 0x3 : 0);       /* encryption supported, 128-bit supported */
477            out_uint32(s, 0);       /* Unknown */
478    
479            DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
480            if (g_num_channels > 0)
481            {
482                    out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
483                    out_uint16_le(s, g_num_channels * 12 + 8);      /* length */
484                    out_uint32_le(s, g_num_channels);       /* number of virtual channels */
485                    for (i = 0; i < g_num_channels; i++)
486                    {
487                            DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
488                            out_uint8a(s, g_channels[i].name, 8);
489                            out_uint32_be(s, g_channels[i].flags);
490                    }
491            }
492    
493          s_mark_end(s);          s_mark_end(s);
494  }  }
495    
496  /* Parse a public key structure */  /* Parse a public key structure */
497  static BOOL sec_parse_public_key(STREAM s, uint8 **modulus, uint8 **exponent)  static BOOL
498    sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
499  {  {
500          uint32 magic, modulus_len;          uint32 magic, modulus_len;
501    
502          in_uint32_le(s, magic);          in_uint32_le(s, magic);
503          if (magic != SEC_RSA_MAGIC)          if (magic != SEC_RSA_MAGIC)
504          {          {
505                  ERROR("RSA magic 0x%x\n", magic);                  error("RSA magic 0x%x\n", magic);
506                  return False;                  return False;
507          }          }
508    
509          in_uint32_le(s, modulus_len);          in_uint32_le(s, modulus_len);
510          if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)          if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
511          {          {
512                  ERROR("modulus len 0x%x\n", modulus_len);                  error("modulus len 0x%x\n", modulus_len);
513                  return False;                  return False;
514          }          }
515    
# Line 429  static BOOL sec_parse_public_key(STREAM Line 521  static BOOL sec_parse_public_key(STREAM
521          return s_check(s);          return s_check(s);
522  }  }
523    
524    static BOOL
525    sec_parse_x509_key(X509 * cert)
526    {
527            EVP_PKEY *epk = NULL;
528            /* By some reason, Microsoft sets the OID of the Public RSA key to
529               the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
530    
531               Kudos to Richard Levitte for the following (. intiutive .)
532               lines of code that resets the OID and let's us extract the key. */
533            if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
534            {
535                    DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
536                    cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
537            }
538            epk = X509_get_pubkey(cert);
539            if (NULL == epk)
540            {
541                    error("Failed to extract public key from certificate\n");
542                    return False;
543            }
544    
545            server_public_key = (RSA *) epk->pkey.ptr;
546    
547            return True;
548    }
549    
550    
551  /* Parse a crypto information structure */  /* Parse a crypto information structure */
552  static BOOL sec_parse_crypt_info(STREAM s, uint32 *rc4_key_size,  static BOOL
553                                   uint8 **server_random, uint8 **modulus,  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
554                                   uint8 **exponent)                       uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
555  {  {
556          uint32 crypt_level, random_len, rsa_info_len;          uint32 crypt_level, random_len, rsa_info_len;
557            uint32 cacert_len, cert_len, flags;
558            X509 *cacert, *server_cert;
559          uint16 tag, length;          uint16 tag, length;
560          uint8 *next_tag, *end;          uint8 *next_tag, *end;
561    
562          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 */
563          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */
564            if (crypt_level == 0)   /* no encryption */
565                    return False;
566          in_uint32_le(s, random_len);          in_uint32_le(s, random_len);
567          in_uint32_le(s, rsa_info_len);          in_uint32_le(s, rsa_info_len);
568    
569          if (random_len != SEC_RANDOM_SIZE)          if (random_len != SEC_RANDOM_SIZE)
570          {          {
571                  ERROR("random len %d\n", random_len);                  error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
572                  return False;                  return False;
573          }          }
574    
# Line 456  static BOOL sec_parse_crypt_info(STREAM Line 579  static BOOL sec_parse_crypt_info(STREAM
579          if (end > s->end)          if (end > s->end)
580                  return False;                  return False;
581    
582          in_uint8s(s, 12);       /* unknown */          in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
583            if (flags & 1)
584            {
585                    DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
586                    in_uint8s(s, 8);        /* unknown */
587    
588          while (s->p < end)                  while (s->p < end)
589                    {
590                            in_uint16_le(s, tag);
591                            in_uint16_le(s, length);
592    
593                            next_tag = s->p + length;
594    
595                            switch (tag)
596                            {
597                                    case SEC_TAG_PUBKEY:
598                                            if (!sec_parse_public_key(s, modulus, exponent))
599                                                    return False;
600                                            DEBUG_RDP5(("Got Public key, RDP4-style\n"));
601    
602                                            break;
603    
604                                    case SEC_TAG_KEYSIG:
605                                            /* Is this a Microsoft key that we just got? */
606                                            /* Care factor: zero! */
607                                            /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
608                                               key as a known key of the hostname. This would prevent some MITM-attacks. */
609                                            break;
610    
611                                    default:
612                                            unimpl("crypt tag 0x%x\n", tag);
613                            }
614    
615                            s->p = next_tag;
616                    }
617            }
618            else
619          {          {
620                  in_uint16_le(s, tag);                  uint32 certcount;
                 in_uint16_le(s, length);  
621    
622                  next_tag = s->p + length;                  DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
623                    in_uint32_le(s, certcount);     /* Number of certificates */
624    
625                  switch (tag)                  if (certcount < 2)
626                  {                  {
627                          case SEC_TAG_PUBKEY:                          error("Server didn't send enough X509 certificates\n");
628                                  if (!sec_parse_public_key                          return False;
629                                      (s, modulus, exponent))                  }
                                         return False;  
630    
631                                  break;                  for (; certcount > 2; certcount--)
632                    {               /* ignore all the certificates between the root and the signing CA */
633                            uint32 ignorelen;
634                            X509 *ignorecert;
635    
636                            DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
637    
638                            in_uint32_le(s, ignorelen);
639                            DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
640                            ignorecert = d2i_X509(NULL, &(s->p), ignorelen);
641    
642                            if (ignorecert == NULL)
643                            {       /* XXX: error out? */
644                                    DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
645                            }
646    
647    #ifdef WITH_DEBUG_RDP5
648                            DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
649                            X509_print_fp(stdout, ignorecert);
650    #endif
651                    }
652    
653                          case SEC_TAG_KEYSIG:                  /* Do da funky X.509 stuffy
                                 /* Is this a Microsoft key that we just got? */  
                                 /* Care factor: zero! */  
                                 break;  
654    
655                          default:                     "How did I find out about this?  I looked up and saw a
656                                  NOTIMP("crypt tag 0x%x\n", tag);                     bright light and when I came to I had a scar on my forehead
657                       and knew about X.500"
658                       - Peter Gutman in a early version of
659                       http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
660                     */
661    
662                    in_uint32_le(s, cacert_len);
663                    DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
664                    cacert = d2i_X509(NULL, &(s->p), cacert_len);
665                    /* Note: We don't need to move s->p here - d2i_X509 is
666                       "kind" enough to do it for us */
667                    if (NULL == cacert)
668                    {
669                            error("Couldn't load CA Certificate from server\n");
670                            return False;
671                  }                  }
672    
673                  s->p = next_tag;                  /* Currently, we don't use the CA Certificate.
674          }                     FIXME:
675                       *) Verify the server certificate (server_cert) with the
676                       CA certificate.
677                       *) Store the CA Certificate with the hostname of the
678                       server we are connecting to as key, and compare it
679                       when we connect the next time, in order to prevent
680                       MITM-attacks.
681                     */
682    
683                    in_uint32_le(s, cert_len);
684                    DEBUG_RDP5(("Certificate length is %d\n", cert_len));
685                    server_cert = d2i_X509(NULL, &(s->p), cert_len);
686                    if (NULL == server_cert)
687                    {
688                            error("Couldn't load Certificate from server\n");
689                            return False;
690                    }
691    
692                    in_uint8s(s, 16);       /* Padding */
693    
694                    /* Note: Verifying the server certificate must be done here,
695                       before sec_parse_public_key since we'll have to apply
696                       serious violence to the key after this */
697    
698                    if (!sec_parse_x509_key(server_cert))
699                    {
700                            DEBUG_RDP5(("Didn't parse X509 correctly\n"));
701                            return False;
702                    }
703                    return True;    /* There's some garbage here we don't care about */
704            }
705          return s_check_end(s);          return s_check_end(s);
706  }  }
707    
708  /* Process crypto information blob */  /* Process crypto information blob */
709  static void sec_process_crypt_info(STREAM s)  static void
710    sec_process_crypt_info(STREAM s)
711  {  {
712          uint8 *server_random, *modulus, *exponent;          uint8 *server_random, *modulus, *exponent;
713          uint8 client_random[SEC_RANDOM_SIZE];          uint8 client_random[SEC_RANDOM_SIZE];
714          uint32 rc4_key_size;          uint32 rc4_key_size;
715            uint8 inr[SEC_MODULUS_SIZE];
716    
717          if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random,          if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
718                                    &modulus, &exponent))          {
719                    DEBUG(("Failed to parse crypt info\n"));
720                  return;                  return;
721            }
722    
723            DEBUG(("Generating client random\n"));
724          /* Generate a client random, and hence determine encryption keys */          /* Generate a client random, and hence determine encryption keys */
725            /* This is what the MS client do: */
726            memset(inr, 0, SEC_RANDOM_SIZE);
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    
735          generate_random(client_random);          generate_random(client_random);
736          sec_rsa_encrypt(sec_crypted_random, client_random,          if (NULL != server_public_key)
737                          SEC_RANDOM_SIZE, modulus, exponent);          {                       /* Which means we should use
738                                       RDP5-style encryption */
739    
740                    memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
741                    reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
742    
743                    RSA_public_encrypt(SEC_MODULUS_SIZE,
744                                       inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
745    
746                    reverse(sec_crypted_random, SEC_MODULUS_SIZE);
747    
748            }
749            else
750            {                       /* RDP4-style encryption */
751                    sec_rsa_encrypt(sec_crypted_random,
752                                    client_random, SEC_RANDOM_SIZE, modulus, exponent);
753            }
754          sec_generate_keys(client_random, server_random, rc4_key_size);          sec_generate_keys(client_random, server_random, rc4_key_size);
755  }  }
756    
757    
758    /* Process SRV_INFO, find RDP version supported by server */
759    static void
760    sec_process_srv_info(STREAM s)
761    {
762            in_uint16_le(s, g_server_rdp_version);
763            DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
764            if (1 == g_server_rdp_version)
765            {
766                    g_use_rdp5 = 0;
767                    g_server_bpp = 8;
768            }
769    }
770    
771    
772  /* Process connect response data blob */  /* Process connect response data blob */
773  static void sec_process_mcs_data(STREAM s)  void
774    sec_process_mcs_data(STREAM s)
775  {  {
776          uint16 tag, length;          uint16 tag, length;
777          uint8 *next_tag;          uint8 *next_tag;
778            uint8 len;
779    
780          in_uint8s(s, 23);       /* header */          in_uint8s(s, 21);       /* header (T.124 ConferenceCreateResponse) */
781            in_uint8(s, len);
782            if (len & 0x80)
783                    in_uint8(s, len);
784    
785          while (s->p < s->end)          while (s->p < s->end)
786          {          {
# Line 528  static void sec_process_mcs_data(STREAM Line 795  static void sec_process_mcs_data(STREAM
795                  switch (tag)                  switch (tag)
796                  {                  {
797                          case SEC_TAG_SRV_INFO:                          case SEC_TAG_SRV_INFO:
798                          case SEC_TAG_SRV_3:                                  sec_process_srv_info(s);
799                                  break;                                  break;
800    
801                          case SEC_TAG_SRV_CRYPT:                          case SEC_TAG_SRV_CRYPT:
802                                  sec_process_crypt_info(s);                                  sec_process_crypt_info(s);
803                                  break;                                  break;
804    
805                            case SEC_TAG_SRV_CHANNELS:
806                                    /* FIXME: We should parse this information and
807                                       use it to map RDP5 channels to MCS
808                                       channels */
809                                    break;
810    
811                          default:                          default:
812                                  NOTIMP("response tag 0x%x\n", tag);                                  unimpl("response tag 0x%x\n", tag);
813                  }                  }
814    
815                  s->p = next_tag;                  s->p = next_tag;
# Line 544  static void sec_process_mcs_data(STREAM Line 817  static void sec_process_mcs_data(STREAM
817  }  }
818    
819  /* Receive secure transport packet */  /* Receive secure transport packet */
820  STREAM sec_recv()  STREAM
821    sec_recv(uint8 * rdpver)
822  {  {
823          uint32 sec_flags;          uint32 sec_flags;
824            uint16 channel;
825          STREAM s;          STREAM s;
826    
827          while ((s = mcs_recv()) != NULL)          while ((s = mcs_recv(&channel, rdpver)) != NULL)
828          {          {
829                  in_uint32_le(s, sec_flags);                  if (rdpver != NULL)
   
                 if (sec_flags & SEC_LICENCE_NEG)  
830                  {                  {
831                          licence_process(s);                          if (*rdpver != 3)
832                          continue;                          {
833                                    if (*rdpver & 0x80)
834                                    {
835                                            in_uint8s(s, 8);        /* signature */
836                                            sec_decrypt(s->p, s->end - s->p);
837                                    }
838                                    return s;
839                            }
840                    }
841                    if (g_encryption || !g_licence_issued)
842                    {
843                            in_uint32_le(s, sec_flags);
844    
845                            if (sec_flags & SEC_ENCRYPT)
846                            {
847                                    in_uint8s(s, 8);        /* signature */
848                                    sec_decrypt(s->p, s->end - s->p);
849                            }
850    
851                            if (sec_flags & SEC_LICENCE_NEG)
852                            {
853                                    licence_process(s);
854                                    continue;
855                            }
856                  }                  }
857    
858                  if (sec_flags & SEC_ENCRYPT)                  if (channel != MCS_GLOBAL_CHANNEL)
859                  {                  {
860                          in_uint8s(s, 8);        /* signature */                          channel_process(s, channel);
861                          sec_decrypt(s->p, s->end - s->p);                          *rdpver = 0xff;
862                            return s;
863                  }                  }
864    
865                  return s;                  return s;
# Line 572  STREAM sec_recv() Line 869  STREAM sec_recv()
869  }  }
870    
871  /* Establish a secure connection */  /* Establish a secure connection */
872  BOOL sec_connect(char *server)  BOOL
873    sec_connect(char *server, char *username)
874  {  {
875          struct stream mcs_data;          struct stream mcs_data;
876    
877          /* We exchange some RDP data during the MCS-Connect */          /* We exchange some RDP data during the MCS-Connect */
878          mcs_data.size = 512;          mcs_data.size = 512;
879          mcs_data.p = mcs_data.data = xmalloc(mcs_data.size);          mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
880          sec_out_mcs_data(&mcs_data);          sec_out_mcs_data(&mcs_data);
881    
882          if (!mcs_connect(server, &mcs_data))          if (!mcs_connect(server, &mcs_data, username))
883                  return False;                  return False;
884    
885          sec_process_mcs_data(&mcs_data);          /*      sec_process_mcs_data(&mcs_data); */
886          sec_establish_key();          if (g_encryption)
887                    sec_establish_key();
888            xfree(mcs_data.data);
889          return True;          return True;
890  }  }
891    
892  /* Disconnect a connection */  /* Disconnect a connection */
893  void sec_disconnect()  void
894    sec_disconnect(void)
895  {  {
896          mcs_disconnect();          mcs_disconnect();
897  }  }

Legend:
Removed from v.24  
changed lines
  Added in v.966

  ViewVC Help
Powered by ViewVC 1.1.26