VirtualBox

source: vbox/trunk/src/VBox/RDP/client-1.8.3/secure.c@ 67954

Last change on this file since 67954 was 55123, checked in by vboxsync, 10 years ago

rdesktop 1.8.3 modified for VBox

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.0 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 (g_sec_decrypt_use_count == 4096)
305 {
306 sec_update(g_sec_decrypt_key, g_sec_decrypt_update_key);
307 rdssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
308 g_sec_decrypt_use_count = 0;
309 }
310
311 rdssl_rc4_crypt(&g_rc4_decrypt_key, data, data, length);
312 g_sec_decrypt_use_count++;
313}
314
315/* Perform an RSA public key encryption operation */
316static void
317sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
318 uint8 * exponent)
319{
320 rdssl_rsa_encrypt(out, in, len, modulus_size, modulus, exponent);
321}
322
323/* Initialise secure transport packet */
324STREAM
325sec_init(uint32 flags, int maxlen)
326{
327 int hdrlen;
328 STREAM s;
329
330 if (!g_licence_issued && !g_licence_error_result)
331 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
332 else
333 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
334 s = mcs_init(maxlen + hdrlen);
335 s_push_layer(s, sec_hdr, hdrlen);
336
337 return s;
338}
339
340/* Transmit secure transport packet over specified channel */
341void
342sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
343{
344 int datalen;
345
346#ifdef WITH_SCARD
347 scard_lock(SCARD_LOCK_SEC);
348#endif
349
350 s_pop_layer(s, sec_hdr);
351 if ((!g_licence_issued && !g_licence_error_result) || (flags & SEC_ENCRYPT))
352 out_uint32_le(s, flags);
353
354 if (flags & SEC_ENCRYPT)
355 {
356 flags &= ~SEC_ENCRYPT;
357 datalen = s->end - s->p - 8;
358
359#if WITH_DEBUG
360 DEBUG(("Sending encrypted packet:\n"));
361 hexdump(s->p + 8, datalen);
362#endif
363
364 sec_sign(s->p, 8, g_sec_sign_key, g_rc4_key_len, s->p + 8, datalen);
365 sec_encrypt(s->p + 8, datalen);
366 }
367
368 mcs_send_to_channel(s, channel);
369
370#ifdef WITH_SCARD
371 scard_unlock(SCARD_LOCK_SEC);
372#endif
373}
374
375/* Transmit secure transport packet */
376
377void
378sec_send(STREAM s, uint32 flags)
379{
380 sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
381}
382
383
384/* Transfer the client random to the server */
385static void
386sec_establish_key(void)
387{
388 uint32 length = g_server_public_key_len + SEC_PADDING_SIZE;
389 uint32 flags = SEC_CLIENT_RANDOM;
390 STREAM s;
391
392 s = sec_init(flags, length + 4);
393
394 out_uint32_le(s, length);
395 out_uint8p(s, g_sec_crypted_random, g_server_public_key_len);
396 out_uint8s(s, SEC_PADDING_SIZE);
397
398 s_mark_end(s);
399 sec_send(s, flags);
400}
401
402/* Output connect initial data blob */
403static void
404sec_out_mcs_data(STREAM s, uint32 selected_protocol)
405{
406 int hostlen = 2 * strlen(g_hostname);
407 int length = 162 + 76 + 12 + 4;
408 unsigned int i;
409
410 if (g_num_channels > 0)
411 length += g_num_channels * 12 + 8;
412
413 if (hostlen > 30)
414 hostlen = 30;
415
416 /* Generic Conference Control (T.124) ConferenceCreateRequest */
417 out_uint16_be(s, 5);
418 out_uint16_be(s, 0x14);
419 out_uint8(s, 0x7c);
420 out_uint16_be(s, 1);
421
422 out_uint16_be(s, (length | 0x8000)); /* remaining length */
423
424 out_uint16_be(s, 8); /* length? */
425 out_uint16_be(s, 16);
426 out_uint8(s, 0);
427 out_uint16_le(s, 0xc001);
428 out_uint8(s, 0);
429
430 out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
431 out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
432
433 /* Client information */
434 out_uint16_le(s, SEC_TAG_CLI_INFO);
435 out_uint16_le(s, 216); /* length */
436 out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 4 : 1); /* RDP version. 1 == RDP4, 4 >= RDP5 to RDP8 */
437 out_uint16_le(s, 8);
438 out_uint16_le(s, g_width);
439 out_uint16_le(s, g_height);
440 out_uint16_le(s, 0xca01);
441 out_uint16_le(s, 0xaa03);
442 out_uint32_le(s, g_keylayout);
443 out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
444
445 /* Unicode name of client, padded to 32 bytes */
446 rdp_out_unistr(s, g_hostname, hostlen);
447 out_uint8s(s, 30 - hostlen);
448
449 /* See
450 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
451 out_uint32_le(s, g_keyboard_type);
452 out_uint32_le(s, g_keyboard_subtype);
453 out_uint32_le(s, g_keyboard_functionkeys);
454 out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
455 out_uint16_le(s, 0xca01); /* colour depth? */
456 out_uint16_le(s, 1);
457
458 out_uint32(s, 0);
459 out_uint8(s, g_server_depth);
460 out_uint16_le(s, 0x0700);
461 out_uint8(s, 0);
462 out_uint32_le(s, 1);
463 out_uint8s(s, 64);
464 out_uint32_le(s, selected_protocol); /* End of client info */
465
466 /* Write a Client Cluster Data (TS_UD_CS_CLUSTER) */
467 uint32 cluster_flags = 0;
468 out_uint16_le(s, SEC_TAG_CLI_CLUSTER); /* header.type */
469 out_uint16_le(s, 12); /* length */
470
471 cluster_flags |= SEC_CC_REDIRECTION_SUPPORTED;
472 cluster_flags |= (SEC_CC_REDIRECT_VERSION_3 << 2);
473
474 if (g_console_session || g_redirect_session_id != 0)
475 cluster_flags |= SEC_CC_REDIRECT_SESSIONID_FIELD_VALID;
476
477 out_uint32_le(s, cluster_flags);
478 out_uint32(s, g_redirect_session_id);
479
480 /* Client encryption settings */
481 out_uint16_le(s, SEC_TAG_CLI_CRYPT);
482 out_uint16_le(s, 12); /* length */
483 out_uint32_le(s, g_encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
484 out_uint32(s, 0); /* Unknown */
485
486 DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
487 if (g_num_channels > 0)
488 {
489 out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
490 out_uint16_le(s, g_num_channels * 12 + 8); /* length */
491 out_uint32_le(s, g_num_channels); /* number of virtual channels */
492 for (i = 0; i < g_num_channels; i++)
493 {
494 DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
495 out_uint8a(s, g_channels[i].name, 8);
496 out_uint32_be(s, g_channels[i].flags);
497 }
498 }
499
500 s_mark_end(s);
501}
502
503/* Parse a public key structure */
504static RD_BOOL
505sec_parse_public_key(STREAM s, uint8 * modulus, uint8 * exponent)
506{
507 uint32 magic, modulus_len;
508
509 in_uint32_le(s, magic);
510 if (magic != SEC_RSA_MAGIC)
511 {
512 error("RSA magic 0x%x\n", magic);
513 return False;
514 }
515
516 in_uint32_le(s, modulus_len);
517 modulus_len -= SEC_PADDING_SIZE;
518 if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE))
519 {
520 error("Bad server public key size (%u bits)\n", modulus_len * 8);
521 return False;
522 }
523
524 in_uint8s(s, 8); /* modulus_bits, unknown */
525 in_uint8a(s, exponent, SEC_EXPONENT_SIZE);
526 in_uint8a(s, modulus, modulus_len);
527 in_uint8s(s, SEC_PADDING_SIZE);
528 g_server_public_key_len = modulus_len;
529
530 return s_check(s);
531}
532
533/* Parse a public signature structure */
534static RD_BOOL
535sec_parse_public_sig(STREAM s, uint32 len, uint8 * modulus, uint8 * exponent)
536{
537 uint8 signature[SEC_MAX_MODULUS_SIZE];
538 uint32 sig_len;
539
540 if (len != 72)
541 {
542 return True;
543 }
544 memset(signature, 0, sizeof(signature));
545 sig_len = len - 8;
546 in_uint8a(s, signature, sig_len);
547 return rdssl_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, g_server_public_key_len,
548 signature, sig_len);
549}
550
551/* Parse a crypto information structure */
552static RD_BOOL
553sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
554 uint8 ** server_random, uint8 * modulus, uint8 * exponent)
555{
556 uint32 crypt_level, random_len, rsa_info_len;
557 uint32 cacert_len, cert_len, flags;
558 RDSSL_CERT *cacert, *server_cert;
559 RDSSL_RKEY *server_public_key;
560 uint16 tag, length;
561 uint8 *next_tag, *end;
562
563 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
564 in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
565 if (crypt_level == 0)
566 {
567 /* no encryption */
568 return False;
569 }
570
571 in_uint32_le(s, random_len);
572 in_uint32_le(s, rsa_info_len);
573
574 if (random_len != SEC_RANDOM_SIZE)
575 {
576 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
577 return False;
578 }
579
580 in_uint8p(s, *server_random, random_len);
581
582 /* RSA info */
583 end = s->p + rsa_info_len;
584 if (end > s->end)
585 return False;
586
587 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
588 if (flags & 1)
589 {
590 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
591 in_uint8s(s, 8); /* unknown */
592
593 while (s->p < end)
594 {
595 in_uint16_le(s, tag);
596 in_uint16_le(s, length);
597
598 next_tag = s->p + length;
599
600 switch (tag)
601 {
602 case SEC_TAG_PUBKEY:
603 if (!sec_parse_public_key(s, modulus, exponent))
604 return False;
605 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
606
607 break;
608
609 case SEC_TAG_KEYSIG:
610 if (!sec_parse_public_sig(s, length, modulus, exponent))
611 return False;
612 break;
613
614 default:
615 unimpl("crypt tag 0x%x\n", tag);
616 }
617
618 s->p = next_tag;
619 }
620 }
621 else
622 {
623 uint32 certcount;
624
625 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
626 in_uint32_le(s, certcount); /* Number of certificates */
627 if (certcount < 2)
628 {
629 error("Server didn't send enough X509 certificates\n");
630 return False;
631 }
632 for (; certcount > 2; certcount--)
633 { /* ignore all the certificates between the root and the signing CA */
634 uint32 ignorelen;
635 RDSSL_CERT *ignorecert;
636
637 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
638 in_uint32_le(s, ignorelen);
639 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
640 ignorecert = rdssl_cert_read(s->p, ignorelen);
641 in_uint8s(s, ignorelen);
642 if (ignorecert == NULL)
643 { /* XXX: error out? */
644 DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
645 }
646
647#ifdef WITH_DEBUG_RDP5
648 DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
649 rdssl_cert_print_fp(stdout, ignorecert);
650#endif
651 }
652 /* Do da funky X.509 stuffy
653
654 "How did I find out about this? I looked up and saw a
655 bright light and when I came to I had a scar on my forehead
656 and knew about X.500"
657 - Peter Gutman in a early version of
658 http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
659 */
660 in_uint32_le(s, cacert_len);
661 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
662 cacert = rdssl_cert_read(s->p, cacert_len);
663 in_uint8s(s, cacert_len);
664 if (NULL == cacert)
665 {
666 error("Couldn't load CA Certificate from server\n");
667 return False;
668 }
669 in_uint32_le(s, cert_len);
670 DEBUG_RDP5(("Certificate length is %d\n", cert_len));
671 server_cert = rdssl_cert_read(s->p, cert_len);
672 in_uint8s(s, cert_len);
673 if (NULL == server_cert)
674 {
675 rdssl_cert_free(cacert);
676 error("Couldn't load Certificate from server\n");
677 return False;
678 }
679 if (!rdssl_certs_ok(server_cert, cacert))
680 {
681 rdssl_cert_free(server_cert);
682 rdssl_cert_free(cacert);
683 error("Security error CA Certificate invalid\n");
684 return False;
685 }
686 rdssl_cert_free(cacert);
687 in_uint8s(s, 16); /* Padding */
688 server_public_key = rdssl_cert_to_rkey(server_cert, &g_server_public_key_len);
689 if (NULL == server_public_key)
690 {
691 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
692 rdssl_cert_free(server_cert);
693 return False;
694 }
695 rdssl_cert_free(server_cert);
696 if ((g_server_public_key_len < SEC_MODULUS_SIZE) ||
697 (g_server_public_key_len > SEC_MAX_MODULUS_SIZE))
698 {
699 error("Bad server public key size (%u bits)\n",
700 g_server_public_key_len * 8);
701 rdssl_rkey_free(server_public_key);
702 return False;
703 }
704 if (rdssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
705 modulus, SEC_MAX_MODULUS_SIZE) != 0)
706 {
707 error("Problem extracting RSA exponent, modulus");
708 rdssl_rkey_free(server_public_key);
709 return False;
710 }
711 rdssl_rkey_free(server_public_key);
712 return True; /* There's some garbage here we don't care about */
713 }
714 return s_check_end(s);
715}
716
717/* Process crypto information blob */
718static void
719sec_process_crypt_info(STREAM s)
720{
721 uint8 *server_random = NULL;
722 uint8 modulus[SEC_MAX_MODULUS_SIZE];
723 uint8 exponent[SEC_EXPONENT_SIZE];
724 uint32 rc4_key_size;
725
726 memset(modulus, 0, sizeof(modulus));
727 memset(exponent, 0, sizeof(exponent));
728 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, modulus, exponent))
729 {
730 DEBUG(("Failed to parse crypt info\n"));
731 return;
732 }
733 DEBUG(("Generating client random\n"));
734 generate_random(g_client_random);
735 sec_rsa_encrypt(g_sec_crypted_random, g_client_random, SEC_RANDOM_SIZE,
736 g_server_public_key_len, modulus, exponent);
737 sec_generate_keys(g_client_random, server_random, rc4_key_size);
738}
739
740
741/* Process SRV_INFO, find RDP version supported by server */
742static void
743sec_process_srv_info(STREAM s)
744{
745 in_uint16_le(s, g_server_rdp_version);
746 DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
747 if (1 == g_server_rdp_version)
748 {
749 g_rdp_version = RDP_V4;
750 g_server_depth = 8;
751 }
752}
753
754
755/* Process connect response data blob */
756void
757sec_process_mcs_data(STREAM s)
758{
759 uint16 tag, length;
760 uint8 *next_tag;
761 uint8 len;
762
763 in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */
764 in_uint8(s, len);
765 if (len & 0x80)
766 in_uint8(s, len);
767
768 while (s->p < s->end)
769 {
770 in_uint16_le(s, tag);
771 in_uint16_le(s, length);
772
773 if (length <= 4)
774 return;
775
776 next_tag = s->p + length - 4;
777
778 switch (tag)
779 {
780 case SEC_TAG_SRV_INFO:
781 sec_process_srv_info(s);
782 break;
783
784 case SEC_TAG_SRV_CRYPT:
785 sec_process_crypt_info(s);
786 break;
787
788 case SEC_TAG_SRV_CHANNELS:
789 /* FIXME: We should parse this information and
790 use it to map RDP5 channels to MCS
791 channels */
792 break;
793
794 default:
795 unimpl("response tag 0x%x\n", tag);
796 }
797
798 s->p = next_tag;
799 }
800}
801
802/* Receive secure transport packet */
803STREAM
804sec_recv(uint8 * rdpver)
805{
806 uint32 sec_flags;
807 uint16 channel;
808 STREAM s;
809
810 while ((s = mcs_recv(&channel, rdpver)) != NULL)
811 {
812 if (rdpver != NULL)
813 {
814 if (*rdpver != 3)
815 {
816 if (*rdpver & 0x80)
817 {
818 in_uint8s(s, 8); /* signature */
819 sec_decrypt(s->p, s->end - s->p);
820 }
821 return s;
822 }
823 }
824 if (g_encryption || (!g_licence_issued && !g_licence_error_result))
825 {
826 in_uint32_le(s, sec_flags);
827
828 if (g_encryption)
829 {
830 if (sec_flags & SEC_ENCRYPT)
831 {
832 in_uint8s(s, 8); /* signature */
833 sec_decrypt(s->p, s->end - s->p);
834 }
835
836 if (sec_flags & SEC_LICENCE_NEG)
837 {
838 licence_process(s);
839 continue;
840 }
841
842 if (sec_flags & 0x0400) /* SEC_REDIRECT_ENCRYPT */
843 {
844 uint8 swapbyte;
845
846 in_uint8s(s, 8); /* signature */
847 sec_decrypt(s->p, s->end - s->p);
848
849 /* Check for a redirect packet, starts with 00 04 */
850 if (s->p[0] == 0 && s->p[1] == 4)
851 {
852 /* for some reason the PDU and the length seem to be swapped.
853 This isn't good, but we're going to do a byte for byte
854 swap. So the first foure value appear as: 00 04 XX YY,
855 where XX YY is the little endian length. We're going to
856 use 04 00 as the PDU type, so after our swap this will look
857 like: XX YY 04 00 */
858 swapbyte = s->p[0];
859 s->p[0] = s->p[2];
860 s->p[2] = swapbyte;
861
862 swapbyte = s->p[1];
863 s->p[1] = s->p[3];
864 s->p[3] = swapbyte;
865
866 swapbyte = s->p[2];
867 s->p[2] = s->p[3];
868 s->p[3] = swapbyte;
869 }
870#ifdef WITH_DEBUG
871 /* warning! this debug statement will show passwords in the clear! */
872 hexdump(s->p, s->end - s->p);
873#endif
874 }
875 }
876 else
877 {
878 if ((sec_flags & 0xffff) == SEC_LICENCE_NEG)
879 {
880 licence_process(s);
881 continue;
882 }
883 s->p -= 4;
884 }
885 }
886
887 if (channel != MCS_GLOBAL_CHANNEL)
888 {
889 channel_process(s, channel);
890 if (rdpver != NULL)
891 *rdpver = 0xff;
892 return s;
893 }
894
895 return s;
896 }
897
898 return NULL;
899}
900
901/* Establish a secure connection */
902RD_BOOL
903sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
904{
905 uint32 selected_proto;
906 struct stream mcs_data;
907
908 /* Start a MCS connect sequence */
909 if (!mcs_connect_start(server, username, domain, password, reconnect, &selected_proto))
910 return False;
911
912 /* We exchange some RDP data during the MCS-Connect */
913 mcs_data.size = 512;
914 mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
915 sec_out_mcs_data(&mcs_data, selected_proto);
916
917 /* finialize the MCS connect sequence */
918 if (!mcs_connect_finalize(&mcs_data))
919 return False;
920
921 /* sec_process_mcs_data(&mcs_data); */
922 if (g_encryption)
923 sec_establish_key();
924 xfree(mcs_data.data);
925 return True;
926}
927
928/* Disconnect a connection */
929void
930sec_disconnect(void)
931{
932 mcs_disconnect();
933}
934
935/* reset the state of the sec layer */
936void
937sec_reset_state(void)
938{
939 g_server_rdp_version = 0;
940 g_sec_encrypt_use_count = 0;
941 g_sec_decrypt_use_count = 0;
942 g_licence_issued = 0;
943 g_licence_error_result = 0;
944 mcs_reset_state();
945}
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