19 |
*/ |
*/ |
20 |
|
|
21 |
#include "rdesktop.h" |
#include "rdesktop.h" |
|
|
|
|
#ifdef WITH_OPENSSL |
|
22 |
#include <openssl/rc4.h> |
#include <openssl/rc4.h> |
|
#else |
|
|
#include "crypto/rc4.h" |
|
|
#endif |
|
23 |
|
|
24 |
extern char username[16]; |
extern char g_username[16]; |
25 |
extern char hostname[16]; |
extern char g_hostname[16]; |
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; |
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((char *) (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 */ |
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); |
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); |
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 |
/* Generate a signature for the HWID buffer */ |
/* Generate a signature for the HWID buffer */ |
160 |
licence_generate_hwid(hwid); |
licence_generate_hwid(hwid); |
161 |
sec_sign(signature, 16, licence_sign_key, 16, hwid, sizeof(hwid)); |
sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid)); |
162 |
|
|
163 |
/* Now encrypt the HWID */ |
/* Now encrypt the HWID */ |
164 |
RC4_set_key(&crypt_key, 16, licence_key); |
RC4_set_key(&crypt_key, 16, g_licence_key); |
165 |
RC4(&crypt_key, sizeof(hwid), hwid, hwid); |
RC4(&crypt_key, sizeof(hwid), hwid, hwid); |
166 |
|
|
167 |
licence_present(null_data, null_data, licence_data, licence_size, hwid, signature); |
licence_present(null_data, null_data, licence_data, licence_size, hwid, signature); |
169 |
return; |
return; |
170 |
} |
} |
171 |
|
|
172 |
licence_send_request(null_data, null_data, username, hostname); |
licence_send_request(null_data, null_data, g_username, g_hostname); |
173 |
} |
} |
174 |
|
|
175 |
/* Send an authentication response packet */ |
/* Send an authentication response packet */ |
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); |
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); |
RC4_set_key(&crypt_key, 16, g_licence_key); |
241 |
RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token); |
RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token); |
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, 16, licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer)); |
sec_sign(out_sig, 16, g_licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer)); |
248 |
|
|
249 |
/* Now encrypt the HWID */ |
/* Now encrypt the HWID */ |
250 |
RC4_set_key(&crypt_key, 16, licence_key); |
RC4_set_key(&crypt_key, 16, g_licence_key); |
251 |
RC4(&crypt_key, LICENCE_HWID_SIZE, hwid, crypt_hwid); |
RC4(&crypt_key, LICENCE_HWID_SIZE, hwid, crypt_hwid); |
252 |
|
|
253 |
licence_send_authresp(out_token, crypt_hwid, out_sig); |
licence_send_authresp(out_token, crypt_hwid, out_sig); |
260 |
RC4_KEY crypt_key; |
RC4_KEY 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); |
RC4_set_key(&crypt_key, 16, g_licence_key); |
271 |
RC4(&crypt_key, length, s->p, s->p); |
RC4(&crypt_key, length, s->p, s->p); |
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 */ |