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-2005
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.
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.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 //#include <openssl/rc4.h>
24 //#include <openssl/md5.h>
25 //#include <openssl/sha.h>
26 //#include <openssl/bn.h>
27 //#include <openssl/x509v3.h>
30 ssl_sha1_info_create(void);
32 ssl_sha1_info_delete(void * sha1_info
);
34 ssl_sha1_clear(void * sha1_info
);
36 ssl_sha1_transform(void * sha1_info
, char * data
, int len
);
38 ssl_sha1_complete(void * sha1_info
, char * data
);
40 ssl_md5_info_create(void);
42 ssl_md5_info_delete(void * md5_info
);
44 ssl_md5_info_create(void);
46 ssl_md5_info_delete(void * md5_info
);
48 ssl_md5_clear(void * md5_info
);
50 ssl_md5_transform(void * md5_info
, char * data
, int len
);
52 ssl_md5_complete(void * md5_info
, char * data
);
54 ssl_rc4_info_create(void);
56 ssl_rc4_info_delete(void * rc4_info
);
58 ssl_rc4_set_key(void * rc4_info
, char * key
, int len
);
60 ssl_rc4_crypt(void * rc4_info
, char * in_data
, char * out_data
, int len
);
62 ssl_mod_exp(char* out
, int out_len
, char* in
, int in_len
,
63 char* mod
, int mod_len
, char* exp
, int exp_len
);
65 extern char g_hostname
[];
68 extern unsigned int g_keylayout
;
69 extern int g_keyboard_type
;
70 extern int g_keyboard_subtype
;
71 extern int g_keyboard_functionkeys
;
72 extern BOOL g_encryption
;
73 extern BOOL g_licence_issued
;
74 extern BOOL g_use_rdp5
;
75 extern BOOL g_console_session
;
76 extern int g_server_depth
;
77 extern uint16 mcs_userid
;
78 extern VCHANNEL g_channels
[];
79 extern unsigned int g_num_channels
;
81 static int rc4_key_len
;
82 static void * rc4_decrypt_key
= 0;
83 static void * rc4_encrypt_key
= 0;
84 //static RSA *server_public_key;
85 static void * server_public_key
;
87 static uint8 sec_sign_key
[16];
88 static uint8 sec_decrypt_key
[16];
89 static uint8 sec_encrypt_key
[16];
90 static uint8 sec_decrypt_update_key
[16];
91 static uint8 sec_encrypt_update_key
[16];
92 static uint8 sec_crypted_random
[SEC_MODULUS_SIZE
];
94 uint16 g_server_rdp_version
= 0;
96 /* These values must be available to reset state - Session Directory */
97 static int sec_encrypt_use_count
= 0;
98 static int sec_decrypt_use_count
= 0;
101 * I believe this is based on SSLv3 with the following differences:
102 * MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
103 * MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
104 * key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
105 * key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
106 * encryption/decryption keys updated every 4096 packets
107 * See http://wp.netscape.com/eng/ssl3/draft302.txt
111 * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
112 * Both SHA1 and MD5 algorithms are used.
115 sec_hash_48(uint8
* out
, uint8
* in
, uint8
* salt1
, uint8
* salt2
, uint8 salt
)
123 for (i
= 0; i
< 3; i
++)
125 memset(pad
, salt
+ i
, i
+ 1);
126 sha
= ssl_sha1_info_create();
128 ssl_sha1_transform(sha
, (char *)pad
, i
+ 1);
129 ssl_sha1_transform(sha
, (char *)in
, 48);
130 ssl_sha1_transform(sha
, (char *)salt1
, 32);
131 ssl_sha1_transform(sha
, (char *)salt2
, 32);
132 ssl_sha1_complete(sha
, (char *)shasig
);
133 ssl_sha1_info_delete(sha
);
134 md5
= ssl_md5_info_create();
136 ssl_md5_transform(md5
, (char *)in
, 48);
137 ssl_md5_transform(md5
, (char *)shasig
, 20);
138 ssl_md5_complete(md5
, (char *)out
+ i
* 16);
139 ssl_md5_info_delete(md5
);
144 * 16-byte transformation used to generate export keys (6.2.2).
147 sec_hash_16(uint8
* out
, uint8
* in
, uint8
* salt1
, uint8
* salt2
)
151 md5
= ssl_md5_info_create();
153 ssl_md5_transform(md5
, (char *)in
, 16);
154 ssl_md5_transform(md5
, (char *)salt1
, 32);
155 ssl_md5_transform(md5
, (char *)salt2
, 32);
156 ssl_md5_complete(md5
, (char *)out
);
157 ssl_md5_info_delete(md5
);
160 /* Reduce key entropy from 64 to 40 bits */
162 sec_make_40bit(uint8
* key
)
169 /* Generate encryption keys given client and server randoms */
171 sec_generate_keys(uint8
* client_random
, uint8
* server_random
, int rc4_key_size
)
173 uint8 pre_master_secret
[48];
174 uint8 master_secret
[48];
177 /* Construct pre-master secret */
178 memcpy(pre_master_secret
, client_random
, 24);
179 memcpy(pre_master_secret
+ 24, server_random
, 24);
181 /* Generate master secret and then key material */
182 sec_hash_48(master_secret
, pre_master_secret
, client_random
, server_random
, 'A');
183 sec_hash_48(key_block
, master_secret
, client_random
, server_random
, 'X');
185 /* First 16 bytes of key material is MAC secret */
186 memcpy(sec_sign_key
, key_block
, 16);
188 /* Generate export keys from next two blocks of 16 bytes */
189 sec_hash_16(sec_decrypt_key
, &key_block
[16], client_random
, server_random
);
190 sec_hash_16(sec_encrypt_key
, &key_block
[32], client_random
, server_random
);
192 if (rc4_key_size
== 1)
194 DEBUG(("40-bit encryption enabled\n"));
195 sec_make_40bit(sec_sign_key
);
196 sec_make_40bit(sec_decrypt_key
);
197 sec_make_40bit(sec_encrypt_key
);
202 DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size
));
206 /* Save initial RC4 keys as update keys */
207 memcpy(sec_decrypt_update_key
, sec_decrypt_key
, 16);
208 memcpy(sec_encrypt_update_key
, sec_encrypt_key
, 16);
210 /* Initialise RC4 state arrays */
212 ssl_rc4_info_delete(rc4_decrypt_key
);
213 rc4_decrypt_key
= ssl_rc4_info_create();
214 ssl_rc4_set_key(rc4_decrypt_key
, (char *)sec_decrypt_key
, rc4_key_len
);
216 ssl_rc4_info_delete(rc4_encrypt_key
);
217 rc4_encrypt_key
= ssl_rc4_info_create();
218 ssl_rc4_set_key(rc4_encrypt_key
, (char *)sec_encrypt_key
, rc4_key_len
);
221 static uint8 pad_54
[40] = {
222 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
224 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
228 static uint8 pad_92
[48] = {
229 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
230 92, 92, 92, 92, 92, 92, 92,
231 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
232 92, 92, 92, 92, 92, 92, 92
235 /* Output a uint32 into a buffer (little-endian) */
237 buf_out_uint32(uint8
* buffer
, uint32 value
)
239 buffer
[0] = (value
) & 0xff;
240 buffer
[1] = (value
>> 8) & 0xff;
241 buffer
[2] = (value
>> 16) & 0xff;
242 buffer
[3] = (value
>> 24) & 0xff;
245 /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
247 sec_sign(uint8
* signature
, int siglen
, uint8
* session_key
, int keylen
, uint8
* data
, int datalen
)
255 buf_out_uint32(lenhdr
, datalen
);
257 sha
= ssl_sha1_info_create();
259 ssl_sha1_transform(sha
, (char *)session_key
, keylen
);
260 ssl_sha1_transform(sha
, (char *)pad_54
, 40);
261 ssl_sha1_transform(sha
, (char *)lenhdr
, 4);
262 ssl_sha1_transform(sha
, (char *)data
, datalen
);
263 ssl_sha1_complete(sha
, (char *)shasig
);
264 ssl_sha1_info_delete(sha
);
266 md5
= ssl_md5_info_create();
268 ssl_md5_transform(md5
, (char *)session_key
, keylen
);
269 ssl_md5_transform(md5
, (char *)pad_92
, 48);
270 ssl_md5_transform(md5
, (char *)shasig
, 20);
271 ssl_md5_complete(md5
, (char *)md5sig
);
272 ssl_md5_info_delete(md5
);
274 memcpy(signature
, md5sig
, siglen
);
277 /* Update an encryption key */
279 sec_update(uint8
* key
, uint8
* update_key
)
286 sha
= ssl_sha1_info_create();
288 ssl_sha1_transform(sha
, (char *)update_key
, rc4_key_len
);
289 ssl_sha1_transform(sha
, (char *)pad_54
, 40);
290 ssl_sha1_transform(sha
, (char *)key
, rc4_key_len
);
291 ssl_sha1_complete(sha
, (char *)shasig
);
292 ssl_sha1_info_delete(sha
);
294 md5
= ssl_md5_info_create();
296 ssl_md5_transform(md5
, (char *)update_key
, rc4_key_len
);
297 ssl_md5_transform(md5
, (char *)pad_92
, 48);
298 ssl_md5_transform(md5
, (char *)shasig
, 20);
299 ssl_md5_complete(md5
, (char *)key
);
300 ssl_md5_info_delete(md5
);
303 update
= ssl_rc4_info_create();
304 ssl_rc4_set_key(update
, (char *)key
, rc4_key_len
);
305 ssl_rc4_crypt(update
, (char *)key
, (char *)key
, rc4_key_len
);
306 ssl_rc4_info_delete(update
);
308 if (rc4_key_len
== 8)
312 /* Encrypt data using RC4 */
314 sec_encrypt(uint8
* data
, int length
)
316 if (sec_encrypt_use_count
== 4096)
318 sec_update(sec_encrypt_key
, sec_encrypt_update_key
);
319 ssl_rc4_set_key(rc4_encrypt_key
, (char *)sec_encrypt_key
, rc4_key_len
);
320 sec_encrypt_use_count
= 0;
322 ssl_rc4_crypt(rc4_encrypt_key
, (char *)data
, (char *)data
, length
);
323 sec_encrypt_use_count
++;
326 /* Decrypt data using RC4 */
328 sec_decrypt(uint8
* data
, int length
)
330 if (sec_decrypt_use_count
== 4096)
332 sec_update(sec_decrypt_key
, sec_decrypt_update_key
);
333 ssl_rc4_set_key(rc4_decrypt_key
, (char *)sec_decrypt_key
, rc4_key_len
);
334 sec_decrypt_use_count
= 0;
336 ssl_rc4_crypt(rc4_decrypt_key
, (char *)data
, (char *)data
, length
);
337 sec_decrypt_use_count
++;
341 reverse(uint8 * p, int len)
346 for (i = 0, j = len - 1; i < j; i++, j--)
354 /* Perform an RSA public key encryption operation */
356 sec_rsa_encrypt(uint8
* out
, uint8
* in
, int len
, uint8
* modulus
, uint8
* exponent
)
358 ssl_mod_exp((char *)out
, 64, (char *)in
, 32, (char *)modulus
, 64, (char *)exponent
, 4);
361 BIGNUM mod, exp, x, y;
362 uint8 inr[SEC_MODULUS_SIZE];
365 reverse(modulus, SEC_MODULUS_SIZE);
366 reverse(exponent, SEC_EXPONENT_SIZE);
367 memcpy(inr, in, len);
376 BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
377 BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
378 BN_bin2bn(inr, len, &x);
379 BN_mod_exp(&y, &x, &exp, &mod, ctx);
380 outlen = BN_bn2bin(&y, out);
381 reverse(out, outlen);
382 if (outlen < SEC_MODULUS_SIZE)
383 memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
392 /* Initialise secure transport packet */
394 sec_init(uint32 flags
, int maxlen
)
399 if (!g_licence_issued
)
400 hdrlen
= (flags
& SEC_ENCRYPT
) ? 12 : 4;
402 hdrlen
= (flags
& SEC_ENCRYPT
) ? 12 : 0;
403 s
= mcs_init(maxlen
+ hdrlen
);
404 s_push_layer(s
, sec_hdr
, hdrlen
);
409 /* Transmit secure transport packet over specified channel */
411 sec_send_to_channel(STREAM s
, uint32 flags
, uint16 channel
)
415 s_pop_layer(s
, sec_hdr
);
416 if (!g_licence_issued
|| (flags
& SEC_ENCRYPT
))
417 out_uint32_le(s
, flags
);
419 if (flags
& SEC_ENCRYPT
)
421 flags
&= ~SEC_ENCRYPT
;
422 datalen
= s
->end
- s
->p
- 8;
425 DEBUG(("Sending encrypted packet:\n"));
426 hexdump(s
->p
+ 8, datalen
);
429 sec_sign(s
->p
, 8, sec_sign_key
, rc4_key_len
, s
->p
+ 8, datalen
);
430 sec_encrypt(s
->p
+ 8, datalen
);
433 mcs_send_to_channel(s
, channel
);
436 /* Transmit secure transport packet */
439 sec_send(STREAM s
, uint32 flags
)
441 sec_send_to_channel(s
, flags
, MCS_GLOBAL_CHANNEL
);
445 /* Transfer the client random to the server */
447 sec_establish_key(void)
449 uint32 length
= SEC_MODULUS_SIZE
+ SEC_PADDING_SIZE
;
450 uint32 flags
= SEC_CLIENT_RANDOM
;
453 s
= sec_init(flags
, 76);
455 out_uint32_le(s
, length
);
456 out_uint8p(s
, sec_crypted_random
, SEC_MODULUS_SIZE
);
457 out_uint8s(s
, SEC_PADDING_SIZE
);
463 /* Output connect initial data blob */
465 sec_out_mcs_data(STREAM s
)
467 int hostlen
= 2 * strlen(g_hostname
);
468 int length
= 158 + 76 + 12 + 4;
471 if (g_num_channels
> 0)
472 length
+= g_num_channels
* 12 + 8;
477 /* Generic Conference Control (T.124) ConferenceCreateRequest */
479 out_uint16_be(s
, 0x14);
483 out_uint16_be(s
, (length
| 0x8000)); /* remaining length */
485 out_uint16_be(s
, 8); /* length? */
486 out_uint16_be(s
, 16);
488 out_uint16_le(s
, 0xc001);
491 out_uint32_le(s
, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
492 out_uint16_be(s
, ((length
- 14) | 0x8000)); /* remaining length */
494 /* Client information */
495 out_uint16_le(s
, SEC_TAG_CLI_INFO
);
496 out_uint16_le(s
, 212); /* length */
497 out_uint16_le(s
, g_use_rdp5
? 4 : 1); /* RDP version. 1 == RDP4, 4 == RDP5. */
499 out_uint16_le(s
, g_width
);
500 out_uint16_le(s
, g_height
);
501 out_uint16_le(s
, 0xca01);
502 out_uint16_le(s
, 0xaa03);
503 out_uint32_le(s
, g_keylayout
);
504 out_uint32_le(s
, 2600); /* Client build. We are now 2600 compatible :-) */
506 /* Unicode name of client, padded to 32 bytes */
507 rdp_out_unistr(s
, g_hostname
, hostlen
);
508 out_uint8s(s
, 30 - hostlen
);
511 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
512 out_uint32_le(s
, g_keyboard_type
);
513 out_uint32_le(s
, g_keyboard_subtype
);
514 out_uint32_le(s
, g_keyboard_functionkeys
);
515 out_uint8s(s
, 64); /* reserved? 4 + 12 doublewords */
516 out_uint16_le(s
, 0xca01); /* colour depth? */
520 out_uint8(s
, g_server_depth
);
521 out_uint16_le(s
, 0x0700);
524 out_uint8s(s
, 64); /* End of client info */
526 out_uint16_le(s
, SEC_TAG_CLI_4
);
527 out_uint16_le(s
, 12);
528 out_uint32_le(s
, g_console_session
? 0xb : 9);
531 /* Client encryption settings */
532 out_uint16_le(s
, SEC_TAG_CLI_CRYPT
);
533 out_uint16_le(s
, 12); /* length */
534 out_uint32_le(s
, g_encryption
? 0x3 : 0); /* encryption supported, 128-bit supported */
535 out_uint32(s
, 0); /* Unknown */
537 DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels
));
538 if (g_num_channels
> 0)
540 out_uint16_le(s
, SEC_TAG_CLI_CHANNELS
);
541 out_uint16_le(s
, g_num_channels
* 12 + 8); /* length */
542 out_uint32_le(s
, g_num_channels
); /* number of virtual channels */
543 for (i
= 0; i
< g_num_channels
; i
++)
545 DEBUG_RDP5(("Requesting channel %s\n", g_channels
[i
].name
));
546 out_uint8a(s
, g_channels
[i
].name
, 8);
547 out_uint32_be(s
, g_channels
[i
].flags
);
554 /* Parse a public key structure */
556 sec_parse_public_key(STREAM s
, uint8
** modulus
, uint8
** exponent
)
558 uint32 magic
, modulus_len
;
560 in_uint32_le(s
, magic
);
561 if (magic
!= SEC_RSA_MAGIC
)
563 error("RSA magic 0x%x\n", magic
);
567 in_uint32_le(s
, modulus_len
);
568 if (modulus_len
!= SEC_MODULUS_SIZE
+ SEC_PADDING_SIZE
)
570 error("modulus len 0x%x\n", modulus_len
);
574 in_uint8s(s
, 8); /* modulus_bits, unknown */
575 in_uint8p(s
, *exponent
, SEC_EXPONENT_SIZE
);
576 in_uint8p(s
, *modulus
, SEC_MODULUS_SIZE
);
577 in_uint8s(s
, SEC_PADDING_SIZE
);
582 /* Parse a crypto information structure */
584 sec_parse_crypt_info(STREAM s
, uint32
* rc4_key_size
,
585 uint8
** server_random
, uint8
** modulus
, uint8
** exponent
)
587 uint32 crypt_level
, random_len
, rsa_info_len
;
588 uint32
/*cacert_len, cert_len,*/ flags
;
589 //X509 *cacert, *server_cert;
591 uint8
*next_tag
, *end
;
593 in_uint32_le(s
, *rc4_key_size
); /* 1 = 40-bit, 2 = 128-bit */
594 in_uint32_le(s
, crypt_level
); /* 1 = low, 2 = medium, 3 = high */
595 if (crypt_level
== 0) /* no encryption */
597 in_uint32_le(s
, random_len
);
598 in_uint32_le(s
, rsa_info_len
);
600 if (random_len
!= SEC_RANDOM_SIZE
)
602 error("random len %d, expected %d\n", random_len
, SEC_RANDOM_SIZE
);
606 in_uint8p(s
, *server_random
, random_len
);
609 end
= s
->p
+ rsa_info_len
;
613 in_uint32_le(s
, flags
); /* 1 = RDP4-style, 0x80000002 = X.509 */
616 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
617 in_uint8s(s
, 8); /* unknown */
621 in_uint16_le(s
, tag
);
622 in_uint16_le(s
, length
);
624 next_tag
= s
->p
+ length
;
629 if (!sec_parse_public_key(s
, modulus
, exponent
))
631 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
636 /* Is this a Microsoft key that we just got? */
637 /* Care factor: zero! */
638 /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
639 key as a known key of the hostname. This would prevent some MITM-attacks. */
643 unimpl("crypt tag 0x%x\n", tag
);
654 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
655 in_uint32_le(s
, certcount
); /* Number of certificates */
659 error("Server didn't send enough X509 certificates\n");
663 for (; certcount
> 2; certcount
--)
664 { /* ignore all the certificates between the root and the signing CA */
668 DEBUG_RDP5(("Ignored certs left: %d\n", certcount
));
670 in_uint32_le(s
, ignorelen
);
671 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen
));
672 ignorecert
= d2i_X509(NULL
, &(s
->p
), ignorelen
);
674 if (ignorecert
== NULL
)
675 { /* XXX: error out? */
676 DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
679 #ifdef WITH_DEBUG_RDP5
680 DEBUG_RDP5(("cert #%d (ignored):\n", certcount
));
681 X509_print_fp(stdout
, ignorecert
);
685 /* Do da funky X.509 stuffy
687 "How did I find out about this? I looked up and saw a
688 bright light and when I came to I had a scar on my forehead
689 and knew about X.500"
690 - Peter Gutman in a early version of
691 http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
694 in_uint32_le(s
, cacert_len
);
695 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len
));
696 cacert
= d2i_X509(NULL
, &(s
->p
), cacert_len
);
697 /* Note: We don't need to move s->p here - d2i_X509 is
698 "kind" enough to do it for us */
701 error("Couldn't load CA Certificate from server\n");
705 /* Currently, we don't use the CA Certificate.
707 *) Verify the server certificate (server_cert) with the
709 *) Store the CA Certificate with the hostname of the
710 server we are connecting to as key, and compare it
711 when we connect the next time, in order to prevent
717 in_uint32_le(s
, cert_len
);
718 DEBUG_RDP5(("Certificate length is %d\n", cert_len
));
719 server_cert
= d2i_X509(NULL
, &(s
->p
), cert_len
);
720 if (NULL
== server_cert
)
722 error("Couldn't load Certificate from server\n");
726 in_uint8s(s
, 16); /* Padding */
728 /* Note: Verifying the server certificate must be done here,
729 before sec_parse_public_key since we'll have to apply
730 serious violence to the key after this */
732 if (!sec_parse_x509_key(server_cert
))
734 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
735 X509_free(server_cert
);
738 X509_free(server_cert
);
739 return True
; /* There's some garbage here we don't care about */
742 return s_check_end(s
);
745 /* Process crypto information blob */
747 sec_process_crypt_info(STREAM s
)
749 uint8
*server_random
, *modulus
= NULL
, *exponent
= NULL
;
750 uint8 client_random
[SEC_RANDOM_SIZE
];
752 uint8 inr
[SEC_MODULUS_SIZE
];
754 if (!sec_parse_crypt_info(s
, &rc4_key_size
, &server_random
, &modulus
, &exponent
))
756 DEBUG(("Failed to parse crypt info\n"));
760 DEBUG(("Generating client random\n"));
761 /* Generate a client random, and hence determine encryption keys */
762 /* This is what the MS client do: */
763 memset(inr
, 0, SEC_RANDOM_SIZE
);
764 /* *ARIGL!* Plaintext attack, anyone?
766 generate_random(inr);
767 ..but that generates connection errors now and then (yes,
768 "now and then". Something like 0 to 3 attempts needed before a
769 successful connection. Nice. Not!
772 generate_random(client_random
);
773 if (NULL
!= server_public_key
)
774 { /* Which means we should use
775 RDP5-style encryption */
777 memcpy(inr
+ SEC_RANDOM_SIZE
, client_random
, SEC_RANDOM_SIZE
);
778 reverse(inr
+ SEC_RANDOM_SIZE
, SEC_RANDOM_SIZE
);
780 RSA_public_encrypt(SEC_MODULUS_SIZE
,
781 inr
, sec_crypted_random
, server_public_key
, RSA_NO_PADDING
);
783 reverse(sec_crypted_random
, SEC_MODULUS_SIZE
);
785 RSA_free(server_public_key
);
786 server_public_key
= NULL
;
790 { /* RDP4-style encryption */
791 sec_rsa_encrypt(sec_crypted_random
,
792 client_random
, SEC_RANDOM_SIZE
, modulus
, exponent
);
794 sec_generate_keys(client_random
, server_random
, rc4_key_size
);
798 /* Process SRV_INFO, find RDP version supported by server */
800 sec_process_srv_info(STREAM s
)
802 in_uint16_le(s
, g_server_rdp_version
);
803 DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version
));
804 if (1 == g_server_rdp_version
)
812 /* Process connect response data blob */
814 sec_process_mcs_data(STREAM s
)
820 in_uint8s(s
, 21); /* header (T.124 ConferenceCreateResponse) */
825 while (s
->p
< s
->end
)
827 in_uint16_le(s
, tag
);
828 in_uint16_le(s
, length
);
833 next_tag
= s
->p
+ length
- 4;
837 case SEC_TAG_SRV_INFO
:
838 sec_process_srv_info(s
);
841 case SEC_TAG_SRV_CRYPT
:
842 sec_process_crypt_info(s
);
845 case SEC_TAG_SRV_CHANNELS
:
846 /* FIXME: We should parse this information and
847 use it to map RDP5 channels to MCS
852 unimpl("response tag 0x%x\n", tag
);
859 /* Receive secure transport packet */
861 sec_recv(uint8
* rdpver
)
867 while ((s
= mcs_recv(&channel
, rdpver
)) != NULL
)
875 in_uint8s(s
, 8); /* signature */
876 sec_decrypt(s
->p
, s
->end
- s
->p
);
881 if (g_encryption
|| !g_licence_issued
)
883 in_uint32_le(s
, sec_flags
);
885 if (sec_flags
& SEC_ENCRYPT
)
887 in_uint8s(s
, 8); /* signature */
888 sec_decrypt(s
->p
, s
->end
- s
->p
);
891 if (sec_flags
& SEC_LICENCE_NEG
)
897 if (sec_flags
& 0x0400) /* SEC_REDIRECT_ENCRYPT */
901 in_uint8s(s
, 8); /* signature */
902 sec_decrypt(s
->p
, s
->end
- s
->p
);
904 /* Check for a redirect packet, starts with 00 04 */
905 if (s
->p
[0] == 0 && s
->p
[1] == 4)
907 /* for some reason the PDU and the length seem to be swapped.
908 This isn't good, but we're going to do a byte for byte
909 swap. So the first foure value appear as: 00 04 XX YY,
910 where XX YY is the little endian length. We're going to
911 use 04 00 as the PDU type, so after our swap this will look
926 /* warning! this debug statement will show passwords in the clear! */
927 hexdump(s
->p
, s
->end
- s
->p
);
933 if (channel
!= MCS_GLOBAL_CHANNEL
)
935 channel_process(s
, channel
);
946 /* Establish a secure connection */
948 sec_connect(char *server
, char *username
)
950 struct stream mcs_data
;
952 /* We exchange some RDP data during the MCS-Connect */
954 mcs_data
.p
= mcs_data
.data
= (uint8
*) xmalloc(mcs_data
.size
);
955 sec_out_mcs_data(&mcs_data
);
957 if (!mcs_connect(server
, &mcs_data
, username
))
960 /* sec_process_mcs_data(&mcs_data); */
963 xfree(mcs_data
.data
);
967 /* Establish a secure connection */
969 sec_reconnect(char *server
)
971 struct stream mcs_data
;
973 /* We exchange some RDP data during the MCS-Connect */
975 mcs_data
.p
= mcs_data
.data
= (uint8
*) xmalloc(mcs_data
.size
);
976 sec_out_mcs_data(&mcs_data
);
978 if (!mcs_reconnect(server
, &mcs_data
))
981 /* sec_process_mcs_data(&mcs_data); */
984 xfree(mcs_data
.data
);
988 /* Disconnect a connection */
995 /* reset the state of the sec layer */
997 sec_reset_state(void)
999 g_server_rdp_version
= 0;
1000 sec_encrypt_use_count
= 0;
1001 sec_decrypt_use_count
= 0;