/[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 642 - (hide annotations)
Thu Mar 18 02:32:00 2004 UTC (20 years, 2 months ago) by matthewc
File MIME type: text/plain
File size: 21324 byte(s)
Annotate the T.124 bits.

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

  ViewVC Help
Powered by ViewVC 1.1.26