/[rdesktop]/jpeg/rdesktop/trunk/secure.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /jpeg/rdesktop/trunk/secure.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1507 - (show annotations)
Mon Jul 20 16:45:11 2009 UTC (14 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 22734 byte(s)
branch for integration of Daniel Jarboe <daniel.jarboe(at)gmail.com>
patches for jpeg
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-2008
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
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "rdesktop.h"
22 #include "ssl.h"
23
24 extern char g_hostname[16];
25 extern int g_width;
26 extern int g_height;
27 extern unsigned int g_keylayout;
28 extern int g_keyboard_type;
29 extern int g_keyboard_subtype;
30 extern int g_keyboard_functionkeys;
31 extern RD_BOOL g_encryption;
32 extern RD_BOOL g_licence_issued;
33 extern RD_BOOL g_use_rdp5;
34 extern RD_BOOL g_console_session;
35 extern int g_server_depth;
36 extern VCHANNEL g_channels[];
37 extern unsigned int g_num_channels;
38
39 static int g_rc4_key_len;
40 static SSL_RC4 g_rc4_decrypt_key;
41 static SSL_RC4 g_rc4_encrypt_key;
42 static uint32 g_server_public_key_len;
43
44 static uint8 g_sec_sign_key[16];
45 static uint8 g_sec_decrypt_key[16];
46 static uint8 g_sec_encrypt_key[16];
47 static uint8 g_sec_decrypt_update_key[16];
48 static uint8 g_sec_encrypt_update_key[16];
49 static uint8 g_sec_crypted_random[SEC_MAX_MODULUS_SIZE];
50
51 uint16 g_server_rdp_version = 0;
52
53 /* These values must be available to reset state - Session Directory */
54 static int g_sec_encrypt_use_count = 0;
55 static int g_sec_decrypt_use_count = 0;
56
57 /*
58 * I believe this is based on SSLv3 with the following differences:
59 * MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
60 * MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
61 * key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
62 * key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
63 * encryption/decryption keys updated every 4096 packets
64 * See http://wp.netscape.com/eng/ssl3/draft302.txt
65 */
66
67 /*
68 * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
69 * Both SHA1 and MD5 algorithms are used.
70 */
71 void
72 sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
73 {
74 uint8 shasig[20];
75 uint8 pad[4];
76 SSL_SHA1 sha1;
77 SSL_MD5 md5;
78 int i;
79
80 for (i = 0; i < 3; i++)
81 {
82 memset(pad, salt + i, i + 1);
83
84 ssl_sha1_init(&sha1);
85 ssl_sha1_update(&sha1, pad, i + 1);
86 ssl_sha1_update(&sha1, in, 48);
87 ssl_sha1_update(&sha1, salt1, 32);
88 ssl_sha1_update(&sha1, salt2, 32);
89 ssl_sha1_final(&sha1, shasig);
90
91 ssl_md5_init(&md5);
92 ssl_md5_update(&md5, in, 48);
93 ssl_md5_update(&md5, shasig, 20);
94 ssl_md5_final(&md5, &out[i * 16]);
95 }
96 }
97
98 /*
99 * 16-byte transformation used to generate export keys (6.2.2).
100 */
101 void
102 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
103 {
104 SSL_MD5 md5;
105
106 ssl_md5_init(&md5);
107 ssl_md5_update(&md5, in, 16);
108 ssl_md5_update(&md5, salt1, 32);
109 ssl_md5_update(&md5, salt2, 32);
110 ssl_md5_final(&md5, out);
111 }
112
113 /* Reduce key entropy from 64 to 40 bits */
114 static void
115 sec_make_40bit(uint8 * key)
116 {
117 key[0] = 0xd1;
118 key[1] = 0x26;
119 key[2] = 0x9e;
120 }
121
122 /* Generate encryption keys given client and server randoms */
123 static void
124 sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
125 {
126 uint8 pre_master_secret[48];
127 uint8 master_secret[48];
128 uint8 key_block[48];
129
130 /* Construct pre-master secret */
131 memcpy(pre_master_secret, client_random, 24);
132 memcpy(pre_master_secret + 24, server_random, 24);
133
134 /* Generate master secret and then key material */
135 sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
136 sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
137
138 /* First 16 bytes of key material is MAC secret */
139 memcpy(g_sec_sign_key, key_block, 16);
140
141 /* Generate export keys from next two blocks of 16 bytes */
142 sec_hash_16(g_sec_decrypt_key, &key_block[16], client_random, server_random);
143 sec_hash_16(g_sec_encrypt_key, &key_block[32], client_random, server_random);
144
145 if (rc4_key_size == 1)
146 {
147 DEBUG(("40-bit encryption enabled\n"));
148 sec_make_40bit(g_sec_sign_key);
149 sec_make_40bit(g_sec_decrypt_key);
150 sec_make_40bit(g_sec_encrypt_key);
151 g_rc4_key_len = 8;
152 }
153 else
154 {
155 DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
156 g_rc4_key_len = 16;
157 }
158
159 /* Save initial RC4 keys as update keys */
160 memcpy(g_sec_decrypt_update_key, g_sec_decrypt_key, 16);
161 memcpy(g_sec_encrypt_update_key, g_sec_encrypt_key, 16);
162
163 /* Initialise RC4 state arrays */
164 ssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
165 ssl_rc4_set_key(&g_rc4_encrypt_key, g_sec_encrypt_key, g_rc4_key_len);
166 }
167
168 static uint8 pad_54[40] = {
169 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
170 54, 54, 54,
171 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
172 54, 54, 54
173 };
174
175 static uint8 pad_92[48] = {
176 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
177 92, 92, 92, 92, 92, 92, 92,
178 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
179 92, 92, 92, 92, 92, 92, 92
180 };
181
182 /* Output a uint32 into a buffer (little-endian) */
183 void
184 buf_out_uint32(uint8 * buffer, uint32 value)
185 {
186 buffer[0] = (value) & 0xff;
187 buffer[1] = (value >> 8) & 0xff;
188 buffer[2] = (value >> 16) & 0xff;
189 buffer[3] = (value >> 24) & 0xff;
190 }
191
192 /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
193 void
194 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
195 {
196 uint8 shasig[20];
197 uint8 md5sig[16];
198 uint8 lenhdr[4];
199 SSL_SHA1 sha1;
200 SSL_MD5 md5;
201
202 buf_out_uint32(lenhdr, datalen);
203
204 ssl_sha1_init(&sha1);
205 ssl_sha1_update(&sha1, session_key, keylen);
206 ssl_sha1_update(&sha1, pad_54, 40);
207 ssl_sha1_update(&sha1, lenhdr, 4);
208 ssl_sha1_update(&sha1, data, datalen);
209 ssl_sha1_final(&sha1, shasig);
210
211 ssl_md5_init(&md5);
212 ssl_md5_update(&md5, session_key, keylen);
213 ssl_md5_update(&md5, pad_92, 48);
214 ssl_md5_update(&md5, shasig, 20);
215 ssl_md5_final(&md5, md5sig);
216
217 memcpy(signature, md5sig, siglen);
218 }
219
220 /* Update an encryption key */
221 static void
222 sec_update(uint8 * key, uint8 * update_key)
223 {
224 uint8 shasig[20];
225 SSL_SHA1 sha1;
226 SSL_MD5 md5;
227 SSL_RC4 update;
228
229 ssl_sha1_init(&sha1);
230 ssl_sha1_update(&sha1, update_key, g_rc4_key_len);
231 ssl_sha1_update(&sha1, pad_54, 40);
232 ssl_sha1_update(&sha1, key, g_rc4_key_len);
233 ssl_sha1_final(&sha1, shasig);
234
235 ssl_md5_init(&md5);
236 ssl_md5_update(&md5, update_key, g_rc4_key_len);
237 ssl_md5_update(&md5, pad_92, 48);
238 ssl_md5_update(&md5, shasig, 20);
239 ssl_md5_final(&md5, key);
240
241 ssl_rc4_set_key(&update, key, g_rc4_key_len);
242 ssl_rc4_crypt(&update, key, key, g_rc4_key_len);
243
244 if (g_rc4_key_len == 8)
245 sec_make_40bit(key);
246 }
247
248 /* Encrypt data using RC4 */
249 static void
250 sec_encrypt(uint8 * data, int length)
251 {
252 if (g_sec_encrypt_use_count == 4096)
253 {
254 sec_update(g_sec_encrypt_key, g_sec_encrypt_update_key);
255 ssl_rc4_set_key(&g_rc4_encrypt_key, g_sec_encrypt_key, g_rc4_key_len);
256 g_sec_encrypt_use_count = 0;
257 }
258
259 ssl_rc4_crypt(&g_rc4_encrypt_key, data, data, length);
260 g_sec_encrypt_use_count++;
261 }
262
263 /* Decrypt data using RC4 */
264 void
265 sec_decrypt(uint8 * data, int length)
266 {
267 if (g_sec_decrypt_use_count == 4096)
268 {
269 sec_update(g_sec_decrypt_key, g_sec_decrypt_update_key);
270 ssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
271 g_sec_decrypt_use_count = 0;
272 }
273
274 ssl_rc4_crypt(&g_rc4_decrypt_key, data, data, length);
275 g_sec_decrypt_use_count++;
276 }
277
278 /* Perform an RSA public key encryption operation */
279 static void
280 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
281 uint8 * exponent)
282 {
283 ssl_rsa_encrypt(out, in, len, modulus_size, modulus, exponent);
284 }
285
286 /* Initialise secure transport packet */
287 STREAM
288 sec_init(uint32 flags, int maxlen)
289 {
290 int hdrlen;
291 STREAM s;
292
293 if (!g_licence_issued)
294 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
295 else
296 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
297 s = mcs_init(maxlen + hdrlen);
298 s_push_layer(s, sec_hdr, hdrlen);
299
300 return s;
301 }
302
303 /* Transmit secure transport packet over specified channel */
304 void
305 sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
306 {
307 int datalen;
308
309 #ifdef WITH_SCARD
310 scard_lock(SCARD_LOCK_SEC);
311 #endif
312
313 s_pop_layer(s, sec_hdr);
314 if (!g_licence_issued || (flags & SEC_ENCRYPT))
315 out_uint32_le(s, flags);
316
317 if (flags & SEC_ENCRYPT)
318 {
319 flags &= ~SEC_ENCRYPT;
320 datalen = s->end - s->p - 8;
321
322 #if WITH_DEBUG
323 DEBUG(("Sending encrypted packet:\n"));
324 hexdump(s->p + 8, datalen);
325 #endif
326
327 sec_sign(s->p, 8, g_sec_sign_key, g_rc4_key_len, s->p + 8, datalen);
328 sec_encrypt(s->p + 8, datalen);
329 }
330
331 mcs_send_to_channel(s, channel);
332
333 #ifdef WITH_SCARD
334 scard_unlock(SCARD_LOCK_SEC);
335 #endif
336 }
337
338 /* Transmit secure transport packet */
339
340 void
341 sec_send(STREAM s, uint32 flags)
342 {
343 sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
344 }
345
346
347 /* Transfer the client random to the server */
348 static void
349 sec_establish_key(void)
350 {
351 uint32 length = g_server_public_key_len + SEC_PADDING_SIZE;
352 uint32 flags = SEC_CLIENT_RANDOM;
353 STREAM s;
354
355 s = sec_init(flags, length + 4);
356
357 out_uint32_le(s, length);
358 out_uint8p(s, g_sec_crypted_random, g_server_public_key_len);
359 out_uint8s(s, SEC_PADDING_SIZE);
360
361 s_mark_end(s);
362 sec_send(s, flags);
363 }
364
365 /* Output connect initial data blob */
366 static void
367 sec_out_mcs_data(STREAM s)
368 {
369 int hostlen = 2 * strlen(g_hostname);
370 int length = 158 + 76 + 12 + 4;
371 unsigned int i;
372
373 if (g_num_channels > 0)
374 length += g_num_channels * 12 + 8;
375
376 if (hostlen > 30)
377 hostlen = 30;
378
379 /* Generic Conference Control (T.124) ConferenceCreateRequest */
380 out_uint16_be(s, 5);
381 out_uint16_be(s, 0x14);
382 out_uint8(s, 0x7c);
383 out_uint16_be(s, 1);
384
385 out_uint16_be(s, (length | 0x8000)); /* remaining length */
386
387 out_uint16_be(s, 8); /* length? */
388 out_uint16_be(s, 16);
389 out_uint8(s, 0);
390 out_uint16_le(s, 0xc001);
391 out_uint8(s, 0);
392
393 out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
394 out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
395
396 /* Client information */
397 out_uint16_le(s, SEC_TAG_CLI_INFO);
398 out_uint16_le(s, 212); /* length */
399 out_uint16_le(s, g_use_rdp5 ? 4 : 1); /* RDP version. 1 == RDP4, 4 == RDP5. */
400 out_uint16_le(s, 8);
401 out_uint16_le(s, g_width);
402 out_uint16_le(s, g_height);
403 out_uint16_le(s, 0xca01);
404 out_uint16_le(s, 0xaa03);
405 out_uint32_le(s, g_keylayout);
406 out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
407
408 /* Unicode name of client, padded to 32 bytes */
409 rdp_out_unistr(s, g_hostname, hostlen);
410 out_uint8s(s, 30 - hostlen);
411
412 /* See
413 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
414 out_uint32_le(s, g_keyboard_type);
415 out_uint32_le(s, g_keyboard_subtype);
416 out_uint32_le(s, g_keyboard_functionkeys);
417 out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
418 out_uint16_le(s, 0xca01); /* colour depth? */
419 out_uint16_le(s, 1);
420
421 out_uint32(s, 0);
422 out_uint8(s, g_server_depth);
423 out_uint16_le(s, 0x0700);
424 out_uint8(s, 0);
425 out_uint32_le(s, 1);
426 out_uint8s(s, 64); /* End of client info */
427
428 out_uint16_le(s, SEC_TAG_CLI_4);
429 out_uint16_le(s, 12);
430 out_uint32_le(s, g_console_session ? 0xb : 9);
431 out_uint32(s, 0);
432
433 /* Client encryption settings */
434 out_uint16_le(s, SEC_TAG_CLI_CRYPT);
435 out_uint16_le(s, 12); /* length */
436 out_uint32_le(s, g_encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
437 out_uint32(s, 0); /* Unknown */
438
439 DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
440 if (g_num_channels > 0)
441 {
442 out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
443 out_uint16_le(s, g_num_channels * 12 + 8); /* length */
444 out_uint32_le(s, g_num_channels); /* number of virtual channels */
445 for (i = 0; i < g_num_channels; i++)
446 {
447 DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
448 out_uint8a(s, g_channels[i].name, 8);
449 out_uint32_be(s, g_channels[i].flags);
450 }
451 }
452
453 s_mark_end(s);
454 }
455
456 /* Parse a public key structure */
457 static RD_BOOL
458 sec_parse_public_key(STREAM s, uint8 * modulus, uint8 * exponent)
459 {
460 uint32 magic, modulus_len;
461
462 in_uint32_le(s, magic);
463 if (magic != SEC_RSA_MAGIC)
464 {
465 error("RSA magic 0x%x\n", magic);
466 return False;
467 }
468
469 in_uint32_le(s, modulus_len);
470 modulus_len -= SEC_PADDING_SIZE;
471 if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE))
472 {
473 error("Bad server public key size (%u bits)\n", modulus_len * 8);
474 return False;
475 }
476
477 in_uint8s(s, 8); /* modulus_bits, unknown */
478 in_uint8a(s, exponent, SEC_EXPONENT_SIZE);
479 in_uint8a(s, modulus, modulus_len);
480 in_uint8s(s, SEC_PADDING_SIZE);
481 g_server_public_key_len = modulus_len;
482
483 return s_check(s);
484 }
485
486 /* Parse a public signature structure */
487 static RD_BOOL
488 sec_parse_public_sig(STREAM s, uint32 len, uint8 * modulus, uint8 * exponent)
489 {
490 uint8 signature[SEC_MAX_MODULUS_SIZE];
491 uint32 sig_len;
492
493 if (len != 72)
494 {
495 return True;
496 }
497 memset(signature, 0, sizeof(signature));
498 sig_len = len - 8;
499 in_uint8a(s, signature, sig_len);
500 return ssl_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, g_server_public_key_len,
501 signature, sig_len);
502 }
503
504 /* Parse a crypto information structure */
505 static RD_BOOL
506 sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
507 uint8 ** server_random, uint8 * modulus, uint8 * exponent)
508 {
509 uint32 crypt_level, random_len, rsa_info_len;
510 uint32 cacert_len, cert_len, flags;
511 SSL_CERT *cacert, *server_cert;
512 SSL_RKEY *server_public_key;
513 uint16 tag, length;
514 uint8 *next_tag, *end;
515
516 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
517 in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
518 if (crypt_level == 0) /* no encryption */
519 return False;
520 in_uint32_le(s, random_len);
521 in_uint32_le(s, rsa_info_len);
522
523 if (random_len != SEC_RANDOM_SIZE)
524 {
525 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
526 return False;
527 }
528
529 in_uint8p(s, *server_random, random_len);
530
531 /* RSA info */
532 end = s->p + rsa_info_len;
533 if (end > s->end)
534 return False;
535
536 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
537 if (flags & 1)
538 {
539 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
540 in_uint8s(s, 8); /* unknown */
541
542 while (s->p < end)
543 {
544 in_uint16_le(s, tag);
545 in_uint16_le(s, length);
546
547 next_tag = s->p + length;
548
549 switch (tag)
550 {
551 case SEC_TAG_PUBKEY:
552 if (!sec_parse_public_key(s, modulus, exponent))
553 return False;
554 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
555
556 break;
557
558 case SEC_TAG_KEYSIG:
559 if (!sec_parse_public_sig(s, length, modulus, exponent))
560 return False;
561 break;
562
563 default:
564 unimpl("crypt tag 0x%x\n", tag);
565 }
566
567 s->p = next_tag;
568 }
569 }
570 else
571 {
572 uint32 certcount;
573
574 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
575 in_uint32_le(s, certcount); /* Number of certificates */
576 if (certcount < 2)
577 {
578 error("Server didn't send enough X509 certificates\n");
579 return False;
580 }
581 for (; certcount > 2; certcount--)
582 { /* ignore all the certificates between the root and the signing CA */
583 uint32 ignorelen;
584 SSL_CERT *ignorecert;
585
586 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
587 in_uint32_le(s, ignorelen);
588 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
589 ignorecert = ssl_cert_read(s->p, ignorelen);
590 in_uint8s(s, ignorelen);
591 if (ignorecert == NULL)
592 { /* XXX: error out? */
593 DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
594 }
595
596 #ifdef WITH_DEBUG_RDP5
597 DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
598 ssl_cert_print_fp(stdout, ignorecert);
599 #endif
600 }
601 /* Do da funky X.509 stuffy
602
603 "How did I find out about this? I looked up and saw a
604 bright light and when I came to I had a scar on my forehead
605 and knew about X.500"
606 - Peter Gutman in a early version of
607 http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
608 */
609 in_uint32_le(s, cacert_len);
610 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
611 cacert = ssl_cert_read(s->p, cacert_len);
612 in_uint8s(s, cacert_len);
613 if (NULL == cacert)
614 {
615 error("Couldn't load CA Certificate from server\n");
616 return False;
617 }
618 in_uint32_le(s, cert_len);
619 DEBUG_RDP5(("Certificate length is %d\n", cert_len));
620 server_cert = ssl_cert_read(s->p, cert_len);
621 in_uint8s(s, cert_len);
622 if (NULL == server_cert)
623 {
624 ssl_cert_free(cacert);
625 error("Couldn't load Certificate from server\n");
626 return False;
627 }
628 if (!ssl_certs_ok(server_cert, cacert))
629 {
630 ssl_cert_free(server_cert);
631 ssl_cert_free(cacert);
632 error("Security error CA Certificate invalid\n");
633 return False;
634 }
635 ssl_cert_free(cacert);
636 in_uint8s(s, 16); /* Padding */
637 server_public_key = ssl_cert_to_rkey(server_cert, &g_server_public_key_len);
638 if (NULL == server_public_key)
639 {
640 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
641 ssl_cert_free(server_cert);
642 return False;
643 }
644 ssl_cert_free(server_cert);
645 if ((g_server_public_key_len < SEC_MODULUS_SIZE) ||
646 (g_server_public_key_len > SEC_MAX_MODULUS_SIZE))
647 {
648 error("Bad server public key size (%u bits)\n",
649 g_server_public_key_len * 8);
650 ssl_rkey_free(server_public_key);
651 return False;
652 }
653 if (ssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
654 modulus, SEC_MAX_MODULUS_SIZE) != 0)
655 {
656 error("Problem extracting RSA exponent, modulus");
657 ssl_rkey_free(server_public_key);
658 return False;
659 }
660 ssl_rkey_free(server_public_key);
661 return True; /* There's some garbage here we don't care about */
662 }
663 return s_check_end(s);
664 }
665
666 /* Process crypto information blob */
667 static void
668 sec_process_crypt_info(STREAM s)
669 {
670 uint8 *server_random = NULL;
671 uint8 client_random[SEC_RANDOM_SIZE];
672 uint8 modulus[SEC_MAX_MODULUS_SIZE];
673 uint8 exponent[SEC_EXPONENT_SIZE];
674 uint32 rc4_key_size;
675
676 memset(modulus, 0, sizeof(modulus));
677 memset(exponent, 0, sizeof(exponent));
678 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, modulus, exponent))
679 {
680 DEBUG(("Failed to parse crypt info\n"));
681 return;
682 }
683 DEBUG(("Generating client random\n"));
684 generate_random(client_random);
685 sec_rsa_encrypt(g_sec_crypted_random, client_random, SEC_RANDOM_SIZE,
686 g_server_public_key_len, modulus, exponent);
687 sec_generate_keys(client_random, server_random, rc4_key_size);
688 }
689
690
691 /* Process SRV_INFO, find RDP version supported by server */
692 static void
693 sec_process_srv_info(STREAM s)
694 {
695 in_uint16_le(s, g_server_rdp_version);
696 DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
697 if (1 == g_server_rdp_version)
698 {
699 g_use_rdp5 = 0;
700 g_server_depth = 8;
701 }
702 }
703
704
705 /* Process connect response data blob */
706 void
707 sec_process_mcs_data(STREAM s)
708 {
709 uint16 tag, length;
710 uint8 *next_tag;
711 uint8 len;
712
713 in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */
714 in_uint8(s, len);
715 if (len & 0x80)
716 in_uint8(s, len);
717
718 while (s->p < s->end)
719 {
720 in_uint16_le(s, tag);
721 in_uint16_le(s, length);
722
723 if (length <= 4)
724 return;
725
726 next_tag = s->p + length - 4;
727
728 switch (tag)
729 {
730 case SEC_TAG_SRV_INFO:
731 sec_process_srv_info(s);
732 break;
733
734 case SEC_TAG_SRV_CRYPT:
735 sec_process_crypt_info(s);
736 break;
737
738 case SEC_TAG_SRV_CHANNELS:
739 /* FIXME: We should parse this information and
740 use it to map RDP5 channels to MCS
741 channels */
742 break;
743
744 default:
745 unimpl("response tag 0x%x\n", tag);
746 }
747
748 s->p = next_tag;
749 }
750 }
751
752 /* Receive secure transport packet */
753 STREAM
754 sec_recv(uint8 * rdpver)
755 {
756 uint32 sec_flags;
757 uint16 channel;
758 STREAM s;
759
760 while ((s = mcs_recv(&channel, rdpver)) != NULL)
761 {
762 if (rdpver != NULL)
763 {
764 if (*rdpver != 3)
765 {
766 if (*rdpver & 0x80)
767 {
768 in_uint8s(s, 8); /* signature */
769 sec_decrypt(s->p, s->end - s->p);
770 }
771 return s;
772 }
773 }
774 if (g_encryption || !g_licence_issued)
775 {
776 in_uint32_le(s, sec_flags);
777
778 if (sec_flags & SEC_ENCRYPT)
779 {
780 in_uint8s(s, 8); /* signature */
781 sec_decrypt(s->p, s->end - s->p);
782 }
783
784 if (sec_flags & SEC_LICENCE_NEG)
785 {
786 licence_process(s);
787 continue;
788 }
789
790 if (sec_flags & 0x0400) /* SEC_REDIRECT_ENCRYPT */
791 {
792 uint8 swapbyte;
793
794 in_uint8s(s, 8); /* signature */
795 sec_decrypt(s->p, s->end - s->p);
796
797 /* Check for a redirect packet, starts with 00 04 */
798 if (s->p[0] == 0 && s->p[1] == 4)
799 {
800 /* for some reason the PDU and the length seem to be swapped.
801 This isn't good, but we're going to do a byte for byte
802 swap. So the first foure value appear as: 00 04 XX YY,
803 where XX YY is the little endian length. We're going to
804 use 04 00 as the PDU type, so after our swap this will look
805 like: XX YY 04 00 */
806 swapbyte = s->p[0];
807 s->p[0] = s->p[2];
808 s->p[2] = swapbyte;
809
810 swapbyte = s->p[1];
811 s->p[1] = s->p[3];
812 s->p[3] = swapbyte;
813
814 swapbyte = s->p[2];
815 s->p[2] = s->p[3];
816 s->p[3] = swapbyte;
817 }
818 #ifdef WITH_DEBUG
819 /* warning! this debug statement will show passwords in the clear! */
820 hexdump(s->p, s->end - s->p);
821 #endif
822 }
823
824 }
825
826 if (channel != MCS_GLOBAL_CHANNEL)
827 {
828 channel_process(s, channel);
829 *rdpver = 0xff;
830 return s;
831 }
832
833 return s;
834 }
835
836 return NULL;
837 }
838
839 /* Establish a secure connection */
840 RD_BOOL
841 sec_connect(char *server, char *username)
842 {
843 struct stream mcs_data;
844
845 /* We exchange some RDP data during the MCS-Connect */
846 mcs_data.size = 512;
847 mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
848 sec_out_mcs_data(&mcs_data);
849
850 if (!mcs_connect(server, &mcs_data, username))
851 return False;
852
853 /* sec_process_mcs_data(&mcs_data); */
854 if (g_encryption)
855 sec_establish_key();
856 xfree(mcs_data.data);
857 return True;
858 }
859
860 /* Establish a secure connection */
861 RD_BOOL
862 sec_reconnect(char *server)
863 {
864 struct stream mcs_data;
865
866 /* We exchange some RDP data during the MCS-Connect */
867 mcs_data.size = 512;
868 mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
869 sec_out_mcs_data(&mcs_data);
870
871 if (!mcs_reconnect(server, &mcs_data))
872 return False;
873
874 /* sec_process_mcs_data(&mcs_data); */
875 if (g_encryption)
876 sec_establish_key();
877 xfree(mcs_data.data);
878 return True;
879 }
880
881 /* Disconnect a connection */
882 void
883 sec_disconnect(void)
884 {
885 mcs_disconnect();
886 }
887
888 /* reset the state of the sec layer */
889 void
890 sec_reset_state(void)
891 {
892 g_server_rdp_version = 0;
893 g_sec_encrypt_use_count = 0;
894 g_sec_decrypt_use_count = 0;
895 mcs_reset_state();
896 }

  ViewVC Help
Powered by ViewVC 1.1.26