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
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 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.
19 */
20 
21 #include "rdesktop.h"
22 #include <string.h>
23 
24 // TODO: remove dependency on OpenSSL
25 #include <openssl/rc4.h>
26 #include <openssl/md5.h>
27 #include <openssl/sha.h>
28 #include <openssl/bn.h>
29 #include <openssl/x509v3.h>
30 
31 /*
32  * I believe this is based on SSLv3 with the following differences:
33  *  MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
34  *  MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
35  *  key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
36  *  key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
37  *  encryption/decryption keys updated every 4096 packets
38  * See http://wp.netscape.com/eng/ssl3/draft302.txt
39  */
40 
41 /*
42  * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
43  * Both SHA1 and MD5 algorithms are used.
44  */
45 void
46 sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
47 {
48 	uint8 shasig[20];
49 	uint8 pad[4];
50 	SHA_CTX sha;
51 	MD5_CTX md5;
52 	int i;
53 
54 	for (i = 0; i < 3; i++)
55 	{
56 		memset(pad, salt + i, i + 1);
57 
58 		SHA1_Init(&sha);
59 		SHA1_Update(&sha, pad, i + 1);
60 		SHA1_Update(&sha, in, 48);
61 		SHA1_Update(&sha, salt1, 32);
62 		SHA1_Update(&sha, salt2, 32);
63 		SHA1_Final(shasig, &sha);
64 
65 		MD5_Init(&md5);
66 		MD5_Update(&md5, in, 48);
67 		MD5_Update(&md5, shasig, 20);
68 		MD5_Final(&out[i * 16], &md5);
69 	}
70 }
71 
72 /*
73  * 16-byte transformation used to generate export keys (6.2.2).
74  */
75 void
76 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
77 {
78 	MD5_CTX md5;
79 
80 	MD5_Init(&md5);
81 	MD5_Update(&md5, in, 16);
82 	MD5_Update(&md5, salt1, 32);
83 	MD5_Update(&md5, salt2, 32);
84 	MD5_Final(out, &md5);
85 }
86 
87 /* Reduce key entropy from 64 to 40 bits */
88 static void
89 sec_make_40bit(uint8 * key)
90 {
91 	key[0] = 0xd1;
92 	key[1] = 0x26;
93 	key[2] = 0x9e;
94 }
95 
96 /* Generate encryption keys given client and server randoms */
97 static void
98 sec_generate_keys(RDPCLIENT * This, uint8 * client_random, uint8 * server_random, int rc4_key_size)
99 {
100 	uint8 pre_master_secret[48];
101 	uint8 master_secret[48];
102 	uint8 key_block[48];
103 
104 	/* Construct pre-master secret */
105 	memcpy(pre_master_secret, client_random, 24);
106 	memcpy(pre_master_secret + 24, server_random, 24);
107 
108 	/* Generate master secret and then key material */
109 	sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
110 	sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
111 
112 	/* First 16 bytes of key material is MAC secret */
113 	memcpy(This->secure.sign_key, key_block, 16);
114 
115 	/* Generate export keys from next two blocks of 16 bytes */
116 	sec_hash_16(This->secure.decrypt_key, &key_block[16], client_random, server_random);
117 	sec_hash_16(This->secure.encrypt_key, &key_block[32], client_random, server_random);
118 
119 	if (rc4_key_size == 1)
120 	{
121 		DEBUG(("40-bit encryption enabled\n"));
122 		sec_make_40bit(This->secure.sign_key);
123 		sec_make_40bit(This->secure.decrypt_key);
124 		sec_make_40bit(This->secure.encrypt_key);
125 		This->secure.rc4_key_len = 8;
126 	}
127 	else
128 	{
129 		DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
130 		This->secure.rc4_key_len = 16;
131 	}
132 
133 	/* Save initial RC4 keys as update keys */
134 	memcpy(This->secure.decrypt_update_key, This->secure.decrypt_key, 16);
135 	memcpy(This->secure.encrypt_update_key, This->secure.encrypt_key, 16);
136 
137 	/* Initialise RC4 state arrays */
138 	RC4_set_key(&This->secure.rc4_decrypt_key, This->secure.rc4_key_len, This->secure.decrypt_key);
139 	RC4_set_key(&This->secure.rc4_encrypt_key, This->secure.rc4_key_len, This->secure.encrypt_key);
140 }
141 
142 static const uint8 pad_54[40] = {
143 	54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
144 	54, 54, 54,
145 	54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
146 	54, 54, 54
147 };
148 
149 static const uint8 pad_92[48] = {
150 	92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
151 	92, 92, 92, 92, 92, 92, 92,
152 	92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
153 	92, 92, 92, 92, 92, 92, 92
154 };
155 
156 /* Output a uint32 into a buffer (little-endian) */
157 void
158 buf_out_uint32(uint8 * buffer, uint32 value)
159 {
160 	buffer[0] = (value) & 0xff;
161 	buffer[1] = (value >> 8) & 0xff;
162 	buffer[2] = (value >> 16) & 0xff;
163 	buffer[3] = (value >> 24) & 0xff;
164 }
165 
166 /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
167 void
168 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
169 {
170 	uint8 shasig[20];
171 	uint8 md5sig[16];
172 	uint8 lenhdr[4];
173 	SHA_CTX sha;
174 	MD5_CTX md5;
175 
176 	buf_out_uint32(lenhdr, datalen);
177 
178 	SHA1_Init(&sha);
179 	SHA1_Update(&sha, session_key, keylen);
180 	SHA1_Update(&sha, pad_54, 40);
181 	SHA1_Update(&sha, lenhdr, 4);
182 	SHA1_Update(&sha, data, datalen);
183 	SHA1_Final(shasig, &sha);
184 
185 	MD5_Init(&md5);
186 	MD5_Update(&md5, session_key, keylen);
187 	MD5_Update(&md5, pad_92, 48);
188 	MD5_Update(&md5, shasig, 20);
189 	MD5_Final(md5sig, &md5);
190 
191 	memcpy(signature, md5sig, siglen);
192 }
193 
194 /* Update an encryption key */
195 static void
196 sec_update(RDPCLIENT * This, uint8 * key, uint8 * update_key)
197 {
198 	uint8 shasig[20];
199 	SHA_CTX sha;
200 	MD5_CTX md5;
201 	RC4_KEY update;
202 
203 	SHA1_Init(&sha);
204 	SHA1_Update(&sha, update_key, This->secure.rc4_key_len);
205 	SHA1_Update(&sha, pad_54, 40);
206 	SHA1_Update(&sha, key, This->secure.rc4_key_len);
207 	SHA1_Final(shasig, &sha);
208 
209 	MD5_Init(&md5);
210 	MD5_Update(&md5, update_key, This->secure.rc4_key_len);
211 	MD5_Update(&md5, pad_92, 48);
212 	MD5_Update(&md5, shasig, 20);
213 	MD5_Final(key, &md5);
214 
215 	RC4_set_key(&update, This->secure.rc4_key_len, key);
216 	RC4(&update, This->secure.rc4_key_len, key, key);
217 
218 	if (This->secure.rc4_key_len == 8)
219 		sec_make_40bit(key);
220 }
221 
222 /* Encrypt data using RC4 */
223 static void
224 sec_encrypt(RDPCLIENT * This, uint8 * data, int length)
225 {
226 	if (This->secure.encrypt_use_count == 4096)
227 	{
228 		sec_update(This, This->secure.encrypt_key, This->secure.encrypt_update_key);
229 		RC4_set_key(&This->secure.rc4_encrypt_key, This->secure.rc4_key_len, This->secure.encrypt_key);
230 		This->secure.encrypt_use_count = 0;
231 	}
232 
233 	RC4(&This->secure.rc4_encrypt_key, length, data, data);
234 	This->secure.encrypt_use_count++;
235 }
236 
237 /* Decrypt data using RC4 */
238 void
239 sec_decrypt(RDPCLIENT * This, uint8 * data, int length)
240 {
241 	if (This->secure.decrypt_use_count == 4096)
242 	{
243 		sec_update(This, This->secure.decrypt_key, This->secure.decrypt_update_key);
244 		RC4_set_key(&This->secure.rc4_decrypt_key, This->secure.rc4_key_len, This->secure.decrypt_key);
245 		This->secure.decrypt_use_count = 0;
246 	}
247 
248 	RC4(&This->secure.rc4_decrypt_key, length, data, data);
249 	This->secure.decrypt_use_count++;
250 }
251 
252 static void
253 reverse(uint8 * p, int len)
254 {
255 	int i, j;
256 	uint8 temp;
257 
258 	for (i = 0, j = len - 1; i < j; i++, j--)
259 	{
260 		temp = p[i];
261 		p[i] = p[j];
262 		p[j] = temp;
263 	}
264 }
265 
266 /* Perform an RSA public key encryption operation */
267 static void
268 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
269 		uint8 * exponent)
270 {
271 	BN_CTX *ctx;
272 	BIGNUM mod, exp, x, y;
273 	uint8 inr[SEC_MAX_MODULUS_SIZE];
274 	int outlen;
275 
276 	reverse(modulus, modulus_size);
277 	reverse(exponent, SEC_EXPONENT_SIZE);
278 	memcpy(inr, in, len);
279 	reverse(inr, len);
280 
281 	ctx = BN_CTX_new();
282 	BN_init(&mod);
283 	BN_init(&exp);
284 	BN_init(&x);
285 	BN_init(&y);
286 
287 	BN_bin2bn(modulus, modulus_size, &mod);
288 	BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
289 	BN_bin2bn(inr, len, &x);
290 	BN_mod_exp(&y, &x, &exp, &mod, ctx);
291 	outlen = BN_bn2bin(&y, out);
292 	reverse(out, outlen);
293 	if ((uint32)outlen < modulus_size)
294 		memset(out + outlen, 0, modulus_size - outlen);
295 
296 	BN_free(&y);
297 	BN_clear_free(&x);
298 	BN_free(&exp);
299 	BN_free(&mod);
300 	BN_CTX_free(ctx);
301 }
302 
303 /* Initialise secure transport packet */
304 STREAM
305 sec_init(RDPCLIENT * This, uint32 flags, int maxlen)
306 {
307 	int hdrlen;
308 	STREAM s;
309 
310 	if (!This->licence_issued)
311 		hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
312 	else
313 		hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
314 	s = mcs_init(This, maxlen + hdrlen);
315 
316 	if(s == NULL)
317 		return s;
318 
319 	s_push_layer(s, sec_hdr, hdrlen);
320 
321 	return s;
322 }
323 
324 /* Transmit secure transport packet over specified channel */
325 
326 // !!! we need a lock here !!!
327 BOOL
328 sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel)
329 {
330 	int datalen;
331 
332 	s_pop_layer(s, sec_hdr);
333 	if (!This->licence_issued || (flags & SEC_ENCRYPT))
334 		out_uint32_le(s, flags);
335 
336 	if (flags & SEC_ENCRYPT)
337 	{
338 		flags &= ~SEC_ENCRYPT;
339 		datalen = (int)(s->end - s->p - 8);
340 
341 #if WITH_DEBUG
342 		DEBUG(("Sending encrypted packet:\n"));
343 		hexdump(s->p + 8, datalen);
344 #endif
345 
346 		sec_sign(s->p, 8, This->secure.sign_key, This->secure.rc4_key_len, s->p + 8, datalen);
347 		sec_encrypt(This, s->p + 8, datalen);
348 	}
349 
350 	return mcs_send_to_channel(This, s, channel);
351 }
352 
353 /* Transmit secure transport packet */
354 
355 BOOL
356 sec_send(RDPCLIENT * This, STREAM s, uint32 flags)
357 {
358 	return sec_send_to_channel(This, s, flags, MCS_GLOBAL_CHANNEL);
359 }
360 
361 
362 /* Transfer the client random to the server */
363 static void
364 sec_establish_key(RDPCLIENT * This)
365 {
366 	uint32 length = This->secure.server_public_key_len + SEC_PADDING_SIZE;
367 	uint32 flags = SEC_CLIENT_RANDOM;
368 	STREAM s;
369 
370 	s = sec_init(This, flags, length + 4);
371 
372 	out_uint32_le(s, length);
373 	out_uint8p(s, This->secure.crypted_random, This->secure.server_public_key_len);
374 	out_uint8s(s, SEC_PADDING_SIZE);
375 
376 	s_mark_end(s);
377 	sec_send(This, s, flags);
378 }
379 
380 /* Output connect initial data blob */
381 static void
382 sec_out_mcs_data(RDPCLIENT * This, STREAM s, wchar_t * hostname)
383 {
384 	int hostlen = 2 * (int)wcslen(hostname);
385 	int length = 158 + 76 + 12 + 4;
386 	unsigned int i;
387 
388 	if (This->num_channels > 0)
389 		length += This->num_channels * 12 + 8;
390 
391 	if (hostlen > 30)
392 		hostlen = 30;
393 
394 	/* Generic Conference Control (T.124) ConferenceCreateRequest */
395 	out_uint16_be(s, 5);
396 	out_uint16_be(s, 0x14);
397 	out_uint8(s, 0x7c);
398 	out_uint16_be(s, 1);
399 
400 	out_uint16_be(s, (length | 0x8000));	/* remaining length */
401 
402 	out_uint16_be(s, 8);	/* length? */
403 	out_uint16_be(s, 16);
404 	out_uint8(s, 0);
405 	out_uint16_le(s, 0xc001);
406 	out_uint8(s, 0);
407 
408 	out_uint32_le(s, 0x61637544);	/* OEM ID: "Duca", as in Ducati. */
409 	out_uint16_be(s, ((length - 14) | 0x8000));	/* remaining length */
410 
411 	/* Client information */
412 	out_uint16_le(s, SEC_TAG_CLI_INFO);
413 	out_uint16_le(s, 212);	/* length */
414 	out_uint16_le(s, This->use_rdp5 ? 4 : 1);	/* RDP version. 1 == RDP4, 4 == RDP5. */
415 	out_uint16_le(s, 8);
416 	out_uint16_le(s, This->width);
417 	out_uint16_le(s, This->height);
418 	out_uint16_le(s, 0xca01);
419 	out_uint16_le(s, 0xaa03);
420 	out_uint32_le(s, This->keylayout);
421 	out_uint32_le(s, 2600);	/* Client build. We are now 2600 compatible :-) */
422 
423 	/* Unicode name of client, padded to 32 bytes */
424 	rdp_out_unistr(This, s, hostname, hostlen);
425 	out_uint8s(s, 30 - hostlen);
426 
427 	/* See
428 	   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
429 	out_uint32_le(s, This->keyboard_type);
430 	out_uint32_le(s, This->keyboard_subtype);
431 	out_uint32_le(s, This->keyboard_functionkeys);
432 	out_uint8s(s, 64);	/* reserved? 4 + 12 doublewords */
433 	out_uint16_le(s, 0xca01);	/* colour depth? */
434 	out_uint16_le(s, 1);
435 
436 	out_uint32(s, 0);
437 	out_uint8(s, This->server_depth);
438 	out_uint16_le(s, 0x0700);
439 	out_uint8(s, 0);
440 	out_uint32_le(s, 1);
441 	out_uint8s(s, 64);	/* End of client info */
442 
443 	out_uint16_le(s, SEC_TAG_CLI_4);
444 	out_uint16_le(s, 12);
445 	out_uint32_le(s, This->console_session ? 0xb : 9);
446 	out_uint32(s, 0);
447 
448 	/* Client encryption settings */
449 	out_uint16_le(s, SEC_TAG_CLI_CRYPT);
450 	out_uint16_le(s, 12);	/* length */
451 	out_uint32_le(s, This->encryption ? 0x3 : 0);	/* encryption supported, 128-bit supported */
452 	out_uint32(s, 0);	/* Unknown */
453 
454 	DEBUG_RDP5(("This->num_channels is %d\n", This->num_channels));
455 	if (This->num_channels > 0)
456 	{
457 		out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
458 		out_uint16_le(s, This->num_channels * 12 + 8);	/* length */
459 		out_uint32_le(s, This->num_channels);	/* number of virtual channels */
460 		for (i = 0; i < This->num_channels; i++)
461 		{
462 			DEBUG_RDP5(("Requesting channel %s\n", This->channels[i].name));
463 			out_uint8a(s, This->channel_defs[i].name, 8);
464 			out_uint32_be(s, This->channel_defs[i].options);
465 		}
466 	}
467 
468 	s_mark_end(s);
469 }
470 
471 /* Parse a public key structure */
472 static BOOL
473 sec_parse_public_key(RDPCLIENT * This, STREAM s, uint8 ** modulus, uint8 ** exponent)
474 {
475 	uint32 magic, modulus_len;
476 
477 	in_uint32_le(s, magic);
478 	if (magic != SEC_RSA_MAGIC)
479 	{
480 		error("RSA magic 0x%x\n", magic);
481 		return False;
482 	}
483 
484 	in_uint32_le(s, modulus_len);
485 	modulus_len -= SEC_PADDING_SIZE;
486 	if ((modulus_len < 64) || (modulus_len > SEC_MAX_MODULUS_SIZE))
487 	{
488 		error("Bad server public key size (%u bits)\n", modulus_len * 8);
489 		return False;
490 	}
491 
492 	in_uint8s(s, 8);	/* modulus_bits, unknown */
493 	in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);
494 	in_uint8p(s, *modulus, modulus_len);
495 	in_uint8s(s, SEC_PADDING_SIZE);
496 	This->secure.server_public_key_len = modulus_len;
497 
498 	return s_check(s);
499 }
500 
501 static BOOL
502 sec_parse_x509_key(RDPCLIENT * This, X509 * cert)
503 {
504 	EVP_PKEY *epk = NULL;
505 	/* By some reason, Microsoft sets the OID of the Public RSA key to
506 	   the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
507 
508 	   Kudos to Richard Levitte for the following (. intiutive .)
509 	   lines of code that resets the OID and let's us extract the key. */
510 	if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
511 	{
512 		DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
513 		ASN1_OBJECT_free(cert->cert_info->key->algor->algorithm);
514 		cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
515 	}
516 	epk = X509_get_pubkey(cert);
517 	if (NULL == epk)
518 	{
519 		error("Failed to extract public key from certificate\n");
520 		return False;
521 	}
522 
523 	This->secure.server_public_key = RSAPublicKey_dup((RSA *) epk->pkey.ptr);
524 	EVP_PKEY_free(epk);
525 
526 	This->secure.server_public_key_len = RSA_size(This->secure.server_public_key);
527 	if ((This->secure.server_public_key_len < 64) || (This->secure.server_public_key_len > SEC_MAX_MODULUS_SIZE))
528 	{
529 		error("Bad server public key size (%u bits)\n", This->secure.server_public_key_len * 8);
530 		return False;
531 	}
532 
533 	return True;
534 }
535 
536 
537 /* Parse a crypto information structure */
538 static BOOL
539 sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size,
540 		     uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
541 {
542 	uint32 crypt_level, random_len, rsa_info_len;
543 	uint32 cacert_len, cert_len, flags;
544 	X509 *cacert, *server_cert;
545 	uint16 tag, length;
546 	uint8 *next_tag, *end;
547 
548 	in_uint32_le(s, *rc4_key_size);	/* 1 = 40-bit, 2 = 128-bit */
549 	in_uint32_le(s, crypt_level);	/* 1 = low, 2 = medium, 3 = high */
550 	if (crypt_level == 0)	/* no encryption */
551 		return False;
552 	in_uint32_le(s, random_len);
553 	in_uint32_le(s, rsa_info_len);
554 
555 	if (random_len != SEC_RANDOM_SIZE)
556 	{
557 		error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
558 		return False;
559 	}
560 
561 	in_uint8p(s, *server_random, random_len);
562 
563 	/* RSA info */
564 	end = s->p + rsa_info_len;
565 	if (end > s->end)
566 		return False;
567 
568 	in_uint32_le(s, flags);	/* 1 = RDP4-style, 0x80000002 = X.509 */
569 	if (flags & 1)
570 	{
571 		DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
572 		in_uint8s(s, 8);	/* unknown */
573 
574 		while (s->p < end)
575 		{
576 			in_uint16_le(s, tag);
577 			in_uint16_le(s, length);
578 
579 			next_tag = s->p + length;
580 
581 			switch (tag)
582 			{
583 				case SEC_TAG_PUBKEY:
584 					if (!sec_parse_public_key(This, s, modulus, exponent))
585 						return False;
586 					DEBUG_RDP5(("Got Public key, RDP4-style\n"));
587 
588 					break;
589 
590 				case SEC_TAG_KEYSIG:
591 					/* Is this a Microsoft key that we just got? */
592 					/* Care factor: zero! */
593 					/* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
594 					   key as a known key of the hostname. This would prevent some MITM-attacks. */
595 					break;
596 
597 				default:
598 					unimpl("crypt tag 0x%x\n", tag);
599 			}
600 
601 			s->p = next_tag;
602 		}
603 	}
604 	else
605 	{
606 		uint32 certcount;
607 
608 		DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
609 		in_uint32_le(s, certcount);	/* Number of certificates */
610 
611 		if (certcount < 2)
612 		{
613 			error("Server didn't send enough X509 certificates\n");
614 			This->disconnect_reason = 1798;
615 			return False;
616 		}
617 
618 		for (; certcount > 2; certcount--)
619 		{		/* ignore all the certificates between the root and the signing CA */
620 			uint32 ignorelen;
621 			X509 *ignorecert;
622 
623 			DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
624 
625 			in_uint32_le(s, ignorelen);
626 			DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
627 			ignorecert = d2i_X509(NULL, &(s->p), ignorelen);
628 
629 			if (ignorecert == NULL)
630 			{	/* XXX: error out? */
631 				DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
632 			}
633 
634 #ifdef WITH_DEBUG_RDP5
635 			DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
636 			X509_print_fp(stdout, ignorecert);
637 #endif
638 		}
639 
640 		/* Do da funky X.509 stuffy
641 
642 		   "How did I find out about this?  I looked up and saw a
643 		   bright light and when I came to I had a scar on my forehead
644 		   and knew about X.500"
645 		   - Peter Gutman in a early version of
646 		   http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
647 		 */
648 
649 		in_uint32_le(s, cacert_len);
650 		DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
651 		cacert = d2i_X509(NULL, &(s->p), cacert_len);
652 		/* Note: We don't need to move s->p here - d2i_X509 is
653 		   "kind" enough to do it for us */
654 		if (NULL == cacert)
655 		{
656 			error("Couldn't load CA Certificate from server\n");
657 			This->disconnect_reason = 1798;
658 			return False;
659 		}
660 
661 		/* Currently, we don't use the CA Certificate.
662 		   FIXME:
663 		   *) Verify the server certificate (server_cert) with the
664 		   CA certificate.
665 		   *) Store the CA Certificate with the hostname of the
666 		   server we are connecting to as key, and compare it
667 		   when we connect the next time, in order to prevent
668 		   MITM-attacks.
669 		 */
670 
671 		X509_free(cacert);
672 
673 		in_uint32_le(s, cert_len);
674 		DEBUG_RDP5(("Certificate length is %d\n", cert_len));
675 		server_cert = d2i_X509(NULL, &(s->p), cert_len);
676 		if (NULL == server_cert)
677 		{
678 			error("Couldn't load Certificate from server\n");
679 			This->disconnect_reason = 1798;
680 			return False;
681 		}
682 
683 		in_uint8s(s, 16);	/* Padding */
684 
685 		/* Note: Verifying the server certificate must be done here,
686 		   before sec_parse_public_key since we'll have to apply
687 		   serious violence to the key after this */
688 
689 		if (!sec_parse_x509_key(This, server_cert))
690 		{
691 			DEBUG_RDP5(("Didn't parse X509 correctly\n"));
692 			X509_free(server_cert);
693 			This->disconnect_reason = 1798;
694 			return False;
695 		}
696 		X509_free(server_cert);
697 		return True;	/* There's some garbage here we don't care about */
698 	}
699 	return s_check_end(s);
700 }
701 
702 /* Process crypto information blob */
703 static void
704 sec_process_crypt_info(RDPCLIENT * This, STREAM s)
705 {
706 	uint8 *server_random, *modulus, *exponent;
707 	uint8 client_random[SEC_RANDOM_SIZE];
708 	uint32 rc4_key_size;
709 
710 	if (!sec_parse_crypt_info(This, s, &rc4_key_size, &server_random, &modulus, &exponent))
711 	{
712 		DEBUG(("Failed to parse crypt info\n"));
713 		return;
714 	}
715 
716 	DEBUG(("Generating client random\n"));
717 	generate_random(client_random);
718 
719 	if (NULL != This->secure.server_public_key)
720 	{			/* Which means we should use
721 				   RDP5-style encryption */
722 		uint8 inr[SEC_MAX_MODULUS_SIZE];
723 		uint32 padding_len = This->secure.server_public_key_len - SEC_RANDOM_SIZE;
724 
725 		/* This is what the MS client do: */
726 		memset(inr, 0, padding_len);
727 		/*  *ARIGL!* Plaintext attack, anyone?
728 		   I tried doing:
729 		   generate_random(inr);
730 		   ..but that generates connection errors now and then (yes,
731 		   "now and then". Something like 0 to 3 attempts needed before a
732 		   successful connection. Nice. Not!
733 		 */
734 		memcpy(inr + padding_len, client_random, SEC_RANDOM_SIZE);
735 		reverse(inr + padding_len, SEC_RANDOM_SIZE);
736 
737 		RSA_public_encrypt(This->secure.server_public_key_len,
738 				   inr, This->secure.crypted_random, This->secure.server_public_key, RSA_NO_PADDING);
739 
740 		reverse(This->secure.crypted_random, This->secure.server_public_key_len);
741 
742 		RSA_free(This->secure.server_public_key);
743 		This->secure.server_public_key = NULL;
744 	}
745 	else
746 	{			/* RDP4-style encryption */
747 		sec_rsa_encrypt(This->secure.crypted_random,
748 				client_random, SEC_RANDOM_SIZE, This->secure.server_public_key_len, modulus,
749 				exponent);
750 	}
751 	sec_generate_keys(This, client_random, server_random, rc4_key_size);
752 }
753 
754 
755 /* Process SRV_INFO, find RDP version supported by server */
756 static void
757 sec_process_srv_info(RDPCLIENT * This, STREAM s)
758 {
759 	in_uint16_le(s, This->server_rdp_version);
760 	DEBUG_RDP5(("Server RDP version is %d\n", This->server_rdp_version));
761 	if (1 == This->server_rdp_version)
762 	{
763 		This->use_rdp5 = 0;
764 		This->server_depth = 8;
765 	}
766 }
767 
768 
769 /* Process connect response data blob */
770 void
771 sec_process_mcs_data(RDPCLIENT * This, STREAM s)
772 {
773 	uint16 tag, length;
774 	uint8 *next_tag;
775 	uint8 len;
776 
777 	in_uint8s(s, 21);	/* header (T.124 ConferenceCreateResponse) */
778 	in_uint8(s, len);
779 	if (len & 0x80)
780 		in_uint8(s, len);
781 
782 	while (s->p < s->end)
783 	{
784 		in_uint16_le(s, tag);
785 		in_uint16_le(s, length);
786 
787 		if (length <= 4)
788 			return;
789 
790 		next_tag = s->p + length - 4;
791 
792 		switch (tag)
793 		{
794 			case SEC_TAG_SRV_INFO:
795 				sec_process_srv_info(This, s);
796 				break;
797 
798 			case SEC_TAG_SRV_CRYPT:
799 				sec_process_crypt_info(This, s);
800 				break;
801 
802 			case SEC_TAG_SRV_CHANNELS:
803 				/* FIXME: We should parse this information and
804 				   use it to map RDP5 channels to MCS
805 				   channels */
806 				break;
807 
808 			default:
809 				unimpl("response tag 0x%x\n", tag);
810 		}
811 
812 		s->p = next_tag;
813 	}
814 }
815 
816 /* Receive secure transport packet */
817 STREAM
818 sec_recv(RDPCLIENT * This, uint8 * rdpver)
819 {
820 	uint32 sec_flags;
821 	uint16 channel;
822 	STREAM s;
823 
824 	while ((s = mcs_recv(This, &channel, rdpver)) != NULL)
825 	{
826 		if (rdpver != NULL)
827 		{
828 			if (*rdpver != 3)
829 			{
830 				if (*rdpver & 0x80)
831 				{
832 					in_uint8s(s, 8);	/* signature */
833 					sec_decrypt(This, s->p, (int)(s->end - s->p));
834 				}
835 				return s;
836 			}
837 		}
838 		if (This->encryption || !This->licence_issued)
839 		{
840 			in_uint32_le(s, sec_flags);
841 
842 			if (sec_flags & SEC_ENCRYPT)
843 			{
844 				in_uint8s(s, 8);	/* signature */
845 				sec_decrypt(This, s->p, (int)(s->end - s->p));
846 			}
847 
848 			if (sec_flags & SEC_LICENCE_NEG)
849 			{
850 				licence_process(This, s);
851 				continue;
852 			}
853 
854 			if (sec_flags & 0x0400)	/* SEC_REDIRECT_ENCRYPT */
855 			{
856 				uint8 swapbyte;
857 
858 				in_uint8s(s, 8);	/* signature */
859 				sec_decrypt(This, s->p, (int)(s->end - s->p));
860 
861 				/* Check for a redirect packet, starts with 00 04 */
862 				if (s->p[0] == 0 && s->p[1] == 4)
863 				{
864 					/* for some reason the PDU and the length seem to be swapped.
865 					   This isn't good, but we're going to do a byte for byte
866 					   swap.  So the first foure value appear as: 00 04 XX YY,
867 					   where XX YY is the little endian length. We're going to
868 					   use 04 00 as the PDU type, so after our swap this will look
869 					   like: XX YY 04 00 */
870 					swapbyte = s->p[0];
871 					s->p[0] = s->p[2];
872 					s->p[2] = swapbyte;
873 
874 					swapbyte = s->p[1];
875 					s->p[1] = s->p[3];
876 					s->p[3] = swapbyte;
877 
878 					swapbyte = s->p[2];
879 					s->p[2] = s->p[3];
880 					s->p[3] = swapbyte;
881 				}
882 #ifdef WITH_DEBUG
883 				/* warning!  this debug statement will show passwords in the clear! */
884 				hexdump(s->p, s->end - s->p);
885 #endif
886 			}
887 
888 		}
889 
890 		if (channel != MCS_GLOBAL_CHANNEL)
891 		{
892 			channel_process(This, s, channel);
893 			*rdpver = 0xff;
894 			return s;
895 		}
896 
897 		return s;
898 	}
899 
900 	return NULL;
901 }
902 
903 /* Establish a secure connection */
904 BOOL
905 sec_connect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie)
906 {
907 	struct stream mcs_data;
908 	void * p = malloc(512);
909 
910 	if(p == NULL)
911 	{
912 		This->disconnect_reason = 262;
913 		return False;
914 	}
915 
916 	/* We exchange some RDP data during the MCS-Connect */
917 	mcs_data.size = 512;
918 	mcs_data.p = mcs_data.data = (uint8 *) p;
919 	sec_out_mcs_data(This, &mcs_data, hostname);
920 
921 	if (!mcs_connect(This, server, cookie, &mcs_data))
922 		return False;
923 
924 	/*      sec_process_mcs_data(&mcs_data); */
925 	if (This->encryption)
926 		sec_establish_key(This);
927 	free(mcs_data.data);
928 	return True;
929 }
930 
931 /* Establish a secure connection */
932 BOOL
933 sec_reconnect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie)
934 {
935 	struct stream mcs_data;
936 	void * p = malloc(512);
937 
938 	if(p == NULL)
939 	{
940 		This->disconnect_reason = 262;
941 		return False;
942 	}
943 
944 	/* We exchange some RDP data during the MCS-Connect */
945 	mcs_data.size = 512;
946 	mcs_data.p = mcs_data.data = (uint8 *) p;
947 	sec_out_mcs_data(This, &mcs_data, hostname);
948 
949 	if (!mcs_reconnect(This, server, cookie, &mcs_data))
950 		return False;
951 
952 	/*      sec_process_mcs_data(&mcs_data); */
953 	if (This->encryption)
954 		sec_establish_key(This);
955 	free(mcs_data.data);
956 	return True;
957 }
958 
959 /* Disconnect a connection */
960 void
961 sec_disconnect(RDPCLIENT * This)
962 {
963 	mcs_disconnect(This);
964 }
965 
966 /* reset the state of the sec layer */
967 void
968 sec_reset_state(RDPCLIENT * This)
969 {
970 	This->server_rdp_version = 0;
971 	This->secure.encrypt_use_count = 0;
972 	This->secure.decrypt_use_count = 0;
973 	mcs_reset_state(This);
974 }
975