/[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 309 by jsorg71, Tue Feb 4 05:32:13 2003 UTC
# Line 1  Line 1 
1  /*  /*
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-2002
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    
23    #ifdef WITH_OPENSSL
24    #include <openssl/rc4.h>
25    #include <openssl/md5.h>
26    #include <openssl/sha.h>
27    #include <openssl/bn.h>
28    #else
29  #include "crypto/rc4.h"  #include "crypto/rc4.h"
30  #include "crypto/md5.h"  #include "crypto/md5.h"
31  #include "crypto/sha.h"  #include "crypto/sha.h"
32  #include "crypto/arith.h"  #include "crypto/bn.h"
33    #endif
34    
35  extern char hostname[16];  extern char hostname[16];
36  extern int width;  extern int width;
37  extern int height;  extern int height;
38  extern int keylayout;  extern int keylayout;
39    extern BOOL encryption;
40    extern BOOL licence_issued;
41    extern int server_bpp;
42    
43  static int rc4_key_len;  static int rc4_key_len;
44  static RC4_KEY rc4_decrypt_key;  static RC4_KEY rc4_decrypt_key;
45  static RC4_KEY rc4_encrypt_key;  static RC4_KEY rc4_encrypt_key;
46    
47  static uint8 sec_sign_key[8];  static uint8 sec_sign_key[16];
48  static uint8 sec_decrypt_key[16];  static uint8 sec_decrypt_key[16];
49  static uint8 sec_encrypt_key[16];  static uint8 sec_encrypt_key[16];
50  static uint8 sec_decrypt_update_key[8];  static uint8 sec_decrypt_update_key[16];
51  static uint8 sec_encrypt_update_key[8];  static uint8 sec_encrypt_update_key[16];
52  static uint8 sec_crypted_random[64];  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
53    
54  /*  /*
55   * General purpose 48-byte transformation, using two 32-byte salts (generally,   * General purpose 48-byte transformation, using two 32-byte salts (generally,
56   * a client and server salt) and a global salt value used for padding.   * a client and server salt) and a global salt value used for padding.
57   * Both SHA1 and MD5 algorithms are used.   * Both SHA1 and MD5 algorithms are used.
58   */   */
59  void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2,  void
60                   uint8 salt)  sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
61  {  {
62          uint8 shasig[20];          uint8 shasig[20];
63          uint8 pad[4];          uint8 pad[4];
# Line 76  void sec_hash_48(uint8 *out, uint8 *in, Line 87  void sec_hash_48(uint8 *out, uint8 *in,
87   * Weaker 16-byte transformation, also using two 32-byte salts, but   * Weaker 16-byte transformation, also using two 32-byte salts, but
88   * only using a single round of MD5.   * only using a single round of MD5.
89   */   */
90  void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)  void
91    sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
92  {  {
93          MD5_CTX md5;          MD5_CTX md5;
94    
# Line 88  void sec_hash_16(uint8 *out, uint8 *in, Line 100  void sec_hash_16(uint8 *out, uint8 *in,
100  }  }
101    
102  /* Reduce key entropy from 64 to 40 bits */  /* Reduce key entropy from 64 to 40 bits */
103  static void sec_make_40bit(uint8 *key)  static void
104    sec_make_40bit(uint8 * key)
105  {  {
106          key[0] = 0xd1;          key[0] = 0xd1;
107          key[1] = 0x26;          key[1] = 0x26;
# Line 96  static void sec_make_40bit(uint8 *key) Line 109  static void sec_make_40bit(uint8 *key)
109  }  }
110    
111  /* Generate a session key and RC4 keys, given client and server randoms */  /* Generate a session key and RC4 keys, given client and server randoms */
112  static void sec_generate_keys(uint8 *client_key, uint8 *server_key,  static void
113                                int rc4_key_size)  sec_generate_keys(uint8 * client_key, uint8 * server_key, int rc4_key_size)
114  {  {
115          uint8 session_key[48];          uint8 session_key[48];
116          uint8 temp_hash[48];          uint8 temp_hash[48];
# Line 111  static void sec_generate_keys(uint8 *cli Line 124  static void sec_generate_keys(uint8 *cli
124          sec_hash_48(temp_hash, input, client_key, server_key, 65);          sec_hash_48(temp_hash, input, client_key, server_key, 65);
125          sec_hash_48(session_key, temp_hash, client_key, server_key, 88);          sec_hash_48(session_key, temp_hash, client_key, server_key, 88);
126    
127          /* Store first 8 bytes of session key, for generating signatures */          /* Store first 16 bytes of session key, for generating signatures */
128          memcpy(sec_sign_key, session_key, 8);          memcpy(sec_sign_key, session_key, 16);
129    
130          /* Generate RC4 keys */          /* Generate RC4 keys */
131          sec_hash_16(sec_decrypt_key, &session_key[16], client_key,          sec_hash_16(sec_decrypt_key, &session_key[16], client_key, server_key);
132                      server_key);          sec_hash_16(sec_encrypt_key, &session_key[32], client_key, server_key);
         sec_hash_16(sec_encrypt_key, &session_key[32], client_key,  
                     server_key);  
133    
134          if (rc4_key_size == 1)          if (rc4_key_size == 1)
135          {          {
136                  DEBUG("40-bit encryption enabled\n");                  DEBUG(("40-bit encryption enabled\n"));
137                  sec_make_40bit(sec_sign_key);                  sec_make_40bit(sec_sign_key);
138                  sec_make_40bit(sec_decrypt_key);                  sec_make_40bit(sec_decrypt_key);
139                  sec_make_40bit(sec_encrypt_key);                  sec_make_40bit(sec_encrypt_key);
# Line 130  static void sec_generate_keys(uint8 *cli Line 141  static void sec_generate_keys(uint8 *cli
141          }          }
142          else          else
143          {          {
144                  DEBUG("128-bit encryption enabled\n");                  DEBUG(("128-bit encryption enabled\n"));
145                  rc4_key_len = 16;                  rc4_key_len = 16;
146          }          }
147    
148          /* Store first 8 bytes of RC4 keys as update keys */          /* Save initial RC4 keys as update keys */
149          memcpy(sec_decrypt_update_key, sec_decrypt_key, 8);          memcpy(sec_decrypt_update_key, sec_decrypt_key, 16);
150          memcpy(sec_encrypt_update_key, sec_encrypt_key, 8);          memcpy(sec_encrypt_update_key, sec_encrypt_key, 16);
151    
152          /* Initialise RC4 state arrays */          /* Initialise RC4 state arrays */
153          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 156  static void sec_generate_keys(uint8 *cli
156    
157  static uint8 pad_54[40] = {  static uint8 pad_54[40] = {
158          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,
159                  54, 54, 54,          54, 54, 54,
160          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,
161                  54, 54, 54          54, 54, 54
162  };  };
163    
164  static uint8 pad_92[48] = {  static uint8 pad_92[48] = {
165          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,
166                  92, 92, 92, 92, 92, 92, 92,          92, 92, 92, 92, 92, 92, 92,
167          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,
168                  92, 92, 92, 92, 92, 92, 92          92, 92, 92, 92, 92, 92, 92
169  };  };
170    
171  /* Output a uint32 into a buffer (little-endian) */  /* Output a uint32 into a buffer (little-endian) */
172  void buf_out_uint32(uint8 *buffer, uint32 value)  void
173    buf_out_uint32(uint8 * buffer, uint32 value)
174  {  {
175          buffer[0] = (value) & 0xff;          buffer[0] = (value) & 0xff;
176          buffer[1] = (value >> 8) & 0xff;          buffer[1] = (value >> 8) & 0xff;
# Line 167  void buf_out_uint32(uint8 *buffer, uint3 Line 179  void buf_out_uint32(uint8 *buffer, uint3
179  }  }
180    
181  /* Generate a signature hash, using a combination of SHA1 and MD5 */  /* Generate a signature hash, using a combination of SHA1 and MD5 */
182  void sec_sign(uint8 *signature, uint8 *session_key, int length,  void
183                uint8 *data, int datalen)  sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
184  {  {
185          uint8 shasig[20];          uint8 shasig[20];
186          uint8 md5sig[16];          uint8 md5sig[16];
# Line 179  void sec_sign(uint8 *signature, uint8 *s Line 191  void sec_sign(uint8 *signature, uint8 *s
191          buf_out_uint32(lenhdr, datalen);          buf_out_uint32(lenhdr, datalen);
192    
193          SHA1_Init(&sha);          SHA1_Init(&sha);
194          SHA1_Update(&sha, session_key, length);          SHA1_Update(&sha, session_key, keylen);
195          SHA1_Update(&sha, pad_54, 40);          SHA1_Update(&sha, pad_54, 40);
196          SHA1_Update(&sha, lenhdr, 4);          SHA1_Update(&sha, lenhdr, 4);
197          SHA1_Update(&sha, data, datalen);          SHA1_Update(&sha, data, datalen);
198          SHA1_Final(shasig, &sha);          SHA1_Final(shasig, &sha);
199    
200          MD5_Init(&md5);          MD5_Init(&md5);
201          MD5_Update(&md5, session_key, length);          MD5_Update(&md5, session_key, keylen);
202          MD5_Update(&md5, pad_92, 48);          MD5_Update(&md5, pad_92, 48);
203          MD5_Update(&md5, shasig, 20);          MD5_Update(&md5, shasig, 20);
204          MD5_Final(md5sig, &md5);          MD5_Final(md5sig, &md5);
205    
206          memcpy(signature, md5sig, length);          memcpy(signature, md5sig, siglen);
207  }  }
208    
209  /* Update an encryption key - similar to the signing process */  /* Update an encryption key - similar to the signing process */
210  static void sec_update(uint8 *key, uint8 *update_key)  static void
211    sec_update(uint8 * key, uint8 * update_key)
212  {  {
213          uint8 shasig[20];          uint8 shasig[20];
214          SHA_CTX sha;          SHA_CTX sha;
# Line 203  static void sec_update(uint8 *key, uint8 Line 216  static void sec_update(uint8 *key, uint8
216          RC4_KEY update;          RC4_KEY update;
217    
218          SHA1_Init(&sha);          SHA1_Init(&sha);
219          SHA1_Update(&sha, update_key, 8);          SHA1_Update(&sha, update_key, rc4_key_len);
220          SHA1_Update(&sha, pad_54, 40);          SHA1_Update(&sha, pad_54, 40);
221          SHA1_Update(&sha, key, 8);          SHA1_Update(&sha, key, rc4_key_len);
222          SHA1_Final(shasig, &sha);          SHA1_Final(shasig, &sha);
223    
224          MD5_Init(&md5);          MD5_Init(&md5);
225          MD5_Update(&md5, update_key, 8);          MD5_Update(&md5, update_key, rc4_key_len);
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(key, &md5);          MD5_Final(key, &md5);
# Line 222  static void sec_update(uint8 *key, uint8 Line 235  static void sec_update(uint8 *key, uint8
235  }  }
236    
237  /* Encrypt data using RC4 */  /* Encrypt data using RC4 */
238  static void sec_encrypt(uint8 *data, int length)  static void
239    sec_encrypt(uint8 * data, int length)
240  {  {
241          static int use_count;          static int use_count;
242    
# Line 238  static void sec_encrypt(uint8 *data, int Line 252  static void sec_encrypt(uint8 *data, int
252  }  }
253    
254  /* Decrypt data using RC4 */  /* Decrypt data using RC4 */
255  static void sec_decrypt(uint8 *data, int length)  static void
256    sec_decrypt(uint8 * data, int length)
257  {  {
258          static int use_count;          static int use_count;
259    
# Line 253  static void sec_decrypt(uint8 *data, int Line 268  static void sec_decrypt(uint8 *data, int
268          use_count++;          use_count++;
269  }  }
270    
271  /* Read in a NUMBER from a buffer */  static void
272  static void sec_read_number(NUMBER * num, uint8 *buffer, int len)  reverse(uint8 * p, int len)
 {  
         INT *data = num->n_part;  
         int i, j;  
   
         for (i = 0, j = 0; j < len; i++, j += 2)  
                 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)  
273  {  {
         INT *data = num->n_part;  
274          int i, j;          int i, j;
275            uint8 temp;
276    
277          for (i = 0, j = 0; j < len; i++, j += 2)          for (i = 0, j = len - 1; i < j; i++, j--)
278          {          {
279                  buffer[j] = data[i] & 0xff;                  temp = p[i];
280                  buffer[j + 1] = data[i] >> 8;                  p[i] = p[j];
281                    p[j] = temp;
282          }          }
283  }  }
284    
285  /* Perform an RSA public key encryption operation */  /* Perform an RSA public key encryption operation */
286  static void sec_rsa_encrypt(uint8 *out, uint8 *in, int len,  static void
287                              uint8 *modulus, uint8 *exponent)  sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
288  {  {
289          NUMBER data, key;          BN_CTX *ctx;
290            BIGNUM mod, exp, x, y;
291          /* Set modulus for arithmetic */          uint8 inr[SEC_MODULUS_SIZE];
292          sec_read_number(&key, modulus, SEC_MODULUS_SIZE);          int outlen;
293          m_init(&key, NULL);  
294            reverse(modulus, SEC_MODULUS_SIZE);
295          /* Exponentiate */          reverse(exponent, SEC_EXPONENT_SIZE);
296          sec_read_number(&data, in, len);          memcpy(inr, in, len);
297          sec_read_number(&key, exponent, SEC_EXPONENT_SIZE);          reverse(inr, len);
298          m_exp(&data, &key, &data);  
299          sec_write_number(&data, out, SEC_MODULUS_SIZE);          ctx = BN_CTX_new();
300            BN_init(&mod);
301            BN_init(&exp);
302            BN_init(&x);
303            BN_init(&y);
304    
305            BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
306            BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
307            BN_bin2bn(inr, len, &x);
308            BN_mod_exp(&y, &x, &exp, &mod, ctx);
309            outlen = BN_bn2bin(&y, out);
310            reverse(out, outlen);
311            if (outlen < SEC_MODULUS_SIZE)
312                    memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
313    
314            BN_free(&y);
315            BN_clear_free(&x);
316            BN_free(&exp);
317            BN_free(&mod);
318            BN_CTX_free(ctx);
319  }  }
320    
321  /* Initialise secure transport packet */  /* Initialise secure transport packet */
322  STREAM sec_init(uint32 flags, int maxlen)  STREAM
323    sec_init(uint32 flags, int maxlen)
324  {  {
325          int hdrlen;          int hdrlen;
326          STREAM s;          STREAM s;
327    
328          hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;          if (!licence_issued)
329                    hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
330            else
331                    hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
332          s = mcs_init(maxlen + hdrlen);          s = mcs_init(maxlen + hdrlen);
333          s_push_layer(s, sec_hdr, hdrlen);          s_push_layer(s, sec_hdr, hdrlen);
334    
# Line 309  STREAM sec_init(uint32 flags, int maxlen Line 336  STREAM sec_init(uint32 flags, int maxlen
336  }  }
337    
338  /* Transmit secure transport packet */  /* Transmit secure transport packet */
339  void sec_send(STREAM s, uint32 flags)  void
340    sec_send(STREAM s, uint32 flags)
341  {  {
342          int datalen;          int datalen;
343    
344          s_pop_layer(s, sec_hdr);          s_pop_layer(s, sec_hdr);
345          out_uint32_le(s, flags);          if (!licence_issued || (flags & SEC_ENCRYPT))
346                    out_uint32_le(s, flags);
347    
348          if (flags & SEC_ENCRYPT)          if (flags & SEC_ENCRYPT)
349          {          {
350                  flags &= ~SEC_ENCRYPT;                  flags &= ~SEC_ENCRYPT;
351                  datalen = s->end - s->p - 8;                  datalen = s->end - s->p - 8;
352    
353  #if RDP_DEBUG  #if WITH_DEBUG
354                  DEBUG("Sending encrypted packet:\n");                  DEBUG(("Sending encrypted packet:\n"));
355                  hexdump(s->p + 8, datalen);                  hexdump(s->p + 8, datalen);
356  #endif  #endif
357    
358                  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);
359                  sec_encrypt(s->p + 8, datalen);                  sec_encrypt(s->p + 8, datalen);
360          }          }
361    
# Line 334  void sec_send(STREAM s, uint32 flags) Line 363  void sec_send(STREAM s, uint32 flags)
363  }  }
364    
365  /* Transfer the client random to the server */  /* Transfer the client random to the server */
366  static void sec_establish_key()  static void
367    sec_establish_key(void)
368  {  {
369          uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;          uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
370          uint32 flags = SEC_CLIENT_RANDOM;          uint32 flags = SEC_CLIENT_RANDOM;
# Line 351  static void sec_establish_key() Line 381  static void sec_establish_key()
381  }  }
382    
383  /* Output connect initial data blob */  /* Output connect initial data blob */
384  static void sec_out_mcs_data(STREAM s)  static void
385    sec_out_mcs_data(STREAM s)
386  {  {
387          int hostlen = 2 * strlen(hostname);          int hostlen = 2 * strlen(hostname);
388    
389            if (hostlen > 30)
390                    hostlen = 30;
391    
392          out_uint16_be(s, 5);    /* unknown */          out_uint16_be(s, 5);    /* unknown */
393          out_uint16_be(s, 0x14);          out_uint16_be(s, 0x14);
394          out_uint8(s, 0x7c);          out_uint8(s, 0x7c);
# Line 392  static void sec_out_mcs_data(STREAM s) Line 426  static void sec_out_mcs_data(STREAM s)
426          out_uint32_le(s, 12);          out_uint32_le(s, 12);
427          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */
428    
429          out_uint16(s, 0xca01);          if (server_bpp == 16)
430            {
431                    out_uint16_le(s, 0xca03); /* 16 bit */
432            }
433            else
434            {
435                    out_uint16_le(s, 0xca01); /* 8 bit */
436            }
437          out_uint16(s, 0);          out_uint16(s, 0);
438    
439          /* Client encryption settings */          /* Client encryption settings */
440          out_uint16_le(s, SEC_TAG_CLI_CRYPT);          out_uint16_le(s, SEC_TAG_CLI_CRYPT);
441          out_uint16(s, 8);       /* length */          out_uint16_le(s, 8);    /* length */
442          out_uint32_le(s, 1);    /* encryption enabled */          out_uint32_le(s, encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
443          s_mark_end(s);          s_mark_end(s);
444  }  }
445    
446  /* Parse a public key structure */  /* Parse a public key structure */
447  static BOOL sec_parse_public_key(STREAM s, uint8 **modulus, uint8 **exponent)  static BOOL
448    sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
449  {  {
450          uint32 magic, modulus_len;          uint32 magic, modulus_len;
451    
452          in_uint32_le(s, magic);          in_uint32_le(s, magic);
453          if (magic != SEC_RSA_MAGIC)          if (magic != SEC_RSA_MAGIC)
454          {          {
455                  ERROR("RSA magic 0x%x\n", magic);                  error("RSA magic 0x%x\n", magic);
456                  return False;                  return False;
457          }          }
458    
459          in_uint32_le(s, modulus_len);          in_uint32_le(s, modulus_len);
460          if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)          if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
461          {          {
462                  ERROR("modulus len 0x%x\n", modulus_len);                  error("modulus len 0x%x\n", modulus_len);
463                  return False;                  return False;
464          }          }
465    
# Line 430  static BOOL sec_parse_public_key(STREAM Line 472  static BOOL sec_parse_public_key(STREAM
472  }  }
473    
474  /* Parse a crypto information structure */  /* Parse a crypto information structure */
475  static BOOL sec_parse_crypt_info(STREAM s, uint32 *rc4_key_size,  static BOOL
476                                   uint8 **server_random, uint8 **modulus,  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
477                                   uint8 **exponent)                       uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
478  {  {
479          uint32 crypt_level, random_len, rsa_info_len;          uint32 crypt_level, random_len, rsa_info_len;
480          uint16 tag, length;          uint16 tag, length;
# Line 440  static BOOL sec_parse_crypt_info(STREAM Line 482  static BOOL sec_parse_crypt_info(STREAM
482    
483          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 */
484          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */
485            if (crypt_level == 0)   /* no encryptation */
486                    return False;
487          in_uint32_le(s, random_len);          in_uint32_le(s, random_len);
488          in_uint32_le(s, rsa_info_len);          in_uint32_le(s, rsa_info_len);
489    
490          if (random_len != SEC_RANDOM_SIZE)          if (random_len != SEC_RANDOM_SIZE)
491          {          {
492                  ERROR("random len %d\n", random_len);                  error("random len %d\n", random_len);
493                  return False;                  return False;
494          }          }
495    
# Line 468  static BOOL sec_parse_crypt_info(STREAM Line 512  static BOOL sec_parse_crypt_info(STREAM
512                  switch (tag)                  switch (tag)
513                  {                  {
514                          case SEC_TAG_PUBKEY:                          case SEC_TAG_PUBKEY:
515                                  if (!sec_parse_public_key                                  if (!sec_parse_public_key(s, modulus, exponent))
                                     (s, modulus, exponent))  
516                                          return False;                                          return False;
517    
518                                  break;                                  break;
# Line 480  static BOOL sec_parse_crypt_info(STREAM Line 523  static BOOL sec_parse_crypt_info(STREAM
523                                  break;                                  break;
524    
525                          default:                          default:
526                                  NOTIMP("crypt tag 0x%x\n", tag);                                  unimpl("crypt tag 0x%x\n", tag);
527                  }                  }
528    
529                  s->p = next_tag;                  s->p = next_tag;
# Line 490  static BOOL sec_parse_crypt_info(STREAM Line 533  static BOOL sec_parse_crypt_info(STREAM
533  }  }
534    
535  /* Process crypto information blob */  /* Process crypto information blob */
536  static void sec_process_crypt_info(STREAM s)  static void
537    sec_process_crypt_info(STREAM s)
538  {  {
539          uint8 *server_random, *modulus, *exponent;          uint8 *server_random, *modulus, *exponent;
540          uint8 client_random[SEC_RANDOM_SIZE];          uint8 client_random[SEC_RANDOM_SIZE];
541          uint32 rc4_key_size;          uint32 rc4_key_size;
542    
543          if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random,          if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
                                   &modulus, &exponent))  
544                  return;                  return;
545    
546          /* Generate a client random, and hence determine encryption keys */          /* Generate a client random, and hence determine encryption keys */
547          generate_random(client_random);          generate_random(client_random);
548          sec_rsa_encrypt(sec_crypted_random, client_random,          sec_rsa_encrypt(sec_crypted_random, client_random, SEC_RANDOM_SIZE, modulus, exponent);
                         SEC_RANDOM_SIZE, modulus, exponent);  
549          sec_generate_keys(client_random, server_random, rc4_key_size);          sec_generate_keys(client_random, server_random, rc4_key_size);
550  }  }
551    
552  /* Process connect response data blob */  /* Process connect response data blob */
553  static void sec_process_mcs_data(STREAM s)  static void
554    sec_process_mcs_data(STREAM s)
555  {  {
556          uint16 tag, length;          uint16 tag, length;
557          uint8 *next_tag;          uint8 *next_tag;
558            uint8 len;
559    
560          in_uint8s(s, 23);       /* header */          in_uint8s(s, 21);       /* header */
561            in_uint8(s, len);
562            if (len & 0x80)
563                    in_uint8(s, len);
564    
565          while (s->p < s->end)          while (s->p < s->end)
566          {          {
# Line 536  static void sec_process_mcs_data(STREAM Line 583  static void sec_process_mcs_data(STREAM
583                                  break;                                  break;
584    
585                          default:                          default:
586                                  NOTIMP("response tag 0x%x\n", tag);                                  unimpl("response tag 0x%x\n", tag);
587                  }                  }
588    
589                  s->p = next_tag;                  s->p = next_tag;
# Line 544  static void sec_process_mcs_data(STREAM Line 591  static void sec_process_mcs_data(STREAM
591  }  }
592    
593  /* Receive secure transport packet */  /* Receive secure transport packet */
594  STREAM sec_recv()  STREAM
595    sec_recv(void)
596  {  {
597          uint32 sec_flags;          uint32 sec_flags;
598          STREAM s;          STREAM s;
599    
600          while ((s = mcs_recv()) != NULL)          while ((s = mcs_recv()) != NULL)
601          {          {
602                  in_uint32_le(s, sec_flags);                  if (encryption || !licence_issued)
   
                 if (sec_flags & SEC_LICENCE_NEG)  
603                  {                  {
604                          licence_process(s);                          in_uint32_le(s, sec_flags);
                         continue;  
                 }  
605    
606                  if (sec_flags & SEC_ENCRYPT)                          if (sec_flags & SEC_LICENCE_NEG)
607                  {                          {
608                          in_uint8s(s, 8);        /* signature */                                  licence_process(s);
609                          sec_decrypt(s->p, s->end - s->p);                                  continue;
610                            }
611    
612                            if (sec_flags & SEC_ENCRYPT)
613                            {
614                                    in_uint8s(s, 8);        /* signature */
615                                    sec_decrypt(s->p, s->end - s->p);
616                            }
617                  }                  }
618    
619                  return s;                  return s;
# Line 572  STREAM sec_recv() Line 623  STREAM sec_recv()
623  }  }
624    
625  /* Establish a secure connection */  /* Establish a secure connection */
626  BOOL sec_connect(char *server)  BOOL
627    sec_connect(char *server)
628  {  {
629          struct stream mcs_data;          struct stream mcs_data;
630    
# Line 585  BOOL sec_connect(char *server) Line 637  BOOL sec_connect(char *server)
637                  return False;                  return False;
638    
639          sec_process_mcs_data(&mcs_data);          sec_process_mcs_data(&mcs_data);
640          sec_establish_key();          if (encryption)
641                    sec_establish_key();
642            xfree(mcs_data.data);
643          return True;          return True;
644  }  }
645    
646  /* Disconnect a connection */  /* Disconnect a connection */
647  void sec_disconnect()  void
648    sec_disconnect(void)
649  {  {
650          mcs_disconnect();          mcs_disconnect();
651  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26