/[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

Annotation of /sourceforge.net/trunk/rdesktop/secure.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 437 - (hide annotations)
Mon Jul 28 21:41:12 2003 UTC (20 years, 9 months ago) by jsorg71
File MIME type: text/plain
File size: 20369 byte(s)
preceeded more global vars with g_

1 forsberg 352 /* -*- c-basic-offset: 8 -*-
2 matty 10 rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP encryption and licensing
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 matty 10
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 matty 32
23     #ifdef WITH_OPENSSL
24     #include <openssl/rc4.h>
25     #include <openssl/md5.h>
26     #include <openssl/sha.h>
27     #include <openssl/bn.h>
28 forsberg 352 #include <openssl/x509v3.h>
29 matty 32 #else
30 matty 10 #include "crypto/rc4.h"
31     #include "crypto/md5.h"
32     #include "crypto/sha.h"
33 matty 32 #include "crypto/bn.h"
34     #endif
35 matty 10
36     extern char hostname[16];
37     extern int width;
38     extern int height;
39     extern int keylayout;
40 jsorg71 437 extern BOOL g_encryption;
41 jsorg71 380 extern BOOL g_licence_issued;
42 forsberg 352 extern BOOL use_rdp5;
43 jsorg71 309 extern int server_bpp;
44 forsberg 412 extern uint16 mcs_userid;
45 matthewc 432 extern VCHANNEL g_channels[];
46     extern unsigned int g_num_channels;
47 matty 10
48     static int rc4_key_len;
49     static RC4_KEY rc4_decrypt_key;
50     static RC4_KEY rc4_encrypt_key;
51 forsberg 352 static RSA *server_public_key;
52 matty 10
53 matthewc 57 static uint8 sec_sign_key[16];
54 matty 10 static uint8 sec_decrypt_key[16];
55     static uint8 sec_encrypt_key[16];
56 matthewc 57 static uint8 sec_decrypt_update_key[16];
57     static uint8 sec_encrypt_update_key[16];
58     static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
59 matty 10
60 forsberg 352 uint16 server_rdp_version = 0;
61    
62 matty 10 /*
63     * General purpose 48-byte transformation, using two 32-byte salts (generally,
64     * a client and server salt) and a global salt value used for padding.
65     * Both SHA1 and MD5 algorithms are used.
66     */
67 matty 25 void
68 astrand 64 sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
69 matty 10 {
70     uint8 shasig[20];
71     uint8 pad[4];
72     SHA_CTX sha;
73     MD5_CTX md5;
74     int i;
75    
76     for (i = 0; i < 3; i++)
77     {
78 matty 24 memset(pad, salt + i, i + 1);
79 matty 10
80     SHA1_Init(&sha);
81 matty 24 SHA1_Update(&sha, pad, i + 1);
82 matty 10 SHA1_Update(&sha, in, 48);
83     SHA1_Update(&sha, salt1, 32);
84     SHA1_Update(&sha, salt2, 32);
85     SHA1_Final(shasig, &sha);
86    
87     MD5_Init(&md5);
88     MD5_Update(&md5, in, 48);
89     MD5_Update(&md5, shasig, 20);
90 matty 24 MD5_Final(&out[i * 16], &md5);
91 matty 10 }
92     }
93    
94     /*
95     * Weaker 16-byte transformation, also using two 32-byte salts, but
96     * only using a single round of MD5.
97     */
98 matty 25 void
99 astrand 64 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
100 matty 10 {
101     MD5_CTX md5;
102    
103     MD5_Init(&md5);
104     MD5_Update(&md5, in, 16);
105     MD5_Update(&md5, salt1, 32);
106     MD5_Update(&md5, salt2, 32);
107     MD5_Final(out, &md5);
108     }
109    
110     /* Reduce key entropy from 64 to 40 bits */
111 matty 25 static void
112 astrand 64 sec_make_40bit(uint8 * key)
113 matty 10 {
114     key[0] = 0xd1;
115     key[1] = 0x26;
116     key[2] = 0x9e;
117     }
118    
119     /* Generate a session key and RC4 keys, given client and server randoms */
120 matty 25 static void
121 astrand 64 sec_generate_keys(uint8 * client_key, uint8 * server_key, int rc4_key_size)
122 matty 10 {
123     uint8 session_key[48];
124     uint8 temp_hash[48];
125     uint8 input[48];
126    
127     /* Construct input data to hash */
128 matty 24 memcpy(input, client_key, 24);
129     memcpy(input + 24, server_key, 24);
130 matty 10
131     /* Generate session key - two rounds of sec_hash_48 */
132 matty 24 sec_hash_48(temp_hash, input, client_key, server_key, 65);
133 matty 10 sec_hash_48(session_key, temp_hash, client_key, server_key, 88);
134    
135 matthewc 57 /* Store first 16 bytes of session key, for generating signatures */
136     memcpy(sec_sign_key, session_key, 16);
137 matty 10
138     /* Generate RC4 keys */
139 astrand 82 sec_hash_16(sec_decrypt_key, &session_key[16], client_key, server_key);
140     sec_hash_16(sec_encrypt_key, &session_key[32], client_key, server_key);
141 matty 10
142     if (rc4_key_size == 1)
143     {
144 matty 30 DEBUG(("40-bit encryption enabled\n"));
145 matty 10 sec_make_40bit(sec_sign_key);
146     sec_make_40bit(sec_decrypt_key);
147     sec_make_40bit(sec_encrypt_key);
148     rc4_key_len = 8;
149     }
150     else
151     {
152 forsberg 352 DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
153 matty 10 rc4_key_len = 16;
154     }
155    
156 matthewc 57 /* Save initial RC4 keys as update keys */
157     memcpy(sec_decrypt_update_key, sec_decrypt_key, 16);
158     memcpy(sec_encrypt_update_key, sec_encrypt_key, 16);
159 matty 10
160     /* Initialise RC4 state arrays */
161     RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
162     RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
163     }
164    
165 matty 24 static uint8 pad_54[40] = {
166     54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
167 matty 25 54, 54, 54,
168 matty 24 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
169 matty 25 54, 54, 54
170 matty 10 };
171    
172 matty 24 static uint8 pad_92[48] = {
173     92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
174 matty 25 92, 92, 92, 92, 92, 92, 92,
175 matty 24 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
176 matty 25 92, 92, 92, 92, 92, 92, 92
177 matty 10 };
178    
179     /* Output a uint32 into a buffer (little-endian) */
180 matty 25 void
181 astrand 64 buf_out_uint32(uint8 * buffer, uint32 value)
182 matty 10 {
183     buffer[0] = (value) & 0xff;
184     buffer[1] = (value >> 8) & 0xff;
185     buffer[2] = (value >> 16) & 0xff;
186     buffer[3] = (value >> 24) & 0xff;
187     }
188    
189     /* Generate a signature hash, using a combination of SHA1 and MD5 */
190 matty 25 void
191 astrand 82 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
192 matty 10 {
193     uint8 shasig[20];
194     uint8 md5sig[16];
195     uint8 lenhdr[4];
196     SHA_CTX sha;
197     MD5_CTX md5;
198    
199 matty 24 buf_out_uint32(lenhdr, datalen);
200 matty 10
201     SHA1_Init(&sha);
202 matthewc 61 SHA1_Update(&sha, session_key, keylen);
203 matty 10 SHA1_Update(&sha, pad_54, 40);
204     SHA1_Update(&sha, lenhdr, 4);
205     SHA1_Update(&sha, data, datalen);
206     SHA1_Final(shasig, &sha);
207    
208     MD5_Init(&md5);
209 matthewc 61 MD5_Update(&md5, session_key, keylen);
210 matty 10 MD5_Update(&md5, pad_92, 48);
211     MD5_Update(&md5, shasig, 20);
212     MD5_Final(md5sig, &md5);
213    
214 matthewc 61 memcpy(signature, md5sig, siglen);
215 matty 10 }
216    
217     /* Update an encryption key - similar to the signing process */
218 matty 25 static void
219 astrand 64 sec_update(uint8 * key, uint8 * update_key)
220 matty 10 {
221     uint8 shasig[20];
222     SHA_CTX sha;
223     MD5_CTX md5;
224     RC4_KEY update;
225    
226     SHA1_Init(&sha);
227 matthewc 57 SHA1_Update(&sha, update_key, rc4_key_len);
228 matty 10 SHA1_Update(&sha, pad_54, 40);
229 matthewc 57 SHA1_Update(&sha, key, rc4_key_len);
230 matty 10 SHA1_Final(shasig, &sha);
231    
232     MD5_Init(&md5);
233 matthewc 57 MD5_Update(&md5, update_key, rc4_key_len);
234 matty 10 MD5_Update(&md5, pad_92, 48);
235     MD5_Update(&md5, shasig, 20);
236     MD5_Final(key, &md5);
237    
238     RC4_set_key(&update, rc4_key_len, key);
239     RC4(&update, rc4_key_len, key, key);
240    
241     if (rc4_key_len == 8)
242     sec_make_40bit(key);
243     }
244    
245     /* Encrypt data using RC4 */
246 matty 25 static void
247 astrand 64 sec_encrypt(uint8 * data, int length)
248 matty 10 {
249     static int use_count;
250    
251     if (use_count == 4096)
252     {
253     sec_update(sec_encrypt_key, sec_encrypt_update_key);
254     RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
255     use_count = 0;
256     }
257    
258     RC4(&rc4_encrypt_key, length, data, data);
259     use_count++;
260     }
261    
262     /* Decrypt data using RC4 */
263 forsberg 352 void
264 astrand 64 sec_decrypt(uint8 * data, int length)
265 matty 10 {
266     static int use_count;
267    
268     if (use_count == 4096)
269     {
270     sec_update(sec_decrypt_key, sec_decrypt_update_key);
271     RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
272     use_count = 0;
273     }
274    
275     RC4(&rc4_decrypt_key, length, data, data);
276     use_count++;
277     }
278    
279 matty 25 static void
280 astrand 64 reverse(uint8 * p, int len)
281 matty 10 {
282     int i, j;
283 matty 32 uint8 temp;
284 matty 10
285 astrand 64 for (i = 0, j = len - 1; i < j; i++, j--)
286 matty 10 {
287 matty 32 temp = p[i];
288     p[i] = p[j];
289     p[j] = temp;
290 matty 10 }
291     }
292    
293     /* Perform an RSA public key encryption operation */
294 matty 25 static void
295 astrand 82 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
296 matty 10 {
297 matthewc 295 BN_CTX *ctx;
298 matty 32 BIGNUM mod, exp, x, y;
299     uint8 inr[SEC_MODULUS_SIZE];
300     int outlen;
301 matty 10
302 matty 32 reverse(modulus, SEC_MODULUS_SIZE);
303     reverse(exponent, SEC_EXPONENT_SIZE);
304     memcpy(inr, in, len);
305     reverse(inr, len);
306 matty 10
307 matthewc 295 ctx = BN_CTX_new();
308 matty 32 BN_init(&mod);
309     BN_init(&exp);
310     BN_init(&x);
311     BN_init(&y);
312    
313     BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
314     BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
315     BN_bin2bn(inr, len, &x);
316 matthewc 295 BN_mod_exp(&y, &x, &exp, &mod, ctx);
317 matty 32 outlen = BN_bn2bin(&y, out);
318     reverse(out, outlen);
319     if (outlen < SEC_MODULUS_SIZE)
320 astrand 64 memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
321 matty 32
322     BN_free(&y);
323     BN_clear_free(&x);
324     BN_free(&exp);
325     BN_free(&mod);
326 matthewc 295 BN_CTX_free(ctx);
327 matty 10 }
328    
329     /* Initialise secure transport packet */
330 matty 25 STREAM
331     sec_init(uint32 flags, int maxlen)
332 matty 10 {
333     int hdrlen;
334     STREAM s;
335    
336 jsorg71 380 if (!g_licence_issued)
337 matty 28 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
338     else
339     hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
340 matty 24 s = mcs_init(maxlen + hdrlen);
341 matty 10 s_push_layer(s, sec_hdr, hdrlen);
342    
343     return s;
344     }
345    
346 forsberg 412 /* Transmit secure transport packet over specified channel */
347 matty 25 void
348 forsberg 412 sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
349 matty 10 {
350     int datalen;
351    
352     s_pop_layer(s, sec_hdr);
353 jsorg71 380 if (!g_licence_issued || (flags & SEC_ENCRYPT))
354 matty 28 out_uint32_le(s, flags);
355 matty 10
356     if (flags & SEC_ENCRYPT)
357     {
358     flags &= ~SEC_ENCRYPT;
359     datalen = s->end - s->p - 8;
360    
361 matty 30 #if WITH_DEBUG
362     DEBUG(("Sending encrypted packet:\n"));
363 matty 24 hexdump(s->p + 8, datalen);
364 matty 10 #endif
365    
366 astrand 82 sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, datalen);
367 matty 24 sec_encrypt(s->p + 8, datalen);
368 matty 10 }
369    
370 forsberg 412 mcs_send_to_channel(s, channel);
371 matty 10 }
372    
373 forsberg 412 /* Transmit secure transport packet */
374    
375     void
376     sec_send(STREAM s, uint32 flags)
377     {
378     sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
379     }
380    
381    
382 matty 10 /* Transfer the client random to the server */
383 matty 25 static void
384 matthewc 192 sec_establish_key(void)
385 matty 10 {
386     uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
387     uint32 flags = SEC_CLIENT_RANDOM;
388     STREAM s;
389    
390     s = sec_init(flags, 76);
391    
392     out_uint32_le(s, length);
393     out_uint8p(s, sec_crypted_random, SEC_MODULUS_SIZE);
394     out_uint8s(s, SEC_PADDING_SIZE);
395    
396     s_mark_end(s);
397     sec_send(s, flags);
398     }
399    
400     /* Output connect initial data blob */
401 matty 25 static void
402     sec_out_mcs_data(STREAM s)
403 matty 10 {
404     int hostlen = 2 * strlen(hostname);
405 matthewc 432 int length = 158 + 76 + 12 + 4;
406     unsigned int i;
407 astrand 101
408 matthewc 432 if (g_num_channels > 0)
409 astrand 435 length += g_num_channels * 12 + 8;
410 forsberg 412
411 jsorg71 88 if (hostlen > 30)
412     hostlen = 30;
413 matty 10
414     out_uint16_be(s, 5); /* unknown */
415     out_uint16_be(s, 0x14);
416     out_uint8(s, 0x7c);
417     out_uint16_be(s, 1);
418    
419 forsberg 352 out_uint16_be(s, (length | 0x8000)); /* remaining length */
420 matty 10
421     out_uint16_be(s, 8); /* length? */
422     out_uint16_be(s, 16);
423     out_uint8(s, 0);
424     out_uint16_le(s, 0xc001);
425     out_uint8(s, 0);
426    
427 matty 24 out_uint32_le(s, 0x61637544); /* "Duca" ?! */
428 forsberg 352 out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
429 matty 10
430     /* Client information */
431     out_uint16_le(s, SEC_TAG_CLI_INFO);
432 forsberg 352 out_uint16_le(s, 212); /* length */
433     out_uint16_le(s, use_rdp5 ? 4 : 1); /* RDP version. 1 == RDP4, 4 == RDP5. */
434 matty 10 out_uint16_le(s, 8);
435     out_uint16_le(s, width);
436     out_uint16_le(s, height);
437     out_uint16_le(s, 0xca01);
438     out_uint16_le(s, 0xaa03);
439     out_uint32_le(s, keylayout);
440 forsberg 352 out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
441 matty 10
442     /* Unicode name of client, padded to 32 bytes */
443     rdp_out_unistr(s, hostname, hostlen);
444 matty 24 out_uint8s(s, 30 - hostlen);
445 matty 10
446     out_uint32_le(s, 4);
447     out_uint32(s, 0);
448     out_uint32_le(s, 12);
449 matty 24 out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
450 matty 10
451 jsorg71 315 switch (server_bpp)
452 jsorg71 309 {
453 jsorg71 315 case 8:
454     out_uint16_le(s, 0xca01);
455     break;
456     case 15:
457     out_uint16_le(s, 0xca02);
458     break;
459     case 16:
460     out_uint16_le(s, 0xca03);
461     break;
462     case 24:
463     out_uint16_le(s, 0xca04);
464     break;
465 jsorg71 309 }
466 matthewc 365 out_uint16_le(s, 1);
467 matty 10
468 forsberg 352 out_uint32(s, 0);
469 forsberg 357 out_uint8(s, server_bpp);
470     out_uint16_le(s, 0x0700);
471     out_uint8(s, 0);
472 forsberg 352 out_uint32_le(s, 1);
473     out_uint8s(s, 64); /* End of client info */
474    
475     out_uint16_le(s, SEC_TAG_CLI_4);
476     out_uint16_le(s, 12);
477     out_uint32_le(s, 9);
478 matthewc 365 out_uint32(s, 0);
479 forsberg 352
480 matty 10 /* Client encryption settings */
481     out_uint16_le(s, SEC_TAG_CLI_CRYPT);
482 forsberg 352 out_uint16_le(s, 12); /* length */
483 jsorg71 437 out_uint32_le(s, g_encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
484 matthewc 365 out_uint32(s, 0); /* Unknown */
485 forsberg 352
486 matthewc 432 DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
487     if (g_num_channels > 0)
488 forsberg 412 {
489     out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
490 matthewc 432 out_uint16_le(s, g_num_channels * 12 + 8); /* length */
491     out_uint32_le(s, g_num_channels); /* number of virtual channels */
492     for (i = 0; i < g_num_channels; i++)
493 forsberg 412 {
494 matthewc 432 DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
495     out_uint8a(s, g_channels[i].name, 8);
496     out_uint32_be(s, g_channels[i].flags);
497 forsberg 412 }
498     }
499 forsberg 352
500 matty 10 s_mark_end(s);
501     }
502    
503     /* Parse a public key structure */
504 matty 25 static BOOL
505 astrand 64 sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
506 matty 10 {
507     uint32 magic, modulus_len;
508    
509     in_uint32_le(s, magic);
510     if (magic != SEC_RSA_MAGIC)
511     {
512 matty 30 error("RSA magic 0x%x\n", magic);
513 matty 10 return False;
514     }
515    
516     in_uint32_le(s, modulus_len);
517     if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
518     {
519 matty 30 error("modulus len 0x%x\n", modulus_len);
520 matty 10 return False;
521     }
522    
523 matty 24 in_uint8s(s, 8); /* modulus_bits, unknown */
524 matty 10 in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);
525     in_uint8p(s, *modulus, SEC_MODULUS_SIZE);
526     in_uint8s(s, SEC_PADDING_SIZE);
527    
528     return s_check(s);
529     }
530    
531 forsberg 352 static BOOL
532     sec_parse_x509_key(X509 * cert)
533     {
534     EVP_PKEY *epk = NULL;
535     /* By some reason, Microsoft sets the OID of the Public RSA key to
536     the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
537    
538     Kudos to Richard Levitte for the following (. intiutive .)
539     lines of code that resets the OID and let's us extract the key. */
540     if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
541     {
542     DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
543     cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
544     }
545     epk = X509_get_pubkey(cert);
546     if (NULL == epk)
547     {
548     error("Failed to extract public key from certificate\n");
549     return False;
550     }
551    
552     server_public_key = (RSA *) epk->pkey.ptr;
553    
554     return True;
555     }
556    
557    
558 matty 10 /* Parse a crypto information structure */
559 matty 25 static BOOL
560 astrand 64 sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
561 astrand 82 uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
562 matty 10 {
563     uint32 crypt_level, random_len, rsa_info_len;
564 matthewc 363 uint32 cacert_len, cert_len, flags;
565 forsberg 352 X509 *cacert, *server_cert;
566 matty 10 uint16 tag, length;
567     uint8 *next_tag, *end;
568    
569 matty 24 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
570     in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
571 forsberg 352 if (crypt_level == 0) /* no encryption */
572 jsorg71 89 return False;
573 matty 10 in_uint32_le(s, random_len);
574     in_uint32_le(s, rsa_info_len);
575    
576     if (random_len != SEC_RANDOM_SIZE)
577     {
578 forsberg 352 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
579 matty 10 return False;
580     }
581    
582     in_uint8p(s, *server_random, random_len);
583    
584     /* RSA info */
585     end = s->p + rsa_info_len;
586     if (end > s->end)
587     return False;
588    
589 forsberg 412 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
590 matthewc 363 if (flags & 1)
591 forsberg 352 {
592     DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
593 matthewc 363 in_uint8s(s, 8); /* unknown */
594 matty 10
595 forsberg 352 while (s->p < end)
596     {
597     in_uint16_le(s, tag);
598     in_uint16_le(s, length);
599    
600     next_tag = s->p + length;
601    
602     switch (tag)
603     {
604     case SEC_TAG_PUBKEY:
605     if (!sec_parse_public_key(s, modulus, exponent))
606     return False;
607     DEBUG_RDP5(("Got Public key, RDP4-style\n"));
608    
609     break;
610    
611     case SEC_TAG_KEYSIG:
612     /* Is this a Microsoft key that we just got? */
613     /* Care factor: zero! */
614     /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
615     key as a known key of the hostname. This would prevent some MITM-attacks. */
616     break;
617    
618     default:
619     unimpl("crypt tag 0x%x\n", tag);
620     }
621    
622     s->p = next_tag;
623     }
624     }
625 matthewc 363 else
626 matty 10 {
627 forsberg 352 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
628 matthewc 363 in_uint8s(s, 4); /* Number of certificates */
629 matty 10
630 forsberg 352 /* Do da funky X.509 stuffy
631 matty 10
632 forsberg 352 "How did I find out about this? I looked up and saw a
633     bright light and when I came to I had a scar on my forehead
634     and knew about X.500"
635     - Peter Gutman in a early version of
636     http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
637     */
638    
639     in_uint32_le(s, cacert_len);
640 forsberg 419 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
641 forsberg 352 cacert = d2i_X509(NULL, &(s->p), cacert_len);
642     /* Note: We don't need to move s->p here - d2i_X509 is
643     "kind" enough to do it for us */
644     if (NULL == cacert)
645 matty 10 {
646 forsberg 352 error("Couldn't load CA Certificate from server\n");
647     return False;
648     }
649 matty 10
650 forsberg 352 /* Currently, we don't use the CA Certificate.
651     FIXME:
652     *) Verify the server certificate (server_cert) with the
653     CA certificate.
654     *) Store the CA Certificate with the hostname of the
655     server we are connecting to as key, and compare it
656     when we connect the next time, in order to prevent
657     MITM-attacks.
658     */
659 matty 10
660 forsberg 352 in_uint32_le(s, cert_len);
661 forsberg 419 DEBUG_RDP5(("Certificate length is %d\n", cert_len));
662 forsberg 352 server_cert = d2i_X509(NULL, &(s->p), cert_len);
663     if (NULL == server_cert)
664     {
665     error("Couldn't load Certificate from server\n");
666     return False;
667     }
668 matty 10
669 forsberg 352 in_uint8s(s, 16); /* Padding */
670    
671     /* Note: Verifying the server certificate must be done here,
672     before sec_parse_public_key since we'll have to apply
673     serious violence to the key after this */
674    
675     if (!sec_parse_x509_key(server_cert))
676     {
677     DEBUG_RDP5(("Didn't parse X509 correctly\n"));
678     return False;
679 matty 10 }
680 forsberg 352 return True; /* There's some garbage here we don't care about */
681 matty 10 }
682     return s_check_end(s);
683     }
684    
685     /* Process crypto information blob */
686 matty 25 static void
687     sec_process_crypt_info(STREAM s)
688 matty 10 {
689     uint8 *server_random, *modulus, *exponent;
690     uint8 client_random[SEC_RANDOM_SIZE];
691     uint32 rc4_key_size;
692 forsberg 352 uint8 inr[SEC_MODULUS_SIZE];
693 matty 10
694 astrand 82 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
695 forsberg 352 {
696     DEBUG(("Failed to parse crypt info\n"));
697 matty 10 return;
698 forsberg 352 }
699 matty 10
700 forsberg 352 DEBUG(("Generating client random\n"));
701 forsberg 412 /* Generate a client random, and hence determine encryption keys */
702 forsberg 352 // This is what the MS client do:
703 forsberg 377 memset(inr, 0, SEC_RANDOM_SIZE);
704     /* *ARIGL!* Plaintext attack, anyone?
705 forsberg 412 I tried doing:
706     generate_random(inr);
707     ..but that generates connection errors now and then (yes,
708     "now and then". Something like 0 to 3 attempts needed before a
709     successful connection. Nice. Not!
710     */
711 forsberg 377
712 matty 10 generate_random(client_random);
713 forsberg 352 if (NULL != server_public_key)
714     { /* Which means we should use
715     RDP5-style encryption */
716    
717     memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
718     reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
719    
720     RSA_public_encrypt(SEC_MODULUS_SIZE,
721     inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
722    
723     reverse(sec_crypted_random, SEC_MODULUS_SIZE);
724    
725     }
726     else
727     { /* RDP4-style encryption */
728     sec_rsa_encrypt(sec_crypted_random,
729     client_random, SEC_RANDOM_SIZE, modulus, exponent);
730     }
731 matty 10 sec_generate_keys(client_random, server_random, rc4_key_size);
732     }
733    
734 forsberg 352
735     /* Process SRV_INFO, find RDP version supported by server */
736     static void
737     sec_process_srv_info(STREAM s)
738     {
739     in_uint16_le(s, server_rdp_version);
740     DEBUG_RDP5(("Server RDP version is %d\n", server_rdp_version));
741 forsberg 421 if (1 == server_rdp_version)
742     use_rdp5 = 0;
743 forsberg 352 }
744    
745    
746 matty 10 /* Process connect response data blob */
747 forsberg 352 void
748 matty 25 sec_process_mcs_data(STREAM s)
749 matty 10 {
750     uint16 tag, length;
751     uint8 *next_tag;
752 jsorg71 90 uint8 len;
753 matty 10
754 forsberg 352 in_uint8s(s, 21); /* header (T.124 stuff, probably) */
755 jsorg71 90 in_uint8(s, len);
756     if (len & 0x80)
757     in_uint8(s, len);
758 matty 10
759     while (s->p < s->end)
760     {
761     in_uint16_le(s, tag);
762     in_uint16_le(s, length);
763    
764     if (length <= 4)
765     return;
766    
767     next_tag = s->p + length - 4;
768    
769     switch (tag)
770     {
771     case SEC_TAG_SRV_INFO:
772 forsberg 352 sec_process_srv_info(s);
773     break;
774    
775 matthewc 432 case SEC_TAG_SRV_CRYPT:
776     sec_process_crypt_info(s);
777     break;
778    
779     case SEC_TAG_SRV_CHANNELS:
780 forsberg 419 /* FIXME: We should parse this information and
781     use it to map RDP5 channels to MCS
782 astrand 435 channels */
783 matty 10 break;
784    
785     default:
786 matty 30 unimpl("response tag 0x%x\n", tag);
787 matty 10 }
788    
789     s->p = next_tag;
790     }
791     }
792    
793     /* Receive secure transport packet */
794 matty 25 STREAM
795 matthewc 192 sec_recv(void)
796 matty 10 {
797     uint32 sec_flags;
798 forsberg 352 uint16 channel;
799 matty 10 STREAM s;
800    
801 forsberg 352 while ((s = mcs_recv(&channel)) != NULL)
802 matty 10 {
803 jsorg71 437 if (g_encryption || !g_licence_issued)
804 matty 10 {
805 matty 28 in_uint32_le(s, sec_flags);
806 matty 10
807 matthewc 432 if (sec_flags & SEC_ENCRYPT)
808     {
809     in_uint8s(s, 8); /* signature */
810     sec_decrypt(s->p, s->end - s->p);
811     }
812    
813 matty 28 if (sec_flags & SEC_LICENCE_NEG)
814     {
815     licence_process(s);
816     continue;
817     }
818 matty 10 }
819    
820 matthewc 432 if (channel != MCS_GLOBAL_CHANNEL)
821 forsberg 352 {
822 matthewc 432 channel_process(s, channel);
823     continue;
824 forsberg 352 }
825    
826 matthewc 432 return s;
827 matty 10 }
828    
829     return NULL;
830     }
831    
832     /* Establish a secure connection */
833 matty 25 BOOL
834 forsberg 352 sec_connect(char *server, char *username)
835 matty 10 {
836     struct stream mcs_data;
837    
838     /* We exchange some RDP data during the MCS-Connect */
839     mcs_data.size = 512;
840 forsberg 412 mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
841 matty 10 sec_out_mcs_data(&mcs_data);
842    
843 forsberg 352 if (!mcs_connect(server, &mcs_data, username))
844 matty 10 return False;
845    
846 forsberg 352 // sec_process_mcs_data(&mcs_data);
847 jsorg71 437 if (g_encryption)
848 matty 28 sec_establish_key();
849 matthewc 218 xfree(mcs_data.data);
850 matty 10 return True;
851     }
852    
853     /* Disconnect a connection */
854 matty 25 void
855 matthewc 192 sec_disconnect(void)
856 matty 10 {
857     mcs_disconnect();
858     }

  ViewVC Help
Powered by ViewVC 1.1.26