VirtualBox

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

Last change on this file since 11982 was 11982, checked in by vboxsync, 16 years ago

All: license header changes for 2.0 (OSE headers, add Sun GPL/LGPL disclaimer)

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