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

Legend:
Removed from v.25  
changed lines
  Added in v.1315

  ViewVC Help
Powered by ViewVC 1.1.26