ReactOS  0.4.12-dev-43-g63b00d8
licence.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 8 -*-
2  rdesktop: A Remote Desktop Protocol client.
3  RDP licensing negotiation
4  Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5  Copyright (C) Thomas Uhle <thomas.uhle@mailbox.tu-dresden.de> 2011
6  Copyright (C) Henrik Andersson <henrik.andersson@cendio.com> 2014
7 
8 
9  This program is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #include "precomp.h"
24 
25 void *
27 void
28 rdssl_rc4_info_delete(void * rc4_info);
29 void
30 rdssl_rc4_set_key(void * rc4_info, char * key, int len);
31 void
32 rdssl_rc4_crypt(void * rc4_info, char * in_data, char * out_data, int len);
33 int
34 rdssl_mod_exp(char* out, int out_len, char* in, int in_len,
35  char* mod, int mod_len, char* exp, int exp_len);
36 
37 extern char g_username[256];
38 extern char g_hostname[256];
40 
41 static uint8 g_licence_key[16];
43 
46 
47 /* Generate a session key and RC4 keys, given client and server randoms */
48 static void
49 licence_generate_keys(uint8 * client_random, uint8 * server_random, uint8 * pre_master_secret)
50 {
51  uint8 master_secret[48];
52  uint8 key_block[48];
53 
54  /* Generate master secret and then key material */
55  sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
56  sec_hash_48(key_block, master_secret, server_random, client_random, 'A');
57 
58  /* Store first 16 bytes of session key as MAC secret */
59  memcpy(g_licence_sign_key, key_block, 16);
60 
61  /* Generate RC4 key from next 16 bytes */
62  sec_hash_16(g_licence_key, &key_block[16], client_random, server_random);
63 }
64 
65 static void
67 {
68  buf_out_uint32(hwid, 2);
69  strncpy((char *) (hwid + 4), g_hostname, LICENCE_HWID_SIZE - 4);
70 }
71 
72 /* Send a lincece info packet to server */
73 static void
74 licence_info(uint8 * client_random, uint8 * rsa_data,
75  uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
76 {
77  uint32 sec_flags = SEC_LICENSE_PKT;
78  uint16 length =
81  STREAM s;
82 
83  s = sec_init(sec_flags, length + 2);
84 
86  out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */
87  out_uint16_le(s, length);
88 
89  out_uint32_le(s, 1);
90  out_uint16(s, 0);
91  out_uint16_le(s, 0x0201);
92 
93  out_uint8p(s, client_random, SEC_RANDOM_SIZE);
94  out_uint16_le(s, 2);
96  out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
98 
99  out_uint16_le(s, 1);
100  out_uint16_le(s, licence_size);
101  out_uint8p(s, licence_data, licence_size);
102 
103  out_uint16_le(s, 1);
105  out_uint8p(s, hwid, LICENCE_HWID_SIZE);
106 
107  out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
108 
109  s_mark_end(s);
110  sec_send(s, sec_flags);
111 }
112 
113 /* Send a new licence request packet */
114 static void
115 licence_send_new_licence_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
116 {
117  uint32 sec_flags = SEC_LICENSE_PKT;
118  uint16 userlen = strlen(user) + 1;
119  uint16 hostlen = strlen(host) + 1;
120  uint16 length =
121  24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + userlen + hostlen;
122  STREAM s;
123 
124  s = sec_init(sec_flags, length + 2);
125 
127  out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */
128  out_uint16_le(s, length);
129 
130  out_uint32_le(s, 1); // KEY_EXCHANGE_ALG_RSA
131  out_uint16(s, 0);
132  out_uint16_le(s, 0xff01);
133 
134  out_uint8p(s, client_random, SEC_RANDOM_SIZE);
135  out_uint16_le(s, 2);
137  out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
139 
140  /* Username LICENSE_BINARY_BLOB */
142  out_uint16_le(s, userlen);
143  out_uint8p(s, user, userlen);
144 
145  /* Machinename LICENSE_BINARY_BLOB */
147  out_uint16_le(s, hostlen);
148  out_uint8p(s, host, hostlen);
149 
150  s_mark_end(s);
151  sec_send(s, sec_flags);
152 }
153 
154 /* Process a licence request packet */
155 static void
157 {
158  uint8 null_data[SEC_MODULUS_SIZE];
159  uint8 *server_random;
160  uint8 signature[LICENCE_SIGNATURE_SIZE];
161  uint8 hwid[LICENCE_HWID_SIZE];
162  uint8 *licence_data;
163  int licence_size;
164  void * crypt_key;
165 
166  /* Retrieve the server random from the incoming packet */
167  in_uint8p(s, server_random, SEC_RANDOM_SIZE);
168 
169  /* We currently use null client keys. This is a bit naughty but, hey,
170  the security of licence negotiation isn't exactly paramount. */
171  memset(null_data, 0, sizeof(null_data));
172  licence_generate_keys(null_data, server_random, null_data);
173 
174  licence_size = load_licence(&licence_data);
175  if (licence_size > 0)
176  {
177  /* Generate a signature for the HWID buffer */
178  licence_generate_hwid(hwid);
179  sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid));
180 
181  /* Now encrypt the HWID */
182  crypt_key = rdssl_rc4_info_create();
183  rdssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16);
184  rdssl_rc4_crypt(crypt_key, (char *)hwid, (char *)hwid, sizeof(hwid));
185  rdssl_rc4_info_delete(crypt_key);
186 
187 #if WITH_DEBUG
188  DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_LICENCE_INFO));
189 #endif
190  licence_info(null_data, null_data, licence_data, licence_size, hwid, signature);
191 
192  xfree(licence_data);
193  return;
194  }
195 
196 #if WITH_DEBUG
197  DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_NEW_LICENCE_REQUEST));
198 #endif
200 }
201 
202 /* Send a platform challenge response packet */
203 static void
205 {
206  uint32 sec_flags = SEC_LICENSE_PKT;
207  uint16 length = 58;
208  STREAM s;
209 
210  s = sec_init(sec_flags, length + 2);
211 
213  out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */
214  out_uint16_le(s, length);
215 
216  out_uint16_le(s, 1);
218  out_uint8p(s, token, LICENCE_TOKEN_SIZE);
219 
220  out_uint16_le(s, 1);
222  out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE);
223 
224  out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
225 
226  s_mark_end(s);
227  sec_send(s, sec_flags);
228 }
229 
230 /* Parse a platform challenge request packet */
231 static RD_BOOL
233 {
234  uint16 tokenlen;
235 
236  in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */
237 
238  in_uint16_le(s, tokenlen);
239  if (tokenlen != LICENCE_TOKEN_SIZE)
240  {
241  error("token len %d\n", tokenlen);
242  return False;
243  }
244 
245  in_uint8p(s, *token, tokenlen);
246  in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE);
247 
248  return s_check_end(s);
249 }
250 
251 /* Process a platform challenge packet */
252 static void
254 {
255  uint8 *in_token = NULL, *in_sig;
256  uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
257  uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE];
258  uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];
259  uint8 out_sig[LICENCE_SIGNATURE_SIZE];
260  void * crypt_key;
261 
262  /* Parse incoming packet and save the encrypted token */
263  licence_parse_platform_challenge(s, &in_token, &in_sig);
264  memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);
265 
266  /* Decrypt the token. It should read TEST in Unicode. */
267  crypt_key = rdssl_rc4_info_create();
268  rdssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16);
269  rdssl_rc4_crypt(crypt_key, (char *)in_token, (char *)decrypt_token, LICENCE_TOKEN_SIZE);
270  rdssl_rc4_info_delete(crypt_key);
271 
272  /* Generate a signature for a buffer of token and HWID */
273  licence_generate_hwid(hwid);
274  memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
275  memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
276  sec_sign(out_sig, 16, g_licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer));
277 
278  /* Now encrypt the HWID */
279  crypt_key = rdssl_rc4_info_create();
280  rdssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16);
281  rdssl_rc4_crypt(crypt_key, (char *)hwid, (char *)crypt_hwid, LICENCE_HWID_SIZE);
282 
283  licence_send_platform_challenge_response(out_token, crypt_hwid, out_sig);
284 }
285 
286 /* Process a new licence packet */
287 static void
289 {
290  void * crypt_key;
291  uint32 length;
292  int i;
293 
294  in_uint8s(s, 2); // Skip license binary blob type
295  in_uint16_le(s, length);
296  if (!s_check_rem(s, length))
297  return;
298 
299  crypt_key = rdssl_rc4_info_create();
300  rdssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16);
301  rdssl_rc4_crypt(crypt_key, (char *)s->p, (char *)s->p, length);
302  rdssl_rc4_info_delete(crypt_key);
303 
304  /* Parse NEW_LICENSE_INFO block */
305  in_uint8s(s, 4); // skip dwVersion
306 
307  /* Skip strings, Scope, CompanyName and ProductId to get
308  to the LicenseInfo which we store in license blob. */
309  length = 0;
310  for (i = 0; i < 4; i++)
311  {
312  in_uint8s(s, length);
313  in_uint32_le(s, length);
314  if (!s_check_rem(s, length))
315  return;
316  }
317 
319  save_licence(s->p, length);
320 }
321 
322 /* process a licence error alert packet */
323 void
325 {
327  uint32 state_transition;
328  uint32 error_info;
329  in_uint32(s, error_code);
330  in_uint32(s, state_transition);
331  in_uint32(s, error_info);
332 
333  /* There is a special case in the error alert handling, when licensing is all good
334  and the server is not sending a license to client, a "Server License Error PDU -
335  Valid Client" packet is sent which means, every thing is ok.
336 
337  Therefor we should flag that everything is ok with license here.
338  */
339  if (error_code == 0x07)
340  {
342  return;
343  }
344 
345  /* handle error codes, for now, just report them */
346  switch (error_code)
347  {
348  case 0x6: // ERR_NO_LICENSE_SERVER
349  warning("License error alert from server: No license server\n");
350  break;
351 
352  case 0x8: // ERR_INVALID_CLIENT
353  warning("License error alert from server: Invalid client\n");
354  break;
355 
356  case 0x4: // ERR_INVALID_SCOPE
357  case 0xb: // ERR_INVALID_PRODUCTID
358  case 0xc: // ERR_INVALID_MESSAGE_LENGTH
359  default:
360  warning("License error alert from server: code %u, state transition %u\n",
361  error_code, state_transition);
362  break;
363  }
364 
365  /* handle error codes, for now, just report them */
366  switch (error_info)
367  {
368  default:
369  break;
370  }
371 
373 }
374 
375 
376 /* Process a licence packet */
377 void
379 {
380  uint8 tag;
381 
382  in_uint8(s, tag);
383  in_uint8s(s, 3); /* version, length */
384 
385 #if WITH_DEBUG
386  DEBUG(("Received licensing PDU (message type 0x%02x)\n", tag));
387 #endif
388 
389  switch (tag)
390  {
391  case LICENCE_TAG_REQUEST:
393  break;
394 
397  break;
398 
401  /* we can handle new and upgrades of licences the same way. */
403  break;
404 
407  break;
408 
409  default:
410  unimpl("licence tag 0x%02x\n", tag);
411  }
412 }
#define out_uint16_le(s, v)
Definition: parse.h:58
void save_licence(unsigned char *data, int length)
#define out_uint8p(s, v, n)
Definition: parse.h:93
static void licence_process_new_license(STREAM s)
Definition: licence.c:288
#define error(str)
Definition: mkdosfs.c:1605
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt)
Definition: secure.c:155
unsigned int uint32
Definition: types.h:32
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
static uint8 g_licence_key[16]
Definition: licence.c:41
STREAM sec_init(uint32 flags, int maxlen)
Definition: secure.c:419
char * host
Definition: whois.c:55
#define LICENCE_TAG_NEW_LICENCE
Definition: constants.h:147
#define out_uint32_le(s, v)
Definition: parse.h:59
#define s_check_rem(s, n)
Definition: parse.h:43
#define out_uint16(s, v)
Definition: parse.h:84
RDP_VERSION g_rdp_version
Definition: uimain.c:74
void rdssl_rc4_crypt(void *rc4_info, char *in_data, char *out_data, int len)
Definition: ssl_calls.c:173
#define in_uint8p(s, v, n)
Definition: parse.h:89
#define LICENCE_SIGNATURE_SIZE
Definition: constants.h:143
void licence_process_error_alert(STREAM s)
Definition: licence.c:324
static void licence_generate_keys(uint8 *client_random, uint8 *server_random, uint8 *pre_master_secret)
Definition: licence.c:49
void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)
Definition: secure.c:187
void rdssl_rc4_set_key(void *rc4_info, char *key, int len)
Definition: ssl_calls.c:123
#define out_uint8(s, v)
Definition: parse.h:92
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define LICENCE_TOKEN_SIZE
Definition: constants.h:141
#define BB_CLIENT_MACHINE_NAME_BLOB
Definition: constants.h:155
static void licence_info(uint8 *client_random, uint8 *rsa_data, uint8 *licence_data, int licence_size, uint8 *hwid, uint8 *signature)
Definition: licence.c:74
static int error_code[8]
Definition: odbccp32.c:58
static RD_BOOL licence_parse_platform_challenge(STREAM s, uint8 **token, uint8 **signature)
Definition: licence.c:232
smooth NULL
Definition: ftsmooth.c:416
#define SEC_LICENSE_PKT
Definition: constants.h:105
#define in_uint8s(s, n)
Definition: parse.h:91
void buf_out_uint32(uint8 *buffer, uint32 value)
Definition: secure.c:304
int RD_BOOL
Definition: types.h:21
#define out_uint8s(s, n)
Definition: parse.h:95
int load_licence(unsigned char **data)
#define LICENCE_TAG_UPGRADE_LICENCE
Definition: constants.h:148
#define s_check_end(s)
Definition: parse.h:44
static void licence_send_platform_challenge_response(uint8 *token, uint8 *crypt_hwid, uint8 *signature)
Definition: licence.c:204
#define SEC_MODULUS_SIZE
Definition: constants.h:92
static void licence_send_new_licence_request(uint8 *client_random, uint8 *rsa_data, char *user, char *host)
Definition: licence.c:115
#define True
Definition: types.h:24
int token
Definition: lex.c:71
#define False
Definition: types.h:25
int rdssl_mod_exp(char *out, int out_len, char *in, int in_len, char *mod, int mod_len, char *exp, int exp_len)
Definition: ssl_calls.c:1485
void xfree(void *mem)
Definition: uimain.c:758
#define LICENCE_TAG_REQUEST
Definition: constants.h:145
Definition: types.h:44
void rdssl_rc4_info_delete(void *rc4_info)
Definition: ssl_calls.c:90
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define LICENCE_TAG_PLATFORM_CHALLANGE
Definition: constants.h:146
#define SEC_RANDOM_SIZE
Definition: constants.h:91
static FILE * out
Definition: regtests2xml.c:44
unsigned char uint8
Definition: types.h:28
static uint8 g_licence_sign_key[16]
Definition: licence.c:42
#define LICENCE_TAG_LICENCE_INFO
Definition: constants.h:149
#define in_uint32(s, v)
Definition: parse.h:83
#define BB_CLIENT_USER_NAME_BLOB
Definition: constants.h:154
#define LICENCE_TAG_PLATFORM_CHALLANGE_RESPONSE
Definition: constants.h:151
Definition: parse.h:22
#define SEC_PADDING_SIZE
Definition: constants.h:94
enum _RDP_VERSION RDP_VERSION
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
void sec_send(STREAM s, uint32 flags)
Definition: secure.c:472
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
static void licence_process_platform_challenge(STREAM s)
Definition: licence.c:253
unsigned short uint16
Definition: types.h:30
RD_BOOL g_licence_error_result
Definition: licence.c:45
#define in_uint8(s, v)
Definition: parse.h:88
void * rdssl_rc4_info_create(void)
Definition: ssl_calls.c:51
void sec_sign(uint8 *signature, int siglen, uint8 *session_key, int keylen, uint8 *data, int datalen)
Definition: secure.c:314
static void licence_process_request(STREAM s)
Definition: licence.c:156
unsigned char * p
Definition: parse.h:24
char g_hostname[256]
Definition: uimain.c:26
static void licence_generate_hwid(uint8 *hwid)
Definition: licence.c:66
DWORD exp
Definition: msg.c:15681
char g_username[256]
Definition: uimain.c:25
#define LICENCE_HWID_SIZE
Definition: constants.h:142
void unimpl(char *format,...)
Definition: uimain.c:801
#define LICENCE_TAG_NEW_LICENCE_REQUEST
Definition: constants.h:150
#define DEBUG(args)
Definition: rdesktop.h:129
#define s_mark_end(s)
Definition: parse.h:41
#define LICENCE_TAG_ERROR_ALERT
Definition: constants.h:152
#define in_uint32_le(s, v)
Definition: parse.h:56
#define memset(x, y, z)
Definition: compat.h:39
void user(int argc, const char *argv[])
Definition: cmds.c:1350
void licence_process(STREAM s)
Definition: licence.c:378
#define warning(s)
Definition: debug.h:71
#define in_uint16_le(s, v)
Definition: parse.h:55
Definition: path.c:42
static int mod
Definition: i386-dis.c:1273
char * tag
Definition: main.c:59
RD_BOOL g_licence_issued
Definition: licence.c:44