/[rdesktop]/jpeg/rdesktop/trunk/licence.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 /jpeg/rdesktop/trunk/licence.c

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

revision 39 by matthewc, Fri Apr 5 07:57:43 2002 UTC revision 1475 by jsorg71, Fri Jul 11 03:51:23 2008 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     RDP licensing negotiation     RDP licensing negotiation
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2008
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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #include "rdesktop.h"  #include "rdesktop.h"
22  #include "crypto/rc4.h"  #include "ssl.h"
23    
24  extern char username[16];  extern char g_username[64];
25  extern char hostname[16];  extern char g_hostname[16];
 extern BOOL licence;  
26    
27  static uint8 licence_key[16];  static uint8 g_licence_key[16];
28  static uint8 licence_sign_key[16];  static uint8 g_licence_sign_key[16];
29    
30  BOOL licence_issued = False;  RD_BOOL g_licence_issued = False;
31    
32  /* Generate a session key and RC4 keys, given client and server randoms */  /* Generate a session key and RC4 keys, given client and server randoms */
33  static void  static void
34  licence_generate_keys(uint8 *client_key, uint8 *server_key, uint8 *client_rsa)  licence_generate_keys(uint8 * client_random, uint8 * server_random, uint8 * pre_master_secret)
35  {  {
36          uint8 session_key[48];          uint8 master_secret[48];
37          uint8 temp_hash[48];          uint8 key_block[48];
38    
39          /* Generate session key - two rounds of sec_hash_48 */          /* Generate master secret and then key material */
40          sec_hash_48(temp_hash, client_rsa, client_key, server_key, 65);          sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
41          sec_hash_48(session_key, temp_hash, server_key, client_key, 65);          sec_hash_48(key_block, master_secret, server_random, client_random, 'A');
42    
43          /* Store first 16 bytes of session key, for generating signatures */          /* Store first 16 bytes of session key as MAC secret */
44          memcpy(licence_sign_key, session_key, 16);          memcpy(g_licence_sign_key, key_block, 16);
45    
46          /* Generate RC4 key */          /* Generate RC4 key from next 16 bytes */
47          sec_hash_16(licence_key, &session_key[16], client_key, server_key);          sec_hash_16(g_licence_key, &key_block[16], client_random, server_random);
48  }  }
49    
50  static void  static void
51  licence_generate_hwid(uint8 *hwid)  licence_generate_hwid(uint8 * hwid)
52  {  {
53          buf_out_uint32(hwid, 2);          buf_out_uint32(hwid, 2);
54          strncpy(hwid + 4, hostname, LICENCE_HWID_SIZE - 4);          strncpy((char *) (hwid + 4), g_hostname, LICENCE_HWID_SIZE - 4);
55  }  }
56    
57  /* Present an existing licence to the server */  /* Present an existing licence to the server */
58  static void  static void
59  licence_present(uint8 *client_random, uint8 *rsa_data,  licence_present(uint8 * client_random, uint8 * rsa_data,
60                  uint8 *licence_data, int licence_size,                  uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
                 uint8 *hwid, uint8 *signature)  
61  {  {
62          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
63          uint16 length = 16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE          uint16 length =
64                          + licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;                  16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
65                    licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
66          STREAM s;          STREAM s;
67    
68          s = sec_init(sec_flags, length + 4);          s = sec_init(sec_flags, length + 4);
69    
70          out_uint16_le(s, LICENCE_TAG_PRESENT);          out_uint8(s, LICENCE_TAG_PRESENT);
71            out_uint8(s, 2);        /* version */
72          out_uint16_le(s, length);          out_uint16_le(s, length);
73    
74          out_uint32_le(s, 1);          out_uint32_le(s, 1);
# Line 97  licence_present(uint8 *client_random, ui Line 97  licence_present(uint8 *client_random, ui
97    
98  /* Send a licence request packet */  /* Send a licence request packet */
99  static void  static void
100  licence_send_request(uint8 *client_random, uint8 *rsa_data,  licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
                      char *user, char *host)  
101  {  {
102          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
103          uint16 userlen = strlen(user) + 1;          uint16 userlen = strlen(user) + 1;
104          uint16 hostlen = strlen(host) + 1;          uint16 hostlen = strlen(host) + 1;
105          uint16 length = 120 + userlen + hostlen;          uint16 length = 128 + userlen + hostlen;
106          STREAM s;          STREAM s;
107    
108          s = sec_init(sec_flags, length + 2);          s = sec_init(sec_flags, length + 2);
109    
110          out_uint16_le(s, LICENCE_TAG_REQUEST);          out_uint8(s, LICENCE_TAG_REQUEST);
111            out_uint8(s, 2);        /* version */
112          out_uint16_le(s, length);          out_uint16_le(s, length);
113    
114          out_uint32_le(s, 1);          out_uint32_le(s, 1);
# Line 121  licence_send_request(uint8 *client_rando Line 121  licence_send_request(uint8 *client_rando
121          out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);          out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
122          out_uint8s(s, SEC_PADDING_SIZE);          out_uint8s(s, SEC_PADDING_SIZE);
123    
124          out_uint16(s, LICENCE_TAG_USER);          out_uint16_le(s, LICENCE_TAG_USER);
125          out_uint16(s, userlen);          out_uint16_le(s, userlen);
126          out_uint8p(s, user, userlen);          out_uint8p(s, user, userlen);
127    
128          out_uint16(s, LICENCE_TAG_HOST);          out_uint16_le(s, LICENCE_TAG_HOST);
129          out_uint16(s, hostlen);          out_uint16_le(s, hostlen);
130          out_uint8p(s, host, hostlen);          out_uint8p(s, host, hostlen);
131    
132          s_mark_end(s);          s_mark_end(s);
# Line 138  static void Line 138  static void
138  licence_process_demand(STREAM s)  licence_process_demand(STREAM s)
139  {  {
140          uint8 null_data[SEC_MODULUS_SIZE];          uint8 null_data[SEC_MODULUS_SIZE];
         uint8 hwid[LICENCE_HWID_SIZE];  
         uint8 signature[LICENCE_SIGNATURE_SIZE];  
141          uint8 *server_random;          uint8 *server_random;
142            uint8 signature[LICENCE_SIGNATURE_SIZE];
143            uint8 hwid[LICENCE_HWID_SIZE];
144          uint8 *licence_data;          uint8 *licence_data;
145          int licence_size;          int licence_size;
146          RC4_KEY crypt_key;          SSL_RC4 crypt_key;
147    
148          /* Retrieve the server random from the incoming packet */          /* Retrieve the server random from the incoming packet */
149          in_uint8p(s, server_random, SEC_RANDOM_SIZE);          in_uint8p(s, server_random, SEC_RANDOM_SIZE);
# Line 154  licence_process_demand(STREAM s) Line 154  licence_process_demand(STREAM s)
154          licence_generate_keys(null_data, server_random, null_data);          licence_generate_keys(null_data, server_random, null_data);
155    
156          licence_size = load_licence(&licence_data);          licence_size = load_licence(&licence_data);
157          if (licence_size == -1)          if (licence_size > 0)
158          {          {
159                  licence_send_request(null_data, null_data, username, hostname);                  /* Generate a signature for the HWID buffer */
160                    licence_generate_hwid(hwid);
161                    sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid));
162    
163                    /* Now encrypt the HWID */
164                    ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
165                    ssl_rc4_crypt(&crypt_key, hwid, hwid, sizeof(hwid));
166    
167                    licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
168                    xfree(licence_data);
169                  return;                  return;
170          }          }
171    
172          /* Generate a signature for the HWID buffer */          licence_send_request(null_data, null_data, g_username, g_hostname);
         licence_generate_hwid(hwid);  
         sec_sign(signature, licence_sign_key, 16, hwid, sizeof(hwid));  
   
         /* Now encrypt the HWID */  
         RC4_set_key(&crypt_key, 16, licence_key);  
         RC4(&crypt_key, sizeof(hwid), hwid, hwid);  
   
         licence_present(null_data, null_data, licence_data, licence_size,  
                                         hwid, signature);  
         xfree(licence_data);  
173  }  }
174    
175  /* Send an authentication response packet */  /* Send an authentication response packet */
176  static void  static void
177  licence_send_authresp(uint8 *token, uint8 *crypt_hwid, uint8 *signature)  licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
178  {  {
179          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
180          uint16 length = 58;          uint16 length = 58;
# Line 183  licence_send_authresp(uint8 *token, uint Line 182  licence_send_authresp(uint8 *token, uint
182    
183          s = sec_init(sec_flags, length + 2);          s = sec_init(sec_flags, length + 2);
184    
185          out_uint16_le(s, LICENCE_TAG_AUTHRESP);          out_uint8(s, LICENCE_TAG_AUTHRESP);
186            out_uint8(s, 2);        /* version */
187          out_uint16_le(s, length);          out_uint16_le(s, length);
188    
189          out_uint16_le(s, 1);          out_uint16_le(s, 1);
# Line 201  licence_send_authresp(uint8 *token, uint Line 201  licence_send_authresp(uint8 *token, uint
201  }  }
202    
203  /* Parse an authentication request packet */  /* Parse an authentication request packet */
204  static BOOL  static RD_BOOL
205  licence_parse_authreq(STREAM s, uint8 **token, uint8 **signature)  licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
206  {  {
207          uint16 tokenlen;          uint16 tokenlen;
208    
# Line 225  licence_parse_authreq(STREAM s, uint8 ** Line 225  licence_parse_authreq(STREAM s, uint8 **
225  static void  static void
226  licence_process_authreq(STREAM s)  licence_process_authreq(STREAM s)
227  {  {
228          uint8 *in_token, *in_sig;          uint8 *in_token = NULL, *in_sig;
229          uint8 out_token[LICENCE_TOKEN_SIZE],          uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
                 decrypt_token[LICENCE_TOKEN_SIZE];  
230          uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE];          uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE];
231          uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];          uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];
232          uint8 out_sig[LICENCE_SIGNATURE_SIZE];          uint8 out_sig[LICENCE_SIGNATURE_SIZE];
233          RC4_KEY crypt_key;          SSL_RC4 crypt_key;
234    
235          /* Parse incoming packet and save the encrypted token */          /* Parse incoming packet and save the encrypted token */
236          licence_parse_authreq(s, &in_token, &in_sig);          licence_parse_authreq(s, &in_token, &in_sig);
237          memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);          memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);
238    
239          /* Decrypt the token. It should read TEST in Unicode. */          /* Decrypt the token. It should read TEST in Unicode. */
240          RC4_set_key(&crypt_key, 16, licence_key);          ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
241          RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);          ssl_rc4_crypt(&crypt_key, in_token, decrypt_token, LICENCE_TOKEN_SIZE);
242    
243          /* Generate a signature for a buffer of token and HWID */          /* Generate a signature for a buffer of token and HWID */
244          licence_generate_hwid(hwid);          licence_generate_hwid(hwid);
245          memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);          memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
246          memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);          memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
247          sec_sign(out_sig, licence_sign_key, 16,          sec_sign(out_sig, 16, g_licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer));
                  sealed_buffer, sizeof(sealed_buffer));  
   
         /* Deliberately break signature if licencing disabled */  
         if (!licence)  
                 memset(out_sig, 0, sizeof(out_sig));  
248    
249          /* Now encrypt the HWID */          /* Now encrypt the HWID */
250          RC4_set_key(&crypt_key, 16, licence_key);          ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
251          RC4(&crypt_key, LICENCE_HWID_SIZE, hwid, crypt_hwid);          ssl_rc4_crypt(&crypt_key, hwid, crypt_hwid, LICENCE_HWID_SIZE);
252    
253          licence_send_authresp(out_token, crypt_hwid, out_sig);          licence_send_authresp(out_token, crypt_hwid, out_sig);
254  }  }
# Line 263  licence_process_authreq(STREAM s) Line 257  licence_process_authreq(STREAM s)
257  static void  static void
258  licence_process_issue(STREAM s)  licence_process_issue(STREAM s)
259  {  {
260          RC4_KEY crypt_key;          SSL_RC4 crypt_key;
261          uint32 length;          uint32 length;
262          uint16 check;          uint16 check;
263            int i;
264    
265          in_uint8s(s, 2);        /* 3d 45 - unknown */          in_uint8s(s, 2);        /* 3d 45 - unknown */
266          in_uint16_le(s, length);          in_uint16_le(s, length);
267          if (!s_check_rem(s, length))          if (!s_check_rem(s, length))
268                  return;                  return;
269    
270          RC4_set_key(&crypt_key, 16, licence_key);          ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
271          RC4(&crypt_key, length, s->p, s->p);          ssl_rc4_crypt(&crypt_key, s->p, s->p, length);
272    
273          in_uint16(s, check);          in_uint16(s, check);
274          if (check != 0)          if (check != 0)
275                  return;                  return;
276    
277          licence_issued = True;          g_licence_issued = True;
278          save_licence(s->p, length-2);  
279            in_uint8s(s, 2);        /* pad */
280    
281            /* advance to fourth string */
282            length = 0;
283            for (i = 0; i < 4; i++)
284            {
285                    in_uint8s(s, length);
286                    in_uint32_le(s, length);
287                    if (!s_check_rem(s, length))
288                            return;
289            }
290    
291            g_licence_issued = True;
292            save_licence(s->p, length);
293  }  }
294    
295  /* Process a licence packet */  /* Process a licence packet */
296  void  void
297  licence_process(STREAM s)  licence_process(STREAM s)
298  {  {
299          uint16 tag;          uint8 tag;
300    
301          in_uint16_le(s, tag);          in_uint8(s, tag);
302          in_uint8s(s, 2);        /* length */          in_uint8s(s, 3);        /* version, length */
303    
304          switch (tag)          switch (tag)
305          {          {
# Line 307  licence_process(STREAM s) Line 316  licence_process(STREAM s)
316                          break;                          break;
317    
318                  case LICENCE_TAG_REISSUE:                  case LICENCE_TAG_REISSUE:
                         break;  
   
319                  case LICENCE_TAG_RESULT:                  case LICENCE_TAG_RESULT:
320                          break;                          break;
321    

Legend:
Removed from v.39  
changed lines
  Added in v.1475

  ViewVC Help
Powered by ViewVC 1.1.26