/[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 1365 - (show annotations)
Thu Jan 4 05:39:39 2007 UTC (17 years, 4 months ago) by jsorg71
File MIME type: text/plain
File size: 24922 byte(s)
copyright year update

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

  ViewVC Help
Powered by ViewVC 1.1.26