VirtualBox

source: vbox/trunk/src/VBox/RDP/client-1.8.4/secure.c@ 78293

Last change on this file since 78293 was 76779, checked in by vboxsync, 6 years ago

RDP: add client-1.8.4.
bugref:9356: Update rdesktop-vrdp to 1.8.4
client-1.8.4 is a Subversion copy of 1.8.3 with the upstream 1.8.3 to 1.8.4
patch applied and a couple of fixes and changes after review, namely:

  • Stopped disabling the new pointer data format for our build, as this is no

longer needed.

  • Adjusted some snprintf buffers to make GCC happy.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - RDP encryption and licensing
4 Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5 Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21/*
22 * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
24 * the General Public License version 2 (GPLv2) at this time for any software where
25 * a choice of GPL license versions is made available with the language indicating
26 * that GPLv2 or any later version may be used, or where a choice of which version
27 * of the GPL is applied is otherwise unspecified.
28 */
29
30#include "rdesktop.h"
31#include "ssl.h"
32
33extern char g_hostname[16];
34extern int g_width;
35extern int g_height;
36extern unsigned int g_keylayout;
37extern int g_keyboard_type;
38extern int g_keyboard_subtype;
39extern int g_keyboard_functionkeys;
40extern RD_BOOL g_encryption;
41extern RD_BOOL g_licence_issued;
42extern RD_BOOL g_licence_error_result;
43extern RDP_VERSION g_rdp_version;
44extern RD_BOOL g_console_session;
45extern uint32 g_redirect_session_id;
46extern int g_server_depth;
47extern VCHANNEL g_channels[];
48extern unsigned int g_num_channels;
49extern uint8 g_client_random[SEC_RANDOM_SIZE];
50
51static int g_rc4_key_len;
52static RDSSL_RC4 g_rc4_decrypt_key;
53static RDSSL_RC4 g_rc4_encrypt_key;
54static uint32 g_server_public_key_len;
55
56static uint8 g_sec_sign_key[16];
57static uint8 g_sec_decrypt_key[16];
58static uint8 g_sec_encrypt_key[16];
59static uint8 g_sec_decrypt_update_key[16];
60static uint8 g_sec_encrypt_update_key[16];
61static uint8 g_sec_crypted_random[SEC_MAX_MODULUS_SIZE];
62
63uint16 g_server_rdp_version = 0;
64
65/* These values must be available to reset state - Session Directory */
66static int g_sec_encrypt_use_count = 0;
67static int g_sec_decrypt_use_count = 0;
68
69/*
70 * I believe this is based on SSLv3 with the following differences:
71 * MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
72 * MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
73 * key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
74 * key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
75 * encryption/decryption keys updated every 4096 packets
76 * See http://wp.netscape.com/eng/ssl3/draft302.txt
77 */
78
79/*
80 * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
81 * Both SHA1 and MD5 algorithms are used.
82 */
83void
84sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
85{
86 uint8 shasig[20];
87 uint8 pad[4];
88 RDSSL_SHA1 sha1;
89 RDSSL_MD5 md5;
90 int i;
91
92 for (i = 0; i < 3; i++)
93 {
94 memset(pad, salt + i, i + 1);
95
96 rdssl_sha1_init(&sha1);
97 rdssl_sha1_update(&sha1, pad, i + 1);
98 rdssl_sha1_update(&sha1, in, 48);
99 rdssl_sha1_update(&sha1, salt1, 32);
100 rdssl_sha1_update(&sha1, salt2, 32);
101 rdssl_sha1_final(&sha1, shasig);
102
103 rdssl_md5_init(&md5);
104 rdssl_md5_update(&md5, in, 48);
105 rdssl_md5_update(&md5, shasig, 20);
106 rdssl_md5_final(&md5, &out[i * 16]);
107 }
108}
109
110/*
111 * 16-byte transformation used to generate export keys (6.2.2).
112 */
113void
114sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
115{
116 RDSSL_MD5 md5;
117
118 rdssl_md5_init(&md5);
119 rdssl_md5_update(&md5, in, 16);
120 rdssl_md5_update(&md5, salt1, 32);
121 rdssl_md5_update(&md5, salt2, 32);
122 rdssl_md5_final(&md5, out);
123}
124
125/*
126 * 16-byte sha1 hash
127 */
128void
129sec_hash_sha1_16(uint8 * out, uint8 * in, uint8 * salt1)
130{
131 RDSSL_SHA1 sha1;
132 rdssl_sha1_init(&sha1);
133 rdssl_sha1_update(&sha1, in, 16);
134 rdssl_sha1_update(&sha1, salt1, 16);
135 rdssl_sha1_final(&sha1, out);
136}
137
138/* create string from hash */
139void
140sec_hash_to_string(char *out, int out_size, uint8 * in, int in_size)
141{
142 int k;
143 memset(out, 0, out_size);
144 for (k = 0; k < in_size; k++, out += 2)
145 {
146 sprintf(out, "%.2x", in[k]);
147 }
148}
149
150/* Reduce key entropy from 64 to 40 bits */
151static void
152sec_make_40bit(uint8 * key)
153{
154 key[0] = 0xd1;
155 key[1] = 0x26;
156 key[2] = 0x9e;
157}
158
159/* Generate encryption keys given client and server randoms */
160static void
161sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
162{
163 uint8 pre_master_secret[48];
164 uint8 master_secret[48];
165 uint8 key_block[48];
166
167 /* Construct pre-master secret */
168 memcpy(pre_master_secret, client_random, 24);
169 memcpy(pre_master_secret + 24, server_random, 24);
170
171 /* Generate master secret and then key material */
172 sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
173 sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
174
175 /* First 16 bytes of key material is MAC secret */
176 memcpy(g_sec_sign_key, key_block, 16);
177
178 /* Generate export keys from next two blocks of 16 bytes */
179 sec_hash_16(g_sec_decrypt_key, &key_block[16], client_random, server_random);
180 sec_hash_16(g_sec_encrypt_key, &key_block[32], client_random, server_random);
181
182 if (rc4_key_size == 1)
183 {
184 DEBUG(("40-bit encryption enabled\n"));
185 sec_make_40bit(g_sec_sign_key);
186 sec_make_40bit(g_sec_decrypt_key);
187 sec_make_40bit(g_sec_encrypt_key);
188 g_rc4_key_len = 8;
189 }
190 else
191 {
192 DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
193 g_rc4_key_len = 16;
194 }
195
196 /* Save initial RC4 keys as update keys */
197 memcpy(g_sec_decrypt_update_key, g_sec_decrypt_key, 16);
198 memcpy(g_sec_encrypt_update_key, g_sec_encrypt_key, 16);
199
200 /* Initialise RC4 state arrays */
201 rdssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
202 rdssl_rc4_set_key(&g_rc4_encrypt_key, g_sec_encrypt_key, g_rc4_key_len);
203}
204
205static uint8 pad_54[40] = {
206 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
207 54, 54, 54,
208 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
209 54, 54, 54
210};
211
212static uint8 pad_92[48] = {
213 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
214 92, 92, 92, 92, 92, 92, 92,
215 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
216 92, 92, 92, 92, 92, 92, 92
217};
218
219/* Output a uint32 into a buffer (little-endian) */
220void
221buf_out_uint32(uint8 * buffer, uint32 value)
222{
223 buffer[0] = (value) & 0xff;
224 buffer[1] = (value >> 8) & 0xff;
225 buffer[2] = (value >> 16) & 0xff;
226 buffer[3] = (value >> 24) & 0xff;
227}
228
229/* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
230void
231sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
232{
233 uint8 shasig[20];
234 uint8 md5sig[16];
235 uint8 lenhdr[4];
236 RDSSL_SHA1 sha1;
237 RDSSL_MD5 md5;
238
239 buf_out_uint32(lenhdr, datalen);
240
241 rdssl_sha1_init(&sha1);
242 rdssl_sha1_update(&sha1, session_key, keylen);
243 rdssl_sha1_update(&sha1, pad_54, 40);
244 rdssl_sha1_update(&sha1, lenhdr, 4);
245 rdssl_sha1_update(&sha1, data, datalen);
246 rdssl_sha1_final(&sha1, shasig);
247
248 rdssl_md5_init(&md5);
249 rdssl_md5_update(&md5, session_key, keylen);
250 rdssl_md5_update(&md5, pad_92, 48);
251 rdssl_md5_update(&md5, shasig, 20);
252 rdssl_md5_final(&md5, md5sig);
253
254 memcpy(signature, md5sig, siglen);
255}
256
257/* Update an encryption key */
258static void
259sec_update(uint8 * key, uint8 * update_key)
260{
261 uint8 shasig[20];
262 RDSSL_SHA1 sha1;
263 RDSSL_MD5 md5;
264 RDSSL_RC4 update;
265
266 rdssl_sha1_init(&sha1);
267 rdssl_sha1_update(&sha1, update_key, g_rc4_key_len);
268 rdssl_sha1_update(&sha1, pad_54, 40);
269 rdssl_sha1_update(&sha1, key, g_rc4_key_len);
270 rdssl_sha1_final(&sha1, shasig);
271
272 rdssl_md5_init(&md5);
273 rdssl_md5_update(&md5, update_key, g_rc4_key_len);
274 rdssl_md5_update(&md5, pad_92, 48);
275 rdssl_md5_update(&md5, shasig, 20);
276 rdssl_md5_final(&md5, key);
277
278 rdssl_rc4_set_key(&update, key, g_rc4_key_len);
279 rdssl_rc4_crypt(&update, key, key, g_rc4_key_len);
280
281 if (g_rc4_key_len == 8)
282 sec_make_40bit(key);
283}
284
285/* Encrypt data using RC4 */
286static void
287sec_encrypt(uint8 * data, int length)
288{
289 if (g_sec_encrypt_use_count == 4096)
290 {
291 sec_update(g_sec_encrypt_key, g_sec_encrypt_update_key);
292 rdssl_rc4_set_key(&g_rc4_encrypt_key, g_sec_encrypt_key, g_rc4_key_len);
293 g_sec_encrypt_use_count = 0;
294 }
295
296 rdssl_rc4_crypt(&g_rc4_encrypt_key, data, data, length);
297 g_sec_encrypt_use_count++;
298}
299
300/* Decrypt data using RC4 */
301void
302sec_decrypt(uint8 * data, int length)
303{
304 if (length <= 0)
305 return;
306
307 if (g_sec_decrypt_use_count == 4096)
308 {
309 sec_update(g_sec_decrypt_key, g_sec_decrypt_update_key);
310 rdssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
311 g_sec_decrypt_use_count = 0;
312 }
313
314 rdssl_rc4_crypt(&g_rc4_decrypt_key, data, data, length);
315 g_sec_decrypt_use_count++;
316}
317
318/* Perform an RSA public key encryption operation */
319static void
320sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
321 uint8 * exponent)
322{
323 rdssl_rsa_encrypt(out, in, len, modulus_size, modulus, exponent);
324}
325
326/* Initialise secure transport packet */
327STREAM
328sec_init(uint32 flags, int maxlen)
329{
330 int hdrlen;
331 STREAM s;
332
333 if (!g_licence_issued && !g_licence_error_result)
334 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
335 else
336 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
337 s = mcs_init(maxlen + hdrlen);
338 s_push_layer(s, sec_hdr, hdrlen);
339
340 return s;
341}
342
343/* Transmit secure transport packet over specified channel */
344void
345sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
346{
347 int datalen;
348
349#ifdef WITH_SCARD
350 scard_lock(SCARD_LOCK_SEC);
351#endif
352
353 s_pop_layer(s, sec_hdr);
354 if ((!g_licence_issued && !g_licence_error_result) || (flags & SEC_ENCRYPT))
355 out_uint32_le(s, flags);
356
357 if (flags & SEC_ENCRYPT)
358 {
359 flags &= ~SEC_ENCRYPT;
360 datalen = s->end - s->p - 8;
361
362#if WITH_DEBUG
363 DEBUG(("Sending encrypted packet:\n"));
364 hexdump(s->p + 8, datalen);
365#endif
366
367 sec_sign(s->p, 8, g_sec_sign_key, g_rc4_key_len, s->p + 8, datalen);
368 sec_encrypt(s->p + 8, datalen);
369 }
370
371 mcs_send_to_channel(s, channel);
372
373#ifdef WITH_SCARD
374 scard_unlock(SCARD_LOCK_SEC);
375#endif
376}
377
378/* Transmit secure transport packet */
379
380void
381sec_send(STREAM s, uint32 flags)
382{
383 sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
384}
385
386
387/* Transfer the client random to the server */
388static void
389sec_establish_key(void)
390{
391 uint32 length = g_server_public_key_len + SEC_PADDING_SIZE;
392 uint32 flags = SEC_CLIENT_RANDOM;
393 STREAM s;
394
395 s = sec_init(flags, length + 4);
396
397 out_uint32_le(s, length);
398 out_uint8p(s, g_sec_crypted_random, g_server_public_key_len);
399 out_uint8s(s, SEC_PADDING_SIZE);
400
401 s_mark_end(s);
402 sec_send(s, flags);
403}
404
405/* Output connect initial data blob */
406static void
407sec_out_mcs_data(STREAM s, uint32 selected_protocol)
408{
409 int hostlen = 2 * strlen(g_hostname);
410 int length = 162 + 76 + 12 + 4;
411 unsigned int i;
412
413 if (g_num_channels > 0)
414 length += g_num_channels * 12 + 8;
415
416 if (hostlen > 30)
417 hostlen = 30;
418
419 /* Generic Conference Control (T.124) ConferenceCreateRequest */
420 out_uint16_be(s, 5);
421 out_uint16_be(s, 0x14);
422 out_uint8(s, 0x7c);
423 out_uint16_be(s, 1);
424
425 out_uint16_be(s, (length | 0x8000)); /* remaining length */
426
427 out_uint16_be(s, 8); /* length? */
428 out_uint16_be(s, 16);
429 out_uint8(s, 0);
430 out_uint16_le(s, 0xc001);
431 out_uint8(s, 0);
432
433 out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
434 out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
435
436 /* Client information */
437 out_uint16_le(s, SEC_TAG_CLI_INFO);
438 out_uint16_le(s, 216); /* length */
439 out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 4 : 1); /* RDP version. 1 == RDP4, 4 >= RDP5 to RDP8 */
440 out_uint16_le(s, 8);
441 out_uint16_le(s, g_width);
442 out_uint16_le(s, g_height);
443 out_uint16_le(s, 0xca01);
444 out_uint16_le(s, 0xaa03);
445 out_uint32_le(s, g_keylayout);
446 out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
447
448 /* Unicode name of client, padded to 32 bytes */
449 rdp_out_unistr(s, g_hostname, hostlen);
450 out_uint8s(s, 30 - hostlen);
451
452 /* See
453 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
454 out_uint32_le(s, g_keyboard_type);
455 out_uint32_le(s, g_keyboard_subtype);
456 out_uint32_le(s, g_keyboard_functionkeys);
457 out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
458 out_uint16_le(s, 0xca01); /* colour depth? */
459 out_uint16_le(s, 1);
460
461 out_uint32(s, 0);
462 out_uint8(s, g_server_depth);
463 out_uint16_le(s, 0x0700);
464 out_uint8(s, 0);
465 out_uint32_le(s, 1);
466 out_uint8s(s, 64);
467 out_uint32_le(s, selected_protocol); /* End of client info */
468
469 /* Write a Client Cluster Data (TS_UD_CS_CLUSTER) */
470 uint32 cluster_flags = 0;
471 out_uint16_le(s, SEC_TAG_CLI_CLUSTER); /* header.type */
472 out_uint16_le(s, 12); /* length */
473
474 cluster_flags |= SEC_CC_REDIRECTION_SUPPORTED;
475 cluster_flags |= (SEC_CC_REDIRECT_VERSION_3 << 2);
476
477 if (g_console_session || g_redirect_session_id != 0)
478 cluster_flags |= SEC_CC_REDIRECT_SESSIONID_FIELD_VALID;
479
480 out_uint32_le(s, cluster_flags);
481 out_uint32(s, g_redirect_session_id);
482
483 /* Client encryption settings */
484 out_uint16_le(s, SEC_TAG_CLI_CRYPT);
485 out_uint16_le(s, 12); /* length */
486 out_uint32_le(s, g_encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
487 out_uint32(s, 0); /* Unknown */
488
489 DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
490 if (g_num_channels > 0)
491 {
492 out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
493 out_uint16_le(s, g_num_channels * 12 + 8); /* length */
494 out_uint32_le(s, g_num_channels); /* number of virtual channels */
495 for (i = 0; i < g_num_channels; i++)
496 {
497 DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
498 out_uint8a(s, g_channels[i].name, 8);
499 out_uint32_be(s, g_channels[i].flags);
500 }
501 }
502
503 s_mark_end(s);
504}
505
506/* Parse a public key structure */
507static RD_BOOL
508sec_parse_public_key(STREAM s, uint8 * modulus, uint8 * exponent)
509{
510 uint32 magic, modulus_len;
511
512 in_uint32_le(s, magic);
513 if (magic != SEC_RSA_MAGIC)
514 {
515 error("RSA magic 0x%x\n", magic);
516 return False;
517 }
518
519 in_uint32_le(s, modulus_len);
520 modulus_len -= SEC_PADDING_SIZE;
521 if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE))
522 {
523 error("Bad server public key size (%u bits)\n", modulus_len * 8);
524 return False;
525 }
526
527 in_uint8s(s, 8); /* modulus_bits, unknown */
528 in_uint8a(s, exponent, SEC_EXPONENT_SIZE);
529 in_uint8a(s, modulus, modulus_len);
530 in_uint8s(s, SEC_PADDING_SIZE);
531 g_server_public_key_len = modulus_len;
532
533 return s_check(s);
534}
535
536/* Parse a public signature structure */
537static RD_BOOL
538sec_parse_public_sig(STREAM s, uint32 len, uint8 * modulus, uint8 * exponent)
539{
540 uint8 signature[SEC_MAX_MODULUS_SIZE];
541 uint32 sig_len;
542
543 if (len != 72)
544 {
545 return True;
546 }
547 memset(signature, 0, sizeof(signature));
548 sig_len = len - 8;
549 in_uint8a(s, signature, sig_len);
550 return rdssl_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, g_server_public_key_len,
551 signature, sig_len);
552}
553
554/* Parse a crypto information structure */
555static RD_BOOL
556sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
557 uint8 ** server_random, uint8 * modulus, uint8 * exponent)
558{
559 uint32 crypt_level, random_len, rsa_info_len;
560 uint32 cacert_len, cert_len, flags;
561 RDSSL_CERT *cacert, *server_cert;
562 RDSSL_RKEY *server_public_key;
563 uint16 tag, length;
564 uint8 *next_tag, *end;
565 struct stream packet = *s;
566
567 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
568 in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
569 if (crypt_level == 0)
570 {
571 /* no encryption */
572 return False;
573 }
574
575 in_uint32_le(s, random_len);
576 in_uint32_le(s, rsa_info_len);
577
578 if (random_len != SEC_RANDOM_SIZE)
579 {
580 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
581 return False;
582 }
583
584 in_uint8p(s, *server_random, random_len);
585
586 /* RSA info */
587 end = s->p + rsa_info_len;
588 if (end > s->end)
589 return False;
590
591 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
592 if (flags & 1)
593 {
594 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
595 in_uint8s(s, 8); /* unknown */
596
597 while (s->p < end)
598 {
599 in_uint16_le(s, tag);
600 in_uint16_le(s, length);
601
602 next_tag = s->p + length;
603
604 switch (tag)
605 {
606 case SEC_TAG_PUBKEY:
607 if (!sec_parse_public_key(s, modulus, exponent))
608 return False;
609 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
610
611 break;
612
613 case SEC_TAG_KEYSIG:
614 if (!sec_parse_public_sig(s, length, modulus, exponent))
615 return False;
616 break;
617
618 default:
619 unimpl("crypt tag 0x%x\n", tag);
620 }
621
622 s->p = next_tag;
623 }
624 }
625 else
626 {
627 uint32 certcount;
628
629 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
630 in_uint32_le(s, certcount); /* Number of certificates */
631 if (certcount < 2)
632 {
633 error("Server didn't send enough X509 certificates\n");
634 return False;
635 }
636 for (; certcount > 2; certcount--)
637 { /* ignore all the certificates between the root and the signing CA */
638 uint32 ignorelen;
639 RDSSL_CERT *ignorecert;
640
641 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
642 in_uint32_le(s, ignorelen);
643 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
644
645 if (!s_check_rem(s, ignorelen))
646 {
647 rdp_protocol_error("sec_parse_crypt_info(), consume ignored certificate from stream would overrun",
648 &packet);
649 }
650
651 ignorecert = rdssl_cert_read(s->p, ignorelen);
652 in_uint8s(s, ignorelen);
653 if (ignorecert == NULL)
654 { /* XXX: error out? */
655 DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
656 }
657
658#ifdef WITH_DEBUG_RDP5
659 DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
660 rdssl_cert_print_fp(stdout, ignorecert);
661#endif
662 }
663 /* Do da funky X.509 stuffy
664
665 "How did I find out about this? I looked up and saw a
666 bright light and when I came to I had a scar on my forehead
667 and knew about X.500"
668 - Peter Gutman in a early version of
669 http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
670 */
671 in_uint32_le(s, cacert_len);
672 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
673 cacert = rdssl_cert_read(s->p, cacert_len);
674 in_uint8s(s, cacert_len);
675 if (NULL == cacert)
676 {
677 error("Couldn't load CA Certificate from server\n");
678 return False;
679 }
680 in_uint32_le(s, cert_len);
681 DEBUG_RDP5(("Certificate length is %d\n", cert_len));
682 server_cert = rdssl_cert_read(s->p, cert_len);
683 in_uint8s(s, cert_len);
684 if (NULL == server_cert)
685 {
686 rdssl_cert_free(cacert);
687 error("Couldn't load Certificate from server\n");
688 return False;
689 }
690 if (!rdssl_certs_ok(server_cert, cacert))
691 {
692 rdssl_cert_free(server_cert);
693 rdssl_cert_free(cacert);
694 error("Security error CA Certificate invalid\n");
695 return False;
696 }
697 rdssl_cert_free(cacert);
698 in_uint8s(s, 16); /* Padding */
699 server_public_key = rdssl_cert_to_rkey(server_cert, &g_server_public_key_len);
700 if (NULL == server_public_key)
701 {
702 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
703 rdssl_cert_free(server_cert);
704 return False;
705 }
706 rdssl_cert_free(server_cert);
707 if ((g_server_public_key_len < SEC_MODULUS_SIZE) ||
708 (g_server_public_key_len > SEC_MAX_MODULUS_SIZE))
709 {
710 error("Bad server public key size (%u bits)\n",
711 g_server_public_key_len * 8);
712 rdssl_rkey_free(server_public_key);
713 return False;
714 }
715 if (rdssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
716 modulus, SEC_MAX_MODULUS_SIZE) != 0)
717 {
718 error("Problem extracting RSA exponent, modulus");
719 rdssl_rkey_free(server_public_key);
720 return False;
721 }
722 rdssl_rkey_free(server_public_key);
723 return True; /* There's some garbage here we don't care about */
724 }
725 return s_check_end(s);
726}
727
728/* Process crypto information blob */
729static void
730sec_process_crypt_info(STREAM s)
731{
732 uint8 *server_random = NULL;
733 uint8 modulus[SEC_MAX_MODULUS_SIZE];
734 uint8 exponent[SEC_EXPONENT_SIZE];
735 uint32 rc4_key_size;
736
737 memset(modulus, 0, sizeof(modulus));
738 memset(exponent, 0, sizeof(exponent));
739 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, modulus, exponent))
740 {
741 DEBUG(("Failed to parse crypt info\n"));
742 return;
743 }
744 DEBUG(("Generating client random\n"));
745 generate_random(g_client_random);
746 sec_rsa_encrypt(g_sec_crypted_random, g_client_random, SEC_RANDOM_SIZE,
747 g_server_public_key_len, modulus, exponent);
748 sec_generate_keys(g_client_random, server_random, rc4_key_size);
749}
750
751
752/* Process SRV_INFO, find RDP version supported by server */
753static void
754sec_process_srv_info(STREAM s)
755{
756 in_uint16_le(s, g_server_rdp_version);
757 DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
758 if (1 == g_server_rdp_version)
759 {
760 g_rdp_version = RDP_V4;
761 g_server_depth = 8;
762 }
763}
764
765
766/* Process connect response data blob */
767void
768sec_process_mcs_data(STREAM s)
769{
770 uint16 tag, length;
771 uint8 *next_tag;
772 uint8 len;
773
774 in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */
775 in_uint8(s, len);
776 if (len & 0x80)
777 in_uint8(s, len);
778
779 while (s->p < s->end)
780 {
781 in_uint16_le(s, tag);
782 in_uint16_le(s, length);
783
784 if (length <= 4)
785 return;
786
787 next_tag = s->p + length - 4;
788
789 switch (tag)
790 {
791 case SEC_TAG_SRV_INFO:
792 sec_process_srv_info(s);
793 break;
794
795 case SEC_TAG_SRV_CRYPT:
796 sec_process_crypt_info(s);
797 break;
798
799 case SEC_TAG_SRV_CHANNELS:
800 /* FIXME: We should parse this information and
801 use it to map RDP5 channels to MCS
802 channels */
803 break;
804
805 default:
806 unimpl("response tag 0x%x\n", tag);
807 }
808
809 s->p = next_tag;
810 }
811}
812
813/* Receive secure transport packet */
814STREAM
815sec_recv(uint8 * rdpver)
816{
817 uint32 sec_flags;
818 uint16 channel;
819 STREAM s;
820 struct stream packet;
821
822 while ((s = mcs_recv(&channel, rdpver)) != NULL)
823 {
824 packet = *s;
825 if (rdpver != NULL)
826 {
827 if (*rdpver != 3)
828 {
829 if (*rdpver & 0x80)
830 {
831 if (!s_check_rem(s, 8)) {
832 rdp_protocol_error("sec_recv(), consume fastpath signature from stream would overrun", &packet);
833 }
834
835 in_uint8s(s, 8); /* signature */
836 sec_decrypt(s->p, s->end - s->p);
837 }
838 return s;
839 }
840 }
841 if (g_encryption || (!g_licence_issued && !g_licence_error_result))
842 {
843 in_uint32_le(s, sec_flags);
844
845 if (g_encryption)
846 {
847 if (sec_flags & SEC_ENCRYPT)
848 {
849 if (!s_check_rem(s, 8)) {
850 rdp_protocol_error("sec_recv(), consume encrypt signature from stream would overrun", &packet);
851 }
852
853 in_uint8s(s, 8); /* signature */
854 sec_decrypt(s->p, s->end - s->p);
855 }
856
857 if (sec_flags & SEC_LICENCE_NEG)
858 {
859 licence_process(s);
860 continue;
861 }
862
863 if (sec_flags & 0x0400) /* SEC_REDIRECT_ENCRYPT */
864 {
865 uint8 swapbyte;
866
867 if (!s_check_rem(s, 8)) {
868 rdp_protocol_error("sec_recv(), consume redirect signature from stream would overrun", &packet);
869 }
870
871 in_uint8s(s, 8); /* signature */
872 sec_decrypt(s->p, s->end - s->p);
873
874 /* Check for a redirect packet, starts with 00 04 */
875 if (s->p[0] == 0 && s->p[1] == 4)
876 {
877 /* for some reason the PDU and the length seem to be swapped.
878 This isn't good, but we're going to do a byte for byte
879 swap. So the first foure value appear as: 00 04 XX YY,
880 where XX YY is the little endian length. We're going to
881 use 04 00 as the PDU type, so after our swap this will look
882 like: XX YY 04 00 */
883 swapbyte = s->p[0];
884 s->p[0] = s->p[2];
885 s->p[2] = swapbyte;
886
887 swapbyte = s->p[1];
888 s->p[1] = s->p[3];
889 s->p[3] = swapbyte;
890
891 swapbyte = s->p[2];
892 s->p[2] = s->p[3];
893 s->p[3] = swapbyte;
894 }
895#ifdef WITH_DEBUG
896 /* warning! this debug statement will show passwords in the clear! */
897 hexdump(s->p, s->end - s->p);
898#endif
899 }
900 }
901 else
902 {
903 if ((sec_flags & 0xffff) == SEC_LICENCE_NEG)
904 {
905 licence_process(s);
906 continue;
907 }
908 s->p -= 4;
909 }
910 }
911
912 if (channel != MCS_GLOBAL_CHANNEL)
913 {
914 channel_process(s, channel);
915 if (rdpver != NULL)
916 *rdpver = 0xff;
917 return s;
918 }
919
920 return s;
921 }
922
923 return NULL;
924}
925
926/* Establish a secure connection */
927RD_BOOL
928sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
929{
930 uint32 selected_proto;
931 struct stream mcs_data;
932
933 /* Start a MCS connect sequence */
934 if (!mcs_connect_start(server, username, domain, password, reconnect, &selected_proto))
935 return False;
936
937 /* We exchange some RDP data during the MCS-Connect */
938 mcs_data.size = 512;
939 mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
940 sec_out_mcs_data(&mcs_data, selected_proto);
941
942 /* finialize the MCS connect sequence */
943 if (!mcs_connect_finalize(&mcs_data))
944 return False;
945
946 /* sec_process_mcs_data(&mcs_data); */
947 if (g_encryption)
948 sec_establish_key();
949 xfree(mcs_data.data);
950 return True;
951}
952
953/* Disconnect a connection */
954void
955sec_disconnect(void)
956{
957 mcs_disconnect();
958}
959
960/* reset the state of the sec layer */
961void
962sec_reset_state(void)
963{
964 g_server_rdp_version = 0;
965 g_sec_encrypt_use_count = 0;
966 g_sec_decrypt_use_count = 0;
967 g_licence_issued = 0;
968 g_licence_error_result = 0;
969 mcs_reset_state();
970}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette