Create a branch for header work.
[reactos.git] / base / applications / mstsc / secure.c
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 <precomp.h>
22
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>
28
29 void *
30 ssl_sha1_info_create(void);
31 void
32 ssl_sha1_info_delete(void * sha1_info);
33 void
34 ssl_sha1_clear(void * sha1_info);
35 void
36 ssl_sha1_transform(void * sha1_info, char * data, int len);
37 void
38 ssl_sha1_complete(void * sha1_info, char * data);
39 void *
40 ssl_md5_info_create(void);
41 void
42 ssl_md5_info_delete(void * md5_info);
43 void *
44 ssl_md5_info_create(void);
45 void
46 ssl_md5_info_delete(void * md5_info);
47 void
48 ssl_md5_clear(void * md5_info);
49 void
50 ssl_md5_transform(void * md5_info, char * data, int len);
51 void
52 ssl_md5_complete(void * md5_info, char * data);
53 void *
54 ssl_rc4_info_create(void);
55 void
56 ssl_rc4_info_delete(void * rc4_info);
57 void
58 ssl_rc4_set_key(void * rc4_info, char * key, int len);
59 void
60 ssl_rc4_crypt(void * rc4_info, char * in_data, char * out_data, int len);
61 int
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);
64
65 extern char g_hostname[];
66 extern int g_width;
67 extern int g_height;
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;
80
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;
86
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];
93
94 uint16 g_server_rdp_version = 0;
95
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;
99
100 /*
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
108 */
109
110 /*
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.
113 */
114 void
115 sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
116 {
117 uint8 shasig[20];
118 uint8 pad[4];
119 void * sha;
120 void * md5;
121 int i;
122
123 for (i = 0; i < 3; i++)
124 {
125 memset(pad, salt + i, i + 1);
126 sha = ssl_sha1_info_create();
127 ssl_sha1_clear(sha);
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();
135 ssl_md5_clear(md5);
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);
140 }
141 }
142
143 /*
144 * 16-byte transformation used to generate export keys (6.2.2).
145 */
146 void
147 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
148 {
149 void * md5;
150
151 md5 = ssl_md5_info_create();
152 ssl_md5_clear(md5);
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);
158 }
159
160 /* Reduce key entropy from 64 to 40 bits */
161 static void
162 sec_make_40bit(uint8 * key)
163 {
164 key[0] = 0xd1;
165 key[1] = 0x26;
166 key[2] = 0x9e;
167 }
168
169 /* Generate encryption keys given client and server randoms */
170 static void
171 sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
172 {
173 uint8 pre_master_secret[48];
174 uint8 master_secret[48];
175 uint8 key_block[48];
176
177 /* Construct pre-master secret */
178 memcpy(pre_master_secret, client_random, 24);
179 memcpy(pre_master_secret + 24, server_random, 24);
180
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');
184
185 /* First 16 bytes of key material is MAC secret */
186 memcpy(sec_sign_key, key_block, 16);
187
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);
191
192 if (rc4_key_size == 1)
193 {
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);
198 rc4_key_len = 8;
199 }
200 else
201 {
202 DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
203 rc4_key_len = 16;
204 }
205
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);
209
210 /* Initialise RC4 state arrays */
211
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);
215
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);
219 }
220
221 static uint8 pad_54[40] = {
222 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
223 54, 54, 54,
224 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
225 54, 54, 54
226 };
227
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
233 };
234
235 /* Output a uint32 into a buffer (little-endian) */
236 void
237 buf_out_uint32(uint8 * buffer, uint32 value)
238 {
239 buffer[0] = (value) & 0xff;
240 buffer[1] = (value >> 8) & 0xff;
241 buffer[2] = (value >> 16) & 0xff;
242 buffer[3] = (value >> 24) & 0xff;
243 }
244
245 /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
246 void
247 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
248 {
249 uint8 shasig[20];
250 uint8 md5sig[16];
251 uint8 lenhdr[4];
252 void * sha;
253 void * md5;
254
255 buf_out_uint32(lenhdr, datalen);
256
257 sha = ssl_sha1_info_create();
258 ssl_sha1_clear(sha);
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);
265
266 md5 = ssl_md5_info_create();
267 ssl_md5_clear(md5);
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);
273
274 memcpy(signature, md5sig, siglen);
275 }
276
277 /* Update an encryption key */
278 static void
279 sec_update(uint8 * key, uint8 * update_key)
280 {
281 uint8 shasig[20];
282 void * sha;
283 void * md5;
284 void * update;
285
286 sha = ssl_sha1_info_create();
287 ssl_sha1_clear(sha);
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);
293
294 md5 = ssl_md5_info_create();
295 ssl_md5_clear(md5);
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);
301
302
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);
307
308 if (rc4_key_len == 8)
309 sec_make_40bit(key);
310 }
311
312 /* Encrypt data using RC4 */
313 static void
314 sec_encrypt(uint8 * data, int length)
315 {
316 if (sec_encrypt_use_count == 4096)
317 {
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;
321 }
322 ssl_rc4_crypt(rc4_encrypt_key, (char *)data, (char *)data, length);
323 sec_encrypt_use_count++;
324 }
325
326 /* Decrypt data using RC4 */
327 void
328 sec_decrypt(uint8 * data, int length)
329 {
330 if (sec_decrypt_use_count == 4096)
331 {
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;
335 }
336 ssl_rc4_crypt(rc4_decrypt_key, (char *)data, (char *)data, length);
337 sec_decrypt_use_count++;
338 }
339
340 /*static void
341 reverse(uint8 * p, int len)
342 {
343 int i, j;
344 uint8 temp;
345
346 for (i = 0, j = len - 1; i < j; i++, j--)
347 {
348 temp = p[i];
349 p[i] = p[j];
350 p[j] = temp;
351 }
352 }*/
353
354 /* Perform an RSA public key encryption operation */
355 static void
356 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
357 {
358 ssl_mod_exp((char *)out, 64, (char *)in, 32, (char *)modulus, 64, (char *)exponent, 4);
359 /*
360 BN_CTX *ctx;
361 BIGNUM mod, exp, x, y;
362 uint8 inr[SEC_MODULUS_SIZE];
363 int outlen;
364
365 reverse(modulus, SEC_MODULUS_SIZE);
366 reverse(exponent, SEC_EXPONENT_SIZE);
367 memcpy(inr, in, len);
368 reverse(inr, len);
369
370 ctx = BN_CTX_new();
371 BN_init(&mod);
372 BN_init(&exp);
373 BN_init(&x);
374 BN_init(&y);
375
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);
384
385 BN_free(&y);
386 BN_clear_free(&x);
387 BN_free(&exp);
388 BN_free(&mod);
389 BN_CTX_free(ctx);*/
390 }
391
392 /* Initialise secure transport packet */
393 STREAM
394 sec_init(uint32 flags, int maxlen)
395 {
396 int hdrlen;
397 STREAM s;
398
399 if (!g_licence_issued)
400 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
401 else
402 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
403 s = mcs_init(maxlen + hdrlen);
404 s_push_layer(s, sec_hdr, hdrlen);
405
406 return s;
407 }
408
409 /* Transmit secure transport packet over specified channel */
410 void
411 sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
412 {
413 int datalen;
414
415 s_pop_layer(s, sec_hdr);
416 if (!g_licence_issued || (flags & SEC_ENCRYPT))
417 out_uint32_le(s, flags);
418
419 if (flags & SEC_ENCRYPT)
420 {
421 flags &= ~SEC_ENCRYPT;
422 datalen = s->end - s->p - 8;
423
424 #ifdef WITH_DEBUG
425 DEBUG(("Sending encrypted packet:\n"));
426 hexdump(s->p + 8, datalen);
427 #endif
428
429 sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, datalen);
430 sec_encrypt(s->p + 8, datalen);
431 }
432
433 mcs_send_to_channel(s, channel);
434 }
435
436 /* Transmit secure transport packet */
437
438 void
439 sec_send(STREAM s, uint32 flags)
440 {
441 sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
442 }
443
444
445 /* Transfer the client random to the server */
446 static void
447 sec_establish_key(void)
448 {
449 uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
450 uint32 flags = SEC_CLIENT_RANDOM;
451 STREAM s;
452
453 s = sec_init(flags, 76);
454
455 out_uint32_le(s, length);
456 out_uint8p(s, sec_crypted_random, SEC_MODULUS_SIZE);
457 out_uint8s(s, SEC_PADDING_SIZE);
458
459 s_mark_end(s);
460 sec_send(s, flags);
461 }
462
463 /* Output connect initial data blob */
464 static void
465 sec_out_mcs_data(STREAM s)
466 {
467 int hostlen = 2 * strlen(g_hostname);
468 int length = 158 + 76 + 12 + 4;
469 unsigned int i;
470
471 if (g_num_channels > 0)
472 length += g_num_channels * 12 + 8;
473
474 if (hostlen > 30)
475 hostlen = 30;
476
477 /* Generic Conference Control (T.124) ConferenceCreateRequest */
478 out_uint16_be(s, 5);
479 out_uint16_be(s, 0x14);
480 out_uint8(s, 0x7c);
481 out_uint16_be(s, 1);
482
483 out_uint16_be(s, (length | 0x8000)); /* remaining length */
484
485 out_uint16_be(s, 8); /* length? */
486 out_uint16_be(s, 16);
487 out_uint8(s, 0);
488 out_uint16_le(s, 0xc001);
489 out_uint8(s, 0);
490
491 out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
492 out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
493
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. */
498 out_uint16_le(s, 8);
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 :-) */
505
506 /* Unicode name of client, padded to 32 bytes */
507 rdp_out_unistr(s, g_hostname, hostlen);
508 out_uint8s(s, 30 - hostlen);
509
510 /* See
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? */
517 out_uint16_le(s, 1);
518
519 out_uint32(s, 0);
520 out_uint8(s, g_server_depth);
521 out_uint16_le(s, 0x0700);
522 out_uint8(s, 0);
523 out_uint32_le(s, 1);
524 out_uint8s(s, 64); /* End of client info */
525
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);
529 out_uint32(s, 0);
530
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 */
536
537 DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
538 if (g_num_channels > 0)
539 {
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++)
544 {
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);
548 }
549 }
550
551 s_mark_end(s);
552 }
553
554 /* Parse a public key structure */
555 static BOOL
556 sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
557 {
558 uint32 magic, modulus_len;
559
560 in_uint32_le(s, magic);
561 if (magic != SEC_RSA_MAGIC)
562 {
563 error("RSA magic 0x%x\n", magic);
564 return False;
565 }
566
567 in_uint32_le(s, modulus_len);
568 if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
569 {
570 error("modulus len 0x%x\n", modulus_len);
571 return False;
572 }
573
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);
578
579 return s_check(s);
580 }
581
582 /* Parse a crypto information structure */
583 static BOOL
584 sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
585 uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
586 {
587 uint32 crypt_level, random_len, rsa_info_len;
588 uint32 /*cacert_len, cert_len,*/ flags;
589 //X509 *cacert, *server_cert;
590 uint16 tag, length;
591 uint8 *next_tag, *end;
592
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 */
596 return False;
597 in_uint32_le(s, random_len);
598 in_uint32_le(s, rsa_info_len);
599
600 if (random_len != SEC_RANDOM_SIZE)
601 {
602 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
603 return False;
604 }
605
606 in_uint8p(s, *server_random, random_len);
607
608 /* RSA info */
609 end = s->p + rsa_info_len;
610 if (end > s->end)
611 return False;
612
613 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
614 if (flags & 1)
615 {
616 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
617 in_uint8s(s, 8); /* unknown */
618
619 while (s->p < end)
620 {
621 in_uint16_le(s, tag);
622 in_uint16_le(s, length);
623
624 next_tag = s->p + length;
625
626 switch (tag)
627 {
628 case SEC_TAG_PUBKEY:
629 if (!sec_parse_public_key(s, modulus, exponent))
630 return False;
631 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
632
633 break;
634
635 case SEC_TAG_KEYSIG:
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. */
640 break;
641
642 default:
643 unimpl("crypt tag 0x%x\n", tag);
644 }
645
646 s->p = next_tag;
647 }
648 }
649 else
650 {
651 #if 0
652 uint32 certcount;
653
654 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
655 in_uint32_le(s, certcount); /* Number of certificates */
656
657 if (certcount < 2)
658 {
659 error("Server didn't send enough X509 certificates\n");
660 return False;
661 }
662
663 for (; certcount > 2; certcount--)
664 { /* ignore all the certificates between the root and the signing CA */
665 uint32 ignorelen;
666 X509 *ignorecert;
667
668 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
669
670 in_uint32_le(s, ignorelen);
671 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
672 ignorecert = d2i_X509(NULL, &(s->p), ignorelen);
673
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"));
677 }
678
679 #ifdef WITH_DEBUG_RDP5
680 DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
681 X509_print_fp(stdout, ignorecert);
682 #endif
683 }
684
685 /* Do da funky X.509 stuffy
686
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
692 */
693
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 */
699 if (NULL == cacert)
700 {
701 error("Couldn't load CA Certificate from server\n");
702 return False;
703 }
704
705 /* Currently, we don't use the CA Certificate.
706 FIXME:
707 *) Verify the server certificate (server_cert) with the
708 CA certificate.
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
712 MITM-attacks.
713 */
714
715 X509_free(cacert);
716
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)
721 {
722 error("Couldn't load Certificate from server\n");
723 return False;
724 }
725
726 in_uint8s(s, 16); /* Padding */
727
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 */
731
732 if (!sec_parse_x509_key(server_cert))
733 {
734 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
735 X509_free(server_cert);
736 return False;
737 }
738 X509_free(server_cert);
739 return True; /* There's some garbage here we don't care about */
740 #endif
741 }
742 return s_check_end(s);
743 }
744
745 /* Process crypto information blob */
746 static void
747 sec_process_crypt_info(STREAM s)
748 {
749 uint8 *server_random, *modulus = NULL, *exponent = NULL;
750 uint8 client_random[SEC_RANDOM_SIZE];
751 uint32 rc4_key_size;
752 uint8 inr[SEC_MODULUS_SIZE];
753
754 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
755 {
756 DEBUG(("Failed to parse crypt info\n"));
757 return;
758 }
759
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?
765 I tried doing:
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!
770 */
771
772 generate_random(client_random);
773 if (NULL != server_public_key)
774 { /* Which means we should use
775 RDP5-style encryption */
776 #if 0
777 memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
778 reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
779
780 RSA_public_encrypt(SEC_MODULUS_SIZE,
781 inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
782
783 reverse(sec_crypted_random, SEC_MODULUS_SIZE);
784
785 RSA_free(server_public_key);
786 server_public_key = NULL;
787 #endif
788 }
789 else
790 { /* RDP4-style encryption */
791 sec_rsa_encrypt(sec_crypted_random,
792 client_random, SEC_RANDOM_SIZE, modulus, exponent);
793 }
794 sec_generate_keys(client_random, server_random, rc4_key_size);
795 }
796
797
798 /* Process SRV_INFO, find RDP version supported by server */
799 static void
800 sec_process_srv_info(STREAM s)
801 {
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)
805 {
806 g_use_rdp5 = 0;
807 g_server_depth = 8;
808 }
809 }
810
811
812 /* Process connect response data blob */
813 void
814 sec_process_mcs_data(STREAM s)
815 {
816 uint16 tag, length;
817 uint8 *next_tag;
818 uint8 len;
819
820 in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */
821 in_uint8(s, len);
822 if (len & 0x80)
823 in_uint8(s, len);
824
825 while (s->p < s->end)
826 {
827 in_uint16_le(s, tag);
828 in_uint16_le(s, length);
829
830 if (length <= 4)
831 return;
832
833 next_tag = s->p + length - 4;
834
835 switch (tag)
836 {
837 case SEC_TAG_SRV_INFO:
838 sec_process_srv_info(s);
839 break;
840
841 case SEC_TAG_SRV_CRYPT:
842 sec_process_crypt_info(s);
843 break;
844
845 case SEC_TAG_SRV_CHANNELS:
846 /* FIXME: We should parse this information and
847 use it to map RDP5 channels to MCS
848 channels */
849 break;
850
851 default:
852 unimpl("response tag 0x%x\n", tag);
853 }
854
855 s->p = next_tag;
856 }
857 }
858
859 /* Receive secure transport packet */
860 STREAM
861 sec_recv(uint8 * rdpver)
862 {
863 uint32 sec_flags;
864 uint16 channel;
865 STREAM s;
866
867 while ((s = mcs_recv(&channel, rdpver)) != NULL)
868 {
869 if (rdpver != NULL)
870 {
871 if (*rdpver != 3)
872 {
873 if (*rdpver & 0x80)
874 {
875 in_uint8s(s, 8); /* signature */
876 sec_decrypt(s->p, s->end - s->p);
877 }
878 return s;
879 }
880 }
881 if (g_encryption || !g_licence_issued)
882 {
883 in_uint32_le(s, sec_flags);
884
885 if (sec_flags & SEC_ENCRYPT)
886 {
887 in_uint8s(s, 8); /* signature */
888 sec_decrypt(s->p, s->end - s->p);
889 }
890
891 if (sec_flags & SEC_LICENCE_NEG)
892 {
893 licence_process(s);
894 continue;
895 }
896
897 if (sec_flags & 0x0400) /* SEC_REDIRECT_ENCRYPT */
898 {
899 uint8 swapbyte;
900
901 in_uint8s(s, 8); /* signature */
902 sec_decrypt(s->p, s->end - s->p);
903
904 /* Check for a redirect packet, starts with 00 04 */
905 if (s->p[0] == 0 && s->p[1] == 4)
906 {
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
912 like: XX YY 04 00 */
913 swapbyte = s->p[0];
914 s->p[0] = s->p[2];
915 s->p[2] = swapbyte;
916
917 swapbyte = s->p[1];
918 s->p[1] = s->p[3];
919 s->p[3] = swapbyte;
920
921 swapbyte = s->p[2];
922 s->p[2] = s->p[3];
923 s->p[3] = swapbyte;
924 }
925 #ifdef WITH_DEBUG
926 /* warning! this debug statement will show passwords in the clear! */
927 hexdump(s->p, s->end - s->p);
928 #endif
929 }
930
931 }
932
933 if (channel != MCS_GLOBAL_CHANNEL)
934 {
935 channel_process(s, channel);
936 *rdpver = 0xff;
937 return s;
938 }
939
940 return s;
941 }
942
943 return NULL;
944 }
945
946 /* Establish a secure connection */
947 BOOL
948 sec_connect(char *server, char *username)
949 {
950 struct stream mcs_data;
951
952 /* We exchange some RDP data during the MCS-Connect */
953 mcs_data.size = 512;
954 mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
955 sec_out_mcs_data(&mcs_data);
956
957 if (!mcs_connect(server, &mcs_data, username))
958 return False;
959
960 /* sec_process_mcs_data(&mcs_data); */
961 if (g_encryption)
962 sec_establish_key();
963 xfree(mcs_data.data);
964 return True;
965 }
966
967 /* Establish a secure connection */
968 BOOL
969 sec_reconnect(char *server)
970 {
971 struct stream mcs_data;
972
973 /* We exchange some RDP data during the MCS-Connect */
974 mcs_data.size = 512;
975 mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
976 sec_out_mcs_data(&mcs_data);
977
978 if (!mcs_reconnect(server, &mcs_data))
979 return False;
980
981 /* sec_process_mcs_data(&mcs_data); */
982 if (g_encryption)
983 sec_establish_key();
984 xfree(mcs_data.data);
985 return True;
986 }
987
988 /* Disconnect a connection */
989 void
990 sec_disconnect(void)
991 {
992 mcs_disconnect();
993 }
994
995 /* reset the state of the sec layer */
996 void
997 sec_reset_state(void)
998 {
999 g_server_rdp_version = 0;
1000 sec_encrypt_use_count = 0;
1001 sec_decrypt_use_count = 0;
1002 mcs_reset_state();
1003 }