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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 430 - (show annotations)
Mon Jun 30 08:59:07 2003 UTC (20 years, 10 months ago) by forsberg
File MIME type: text/plain
File size: 15299 byte(s)
This commit was generated by cvs2svn to compensate for changes in r428,
which included commits to RCS files with non-trunk default branches.

1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - RDP encryption and licensing
4 Copyright (C) Matthew Chapman 1999-2001
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 #define WITH_OPENSSL
22 #include "../rdesktop/rdesktop.h"
23
24 #ifdef WITH_OPENSSL
25 #include <openssl/rc4.h>
26 #include <openssl/md5.h>
27 #include <openssl/sha.h>
28 #include <openssl/bn.h>
29 #else
30 #include "crypto/rc4.h"
31 #include "crypto/md5.h"
32 #include "crypto/sha.h"
33 #include "crypto/bn.h"
34 #endif
35
36 extern char hostname[16];
37 extern int width;
38 extern int height;
39 extern int keylayout;
40 extern BOOL encryption;
41 extern BOOL licence_issued;
42
43 static int rc4_key_len;
44 static RC4_KEY rc4_decrypt_key;
45 static RC4_KEY rc4_encrypt_key;
46 static RC4_KEY rc4_encrypt_key2;
47
48 static uint8 sec_sign_key[16];
49 static uint8 sec_decrypt_key[16];
50 static uint8 sec_encrypt_key[16];
51 static uint8 sec_encrypt_key2[16];
52 static uint8 sec_decrypt_update_key[16];
53 static uint8 sec_encrypt_update_key[16];
54 static uint8 sec_encrypt_update_key2[16];
55 static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
56
57 /*
58 * General purpose 48-byte transformation, using two 32-byte salts (generally,
59 * a client and server salt) and a global salt value used for padding.
60 * Both SHA1 and MD5 algorithms are used.
61 */
62 void
63 sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
64 {
65 uint8 shasig[20];
66 uint8 pad[4];
67 SHA_CTX sha;
68 MD5_CTX md5;
69 int i;
70
71 for (i = 0; i < 3; i++)
72 {
73 memset(pad, salt + i, i + 1);
74
75 SHA1_Init(&sha);
76 SHA1_Update(&sha, pad, i + 1);
77 SHA1_Update(&sha, in, 48);
78 SHA1_Update(&sha, salt1, 32);
79 SHA1_Update(&sha, salt2, 32);
80 SHA1_Final(shasig, &sha);
81
82 MD5_Init(&md5);
83 MD5_Update(&md5, in, 48);
84 MD5_Update(&md5, shasig, 20);
85 MD5_Final(&out[i * 16], &md5);
86 }
87 }
88
89 /*
90 * Weaker 16-byte transformation, also using two 32-byte salts, but
91 * only using a single round of MD5.
92 */
93 void
94 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
95 {
96 MD5_CTX md5;
97
98 MD5_Init(&md5);
99 MD5_Update(&md5, in, 16);
100 MD5_Update(&md5, salt1, 32);
101 MD5_Update(&md5, salt2, 32);
102 MD5_Final(out, &md5);
103 }
104
105 /* Reduce key entropy from 64 to 40 bits */
106 static void
107 sec_make_40bit(uint8 * key)
108 {
109 key[0] = 0xd1;
110 key[1] = 0x26;
111 key[2] = 0x9e;
112 }
113
114 /* Generate a session key and RC4 keys, given client and server randoms */
115 void
116 sec_generate_keys(uint8 * client_key, uint8 * server_key, int rc4_key_size)
117 {
118 uint8 session_key[48];
119 uint8 temp_hash[48];
120 uint8 input[48];
121
122 /* Construct input data to hash */
123 memcpy(input, client_key, 24);
124 memcpy(input + 24, server_key, 24);
125
126 /* Generate session key - two rounds of sec_hash_48 */
127 sec_hash_48(temp_hash, input, client_key, server_key, 65);
128 sec_hash_48(session_key, temp_hash, client_key, server_key, 88);
129
130 /* Store first 16 bytes of session key, for generating signatures */
131 memcpy(sec_sign_key, session_key, 16);
132
133 /* Generate RC4 keys */
134 sec_hash_16(sec_decrypt_key, &session_key[16], client_key, server_key);
135 sec_hash_16(sec_encrypt_key, &session_key[32], client_key, server_key);
136
137 if (rc4_key_size == 1)
138 {
139 DEBUG(("40-bit encryption enabled\n"));
140 sec_make_40bit(sec_sign_key);
141 sec_make_40bit(sec_decrypt_key);
142 sec_make_40bit(sec_encrypt_key);
143 rc4_key_len = 8;
144 }
145 else
146 {
147 DEBUG(("128-bit encryption enabled\n"));
148 rc4_key_len = 16;
149 }
150
151 /* Save initial RC4 keys as update keys */
152 memcpy(sec_decrypt_update_key, sec_decrypt_key, 16);
153 memcpy(sec_encrypt_update_key, sec_encrypt_key, 16);
154 memcpy(sec_encrypt_key2, sec_encrypt_key, 16);
155 memcpy(sec_encrypt_update_key2, sec_encrypt_key2, 16);
156
157 /* Initialise RC4 state arrays */
158 RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
159 RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
160 RC4_set_key(&rc4_encrypt_key2, rc4_key_len, sec_encrypt_key2);
161 }
162
163 static uint8 pad_54[40] = {
164 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
165 54, 54, 54,
166 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
167 54, 54, 54
168 };
169
170 static uint8 pad_92[48] = {
171 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
172 92, 92, 92, 92, 92, 92, 92,
173 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
174 92, 92, 92, 92, 92, 92, 92
175 };
176
177 // #if 0
178 /* Output a uint32 into a buffer (little-endian) */
179 void
180 buf_out_uint32(uint8 * buffer, uint32 value)
181 {
182 buffer[0] = (value) & 0xff;
183 buffer[1] = (value >> 8) & 0xff;
184 buffer[2] = (value >> 16) & 0xff;
185 buffer[3] = (value >> 24) & 0xff;
186 }
187
188 void
189 buf_out_uint16le(uint8 * buffer, uint16 value)
190 {
191 buffer[0] = (value) & 0xff;
192 buffer[1] = (value >> 8) & 0xff;
193 }
194
195 void
196 buf_out_uint16be(uint8 * buffer, uint16 value)
197 {
198 buffer[1] = (value) & 0xff;
199 buffer[0] = (value >> 8) & 0xff;
200 }
201
202 uint32
203 buf_in_uint32le(uint8 * buffer)
204 {
205 return (uint32) (buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24));
206 }
207
208 uint16
209 buf_in_uint16be(uint8 * buffer)
210 {
211 return (uint16) ((buffer[0] << 8) | buffer[1]);
212 }
213
214
215
216 /* Generate a signature hash, using a combination of SHA1 and MD5 */
217 void
218 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
219 {
220 uint8 shasig[20];
221 uint8 md5sig[16];
222 uint8 lenhdr[4];
223 SHA_CTX sha;
224 MD5_CTX md5;
225
226 buf_out_uint32(lenhdr, datalen);
227
228 SHA1_Init(&sha);
229 SHA1_Update(&sha, session_key, keylen);
230 SHA1_Update(&sha, pad_54, 40);
231 SHA1_Update(&sha, lenhdr, 4);
232 SHA1_Update(&sha, data, datalen);
233 SHA1_Final(shasig, &sha);
234
235 MD5_Init(&md5);
236 MD5_Update(&md5, session_key, keylen);
237 MD5_Update(&md5, pad_92, 48);
238 MD5_Update(&md5, shasig, 20);
239 MD5_Final(md5sig, &md5);
240
241 memcpy(signature, md5sig, siglen);
242 }
243
244 void
245 sec_sign_buf(uint8 * signature, int siglen, uint8 * data, int datalen)
246 {
247 sec_sign(signature, siglen, sec_sign_key, rc4_key_len, data, datalen);
248 }
249
250
251
252 // #endif
253
254 /* Update an encryption key - similar to the signing process */
255 static void
256 sec_update(uint8 * key, uint8 * update_key)
257 {
258 uint8 shasig[20];
259 SHA_CTX sha;
260 MD5_CTX md5;
261 RC4_KEY update;
262
263 SHA1_Init(&sha);
264 SHA1_Update(&sha, update_key, rc4_key_len);
265 SHA1_Update(&sha, pad_54, 40);
266 SHA1_Update(&sha, key, rc4_key_len);
267 SHA1_Final(shasig, &sha);
268
269 MD5_Init(&md5);
270 MD5_Update(&md5, update_key, rc4_key_len);
271 MD5_Update(&md5, pad_92, 48);
272 MD5_Update(&md5, shasig, 20);
273 MD5_Final(key, &md5);
274
275 RC4_set_key(&update, rc4_key_len, key);
276 RC4(&update, rc4_key_len, key, key);
277
278 if (rc4_key_len == 8)
279 sec_make_40bit(key);
280 }
281
282 /* Encrypt data using RC4 */
283 void
284 sec_encrypt(uint8 * data, int length)
285 {
286 static int use_count;
287
288 if (use_count == 4096)
289 {
290 sec_update(sec_encrypt_key, sec_encrypt_update_key);
291 RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
292 use_count = 0;
293 }
294
295 RC4(&rc4_encrypt_key, length, data, data);
296 use_count++;
297 }
298
299 /* Encrypt data using RC4 */
300 void
301 sec_encrypt2(uint8 * data, int length)
302 {
303 static int use_count;
304
305 if (use_count == 4096)
306 {
307 sec_update(sec_encrypt_key2, sec_encrypt_update_key2);
308 RC4_set_key(&rc4_encrypt_key2, rc4_key_len, sec_encrypt_key2);
309 use_count = 0;
310 }
311
312 RC4(&rc4_encrypt_key2, length, data, data);
313 use_count++;
314 }
315
316 /* Decrypt data using RC4 */
317 void
318 sec_decrypt(uint8 * data, int length)
319 {
320 static int use_count;
321
322 if (use_count == 4096)
323 {
324 sec_update(sec_decrypt_key, sec_decrypt_update_key);
325 RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
326 use_count = 0;
327 }
328
329 RC4(&rc4_decrypt_key, length, data, data);
330 use_count++;
331 }
332
333 #if 0
334 static void
335 reverse(uint8 * p, int len)
336 {
337 int i, j;
338 uint8 temp;
339
340 for (i = 0, j = len - 1; i < j; i++, j--)
341 {
342 temp = p[i];
343 p[i] = p[j];
344 p[j] = temp;
345 }
346 }
347
348 /* Perform an RSA public key encryption operation */
349 static void
350 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
351 {
352 BN_CTX ctx;
353 BIGNUM mod, exp, x, y;
354 uint8 inr[SEC_MODULUS_SIZE];
355 int outlen;
356
357 reverse(modulus, SEC_MODULUS_SIZE);
358 reverse(exponent, SEC_EXPONENT_SIZE);
359 memcpy(inr, in, len);
360 reverse(inr, len);
361
362 BN_CTX_init(&ctx);
363 BN_init(&mod);
364 BN_init(&exp);
365 BN_init(&x);
366 BN_init(&y);
367
368 BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
369 BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
370 BN_bin2bn(inr, len, &x);
371 BN_mod_exp(&y, &x, &exp, &mod, &ctx);
372 outlen = BN_bn2bin(&y, out);
373 reverse(out, outlen);
374 if (outlen < SEC_MODULUS_SIZE)
375 memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
376
377 BN_free(&y);
378 BN_clear_free(&x);
379 BN_free(&exp);
380 BN_free(&mod);
381 BN_CTX_free(&ctx);
382 }
383
384 /* Initialise secure transport packet */
385 STREAM
386 sec_init(uint32 flags, int maxlen)
387 {
388 int hdrlen;
389 STREAM s;
390
391 if (!licence_issued)
392 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
393 else
394 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
395 s = mcs_init(maxlen + hdrlen);
396 s_push_layer(s, sec_hdr, hdrlen);
397
398 return s;
399 }
400
401 /* Transmit secure transport packet */
402 void
403 sec_send(STREAM s, uint32 flags)
404 {
405 int datalen;
406
407 s_pop_layer(s, sec_hdr);
408 if (!licence_issued || (flags & SEC_ENCRYPT))
409 out_uint32_le(s, flags);
410
411 if (flags & SEC_ENCRYPT)
412 {
413 flags &= ~SEC_ENCRYPT;
414 datalen = s->end - s->p - 8;
415
416 #if WITH_DEBUG
417 DEBUG(("Sending encrypted packet:\n"));
418 hexdump(s->p + 8, datalen);
419 #endif
420
421 sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, datalen);
422 sec_encrypt(s->p + 8, datalen);
423 }
424
425 mcs_send(s);
426 }
427
428 /* Transfer the client random to the server */
429 static void
430 sec_establish_key()
431 {
432 uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
433 uint32 flags = SEC_CLIENT_RANDOM;
434 STREAM s;
435
436 s = sec_init(flags, 76);
437
438 out_uint32_le(s, length);
439 out_uint8p(s, sec_crypted_random, SEC_MODULUS_SIZE);
440 out_uint8s(s, SEC_PADDING_SIZE);
441
442 s_mark_end(s);
443 sec_send(s, flags);
444 }
445
446 /* Output connect initial data blob */
447 static void
448 sec_out_mcs_data(STREAM s)
449 {
450 int hostlen = 2 * strlen(hostname);
451
452 out_uint16_be(s, 5); /* unknown */
453 out_uint16_be(s, 0x14);
454 out_uint8(s, 0x7c);
455 out_uint16_be(s, 1);
456
457 out_uint16_be(s, (158 | 0x8000)); /* remaining length */
458
459 out_uint16_be(s, 8); /* length? */
460 out_uint16_be(s, 16);
461 out_uint8(s, 0);
462 out_uint16_le(s, 0xc001);
463 out_uint8(s, 0);
464
465 out_uint32_le(s, 0x61637544); /* "Duca" ?! */
466 out_uint16_be(s, (144 | 0x8000)); /* remaining length */
467
468 /* Client information */
469 out_uint16_le(s, SEC_TAG_CLI_INFO);
470 out_uint16_le(s, 136); /* length */
471 out_uint16_le(s, 1);
472 out_uint16_le(s, 8);
473 out_uint16_le(s, width);
474 out_uint16_le(s, height);
475 out_uint16_le(s, 0xca01);
476 out_uint16_le(s, 0xaa03);
477 out_uint32_le(s, keylayout);
478 out_uint32_le(s, 419); /* client build? we are 419 compatible :-) */
479
480 /* Unicode name of client, padded to 32 bytes */
481 rdp_out_unistr(s, hostname, hostlen);
482 out_uint8s(s, 30 - hostlen);
483
484 out_uint32_le(s, 4);
485 out_uint32(s, 0);
486 out_uint32_le(s, 12);
487 out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
488
489 out_uint16_le(s, 0xca01);
490 out_uint16(s, 0);
491
492 /* Client encryption settings */
493 out_uint16_le(s, SEC_TAG_CLI_CRYPT);
494 out_uint16_le(s, 8); /* length */
495 out_uint32_le(s, encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
496 s_mark_end(s);
497 }
498
499 /* Parse a public key structure */
500 static BOOL
501 sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
502 {
503 uint32 magic, modulus_len;
504
505 in_uint32_le(s, magic);
506 if (magic != SEC_RSA_MAGIC)
507 {
508 error("RSA magic 0x%x\n", magic);
509 return False;
510 }
511
512 in_uint32_le(s, modulus_len);
513 if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
514 {
515 error("modulus len 0x%x\n", modulus_len);
516 return False;
517 }
518
519 in_uint8s(s, 8); /* modulus_bits, unknown */
520 in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);
521 in_uint8p(s, *modulus, SEC_MODULUS_SIZE);
522 in_uint8s(s, SEC_PADDING_SIZE);
523
524 return s_check(s);
525 }
526
527 /* Parse a crypto information structure */
528 static BOOL
529 sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
530 uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
531 {
532 uint32 crypt_level, random_len, rsa_info_len;
533 uint16 tag, length;
534 uint8 *next_tag, *end;
535
536 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
537 in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
538 in_uint32_le(s, random_len);
539 in_uint32_le(s, rsa_info_len);
540
541 if (random_len != SEC_RANDOM_SIZE)
542 {
543 error("random len %d\n", random_len);
544 return False;
545 }
546
547 in_uint8p(s, *server_random, random_len);
548
549 /* RSA info */
550 end = s->p + rsa_info_len;
551 if (end > s->end)
552 return False;
553
554 in_uint8s(s, 12); /* unknown */
555
556 while (s->p < end)
557 {
558 in_uint16_le(s, tag);
559 in_uint16_le(s, length);
560
561 next_tag = s->p + length;
562
563 switch (tag)
564 {
565 case SEC_TAG_PUBKEY:
566 if (!sec_parse_public_key(s, modulus, exponent))
567 return False;
568
569 break;
570
571 case SEC_TAG_KEYSIG:
572 /* Is this a Microsoft key that we just got? */
573 /* Care factor: zero! */
574 break;
575
576 default:
577 unimpl("crypt tag 0x%x\n", tag);
578 }
579
580 s->p = next_tag;
581 }
582
583 return s_check_end(s);
584 }
585
586 /* Process crypto information blob */
587 static void
588 sec_process_crypt_info(STREAM s)
589 {
590 uint8 *server_random, *modulus, *exponent;
591 uint8 client_random[SEC_RANDOM_SIZE];
592 uint32 rc4_key_size;
593
594 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
595 return;
596
597 /* Generate a client random, and hence determine encryption keys */
598 generate_random(client_random);
599 sec_rsa_encrypt(sec_crypted_random, client_random, SEC_RANDOM_SIZE, modulus, exponent);
600 sec_generate_keys(client_random, server_random, rc4_key_size);
601 }
602
603 /* Process connect response data blob */
604 static void
605 sec_process_mcs_data(STREAM s)
606 {
607 uint16 tag, length;
608 uint8 *next_tag;
609
610 in_uint8s(s, 23); /* header */
611
612 while (s->p < s->end)
613 {
614 in_uint16_le(s, tag);
615 in_uint16_le(s, length);
616
617 if (length <= 4)
618 return;
619
620 next_tag = s->p + length - 4;
621
622 switch (tag)
623 {
624 case SEC_TAG_SRV_INFO:
625 case SEC_TAG_SRV_3:
626 break;
627
628 case SEC_TAG_SRV_CRYPT:
629 sec_process_crypt_info(s);
630 break;
631
632 default:
633 unimpl("response tag 0x%x\n", tag);
634 }
635
636 s->p = next_tag;
637 }
638 }
639
640 /* Receive secure transport packet */
641 STREAM
642 sec_recv()
643 {
644 uint32 sec_flags;
645 STREAM s;
646
647 while ((s = mcs_recv()) != NULL)
648 {
649 if (encryption || !licence_issued)
650 {
651 in_uint32_le(s, sec_flags);
652
653 if (sec_flags & SEC_LICENCE_NEG)
654 {
655 licence_process(s);
656 continue;
657 }
658
659 if (sec_flags & SEC_ENCRYPT)
660 {
661 in_uint8s(s, 8); /* signature */
662 sec_decrypt(s->p, s->end - s->p);
663 }
664 }
665
666 return s;
667 }
668
669 return NULL;
670 }
671
672 /* Establish a secure connection */
673 BOOL
674 sec_connect(char *server)
675 {
676 struct stream mcs_data;
677
678 /* We exchange some RDP data during the MCS-Connect */
679 mcs_data.size = 512;
680 mcs_data.p = mcs_data.data = xmalloc(mcs_data.size);
681 sec_out_mcs_data(&mcs_data);
682
683 if (!mcs_connect(server, &mcs_data))
684 return False;
685
686 sec_process_mcs_data(&mcs_data);
687 if (encryption)
688 sec_establish_key();
689 return True;
690 }
691
692 /* Disconnect a connection */
693 void
694 sec_disconnect()
695 {
696 mcs_disconnect();
697 }
698 #endif

  ViewVC Help
Powered by ViewVC 1.1.26