VirtualBox

source: vbox/trunk/src/VBox/RDP/client/secure.c@ 51770

Last change on this file since 51770 was 37224, checked in by vboxsync, 13 years ago

RDP/client: fix OSE

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