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

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

  ViewVC Help
Powered by ViewVC 1.1.26