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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1389 - (hide annotations)
Sat Feb 10 05:15:58 2007 UTC (17 years, 3 months ago) by jsorg71
Original Path: sourceforge.net/trunk/rdesktop/secure.c
File MIME type: text/plain
File size: 22725 byte(s)
g_ prefix for global vars

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

  ViewVC Help
Powered by ViewVC 1.1.26