/[rdesktop]/sourceforge.net/trunk/rdesktop/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 /sourceforge.net/trunk/rdesktop/secure.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1385 - (show annotations)
Sat Jan 27 20:38:30 2007 UTC (17 years, 4 months ago) by jsorg71
File MIME type: text/plain
File size: 22613 byte(s)
call ssl.c set key function, not openssl

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-2007
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 uint16 mcs_userid;
37 extern VCHANNEL g_channels[];
38 extern unsigned int g_num_channels;
39
40 static int rc4_key_len;
41 static SSL_RC4 rc4_decrypt_key;
42 static SSL_RC4 rc4_encrypt_key;
43 static uint32 server_public_key_len;
44
45 static uint8 sec_sign_key[16];
46 static uint8 sec_decrypt_key[16];
47 static uint8 sec_encrypt_key[16];
48 static uint8 sec_decrypt_update_key[16];
49 static uint8 sec_encrypt_update_key[16];
50 static uint8 sec_crypted_random[SEC_MAX_MODULUS_SIZE];
51
52 uint16 g_server_rdp_version = 0;
53
54 /* These values must be available to reset state - Session Directory */
55 static int sec_encrypt_use_count = 0;
56 static int sec_decrypt_use_count = 0;
57
58 /*
59 * I believe this is based on SSLv3 with the following differences:
60 * MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
61 * MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
62 * key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
63 * key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
64 * encryption/decryption keys updated every 4096 packets
65 * See http://wp.netscape.com/eng/ssl3/draft302.txt
66 */
67
68 /*
69 * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
70 * Both SHA1 and MD5 algorithms are used.
71 */
72 void
73 sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
74 {
75 uint8 shasig[20];
76 uint8 pad[4];
77 SSL_SHA1 sha1;
78 SSL_MD5 md5;
79 int i;
80
81 for (i = 0; i < 3; i++)
82 {
83 memset(pad, salt + i, i + 1);
84
85 ssl_sha1_init(&sha1);
86 ssl_sha1_update(&sha1, pad, i + 1);
87 ssl_sha1_update(&sha1, in, 48);
88 ssl_sha1_update(&sha1, salt1, 32);
89 ssl_sha1_update(&sha1, salt2, 32);
90 ssl_sha1_final(&sha1, shasig);
91
92 ssl_md5_init(&md5);
93 ssl_md5_update(&md5, in, 48);
94 ssl_md5_update(&md5, shasig, 20);
95 ssl_md5_final(&md5, &out[i * 16]);
96 }
97 }
98
99 /*
100 * 16-byte transformation used to generate export keys (6.2.2).
101 */
102 void
103 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
104 {
105 SSL_MD5 md5;
106
107 ssl_md5_init(&md5);
108 ssl_md5_update(&md5, in, 16);
109 ssl_md5_update(&md5, salt1, 32);
110 ssl_md5_update(&md5, salt2, 32);
111 ssl_md5_final(&md5, out);
112 }
113
114 /* Reduce key entropy from 64 to 40 bits */
115 static void
116 sec_make_40bit(uint8 * key)
117 {
118 key[0] = 0xd1;
119 key[1] = 0x26;
120 key[2] = 0x9e;
121 }
122
123 /* Generate encryption keys given client and server randoms */
124 static void
125 sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
126 {
127 uint8 pre_master_secret[48];
128 uint8 master_secret[48];
129 uint8 key_block[48];
130
131 /* Construct pre-master secret */
132 memcpy(pre_master_secret, client_random, 24);
133 memcpy(pre_master_secret + 24, server_random, 24);
134
135 /* Generate master secret and then key material */
136 sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
137 sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
138
139 /* First 16 bytes of key material is MAC secret */
140 memcpy(sec_sign_key, key_block, 16);
141
142 /* Generate export keys from next two blocks of 16 bytes */
143 sec_hash_16(sec_decrypt_key, &key_block[16], client_random, server_random);
144 sec_hash_16(sec_encrypt_key, &key_block[32], client_random, server_random);
145
146 if (rc4_key_size == 1)
147 {
148 DEBUG(("40-bit encryption enabled\n"));
149 sec_make_40bit(sec_sign_key);
150 sec_make_40bit(sec_decrypt_key);
151 sec_make_40bit(sec_encrypt_key);
152 rc4_key_len = 8;
153 }
154 else
155 {
156 DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
157 rc4_key_len = 16;
158 }
159
160 /* Save initial RC4 keys as update keys */
161 memcpy(sec_decrypt_update_key, sec_decrypt_key, 16);
162 memcpy(sec_encrypt_update_key, sec_encrypt_key, 16);
163
164 /* Initialise RC4 state arrays */
165 ssl_rc4_set_key(&rc4_decrypt_key, sec_decrypt_key, rc4_key_len);
166 ssl_rc4_set_key(&rc4_encrypt_key, sec_encrypt_key, rc4_key_len);
167 }
168
169 static uint8 pad_54[40] = {
170 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
171 54, 54, 54,
172 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
173 54, 54, 54
174 };
175
176 static uint8 pad_92[48] = {
177 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
178 92, 92, 92, 92, 92, 92, 92,
179 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
180 92, 92, 92, 92, 92, 92, 92
181 };
182
183 /* Output a uint32 into a buffer (little-endian) */
184 void
185 buf_out_uint32(uint8 * buffer, uint32 value)
186 {
187 buffer[0] = (value) & 0xff;
188 buffer[1] = (value >> 8) & 0xff;
189 buffer[2] = (value >> 16) & 0xff;
190 buffer[3] = (value >> 24) & 0xff;
191 }
192
193 /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
194 void
195 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
196 {
197 uint8 shasig[20];
198 uint8 md5sig[16];
199 uint8 lenhdr[4];
200 SSL_SHA1 sha1;
201 SSL_MD5 md5;
202
203 buf_out_uint32(lenhdr, datalen);
204
205 ssl_sha1_init(&sha1);
206 ssl_sha1_update(&sha1, session_key, keylen);
207 ssl_sha1_update(&sha1, pad_54, 40);
208 ssl_sha1_update(&sha1, lenhdr, 4);
209 ssl_sha1_update(&sha1, data, datalen);
210 ssl_sha1_final(&sha1, shasig);
211
212 ssl_md5_init(&md5);
213 ssl_md5_update(&md5, session_key, keylen);
214 ssl_md5_update(&md5, pad_92, 48);
215 ssl_md5_update(&md5, shasig, 20);
216 ssl_md5_final(&md5, md5sig);
217
218 memcpy(signature, md5sig, siglen);
219 }
220
221 /* Update an encryption key */
222 static void
223 sec_update(uint8 * key, uint8 * update_key)
224 {
225 uint8 shasig[20];
226 SSL_SHA1 sha1;
227 SSL_MD5 md5;
228 SSL_RC4 update;
229
230 ssl_sha1_init(&sha1);
231 ssl_sha1_update(&sha1, update_key, rc4_key_len);
232 ssl_sha1_update(&sha1, pad_54, 40);
233 ssl_sha1_update(&sha1, key, rc4_key_len);
234 ssl_sha1_final(&sha1, shasig);
235
236 ssl_md5_init(&md5);
237 ssl_md5_update(&md5, update_key, rc4_key_len);
238 ssl_md5_update(&md5, pad_92, 48);
239 ssl_md5_update(&md5, shasig, 20);
240 ssl_md5_final(&md5, key);
241
242 ssl_rc4_set_key(&update, key, rc4_key_len);
243 ssl_rc4_crypt(&update, key, key, rc4_key_len);
244
245 if (rc4_key_len == 8)
246 sec_make_40bit(key);
247 }
248
249 /* Encrypt data using RC4 */
250 static void
251 sec_encrypt(uint8 * data, int length)
252 {
253 if (sec_encrypt_use_count == 4096)
254 {
255 sec_update(sec_encrypt_key, sec_encrypt_update_key);
256 ssl_rc4_set_key(&rc4_encrypt_key, sec_encrypt_key, rc4_key_len);
257 sec_encrypt_use_count = 0;
258 }
259
260 ssl_rc4_crypt(&rc4_encrypt_key, data, data, length);
261 sec_encrypt_use_count++;
262 }
263
264 /* Decrypt data using RC4 */
265 void
266 sec_decrypt(uint8 * data, int length)
267 {
268 if (sec_decrypt_use_count == 4096)
269 {
270 sec_update(sec_decrypt_key, sec_decrypt_update_key);
271 ssl_rc4_set_key(&rc4_decrypt_key, sec_decrypt_key, rc4_key_len);
272 sec_decrypt_use_count = 0;
273 }
274
275 ssl_rc4_crypt(&rc4_decrypt_key, data, data, length);
276 sec_decrypt_use_count++;
277 }
278
279 /* Perform an RSA public key encryption operation */
280 static void
281 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
282 uint8 * exponent)
283 {
284 ssl_rsa_encrypt(out, in, len, modulus_size, modulus, exponent);
285 }
286
287 /* Initialise secure transport packet */
288 STREAM
289 sec_init(uint32 flags, int maxlen)
290 {
291 int hdrlen;
292 STREAM s;
293
294 if (!g_licence_issued)
295 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
296 else
297 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
298 s = mcs_init(maxlen + hdrlen);
299 s_push_layer(s, sec_hdr, hdrlen);
300
301 return s;
302 }
303
304 /* Transmit secure transport packet over specified channel */
305 void
306 sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
307 {
308 int datalen;
309
310 #ifdef WITH_SCARD
311 scard_lock(SCARD_LOCK_SEC);
312 #endif
313
314 s_pop_layer(s, sec_hdr);
315 if (!g_licence_issued || (flags & SEC_ENCRYPT))
316 out_uint32_le(s, flags);
317
318 if (flags & SEC_ENCRYPT)
319 {
320 flags &= ~SEC_ENCRYPT;
321 datalen = s->end - s->p - 8;
322
323 #if WITH_DEBUG
324 DEBUG(("Sending encrypted packet:\n"));
325 hexdump(s->p + 8, datalen);
326 #endif
327
328 sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, datalen);
329 sec_encrypt(s->p + 8, datalen);
330 }
331
332 mcs_send_to_channel(s, channel);
333
334 #ifdef WITH_SCARD
335 scard_unlock(SCARD_LOCK_SEC);
336 #endif
337 }
338
339 /* Transmit secure transport packet */
340
341 void
342 sec_send(STREAM s, uint32 flags)
343 {
344 sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
345 }
346
347
348 /* Transfer the client random to the server */
349 static void
350 sec_establish_key(void)
351 {
352 uint32 length = server_public_key_len + SEC_PADDING_SIZE;
353 uint32 flags = SEC_CLIENT_RANDOM;
354 STREAM s;
355
356 s = sec_init(flags, length + 4);
357
358 out_uint32_le(s, length);
359 out_uint8p(s, sec_crypted_random, server_public_key_len);
360 out_uint8s(s, SEC_PADDING_SIZE);
361
362 s_mark_end(s);
363 sec_send(s, flags);
364 }
365
366 /* Output connect initial data blob */
367 static void
368 sec_out_mcs_data(STREAM s)
369 {
370 int hostlen = 2 * strlen(g_hostname);
371 int length = 158 + 76 + 12 + 4;
372 unsigned int i;
373
374 if (g_num_channels > 0)
375 length += g_num_channels * 12 + 8;
376
377 if (hostlen > 30)
378 hostlen = 30;
379
380 /* Generic Conference Control (T.124) ConferenceCreateRequest */
381 out_uint16_be(s, 5);
382 out_uint16_be(s, 0x14);
383 out_uint8(s, 0x7c);
384 out_uint16_be(s, 1);
385
386 out_uint16_be(s, (length | 0x8000)); /* remaining length */
387
388 out_uint16_be(s, 8); /* length? */
389 out_uint16_be(s, 16);
390 out_uint8(s, 0);
391 out_uint16_le(s, 0xc001);
392 out_uint8(s, 0);
393
394 out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
395 out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
396
397 /* Client information */
398 out_uint16_le(s, SEC_TAG_CLI_INFO);
399 out_uint16_le(s, 212); /* length */
400 out_uint16_le(s, g_use_rdp5 ? 4 : 1); /* RDP version. 1 == RDP4, 4 == RDP5. */
401 out_uint16_le(s, 8);
402 out_uint16_le(s, g_width);
403 out_uint16_le(s, g_height);
404 out_uint16_le(s, 0xca01);
405 out_uint16_le(s, 0xaa03);
406 out_uint32_le(s, g_keylayout);
407 out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
408
409 /* Unicode name of client, padded to 32 bytes */
410 rdp_out_unistr(s, g_hostname, hostlen);
411 out_uint8s(s, 30 - hostlen);
412
413 /* See
414 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
415 out_uint32_le(s, g_keyboard_type);
416 out_uint32_le(s, g_keyboard_subtype);
417 out_uint32_le(s, g_keyboard_functionkeys);
418 out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
419 out_uint16_le(s, 0xca01); /* colour depth? */
420 out_uint16_le(s, 1);
421
422 out_uint32(s, 0);
423 out_uint8(s, g_server_depth);
424 out_uint16_le(s, 0x0700);
425 out_uint8(s, 0);
426 out_uint32_le(s, 1);
427 out_uint8s(s, 64); /* End of client info */
428
429 out_uint16_le(s, SEC_TAG_CLI_4);
430 out_uint16_le(s, 12);
431 out_uint32_le(s, g_console_session ? 0xb : 9);
432 out_uint32(s, 0);
433
434 /* Client encryption settings */
435 out_uint16_le(s, SEC_TAG_CLI_CRYPT);
436 out_uint16_le(s, 12); /* length */
437 out_uint32_le(s, g_encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
438 out_uint32(s, 0); /* Unknown */
439
440 DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
441 if (g_num_channels > 0)
442 {
443 out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
444 out_uint16_le(s, g_num_channels * 12 + 8); /* length */
445 out_uint32_le(s, g_num_channels); /* number of virtual channels */
446 for (i = 0; i < g_num_channels; i++)
447 {
448 DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
449 out_uint8a(s, g_channels[i].name, 8);
450 out_uint32_be(s, g_channels[i].flags);
451 }
452 }
453
454 s_mark_end(s);
455 }
456
457 /* Parse a public key structure */
458 static RD_BOOL
459 sec_parse_public_key(STREAM s, uint8 * modulus, uint8 * exponent)
460 {
461 uint32 magic, modulus_len;
462
463 in_uint32_le(s, magic);
464 if (magic != SEC_RSA_MAGIC)
465 {
466 error("RSA magic 0x%x\n", magic);
467 return False;
468 }
469
470 in_uint32_le(s, modulus_len);
471 modulus_len -= SEC_PADDING_SIZE;
472 if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE))
473 {
474 error("Bad server public key size (%u bits)\n", modulus_len * 8);
475 return False;
476 }
477
478 in_uint8s(s, 8); /* modulus_bits, unknown */
479 in_uint8a(s, exponent, SEC_EXPONENT_SIZE);
480 in_uint8a(s, modulus, modulus_len);
481 in_uint8s(s, SEC_PADDING_SIZE);
482 server_public_key_len = modulus_len;
483
484 return s_check(s);
485 }
486
487 /* Parse a public signature structure */
488 static RD_BOOL
489 sec_parse_public_sig(STREAM s, uint32 len, uint8 * modulus, uint8 * exponent)
490 {
491 uint8 signature[SEC_MAX_MODULUS_SIZE];
492 uint32 sig_len;
493
494 if (len != 72)
495 {
496 return True;
497 }
498 memset(signature, 0, sizeof(signature));
499 sig_len = len - 8;
500 in_uint8a(s, signature, sig_len);
501 return ssl_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, server_public_key_len,
502 signature, sig_len);
503 }
504
505 /* Parse a crypto information structure */
506 static RD_BOOL
507 sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
508 uint8 ** server_random, uint8 * modulus, uint8 * exponent)
509 {
510 uint32 crypt_level, random_len, rsa_info_len;
511 uint32 cacert_len, cert_len, flags;
512 SSL_CERT *cacert, *server_cert;
513 SSL_RKEY *server_public_key;
514 uint16 tag, length;
515 uint8 *next_tag, *end;
516
517 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
518 in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
519 if (crypt_level == 0) /* no encryption */
520 return False;
521 in_uint32_le(s, random_len);
522 in_uint32_le(s, rsa_info_len);
523
524 if (random_len != SEC_RANDOM_SIZE)
525 {
526 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
527 return False;
528 }
529
530 in_uint8p(s, *server_random, random_len);
531
532 /* RSA info */
533 end = s->p + rsa_info_len;
534 if (end > s->end)
535 return False;
536
537 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
538 if (flags & 1)
539 {
540 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
541 in_uint8s(s, 8); /* unknown */
542
543 while (s->p < end)
544 {
545 in_uint16_le(s, tag);
546 in_uint16_le(s, length);
547
548 next_tag = s->p + length;
549
550 switch (tag)
551 {
552 case SEC_TAG_PUBKEY:
553 if (!sec_parse_public_key(s, modulus, exponent))
554 return False;
555 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
556
557 break;
558
559 case SEC_TAG_KEYSIG:
560 if (!sec_parse_public_sig(s, length, modulus, exponent))
561 return False;
562 break;
563
564 default:
565 unimpl("crypt tag 0x%x\n", tag);
566 }
567
568 s->p = next_tag;
569 }
570 }
571 else
572 {
573 uint32 certcount;
574
575 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
576 in_uint32_le(s, certcount); /* Number of certificates */
577 if (certcount < 2)
578 {
579 error("Server didn't send enough X509 certificates\n");
580 return False;
581 }
582 for (; certcount > 2; certcount--)
583 { /* ignore all the certificates between the root and the signing CA */
584 uint32 ignorelen;
585 SSL_CERT *ignorecert;
586
587 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
588 in_uint32_le(s, ignorelen);
589 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
590 ignorecert = ssl_cert_read(s->p, ignorelen);
591 in_uint8s(s, ignorelen);
592 if (ignorecert == NULL)
593 { /* XXX: error out? */
594 DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
595 }
596
597 #ifdef WITH_DEBUG_RDP5
598 DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
599 ssl_cert_print_fp(stdout, ignorecert);
600 #endif
601 }
602 /* Do da funky X.509 stuffy
603
604 "How did I find out about this? I looked up and saw a
605 bright light and when I came to I had a scar on my forehead
606 and knew about X.500"
607 - Peter Gutman in a early version of
608 http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
609 */
610 in_uint32_le(s, cacert_len);
611 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
612 cacert = ssl_cert_read(s->p, cacert_len);
613 in_uint8s(s, cacert_len);
614 if (NULL == cacert)
615 {
616 error("Couldn't load CA Certificate from server\n");
617 return False;
618 }
619 in_uint32_le(s, cert_len);
620 DEBUG_RDP5(("Certificate length is %d\n", cert_len));
621 server_cert = ssl_cert_read(s->p, cert_len);
622 in_uint8s(s, cert_len);
623 if (NULL == server_cert)
624 {
625 ssl_cert_free(cacert);
626 error("Couldn't load Certificate from server\n");
627 return False;
628 }
629 if (!ssl_certs_ok(server_cert, cacert))
630 {
631 ssl_cert_free(server_cert);
632 ssl_cert_free(cacert);
633 error("Security error CA Certificate invalid\n");
634 return False;
635 }
636 ssl_cert_free(cacert);
637 in_uint8s(s, 16); /* Padding */
638 server_public_key = ssl_cert_to_rkey(server_cert, &server_public_key_len);
639 if (NULL == server_public_key)
640 {
641 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
642 ssl_cert_free(server_cert);
643 return False;
644 }
645 ssl_cert_free(server_cert);
646 if ((server_public_key_len < SEC_MODULUS_SIZE) ||
647 (server_public_key_len > SEC_MAX_MODULUS_SIZE))
648 {
649 error("Bad server public key size (%u bits)\n", 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(sec_crypted_random, client_random, SEC_RANDOM_SIZE,
686 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 sec_encrypt_use_count = 0;
894 sec_decrypt_use_count = 0;
895 mcs_reset_state();
896 }

  ViewVC Help
Powered by ViewVC 1.1.26