ReactOS 0.4.15-dev-7958-gcd0bb1a
secure.c
Go to the documentation of this file.
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#include "precomp.h"
22
23void *
25void
27void
29void
30rdssl_sha1_transform(void * sha1_info, char * data, int len);
31void
32rdssl_sha1_complete(void * sha1_info, char * data);
33void *
35void
37void *
39void
41void
43void
44rdssl_md5_transform(void * md5_info, char * data, int len);
45void
46rdssl_md5_complete(void * md5_info, char * data);
47void *
49void
50rdssl_rc4_info_delete(void * rc4_info);
51void
52rdssl_rc4_set_key(void * rc4_info, char * key, int len);
53void
54rdssl_rc4_crypt(void * rc4_info, char * in_data, char * out_data, int len);
55int
56rdssl_mod_exp(char* out, int out_len, char* in, int in_len,
57 char* mod, int mod_len, char* exp, int exp_len);
58int
59rdssl_sign_ok(char* e_data, int e_len, char* n_data, int n_len,
60 char* sign_data, int sign_len, char* sign_data2, int sign_len2, char* testkey);
63void
65uint8 *
69int
70rdssl_rkey_get_exp_mod(uint8 * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
71 uint32 max_mod_len);
72void
74
75extern char g_hostname[16];
76extern int g_width;
77extern int g_height;
78extern unsigned int g_keylayout;
79extern int g_keyboard_type;
80extern int g_keyboard_subtype;
88extern int g_server_depth;
89extern VCHANNEL g_channels[];
90extern unsigned int g_num_channels;
92
93static int g_rc4_key_len;
94static void * g_rc4_decrypt_key;
95static void * g_rc4_encrypt_key;
97
104
106
107/* These values must be available to reset state - Session Directory */
110
111#define SEC_MODULUS_SIZE 64
112
113static uint8 g_testkey[176] =
114{
115 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
116 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x5c, 0x00,
117 0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00,
118 0x00, 0x02, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
119 0x01, 0x00, 0x01, 0x00, 0x79, 0x6f, 0xb4, 0xdf,
120 0xa6, 0x95, 0xb9, 0xa9, 0x61, 0xe3, 0xc4, 0x5e,
121 0xff, 0x6b, 0xd8, 0x81, 0x8a, 0x12, 0x4a, 0x93,
122 0x42, 0x97, 0x18, 0x93, 0xac, 0xd1, 0x3a, 0x38,
123 0x3c, 0x68, 0x50, 0x19, 0x31, 0xb6, 0x84, 0x51,
124 0x79, 0xfb, 0x1c, 0xe7, 0xe3, 0x99, 0x20, 0xc7,
125 0x84, 0xdf, 0xd1, 0xaa, 0xb5, 0x15, 0xef, 0x47,
126 0x7e, 0xfc, 0x88, 0xeb, 0x29, 0xc3, 0x27, 0x5a,
127 0x35, 0xf8, 0xfd, 0xaa, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00,
129 0x08, 0x00, 0x48, 0x00,
130 0x32, 0x3b, 0xde, 0x6f, 0x18, 0x97, 0x1e, 0xc3,
131 0x6b, 0x2b, 0x2d, 0xe4, 0xfc, 0x2d, 0xa2, 0x8e,
132 0x32, 0x3c, 0xf3, 0x1b, 0x24, 0x90, 0x57, 0x4d,
133 0x8e, 0xe4, 0x69, 0xfc, 0x16, 0x8d, 0x41, 0x92,
134 0x78, 0xc7, 0x9c, 0xb4, 0x26, 0xff, 0xe8, 0x3e,
135 0xa1, 0x8a, 0xf5, 0x57, 0xc0, 0x7f, 0x3e, 0x21,
136 0x17, 0x32, 0x30, 0x6f, 0x79, 0xe1, 0x36, 0xcd,
137 0xb6, 0x8e, 0xbe, 0x57, 0x57, 0xd2, 0xa9, 0x36
138};
139
140/*
141 * I believe this is based on SSLv3 with the following differences:
142 * MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
143 * MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
144 * key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
145 * key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
146 * encryption/decryption keys updated every 4096 packets
147 * See http://wp.netscape.com/eng/ssl3/draft302.txt
148 */
149
150/*
151 * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
152 * Both SHA1 and MD5 algorithms are used.
153 */
154void
155sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
156{
157 uint8 shasig[20];
158 uint8 pad[4];
159 void * sha;
160 void * md5;
161 int i;
162
163 for (i = 0; i < 3; i++)
164 {
165 memset(pad, salt + i, i + 1);
168 rdssl_sha1_transform(sha, (char *)pad, i + 1);
169 rdssl_sha1_transform(sha, (char *)in, 48);
170 rdssl_sha1_transform(sha, (char *)salt1, 32);
171 rdssl_sha1_transform(sha, (char *)salt2, 32);
172 rdssl_sha1_complete(sha, (char *)shasig);
176 rdssl_md5_transform(md5, (char *)in, 48);
177 rdssl_md5_transform(md5, (char *)shasig, 20);
178 rdssl_md5_complete(md5, (char *)out + i * 16);
180 }
181}
182
183/*
184 * 16-byte transformation used to generate export keys (6.2.2).
185 */
186void
187sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
188{
189 void * md5;
190
193 rdssl_md5_transform(md5, (char *)in, 16);
194 rdssl_md5_transform(md5, (char *)salt1, 32);
195 rdssl_md5_transform(md5, (char *)salt2, 32);
196 rdssl_md5_complete(md5, (char *)out);
198}
199
200/*
201 * 16-byte sha1 hash
202 */
203void
205{
206 void * sha;
209 rdssl_sha1_transform(&sha, (char *)in, 16);
210 rdssl_sha1_transform(&sha, (char *)salt1, 16);
211 rdssl_sha1_complete(&sha, (char *)out);
213}
214
215/* create string from hash */
216void
218{
219 int k;
220 memset(out, 0, out_size);
221 for (k = 0; k < in_size; k++, out += 2)
222 {
223 sprintf(out, "%.2x", in[k]);
224 }
225}
226
227/* Reduce key entropy from 64 to 40 bits */
228static void
230{
231 key[0] = 0xd1;
232 key[1] = 0x26;
233 key[2] = 0x9e;
234}
235
236/* Generate encryption keys given client and server randoms */
237static void
238sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
239{
240 uint8 pre_master_secret[48];
241 uint8 master_secret[48];
242 uint8 key_block[48];
243
244 /* Construct pre-master secret */
245 memcpy(pre_master_secret, client_random, 24);
246 memcpy(pre_master_secret + 24, server_random, 24);
247
248 /* Generate master secret and then key material */
249 sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
250 sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
251
252 /* First 16 bytes of key material is MAC secret */
253 memcpy(g_sec_sign_key, key_block, 16);
254
255 /* Generate export keys from next two blocks of 16 bytes */
256 sec_hash_16(g_sec_decrypt_key, &key_block[16], client_random, server_random);
257 sec_hash_16(g_sec_encrypt_key, &key_block[32], client_random, server_random);
258
259 if (rc4_key_size == 1)
260 {
261 DEBUG(("40-bit encryption enabled\n"));
265 g_rc4_key_len = 8;
266 }
267 else
268 {
269 DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
270 g_rc4_key_len = 16;
271 }
272
273 /* Save initial RC4 keys as update keys */
276
277 /* Initialise RC4 state arrays */
278
282
286}
287
288static uint8 pad_54[40] = {
289 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
290 54, 54, 54,
291 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
292 54, 54, 54
293};
294
295static uint8 pad_92[48] = {
296 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
297 92, 92, 92, 92, 92, 92, 92,
298 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
299 92, 92, 92, 92, 92, 92, 92
300};
301
302/* Output a uint32 into a buffer (little-endian) */
303void
305{
306 buffer[0] = (value) & 0xff;
307 buffer[1] = (value >> 8) & 0xff;
308 buffer[2] = (value >> 16) & 0xff;
309 buffer[3] = (value >> 24) & 0xff;
310}
311
312/* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
313void
314sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
315{
316 uint8 shasig[20];
317 uint8 md5sig[16];
318 uint8 lenhdr[4];
319 void * sha;
320 void * md5;
321
322 buf_out_uint32(lenhdr, datalen);
323
326 rdssl_sha1_transform(sha, (char *)session_key, keylen);
327 rdssl_sha1_transform(sha, (char *)pad_54, 40);
328 rdssl_sha1_transform(sha, (char *)lenhdr, 4);
330 rdssl_sha1_complete(sha, (char *)shasig);
332
335 rdssl_md5_transform(md5, (char *)session_key, keylen);
336 rdssl_md5_transform(md5, (char *)pad_92, 48);
337 rdssl_md5_transform(md5, (char *)shasig, 20);
338 rdssl_md5_complete(md5, (char *)md5sig);
340
341 memcpy(signature, md5sig, siglen);
342}
343
344/* Update an encryption key */
345static void
346sec_update(uint8 * key, uint8 * update_key)
347{
348 uint8 shasig[20];
349 void * sha;
350 void * md5;
351 void * update;
352
355 rdssl_sha1_transform(sha, (char *)update_key, g_rc4_key_len);
356 rdssl_sha1_transform(sha, (char *)pad_54, 40);
358 rdssl_sha1_complete(sha, (char *)shasig);
360
363 rdssl_md5_transform(md5, (char *)update_key, g_rc4_key_len);
364 rdssl_md5_transform(md5, (char *)pad_92, 48);
365 rdssl_md5_transform(md5, (char *)shasig, 20);
366 rdssl_md5_complete(md5, (char *)key);
368
369
370 update = rdssl_rc4_info_create();
371 rdssl_rc4_set_key(update, (char *)key, g_rc4_key_len);
372 rdssl_rc4_crypt(update, (char *)key, (char *)key, g_rc4_key_len);
373 rdssl_rc4_info_delete(update);
374
375 if (g_rc4_key_len == 8)
377}
378
379/* Encrypt data using RC4 */
380static void
382{
383 if (g_sec_encrypt_use_count == 4096)
384 {
388 }
389
392}
393
394/* Decrypt data using RC4 */
395void
397{
398 if (g_sec_decrypt_use_count == 4096)
399 {
403 }
404
407}
408
409/* Perform an RSA public key encryption operation */
410static void
412 uint8 * exponent)
413{
414 rdssl_mod_exp((char *)out, 64, (char *)in, 32, (char *)modulus, 64, (char *)exponent, 4);
415}
416
417/* Initialise secure transport packet */
418STREAM
420{
421 int hdrlen;
422 STREAM s;
423
425 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
426 else
427 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
428 s = mcs_init(maxlen + hdrlen);
429 s_push_layer(s, sec_hdr, hdrlen);
430
431 return s;
432}
433
434/* Transmit secure transport packet over specified channel */
435void
437{
438 int datalen;
439
440#ifdef WITH_SCARD
442#endif
443
444 s_pop_layer(s, sec_hdr);
447
448 if (flags & SEC_ENCRYPT)
449 {
450 flags &= ~SEC_ENCRYPT;
451 datalen = s->end - s->p - 8;
452
453#ifdef WITH_DEBUG
454 DEBUG(("Sending encrypted packet:\n"));
455 hexdump(s->p + 8, datalen);
456#endif
457
459 sec_encrypt(s->p + 8, datalen);
460 }
461
462 mcs_send_to_channel(s, channel);
463
464#ifdef WITH_SCARD
466#endif
467}
468
469/* Transmit secure transport packet */
470
471void
473{
475}
476
477
478/* Transfer the client random to the server */
479static void
481{
484 STREAM s;
485
486 s = sec_init(flags, length + 4);
487
491
492 s_mark_end(s);
493 sec_send(s, flags);
494}
495
496/* Output connect initial data blob */
497static void
498sec_out_mcs_data(STREAM s, uint32 selected_protocol)
499{
500 int hostlen = 2 * strlen(g_hostname);
501 int length = 162 + 76 + 12 + 4;
502 unsigned int i;
503 uint32 cluster_flags = 0;
504
505 if (g_num_channels > 0)
506 length += g_num_channels * 12 + 8;
507
508 if (hostlen > 30)
509 hostlen = 30;
510
511 /* Generic Conference Control (T.124) ConferenceCreateRequest */
512 out_uint16_be(s, 5);
513 out_uint16_be(s, 0x14);
514 out_uint8(s, 0x7c);
515 out_uint16_be(s, 1);
516
517 out_uint16_be(s, (length | 0x8000)); /* remaining length */
518
519 out_uint16_be(s, 8); /* length? */
520 out_uint16_be(s, 16);
521 out_uint8(s, 0);
522 out_uint16_le(s, 0xc001);
523 out_uint8(s, 0);
524
525 out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
526 out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
527
528 /* Client information */
530 out_uint16_le(s, 216); /* length */
531 out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 4 : 1); /* RDP version. 1 == RDP4, 4 >= RDP5 to RDP8 */
532 out_uint16_le(s, 8);
535 out_uint16_le(s, 0xca01);
536 out_uint16_le(s, 0xaa03);
538 out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
539
540 /* Unicode name of client, padded to 32 bytes */
541 rdp_out_unistr(s, g_hostname, hostlen);
542 out_uint8s(s, 30 - hostlen);
543
544 /* See
545 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
549 out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
550 out_uint16_le(s, 0xca01); /* colour depth? */
551 out_uint16_le(s, 1);
552
553 out_uint32(s, 0);
555 out_uint16_le(s, 0x0700);
556 out_uint8(s, 0);
557 out_uint32_le(s, 1);
558 out_uint8s(s, 64);
559 out_uint32_le(s, selected_protocol); /* End of client info */
560
561 /* Write a Client Cluster Data (TS_UD_CS_CLUSTER) */
562 out_uint16_le(s, SEC_TAG_CLI_CLUSTER); /* header.type */
563 out_uint16_le(s, 12); /* length */
564
565 cluster_flags |= SEC_CC_REDIRECTION_SUPPORTED;
566 cluster_flags |= (SEC_CC_REDIRECT_VERSION_3 << 2);
567
570
571 out_uint32_le(s, cluster_flags);
573
574 /* Client encryption settings */
576 out_uint16_le(s, 12); /* length */
577 out_uint32_le(s, g_encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
578 out_uint32(s, 0); /* Unknown */
579
580 DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
581 if (g_num_channels > 0)
582 {
584 out_uint16_le(s, g_num_channels * 12 + 8); /* length */
585 out_uint32_le(s, g_num_channels); /* number of virtual channels */
586 for (i = 0; i < g_num_channels; i++)
587 {
588 DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
591 }
592 }
593
594 s_mark_end(s);
595}
596
597/* Parse a public key structure */
598static RD_BOOL
600{
601 uint32 magic, modulus_len;
602
604 if (magic != SEC_RSA_MAGIC)
605 {
606 error("RSA magic 0x%x\n", magic);
607 return False;
608 }
609
610 in_uint32_le(s, modulus_len);
611 modulus_len -= SEC_PADDING_SIZE;
612 if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE))
613 {
614 error("Bad server public key size (%u bits)\n", modulus_len * 8);
615 return False;
616 }
617
618 in_uint8s(s, 8); /* modulus_bits, unknown */
619 in_uint8a(s, exponent, SEC_EXPONENT_SIZE);
620 in_uint8a(s, modulus, modulus_len);
622 g_server_public_key_len = modulus_len;
623
624 return s_check(s);
625}
626
627/* Parse a public signature structure */
628static RD_BOOL
630{
631 uint8 signature[SEC_MAX_MODULUS_SIZE];
632 uint8 signature_[SEC_MAX_MODULUS_SIZE];
633 uint32 sig_len;
634
635 if (len != 72)
636 {
637 return True;
638 }
639 memset(signature, 0, sizeof(signature));
640 sig_len = len - 8;
641 in_uint8a(s, signature, sig_len);
642 if(rdssl_sign_ok((char *)exponent, SEC_EXPONENT_SIZE, (char *)modulus, g_server_public_key_len,
643 (char *)signature_, SEC_MODULUS_SIZE, (char *)signature, sig_len, (char *)g_testkey))
644 {
645 DEBUG_RDP5(("key signature doesn't match test key\n"));
646 }
647 return s_check(s);
648}
649
650/* Parse a crypto information structure */
651static RD_BOOL
653 uint8 ** server_random, uint8 * modulus, uint8 * exponent)
654{
655 uint32 crypt_level, random_len, rsa_info_len;
656 uint32 cacert_len, cert_len, flags;
657 PCCERT_CONTEXT cacert, server_cert;
658 BYTE *server_public_key;
660 uint8 *next_tag, *end;
661
662 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
663 in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
664 if (crypt_level == 0)
665 {
666 /* no encryption */
667 return False;
668 }
669
670 in_uint32_le(s, random_len);
671 in_uint32_le(s, rsa_info_len);
672
673 if (random_len != SEC_RANDOM_SIZE)
674 {
675 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
676 return False;
677 }
678
679 in_uint8p(s, *server_random, random_len);
680
681 /* RSA info */
682 end = s->p + rsa_info_len;
683 if (end > s->end)
684 return False;
685
686 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
687 if (flags & 1)
688 {
689 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
690 in_uint8s(s, 8); /* unknown */
691
692 while (s->p < end)
693 {
696
697 next_tag = s->p + length;
698
699 switch (tag)
700 {
701 case SEC_TAG_PUBKEY:
702 if (!sec_parse_public_key(s, modulus, exponent))
703 return False;
704 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
705
706 break;
707
708 case SEC_TAG_KEYSIG:
709 if (!sec_parse_public_sig(s, length, modulus, exponent))
710 return False;
711 break;
712
713 default:
714 unimpl("crypt tag 0x%x\n", tag);
715 }
716
717 s->p = next_tag;
718 }
719 }
720 else
721 {
722 uint32 certcount;
723
724 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
725 in_uint32_le(s, certcount); /* Number of certificates */
726 if (certcount < 2)
727 {
728 error("Server didn't send enough X509 certificates\n");
729 return False;
730 }
731 for (; certcount > 2; certcount--)
732 { /* ignore all the certificates between the root and the signing CA */
733 uint32 ignorelen;
734 PCCERT_CONTEXT ignorecert;
735
736 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
737 in_uint32_le(s, ignorelen);
738 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
739 ignorecert = rdssl_cert_read(s->p, ignorelen);
740 in_uint8s(s, ignorelen);
741 if (ignorecert == NULL)
742 { /* XXX: error out? */
743 DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
744 }
745
746#ifdef WITH_DEBUG_RDP5
747 DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
748 rdssl_cert_print_fp(stdout, ignorecert);
749#endif
750 }
751 /* Do da funky X.509 stuffy
752
753 "How did I find out about this? I looked up and saw a
754 bright light and when I came to I had a scar on my forehead
755 and knew about X.500"
756 - Peter Gutman in a early version of
757 http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
758 */
759 in_uint32_le(s, cacert_len);
760 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
761 cacert = rdssl_cert_read(s->p, cacert_len);
762 in_uint8s(s, cacert_len);
763 if (NULL == cacert)
764 {
765 error("Couldn't load CA Certificate from server\n");
766 return False;
767 }
768 in_uint32_le(s, cert_len);
769 DEBUG_RDP5(("Certificate length is %d\n", cert_len));
770 server_cert = rdssl_cert_read(s->p, cert_len);
771 in_uint8s(s, cert_len);
772 if (NULL == server_cert)
773 {
774 rdssl_cert_free(cacert);
775 error("Couldn't load Certificate from server\n");
776 return False;
777 }
778 if (!rdssl_certs_ok(server_cert, cacert))
779 {
780 rdssl_cert_free(server_cert);
781 rdssl_cert_free(cacert);
782 error("Security error CA Certificate invalid\n");
783 return False;
784 }
785 rdssl_cert_free(cacert);
786 in_uint8s(s, 16); /* Padding */
787 server_public_key = rdssl_cert_to_rkey(server_cert, &g_server_public_key_len);
788 if (NULL == server_public_key)
789 {
790 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
791 rdssl_cert_free(server_cert);
792 return False;
793 }
794 rdssl_cert_free(server_cert);
797 {
798 error("Bad server public key size (%u bits)\n",
800 rdssl_rkey_free(server_public_key);
801 return False;
802 }
803 if (rdssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
805 {
806 error("Problem extracting RSA exponent, modulus");
807 rdssl_rkey_free(server_public_key);
808 return False;
809 }
810 rdssl_rkey_free(server_public_key);
811 return True; /* There's some garbage here we don't care about */
812 }
813 return s_check_end(s);
814}
815
816/* Process crypto information blob */
817static void
819{
820 uint8 *server_random = NULL;
822 uint8 exponent[SEC_EXPONENT_SIZE];
823 uint32 rc4_key_size;
824
825 memset(modulus, 0, sizeof(modulus));
826 memset(exponent, 0, sizeof(exponent));
827 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, modulus, exponent))
828 {
829 DEBUG(("Failed to parse crypt info\n"));
830 return;
831 }
832 DEBUG(("Generating client random\n"));
836 sec_generate_keys(g_client_random, server_random, rc4_key_size);
837}
838
839
840/* Process SRV_INFO, find RDP version supported by server */
841static void
843{
845 DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
846 if (1 == g_server_rdp_version)
847 {
849 g_server_depth = 8;
850 }
851}
852
853
854/* Process connect response data blob */
855void
857{
859 uint8 *next_tag;
860 uint8 len;
861
862 in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */
863 in_uint8(s, len);
864 if (len & 0x80)
865 in_uint8(s, len);
866
867 while (s->p < s->end)
868 {
871
872 if (length <= 4)
873 return;
874
875 next_tag = s->p + length - 4;
876
877 switch (tag)
878 {
879 case SEC_TAG_SRV_INFO:
881 break;
882
885 break;
886
888 /* FIXME: We should parse this information and
889 use it to map RDP5 channels to MCS
890 channels */
891 break;
892
893 default:
894 unimpl("response tag 0x%x\n", tag);
895 }
896
897 s->p = next_tag;
898 }
899}
900
901/* Receive secure transport packet */
902STREAM
904{
905 uint16 sec_flags;
906 /* uint16 sec_flags_hi; */
907 uint16 channel;
908 STREAM s;
909
910 while ((s = mcs_recv(&channel, rdpver)) != NULL)
911 {
912 if (rdpver != NULL)
913 {
914 if (*rdpver != 3)
915 {
916 if (*rdpver & 0x80)
917 {
918 in_uint8s(s, 8); /* signature */
919 sec_decrypt(s->p, s->end - s->p);
920 }
921 return s;
922 }
923 }
925 {
926 /* TS_SECURITY_HEADER */
927 in_uint16_le(s, sec_flags);
928 in_uint8s(s, 2); /* sec_flags_hi */
929
930 if (g_encryption)
931 {
932 if (sec_flags & SEC_ENCRYPT)
933 {
934 in_uint8s(s, 8); /* signature */
935 sec_decrypt(s->p, s->end - s->p);
936 }
937
938 if (sec_flags & SEC_LICENSE_PKT)
939 {
941 continue;
942 }
943
944 if (sec_flags & SEC_REDIRECTION_PKT) /* SEC_REDIRECT_ENCRYPT */
945 {
946 uint8 swapbyte;
947
948 in_uint8s(s, 8); /* signature */
949 sec_decrypt(s->p, s->end - s->p);
950
951 /* Check for a redirect packet, starts with 00 04 */
952 if (s->p[0] == 0 && s->p[1] == 4)
953 {
954 /* for some reason the PDU and the length seem to be swapped.
955 This isn't good, but we're going to do a byte for byte
956 swap. So the first four values appear as: 00 04 XX YY,
957 where XX YY is the little endian length. We're going to
958 use 04 00 as the PDU type, so after our swap this will look
959 like: XX YY 04 00 */
960 swapbyte = s->p[0];
961 s->p[0] = s->p[2];
962 s->p[2] = swapbyte;
963
964 swapbyte = s->p[1];
965 s->p[1] = s->p[3];
966 s->p[3] = swapbyte;
967
968 swapbyte = s->p[2];
969 s->p[2] = s->p[3];
970 s->p[3] = swapbyte;
971 }
972#ifdef WITH_DEBUG
973 /* warning! this debug statement will show passwords in the clear! */
974 hexdump(s->p, s->end - s->p);
975#endif
976 }
977 }
978 else
979 {
980 if (sec_flags & SEC_LICENSE_PKT)
981 {
983 continue;
984 }
985 s->p -= 4;
986 }
987 }
988
989 if (channel != MCS_GLOBAL_CHANNEL)
990 {
991 channel_process(s, channel);
992 if (rdpver != NULL)
993 *rdpver = 0xff;
994 return s;
995 }
996
997 return s;
998 }
999
1000 return NULL;
1001}
1002
1003/* Establish a secure connection */
1004RD_BOOL
1005sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
1006{
1007 uint32 selected_proto;
1008 struct stream mcs_data;
1009
1010 /* Start a MCS connect sequence */
1011 if (!mcs_connect_start(server, username, domain, password, reconnect, &selected_proto))
1012 return False;
1013
1014 /* We exchange some RDP data during the MCS-Connect */
1015 mcs_data.size = 512;
1016 mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
1017 sec_out_mcs_data(&mcs_data, selected_proto);
1018
1019 /* finalize the MCS connect sequence */
1020 if (!mcs_connect_finalize(&mcs_data))
1021 return False;
1022
1023 /* sec_process_mcs_data(&mcs_data); */
1024 if (g_encryption)
1026 xfree(mcs_data.data);
1027 return True;
1028}
1029
1030/* Disconnect a connection */
1031void
1033{
1035}
1036
1037/* reset the state of the sec layer */
1038void
1040{
1044 g_licence_issued = 0;
1047}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
void channel_process(STREAM s, uint16 mcs_channel)
Definition: channels.c:138
#define SEC_EXPONENT_SIZE
Definition: constants.h:95
#define SEC_PADDING_SIZE
Definition: constants.h:94
#define SEC_TAG_CLI_CRYPT
Definition: constants.h:120
#define SEC_LICENSE_PKT
Definition: constants.h:105
#define SEC_TAG_SRV_INFO
Definition: constants.h:115
#define SEC_REDIRECTION_PKT
Definition: constants.h:108
#define SEC_TAG_KEYSIG
Definition: constants.h:125
#define SEC_TAG_SRV_CRYPT
Definition: constants.h:116
#define SEC_TAG_SRV_CHANNELS
Definition: constants.h:117
#define SCARD_LOCK_SEC
Definition: constants.h:580
#define SEC_TAG_PUBKEY
Definition: constants.h:124
#define SEC_ENCRYPT
Definition: constants.h:101
#define SEC_CC_REDIRECT_VERSION_3
Definition: constants.h:135
#define SEC_RSA_MAGIC
Definition: constants.h:127
#define SEC_CC_REDIRECT_SESSIONID_FIELD_VALID
Definition: constants.h:131
#define SEC_CC_REDIRECTION_SUPPORTED
Definition: constants.h:130
#define SEC_TAG_CLI_CHANNELS
Definition: constants.h:121
#define SEC_MAX_MODULUS_SIZE
Definition: constants.h:93
#define SEC_EXCHANGE_PKT
Definition: constants.h:98
#define SEC_TAG_CLI_CLUSTER
Definition: constants.h:122
#define SEC_TAG_CLI_INFO
Definition: constants.h:119
#define MCS_GLOBAL_CHANNEL
Definition: constants.h:87
#define SEC_RANDOM_SIZE
Definition: constants.h:91
void licence_process(STREAM s)
Definition: licence.c:378
RD_BOOL mcs_connect_start(char *server, char *username, char *domain, char *password, RD_BOOL reconnect, uint32 *selected_protocol)
Definition: mcs.c:311
STREAM mcs_init(int length)
Definition: mcs.c:242
void mcs_reset_state(void)
Definition: mcs.c:363
STREAM mcs_recv(uint16 *channel, uint8 *rdpver)
Definition: mcs.c:280
void mcs_disconnect(void)
Definition: mcs.c:356
void mcs_send_to_channel(STREAM s, uint16 channel)
Definition: mcs.c:254
RD_BOOL mcs_connect_finalize(STREAM mcs_data)
Definition: mcs.c:318
#define s_mark_end(s)
Definition: parse.h:41
#define out_uint32_le(s, v)
Definition: parse.h:59
#define s_check(s)
Definition: parse.h:42
#define out_uint32_be(s, v)
Definition: parse.h:78
#define s_pop_layer(s, h)
Definition: parse.h:40
#define out_uint8(s, v)
Definition: parse.h:92
#define s_push_layer(s, h, n)
Definition: parse.h:39
#define in_uint16_le(s, v)
Definition: parse.h:55
#define out_uint16_be(s, v)
Definition: parse.h:77
#define in_uint8p(s, v, n)
Definition: parse.h:89
#define s_check_end(s)
Definition: parse.h:44
#define in_uint8a(s, v, n)
Definition: parse.h:90
#define in_uint8s(s, n)
Definition: parse.h:91
#define out_uint8s(s, n)
Definition: parse.h:95
#define in_uint8(s, v)
Definition: parse.h:88
#define out_uint16_le(s, v)
Definition: parse.h:58
#define out_uint8p(s, v, n)
Definition: parse.h:93
#define out_uint32(s, v)
Definition: parse.h:85
#define in_uint32_le(s, v)
Definition: parse.h:56
#define out_uint8a(s, v, n)
Definition: parse.h:94
void xfree(void *mem)
Definition: uimain.c:758
void scard_lock(int lock)
void unimpl(char *format,...)
Definition: uimain.c:801
void hexdump(unsigned char *p, unsigned int len)
Definition: shimdbg.c:234
void rdp_out_unistr(STREAM s, char *string, int len)
Definition: rdp.c:188
void scard_unlock(int lock)
void generate_random(uint8 *random)
Definition: uimain.c:709
void * xmalloc(int size)
Definition: uimain.c:747
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
#define DEBUG(args)
Definition: rdesktop.h:129
static RD_BOOL sec_parse_public_sig(STREAM s, uint32 len, uint8 *modulus, uint8 *exponent)
Definition: secure.c:629
int g_server_depth
Definition: uimain.c:41
void sec_process_mcs_data(STREAM s)
Definition: secure.c:856
static uint32 g_server_public_key_len
Definition: secure.c:96
static int g_rc4_key_len
Definition: secure.c:93
void rdssl_rc4_crypt(void *rc4_info, char *in_data, char *out_data, int len)
Definition: ssl_calls.c:173
int rdssl_sign_ok(char *e_data, int e_len, char *n_data, int n_len, char *sign_data, int sign_len, char *sign_data2, int sign_len2, char *testkey)
Definition: ssl_calls.c:1594
static uint8 g_sec_sign_key[16]
Definition: secure.c:98
void sec_hash_sha1_16(uint8 *out, uint8 *in, uint8 *salt1)
Definition: secure.c:204
void rdssl_rkey_free(uint8 *rkey)
Definition: ssl_calls.c:1777
void * rdssl_rc4_info_create(void)
Definition: ssl_calls.c:51
int g_width
Definition: uimain.c:42
static void sec_generate_keys(uint8 *client_random, uint8 *server_random, int rc4_key_size)
Definition: secure.c:238
int rdssl_rkey_get_exp_mod(uint8 *rkey, uint8 *exponent, uint32 max_exp_len, uint8 *modulus, uint32 max_mod_len)
Definition: ssl_calls.c:1762
void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt)
Definition: secure.c:155
static void * g_rc4_decrypt_key
Definition: secure.c:94
void rdssl_sha1_clear(void *sha1_info)
Definition: ssl_calls.c:393
int g_height
Definition: uimain.c:43
static uint8 g_sec_encrypt_update_key[16]
Definition: secure.c:102
static void sec_make_40bit(uint8 *key)
Definition: secure.c:229
void rdssl_sha1_transform(void *sha1_info, char *data, int len)
Definition: ssl_calls.c:400
void buf_out_uint32(uint8 *buffer, uint32 value)
Definition: secure.c:304
void rdssl_rc4_set_key(void *rc4_info, char *key, int len)
Definition: ssl_calls.c:123
PCCERT_CONTEXT rdssl_cert_read(uint8 *data, uint32 len)
Definition: ssl_calls.c:1639
static uint8 g_sec_crypted_random[SEC_MAX_MODULUS_SIZE]
Definition: secure.c:103
int g_keyboard_type
Definition: uimain.c:45
static RD_BOOL sec_parse_public_key(STREAM s, uint8 *modulus, uint8 *exponent)
Definition: secure.c:599
void rdssl_md5_clear(void *md5_info)
Definition: ssl_calls.c:428
static void sec_out_mcs_data(STREAM s, uint32 selected_protocol)
Definition: secure.c:498
int g_keyboard_functionkeys
Definition: uimain.c:47
static uint8 pad_54[40]
Definition: secure.c:288
RD_BOOL g_licence_issued
Definition: licence.c:44
static uint8 g_sec_decrypt_key[16]
Definition: secure.c:99
RD_BOOL g_licence_error_result
Definition: licence.c:45
void rdssl_cert_free(PCCERT_CONTEXT context)
Definition: ssl_calls.c:1656
unsigned int g_keylayout
Definition: uimain.c:44
static int g_sec_encrypt_use_count
Definition: secure.c:108
char g_hostname[16]
Definition: uimain.c:26
RD_BOOL g_encryption
Definition: uimain.c:40
void rdssl_sha1_info_delete(void *sha1_info)
Definition: ssl_calls.c:386
void rdssl_md5_transform(void *md5_info, char *data, int len)
Definition: ssl_calls.c:435
void sec_send(STREAM s, uint32 flags)
Definition: secure.c:472
static RD_BOOL sec_parse_crypt_info(STREAM s, uint32 *rc4_key_size, uint8 **server_random, uint8 *modulus, uint8 *exponent)
Definition: secure.c:652
RD_BOOL sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
Definition: secure.c:1005
uint16 g_server_rdp_version
Definition: secure.c:105
static int g_sec_decrypt_use_count
Definition: secure.c:109
RDP_VERSION g_rdp_version
Definition: uimain.c:74
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
Definition: secure.c:436
void rdssl_sha1_complete(void *sha1_info, char *data)
Definition: ssl_calls.c:407
void * rdssl_sha1_info_create(void)
Definition: ssl_calls.c:379
int g_keyboard_subtype
Definition: uimain.c:46
void sec_hash_to_string(char *out, int out_size, uint8 *in, int in_size)
Definition: secure.c:217
void sec_reset_state(void)
Definition: secure.c:1039
void rdssl_md5_complete(void *md5_info, char *data)
Definition: ssl_calls.c:442
static uint8 g_sec_decrypt_update_key[16]
Definition: secure.c:101
void sec_disconnect(void)
Definition: secure.c:1032
RD_BOOL rdssl_certs_ok(PCCERT_CONTEXT server_cert, PCCERT_CONTEXT cacert)
Definition: ssl_calls.c:1743
uint8 * rdssl_cert_to_rkey(PCCERT_CONTEXT cert, uint32 *key_len)
Definition: ssl_calls.c:1663
#define SEC_MODULUS_SIZE
Definition: secure.c:111
uint8 g_client_random[SEC_RANDOM_SIZE]
Definition: uimain.c:78
static uint8 g_sec_encrypt_key[16]
Definition: secure.c:100
static void sec_update(uint8 *key, uint8 *update_key)
Definition: secure.c:346
static uint8 pad_92[48]
Definition: secure.c:295
uint32 g_redirect_session_id
Definition: uimain.c:67
static void sec_establish_key(void)
Definition: secure.c:480
static void sec_rsa_encrypt(uint8 *out, uint8 *in, int len, uint32 modulus_size, uint8 *modulus, uint8 *exponent)
Definition: secure.c:411
void rdssl_md5_info_delete(void *md5_info)
Definition: ssl_calls.c:421
void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)
Definition: secure.c:187
static uint8 g_testkey[176]
Definition: secure.c:113
STREAM sec_recv(uint8 *rdpver)
Definition: secure.c:903
static void sec_process_srv_info(STREAM s)
Definition: secure.c:842
STREAM sec_init(uint32 flags, int maxlen)
Definition: secure.c:419
unsigned int g_num_channels
Definition: channels.c:33
static void sec_process_crypt_info(STREAM s)
Definition: secure.c:818
RD_BOOL g_console_session
Definition: uimain.c:48
static void sec_encrypt(uint8 *data, int length)
Definition: secure.c:381
void sec_sign(uint8 *signature, int siglen, uint8 *session_key, int keylen, uint8 *data, int datalen)
Definition: secure.c:314
void * rdssl_md5_info_create(void)
Definition: ssl_calls.c:414
static void * g_rc4_encrypt_key
Definition: secure.c:95
void sec_decrypt(uint8 *data, int length)
Definition: secure.c:396
VCHANNEL g_channels[]
Definition: channels.c:32
void rdssl_rc4_info_delete(void *rc4_info)
Definition: ssl_calls.c:90
int rdssl_mod_exp(char *out, int out_len, char *in, int in_len, char *mod, int mod_len, char *exp, int exp_len)
Definition: ssl_calls.c:1485
unsigned short uint16
Definition: types.h:30
unsigned int uint32
Definition: types.h:32
#define False
Definition: types.h:25
@ RDP_V5
Definition: types.h:44
@ RDP_V4
Definition: types.h:43
enum _RDP_VERSION RDP_VERSION
int RD_BOOL
Definition: types.h:21
#define True
Definition: types.h:24
unsigned char uint8
Definition: types.h:28
#define md5
Definition: compat-1.3.h:2034
#define md5_info
Definition: compat-1.3.h:2038
#define sha1_info
Definition: compat-1.3.h:2265
#define NULL
Definition: types.h:112
static const WCHAR sha[]
Definition: oid.c:1218
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint buffer
Definition: glext.h:5915
GLuint in
Definition: glext.h:9616
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static int mod
Definition: i386-dis.c:1288
#define stdout
Definition: stdio.h:99
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1031
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static BYTE cert[]
Definition: msg.c:1437
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:100
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG in_size
Definition: file.c:100
DWORD exp
Definition: msg.c:16058
static WCHAR password[]
Definition: url.c:33
static WCHAR username[]
Definition: url.c:32
int k
Definition: mpi.c:3369
u32_t magic(void)
static FILE * out
Definition: regtests2xml.c:44
#define memset(x, y, z)
Definition: compat.h:39
Definition: http.c:7252
Definition: cookie.c:42
Definition: copy.c:22
Definition: name.c:39
Definition: parse.h:23
unsigned char * p
Definition: parse.h:24
unsigned int size
Definition: parse.h:27
unsigned char * data
Definition: parse.h:26
Definition: ecma_167.h:138
Definition: pdh_main.c:94
static rfbScreenInfoPtr server
Definition: vnc.c:74
unsigned char BYTE
Definition: xxhash.c:193