xref: /reactos/base/applications/mstsc/licence.c (revision 845faec4)
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 *
26 rdssl_rc4_info_create(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];
39 extern RDP_VERSION g_rdp_version;
40 
41 static uint8 g_licence_key[16];
42 static uint8 g_licence_sign_key[16];
43 
44 RD_BOOL g_licence_issued = False;
45 RD_BOOL g_licence_error_result = False;
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
66 licence_generate_hwid(uint8 * hwid)
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 =
79 		24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
80 		licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
81 	STREAM s;
82 
83 	s = sec_init(sec_flags, length + 2);
84 
85 	out_uint8(s, LICENCE_TAG_LICENCE_INFO);
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);
95 	out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
96 	out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
97 	out_uint8s(s, SEC_PADDING_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);
104 	out_uint16_le(s, LICENCE_HWID_SIZE);
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 
126 	out_uint8(s, LICENCE_TAG_NEW_LICENCE_REQUEST);
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);
136 	out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
137 	out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
138 	out_uint8s(s, SEC_PADDING_SIZE);
139 
140 	/* Username LICENSE_BINARY_BLOB */
141 	out_uint16_le(s, BB_CLIENT_USER_NAME_BLOB);
142 	out_uint16_le(s, userlen);
143 	out_uint8p(s, user, userlen);
144 
145 	/* Machinename LICENSE_BINARY_BLOB */
146 	out_uint16_le(s, BB_CLIENT_MACHINE_NAME_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
156 licence_process_request(STREAM s)
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
199 	licence_send_new_licence_request(null_data, null_data, g_username, g_hostname);
200 }
201 
202 /* Send a platform challenge response packet */
203 static void
204 licence_send_platform_challenge_response(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
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 
212 	out_uint8(s, LICENCE_TAG_PLATFORM_CHALLANGE_RESPONSE);
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);
217 	out_uint16_le(s, LICENCE_TOKEN_SIZE);
218 	out_uint8p(s, token, LICENCE_TOKEN_SIZE);
219 
220 	out_uint16_le(s, 1);
221 	out_uint16_le(s, LICENCE_HWID_SIZE);
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
232 licence_parse_platform_challenge(STREAM s, uint8 ** token, uint8 ** signature)
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
253 licence_process_platform_challenge(STREAM s)
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
288 licence_process_new_license(STREAM s)
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 
318 	g_licence_issued = True;
319 	save_licence(s->p, length);
320 }
321 
322 /* process a licence error alert packet */
323 void
324 licence_process_error_alert(STREAM s)
325 {
326 	uint32 error_code;
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 	{
341 		g_licence_issued = True;
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 
372 	g_licence_error_result = True;
373 }
374 
375 
376 /* Process a licence packet */
377 void
378 licence_process(STREAM s)
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:
392 			licence_process_request(s);
393 			break;
394 
395 		case LICENCE_TAG_PLATFORM_CHALLANGE:
396 			licence_process_platform_challenge(s);
397 			break;
398 
399 		case LICENCE_TAG_NEW_LICENCE:
400 		case LICENCE_TAG_UPGRADE_LICENCE:
401 			/* we can handle new and upgrades of licences the same way. */
402 			licence_process_new_license(s);
403 			break;
404 
405 		case LICENCE_TAG_ERROR_ALERT:
406 			licence_process_error_alert(s);
407 			break;
408 
409 		default:
410 			unimpl("licence tag 0x%02x\n", tag);
411 	}
412 }
413