~ubuntu-branches/ubuntu/quantal/freerdp/quantal

« back to all changes in this revision

Viewing changes to libfreerdp/secure.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2010-06-23 21:39:09 UTC
  • Revision ID: james.westby@ubuntu.com-20100623213909-bb9pvvv03913tdv6
Tags: upstream-0.7.1
ImportĀ upstreamĀ versionĀ 0.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- c-basic-offset: 8 -*-
 
2
   FreeRDP: A Remote Desktop Protocol client.
 
3
   Protocol services - RDP encryption and licensing
 
4
   Copyright (C) Matthew Chapman 1999-2008
 
5
 
 
6
   This program is free software; you can redistribute it and/or modify
 
7
   it under the terms of the GNU General Public License as published by
 
8
   the Free Software Foundation; either version 2 of the License, or
 
9
   (at your option) any later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program; if not, write to the Free Software
 
18
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
*/
 
20
 
 
21
#include "frdp.h"
 
22
#include "mcs.h"
 
23
#include "chan.h"
 
24
#include "secure.h"
 
25
#include "licence.h"
 
26
#include "rdp.h"
 
27
#include "rdpset.h"
 
28
#include "iso.h"
 
29
#include "mem.h"
 
30
#include "debug.h"
 
31
#include "tcp.h"
 
32
 
 
33
#ifndef DISABLE_TLS
 
34
#include "tls.h"
 
35
#include "credssp.h"
 
36
#endif
 
37
 
 
38
/* these are read only */
 
39
static uint8 pad_54[40] = {
 
40
        54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
 
41
        54, 54, 54,
 
42
        54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
 
43
        54, 54, 54
 
44
};
 
45
 
 
46
static uint8 pad_92[48] = {
 
47
        92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
 
48
        92, 92, 92, 92, 92, 92, 92,
 
49
        92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
 
50
        92, 92, 92, 92, 92, 92, 92
 
51
};
 
52
 
 
53
/*
 
54
 * I believe this is based on SSLv3 with the following differences:
 
55
 *  MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
 
56
 *  MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
 
57
 *  key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
 
58
 *  key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
 
59
 *  encryption/decryption keys updated every 4096 packets
 
60
 * See http://wp.netscape.com/eng/ssl3/draft302.txt
 
61
 */
 
62
 
 
63
/*
 
64
 * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
 
65
 * Both SHA1 and MD5 algorithms are used.
 
66
 */
 
67
void
 
68
sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
 
69
{
 
70
        int i;
 
71
        uint8 pad[4];
 
72
        uint8 shasig[20];
 
73
        CRYPTO_MD5 md5;
 
74
        CRYPTO_SHA1 sha1;
 
75
 
 
76
        for (i = 0; i < 3; i++)
 
77
        {
 
78
                memset(pad, salt + i, i + 1);
 
79
 
 
80
                crypto_sha1_init(&sha1);
 
81
                crypto_sha1_update(&sha1, pad, i + 1);
 
82
                crypto_sha1_update(&sha1, in, 48);
 
83
                crypto_sha1_update(&sha1, salt1, 32);
 
84
                crypto_sha1_update(&sha1, salt2, 32);
 
85
                crypto_sha1_final(&sha1, shasig);
 
86
 
 
87
                crypto_md5_init(&md5);
 
88
                crypto_md5_update(&md5, in, 48);
 
89
                crypto_md5_update(&md5, shasig, 20);
 
90
                crypto_md5_final(&md5, &out[i * 16]);
 
91
        }
 
92
}
 
93
 
 
94
/*
 
95
 * 16-byte transformation used to generate export keys (6.2.2).
 
96
 */
 
97
void
 
98
sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
 
99
{
 
100
        CRYPTO_MD5 md5;
 
101
 
 
102
        crypto_md5_init(&md5);
 
103
        crypto_md5_update(&md5, in, 16);
 
104
        crypto_md5_update(&md5, salt1, 32);
 
105
        crypto_md5_update(&md5, salt2, 32);
 
106
        crypto_md5_final(&md5, out);
 
107
}
 
108
 
 
109
/* Reduce key entropy from 64 to 40 bits */
 
110
static void
 
111
sec_make_40bit(uint8 * key)
 
112
{
 
113
        key[0] = 0xd1;
 
114
        key[1] = 0x26;
 
115
        key[2] = 0x9e;
 
116
}
 
117
 
 
118
/* Generate encryption keys given client and server randoms */
 
119
static void
 
120
sec_generate_keys(rdpSec * sec, uint8 * client_random, uint8 * server_random, int rc4_key_size)
 
121
{
 
122
        uint8 pre_master_secret[48];
 
123
        uint8 master_secret[48];
 
124
        uint8 key_block[48];
 
125
 
 
126
        /* Construct pre-master secret */
 
127
        memcpy(pre_master_secret, client_random, 24);
 
128
        memcpy(pre_master_secret + 24, server_random, 24);
 
129
 
 
130
        /* Generate master secret and then key material */
 
131
        sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
 
132
        sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
 
133
 
 
134
        /* First 16 bytes of key material is MAC secret */
 
135
        memcpy(sec->sec_sign_key, key_block, 16);
 
136
 
 
137
        /* Generate export keys from next two blocks of 16 bytes */
 
138
        sec_hash_16(sec->sec_decrypt_key, &key_block[16], client_random, server_random);
 
139
        sec_hash_16(sec->sec_encrypt_key, &key_block[32], client_random, server_random);
 
140
 
 
141
        if (rc4_key_size == 1)
 
142
        {
 
143
                DEBUG("40-bit encryption enabled\n");
 
144
                sec_make_40bit(sec->sec_sign_key);
 
145
                sec_make_40bit(sec->sec_decrypt_key);
 
146
                sec_make_40bit(sec->sec_encrypt_key);
 
147
                sec->rc4_key_len = 8;
 
148
        }
 
149
        else
 
150
        {
 
151
                DEBUG("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size);
 
152
                sec->rc4_key_len = 16;
 
153
        }
 
154
 
 
155
        /* Save initial RC4 keys as update keys */
 
156
        memcpy(sec->sec_decrypt_update_key, sec->sec_decrypt_key, 16);
 
157
        memcpy(sec->sec_encrypt_update_key, sec->sec_encrypt_key, 16);
 
158
 
 
159
        /* Initialise RC4 state arrays */
 
160
        crypto_rc4_set_key((CRYPTO_RC4*)&(sec->rc4_decrypt_key), sec->sec_decrypt_key, sec->rc4_key_len);
 
161
        crypto_rc4_set_key((CRYPTO_RC4*)&(sec->rc4_encrypt_key), sec->sec_encrypt_key, sec->rc4_key_len);
 
162
}
 
163
 
 
164
/* Output a uint32 into a buffer (little-endian) */
 
165
void
 
166
buf_out_uint32(uint8 * buffer, uint32 value)
 
167
{
 
168
        buffer[0] = (value) & 0xff;
 
169
        buffer[1] = (value >> 8) & 0xff;
 
170
        buffer[2] = (value >> 16) & 0xff;
 
171
        buffer[3] = (value >> 24) & 0xff;
 
172
}
 
173
 
 
174
/* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
 
175
void
 
176
sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
 
177
{
 
178
        uint8 shasig[20];
 
179
        uint8 md5sig[16];
 
180
        uint8 lenhdr[4];
 
181
        CRYPTO_SHA1 sha1;
 
182
        CRYPTO_MD5 md5;
 
183
 
 
184
        buf_out_uint32(lenhdr, datalen);
 
185
 
 
186
        crypto_sha1_init(&sha1);
 
187
        crypto_sha1_update(&sha1, session_key, keylen);
 
188
        crypto_sha1_update(&sha1, pad_54, 40);
 
189
        crypto_sha1_update(&sha1, lenhdr, 4);
 
190
        crypto_sha1_update(&sha1, data, datalen);
 
191
        crypto_sha1_final(&sha1, shasig);
 
192
 
 
193
        crypto_md5_init(&md5);
 
194
        crypto_md5_update(&md5, session_key, keylen);
 
195
        crypto_md5_update(&md5, pad_92, 48);
 
196
        crypto_md5_update(&md5, shasig, 20);
 
197
        crypto_md5_final(&md5, md5sig);
 
198
 
 
199
        memcpy(signature, md5sig, siglen);
 
200
}
 
201
 
 
202
/* Update an encryption key */
 
203
static void
 
204
sec_update(rdpSec * sec, uint8 * key, uint8 * update_key)
 
205
{
 
206
        uint8 shasig[20];
 
207
        CRYPTO_SHA1 sha1;
 
208
        CRYPTO_MD5 md5;
 
209
        CRYPTO_RC4 update;
 
210
 
 
211
        crypto_sha1_init(&sha1);
 
212
        crypto_sha1_update(&sha1, update_key, sec->rc4_key_len);
 
213
        crypto_sha1_update(&sha1, pad_54, 40);
 
214
        crypto_sha1_update(&sha1, key, sec->rc4_key_len);
 
215
        crypto_sha1_final(&sha1, shasig);
 
216
 
 
217
        crypto_md5_init(&md5);
 
218
        crypto_md5_update(&md5, update_key, sec->rc4_key_len);
 
219
        crypto_md5_update(&md5, pad_92, 48);
 
220
        crypto_md5_update(&md5, shasig, 20);
 
221
        crypto_md5_final(&md5, key);
 
222
 
 
223
        crypto_rc4_set_key(&update, key, sec->rc4_key_len);
 
224
        crypto_rc4(&update, sec->rc4_key_len, key, key);
 
225
 
 
226
        if (sec->rc4_key_len == 8)
 
227
                sec_make_40bit(key);
 
228
}
 
229
 
 
230
/* Encrypt data using RC4 */
 
231
static void
 
232
sec_encrypt(rdpSec * sec, uint8 * data, int length)
 
233
{
 
234
        if (sec->sec_encrypt_use_count == 4096)
 
235
        {
 
236
                sec_update(sec, sec->sec_encrypt_key, sec->sec_encrypt_update_key);
 
237
                crypto_rc4_set_key((CRYPTO_RC4*)&(sec->rc4_encrypt_key), sec->sec_encrypt_key, sec->rc4_key_len);
 
238
                sec->sec_encrypt_use_count = 0;
 
239
        }
 
240
 
 
241
        crypto_rc4((CRYPTO_RC4*)&(sec->rc4_encrypt_key), length, data, data);
 
242
        sec->sec_encrypt_use_count++;
 
243
}
 
244
 
 
245
/* Decrypt data using RC4 */
 
246
void
 
247
sec_decrypt(rdpSec * sec, uint8 * data, int length)
 
248
{
 
249
        if (sec->sec_decrypt_use_count == 4096)
 
250
        {
 
251
                sec_update(sec, sec->sec_decrypt_key, sec->sec_decrypt_update_key);
 
252
                crypto_rc4_set_key((CRYPTO_RC4*)&(sec->rc4_decrypt_key), sec->sec_decrypt_key, sec->rc4_key_len);
 
253
                sec->sec_decrypt_use_count = 0;
 
254
        }
 
255
 
 
256
        crypto_rc4((CRYPTO_RC4*)&(sec->rc4_decrypt_key), length, data, data);
 
257
        sec->sec_decrypt_use_count++;
 
258
}
 
259
 
 
260
/* Perform an RSA public key encryption operation */
 
261
static void
 
262
sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
 
263
                uint8 * exponent)
 
264
{
 
265
        crypto_rsa_encrypt(len, in, out, modulus_size, modulus, exponent);
 
266
}
 
267
 
 
268
/* Initialise secure transport packet */
 
269
STREAM
 
270
sec_init(rdpSec * sec, uint32 flags, int maxlen)
 
271
{
 
272
        STREAM s;
 
273
        int hdrlen;
 
274
 
 
275
        if (!(sec->licence->licence_issued))
 
276
                hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
 
277
        else
 
278
                hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
 
279
        
 
280
        s = mcs_init(sec->mcs, maxlen + hdrlen);
 
281
        s_push_layer(s, sec_hdr, hdrlen);
 
282
 
 
283
        return s;
 
284
}
 
285
 
 
286
/* Initialise fast path secure transport packet */
 
287
STREAM
 
288
sec_fp_init(rdpSec * sec, uint32 flags, int maxlen)
 
289
{
 
290
        STREAM s;
 
291
        int hdrlen;
 
292
 
 
293
        hdrlen = (flags & SEC_ENCRYPT) ? 8 : 0;
 
294
        s = mcs_fp_init(sec->mcs, maxlen + hdrlen);
 
295
        s_push_layer(s, sec_hdr, hdrlen);
 
296
        
 
297
        return s;
 
298
}
 
299
 
 
300
/* Transmit secure transport packet over specified channel */
 
301
void
 
302
sec_send_to_channel(rdpSec * sec, STREAM s, uint32 flags, uint16 channel)
 
303
{
 
304
        int datalen;
 
305
 
 
306
        s_pop_layer(s, sec_hdr);
 
307
        
 
308
        if (!(sec->licence->licence_issued) || (flags & SEC_ENCRYPT))
 
309
                out_uint32_le(s, flags);
 
310
 
 
311
        if (flags & SEC_ENCRYPT)
 
312
        {
 
313
                flags &= ~SEC_ENCRYPT;
 
314
                datalen = s->end - s->p - 8;
 
315
 
 
316
#if WITH_DEBUG
 
317
                DEBUG("Sending encrypted packet:\n");
 
318
                hexdump(s->p + 8, datalen);
 
319
#endif
 
320
 
 
321
                sec_sign(s->p, 8, sec->sec_sign_key, sec->rc4_key_len, s->p + 8, datalen);
 
322
                sec_encrypt(sec, s->p + 8, datalen);
 
323
        }
 
324
 
 
325
        mcs_send_to_channel(sec->mcs, s, channel);
 
326
}
 
327
 
 
328
/* Transmit secure transport packet */
 
329
 
 
330
void
 
331
sec_send(rdpSec * sec, STREAM s, uint32 flags)
 
332
{
 
333
        sec_send_to_channel(sec, s, flags, MCS_GLOBAL_CHANNEL);
 
334
}
 
335
 
 
336
/* Transmit secure fast path packet */
 
337
void
 
338
sec_fp_send(rdpSec * sec, STREAM s, uint32 flags)
 
339
{
 
340
        int datalen;
 
341
 
 
342
        s_pop_layer(s, sec_hdr);
 
343
        if (flags & SEC_ENCRYPT)
 
344
        {
 
345
                datalen = ((int) (s->end - s->p)) - 8;
 
346
                sec_sign(s->p, 8, sec->sec_sign_key, sec->rc4_key_len, s->p + 8, datalen);
 
347
                sec_encrypt(sec, s->p + 8, datalen);
 
348
        }
 
349
        mcs_fp_send(sec->mcs, s, flags);
 
350
}
 
351
 
 
352
/* Transfer the client random to the server */
 
353
static void
 
354
sec_establish_key(rdpSec * sec)
 
355
{
 
356
        uint32 length = sec->server_public_key_len + SEC_PADDING_SIZE;
 
357
        uint32 flags = SEC_EXCHANGE_PKT;
 
358
        STREAM s;
 
359
 
 
360
        s = sec_init(sec, flags, length + 4);
 
361
 
 
362
        out_uint32_le(s, length);
 
363
        out_uint8p(s, sec->sec_crypted_random, sec->server_public_key_len);
 
364
        out_uint8s(s, SEC_PADDING_SIZE);
 
365
 
 
366
        s_mark_end(s);
 
367
        sec_send(sec, s, flags);
 
368
}
 
369
 
 
370
/* Prepare PER encoded T.125 ConnectData for ConferenceCreateRequest connect-initial */
 
371
static void
 
372
sec_out_connectdata(rdpSec * sec, STREAM s)
 
373
{
 
374
        int i;
 
375
        rdpSet * settings = sec->rdp->settings;
 
376
        int out_len;
 
377
        int length = 158 + 76 + 12 + 4;
 
378
 
 
379
        if (settings->num_channels > 0)
 
380
                length += settings->num_channels * 12 + 8;
 
381
 
 
382
        /* t124Identifier = 0.0.20.124.0.1 */
 
383
        out_uint16_be(s, 5);
 
384
        out_uint16_be(s, 0x14);
 
385
        out_uint8(s, 0x7c);
 
386
        out_uint16_be(s, 1);
 
387
        /* connectPDU octet string */
 
388
        out_uint16_be(s, (length | 0x8000));    /* connectPDU length in two bytes*/
 
389
        /* connectPDU content is ConnectGCCPDU PER encoded: */
 
390
        out_uint16_be(s, 8);    /* ConferenceCreateRequest ... */
 
391
        out_uint16_be(s, 16);
 
392
        out_uint8(s, 0);
 
393
        out_uint16_le(s, 0xc001);       /* userData key is h221NonStandard */
 
394
        out_uint8(s, 0);        /* 4 bytes: */
 
395
        out_uint32_le(s, 0x61637544);   /* "Duca" */
 
396
        out_uint16_be(s, ((length - 14) | 0x8000));     /* userData value length in two bytes */
 
397
 
 
398
        /*
 
399
         * Client Core Data (216 bytes plus optional connectionType, pad1octet and serverSelectedProtocol)
 
400
         */
 
401
 
 
402
        out_uint16_le(s, UDH_CS_CORE);  /* User Data Header type */
 
403
        out_uint16_le(s, 212);  /* total length */
 
404
 
 
405
        out_uint32_le(s, sec->rdp->settings->rdp_version >= 5 ? 0x00080004 : 0x00080001);       /* client version */
 
406
        out_uint16_le(s, sec->rdp->settings->width);    // desktopWidth
 
407
        out_uint16_le(s, sec->rdp->settings->height);   // desktopHeight
 
408
        out_uint16_le(s, RNS_UD_COLOR_8BPP);    // colorDepth - ignored because of postBeta2ColorDepth
 
409
        out_uint16_le(s, RNS_UD_SAS_DEL); // SASSequence (Secure Access Sequence)
 
410
        out_uint32_le(s, sec->rdp->settings->keyboard_layout); // keyboardLayout
 
411
        out_uint32_le(s, 2600); // clientBuild
 
412
 
 
413
        /* Unicode name of client, truncated to 15 characters */
 
414
        if (strlen(sec->rdp->settings->hostname) > 15)
 
415
        {
 
416
                sec->rdp->settings->hostname[15] = 0; /* Modified in-place! */
 
417
        }
 
418
        out_len = rdp_out_unistr(sec->rdp, s, sec->rdp->settings->hostname);
 
419
        out_uint8s(s, 30 - out_len);    /* pad to 32 bytes (double zero termination has already been added) */
 
420
 
 
421
        out_uint32_le(s, sec->rdp->settings->keyboard_type);    /* keyboardType */
 
422
        out_uint32_le(s, sec->rdp->settings->keyboard_subtype); /* keyboardSubType */
 
423
        out_uint32_le(s, sec->rdp->settings->keyboard_functionkeys);    /* keyboardFunctionKey */
 
424
 
 
425
        /* Input Method Editor (IME) file name associated with the input locale.
 
426
           Up to 31 Unicode characters plus a NULL terminator */
 
427
        // if (strlen(sec->rdp->settings->keyboard_ime) > 31)
 
428
        //      sec->rdp->settings->keyboard_ime[31] = 0; /* Modified in-place! */
 
429
        // out_len = rdp_out_unistr(sec->rdp, s, sec->rdp->settings->hostname);
 
430
        // out_uint8s(s, 62 - out_len); /* pad to 64 bytes (double zero termination has already been added) */
 
431
        out_uint8s(s, 64);      /* imeFileName */
 
432
 
 
433
        out_uint16_le(s, RNS_UD_COLOR_8BPP); // postBeta2ColorDepth
 
434
        out_uint16_le(s, 1); // clientProductID
 
435
        out_uint32_le(s, 0); // serialNumber (should be initialized to 0)
 
436
 
 
437
        i = MIN(sec->rdp->settings->server_depth, 24);  /* 32 must be reported as 24 and RNS_UD_CS_WANT_32BPP_SESSION */
 
438
        out_uint16_le(s, i); // (requested) highColorDepth
 
439
 
 
440
        i = RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT;
 
441
        out_uint16_le(s, i); // supportedColorDepths
 
442
 
 
443
        i = RNS_UD_CS_SUPPORT_ERRINFO_PDU;
 
444
        if (sec->rdp->settings->server_depth == 32)
 
445
        {
 
446
                i |= RNS_UD_CS_WANT_32BPP_SESSION;
 
447
        }
 
448
        out_uint32_le(s, i); // earlyCapabilityFlags
 
449
 
 
450
        out_uint8s(s, 64); // clientDigProductId (64 bytes)
 
451
 
 
452
        /* Optional fields left out:
 
453
           connectionType (1 byte) and pad1octet (1 byte) (because no earlyCapabilityFlags RNS_UD_CS_VALID_CONNECTION_TYPE)
 
454
           serverSelectedProtocol (4 bytes) (default 0 = PROTOCOL_RDP)
 
455
        */
 
456
 
 
457
        /*
 
458
         * Client Security Data (12 bytes)
 
459
         */
 
460
 
 
461
        out_uint16_le(s, UDH_CS_SECURITY);      /* User Data Header type */
 
462
        out_uint16_le(s, 12);   /* total length */
 
463
 
 
464
        out_uint32_le(s, sec->rdp->settings->encryption ? ENCRYPTION_40BIT_FLAG | ENCRYPTION_128BIT_FLAG : 0); // encryptionMethods
 
465
        out_uint32_le(s, 0); // extEncryptionMethods
 
466
 
 
467
        /*
 
468
         * Client Network Data (optional and variable-length)
 
469
         */
 
470
 
 
471
        DEBUG_RDP5("num_channels is %d\n", settings->num_channels);
 
472
        if (settings->num_channels > 0)
 
473
        {
 
474
                out_uint16_le(s, UDH_CS_NET);   /* User Data Header type */
 
475
                out_uint16_le(s, settings->num_channels * 12 + 8);      /* total length */
 
476
 
 
477
                out_uint32_le(s, settings->num_channels);       // channelCount
 
478
                for (i = 0; i < settings->num_channels; i++)
 
479
                {
 
480
                        DEBUG_RDP5("Requesting channel %s\n", settings->channels[i].name);
 
481
                        out_uint8a(s, settings->channels[i].name, 8); // name (8 bytes) 7 characters with null terminator
 
482
                        out_uint32_be(s, settings->channels[i].flags); // options (4 bytes)
 
483
                }
 
484
        }
 
485
 
 
486
        /*
 
487
         * Client Cluster Data (12 bytes)
 
488
         */
 
489
 
 
490
        out_uint16_le(s, UDH_CS_CLUSTER);       /* User Data Header type */
 
491
        out_uint16_le(s, 12);   /* total length */
 
492
        out_uint32_le(s, (sec->rdp->settings->console_session || sec->rdp->redirect_session_id) ?
 
493
                REDIRECTED_SESSIONID_FIELD_VALID | REDIRECTION_SUPPORTED | REDIRECTION_VERSION4 :
 
494
                REDIRECTION_SUPPORTED | REDIRECTION_VERSION4); // flags
 
495
        out_uint32_le(s, sec->rdp->redirect_session_id); // RedirectedSessionID
 
496
 
 
497
        s_mark_end(s);
 
498
}
 
499
 
 
500
/* Parse a public key structure */
 
501
static RD_BOOL
 
502
sec_parse_public_key(rdpSec * sec, STREAM s, uint8 * modulus, uint8 * exponent)
 
503
{
 
504
        uint32 magic, modulus_len;
 
505
 
 
506
        in_uint32_le(s, magic);
 
507
        if (magic != SEC_RSA_MAGIC)
 
508
        {
 
509
                ui_error(sec->rdp->inst, "RSA magic 0x%x\n", magic);
 
510
                return False;
 
511
        }
 
512
 
 
513
        in_uint32_le(s, modulus_len);
 
514
        modulus_len -= SEC_PADDING_SIZE;
 
515
        if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE))
 
516
        {
 
517
                ui_error(sec->rdp->inst, "Bad server public key size (%u bits)\n", modulus_len * 8);
 
518
                return False;
 
519
        }
 
520
 
 
521
        in_uint8s(s, 8);        /* modulus_bits, unknown */
 
522
        in_uint8a(s, exponent, SEC_EXPONENT_SIZE);
 
523
        in_uint8a(s, modulus, modulus_len);
 
524
        in_uint8s(s, SEC_PADDING_SIZE);
 
525
        sec->server_public_key_len = modulus_len;
 
526
 
 
527
        return s_check(s);
 
528
}
 
529
 
 
530
/* Parse a public signature structure */
 
531
static RD_BOOL
 
532
sec_parse_public_sig(rdpSec * sec, STREAM s, uint32 len, uint8 * modulus, uint8 * exponent)
 
533
{
 
534
        uint32 sig_len;
 
535
        uint8 signature[SEC_MAX_MODULUS_SIZE];
 
536
 
 
537
        if (len != 72)
 
538
                return True;
 
539
 
 
540
        memset(signature, 0, sizeof(signature));
 
541
        sig_len = len - 8;
 
542
        in_uint8a(s, signature, sig_len);
 
543
        
 
544
        return crypto_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, sec->server_public_key_len, signature, sig_len);
 
545
}
 
546
 
 
547
/* Parse a crypto information structure */
 
548
static RD_BOOL
 
549
sec_parse_crypt_info(rdpSec * sec, STREAM s, uint32 * rc4_key_size, uint8 ** server_random, uint8 * modulus, uint8 * exponent)
 
550
{
 
551
        uint32 crypt_level, random_len, rsa_info_len;
 
552
        uint32 cacert_len, cert_len, flags;
 
553
        CRYPTO_CERT *cacert, *server_cert;
 
554
        CRYPTO_RKEY *server_public_key;
 
555
        uint16 tag, length;
 
556
        uint8 *next_tag, *end;
 
557
 
 
558
        in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
 
559
        in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */
 
560
        if (crypt_level == 0)   /* no encryption */
 
561
                return False;
 
562
        in_uint32_le(s, random_len);
 
563
        in_uint32_le(s, rsa_info_len);
 
564
 
 
565
        if (random_len != SEC_RANDOM_SIZE)
 
566
        {
 
567
                ui_error(sec->rdp->inst, "random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
 
568
                return False;
 
569
        }
 
570
 
 
571
        in_uint8p(s, *server_random, random_len);
 
572
 
 
573
        /* RSA info */
 
574
        end = s->p + rsa_info_len;
 
575
        if (end > s->end)
 
576
                return False;
 
577
 
 
578
        in_uint32_le(s, flags); /* 1 = Server Proprietary Certificate, 2 = X.509, 0x80000000 = temp */
 
579
        
 
580
        if (flags & 1)
 
581
        {
 
582
                DEBUG_RDP5("We're going for the RDP4-style Server Proprietary Certificate\n");
 
583
                in_uint8s(s, 4);        /* dwSigAlgId = SIGNATURE_ALG_RSA */
 
584
                in_uint8s(s, 4);        /* dwKeyAlgId = KEY_EXCHANGE_ALG_RSA */
 
585
 
 
586
                while (s->p < end)
 
587
                {
 
588
                        in_uint16_le(s, tag);
 
589
                        in_uint16_le(s, length);
 
590
 
 
591
                        next_tag = s->p + length;
 
592
 
 
593
                        switch (tag)
 
594
                        {
 
595
                                case BB_RSA_KEY_BLOB:
 
596
                                        if (!sec_parse_public_key(sec, s, modulus, exponent))
 
597
                                                return False;
 
598
                                        DEBUG_RDP5("Got Public key, RDP4-style\n");
 
599
 
 
600
                                        break;
 
601
 
 
602
                                case BB_RSA_SIGNATURE_BLOB:
 
603
                                        if (!sec_parse_public_sig(sec, s, length, modulus, exponent))
 
604
                                                return False;
 
605
                                        break;
 
606
 
 
607
                                default:
 
608
                                        ui_unimpl(NULL, "crypt tag 0x%x\n", tag);
 
609
                        }
 
610
 
 
611
                        s->p = next_tag;
 
612
                }
 
613
        }
 
614
        else
 
615
        {
 
616
                uint32 certcount;
 
617
 
 
618
                DEBUG_RDP5("We're going for the RDP5-style encryption\n");
 
619
                in_uint32_le(s, certcount);     /* Number of certificates */
 
620
                if (certcount < 2)
 
621
                {
 
622
                        ui_error(sec->rdp->inst, "Server didn't send enough X509 certificates\n");
 
623
                        return False;
 
624
                }
 
625
                for (; certcount > 2; certcount--)
 
626
                {       
 
627
                        /* ignore all the certificates between the root and the signing CA */
 
628
                        uint32 ignorelen;
 
629
                        CRYPTO_CERT *ignorecert;
 
630
 
 
631
                        DEBUG_RDP5("Ignored certs left: %d\n", certcount);
 
632
                        in_uint32_le(s, ignorelen);
 
633
                        DEBUG_RDP5("Ignored Certificate length is %d\n", ignorelen);
 
634
                        ignorecert = crypto_cert_read(s->p, ignorelen);
 
635
                        in_uint8s(s, ignorelen);
 
636
                        if (ignorecert == NULL)
 
637
                        {       /* XXX: error out? */
 
638
                                DEBUG_RDP5("got a bad cert: this will probably screw up the rest of the communication\n");
 
639
                        }
 
640
 
 
641
#ifdef WITH_DEBUG_RDP5
 
642
                        DEBUG_RDP5("cert #%d (ignored):\n", certcount);
 
643
                        crypto_cert_print_fp(stdout, ignorecert);
 
644
#endif
 
645
                        crypto_cert_free(ignorecert);
 
646
                }
 
647
                /* Do da funky X.509 stuffy
 
648
 
 
649
                   "How did I find out about this?  I looked up and saw a
 
650
                   bright light and when I came to I had a scar on my forehead
 
651
                   and knew about X.500"
 
652
                   - Peter Gutman in a early version of
 
653
                   http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
 
654
                 */
 
655
                in_uint32_le(s, cacert_len);
 
656
                DEBUG_RDP5("CA Certificate length is %d\n", cacert_len);
 
657
                cacert = crypto_cert_read(s->p, cacert_len);
 
658
                in_uint8s(s, cacert_len);
 
659
                if (NULL == cacert)
 
660
                {
 
661
                        ui_error(sec->rdp->inst, "Couldn't load CA Certificate from server\n");
 
662
                        return False;
 
663
                }
 
664
                in_uint32_le(s, cert_len);
 
665
                DEBUG_RDP5("Certificate length is %d\n", cert_len);
 
666
                server_cert = crypto_cert_read(s->p, cert_len);
 
667
                in_uint8s(s, cert_len);
 
668
                if (NULL == server_cert)
 
669
                {
 
670
                        crypto_cert_free(cacert);
 
671
                        ui_error(sec->rdp->inst, "Couldn't load Certificate from server\n");
 
672
                        return False;
 
673
                }
 
674
                if (!crypto_cert_verify(server_cert, cacert))
 
675
                {
 
676
                        crypto_cert_free(server_cert);
 
677
                        crypto_cert_free(cacert);
 
678
                        ui_error(sec->rdp->inst, "Security error CA Certificate invalid\n");
 
679
                        return False;
 
680
                }
 
681
                crypto_cert_free(cacert);
 
682
                in_uint8s(s, 16);       /* Padding */
 
683
                server_public_key = crypto_cert_to_rkey(server_cert, &(sec->server_public_key_len));
 
684
                if (NULL == server_public_key)
 
685
                {
 
686
                        DEBUG_RDP5("Didn't parse X509 correctly\n");
 
687
                        crypto_cert_free(server_cert);
 
688
                        return False;
 
689
                }
 
690
                crypto_cert_free(server_cert);
 
691
                if ((sec->server_public_key_len < SEC_MODULUS_SIZE) ||
 
692
                    (sec->server_public_key_len > SEC_MAX_MODULUS_SIZE))
 
693
                {
 
694
                        ui_error(sec->rdp->inst, "Bad server public key size (%u bits)\n",
 
695
                                 sec->server_public_key_len * 8);
 
696
                        crypto_rkey_free(server_public_key);
 
697
                        return False;
 
698
                }
 
699
                if (crypto_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
 
700
                                         modulus, SEC_MAX_MODULUS_SIZE) != 0)
 
701
                {
 
702
                        ui_error(sec->rdp->inst, "Problem extracting RSA exponent, modulus");
 
703
                        crypto_rkey_free(server_public_key);
 
704
                        return False;
 
705
                }
 
706
                crypto_rkey_free(server_public_key);
 
707
                return True;    /* There's some garbage here we don't care about */
 
708
        }
 
709
        return s_check_end(s);
 
710
}
 
711
 
 
712
/* Process crypto information blob */
 
713
static void
 
714
sec_process_crypt_info(rdpSec * sec, STREAM s)
 
715
{
 
716
        uint8 *server_random = NULL;
 
717
        uint8 client_random[SEC_RANDOM_SIZE];
 
718
        uint8 modulus[SEC_MAX_MODULUS_SIZE];
 
719
        uint8 exponent[SEC_EXPONENT_SIZE];
 
720
        uint32 rc4_key_size;
 
721
 
 
722
        memset(modulus, 0, sizeof(modulus));
 
723
        memset(exponent, 0, sizeof(exponent));
 
724
        if (!sec_parse_crypt_info(sec, s, &rc4_key_size, &server_random, modulus, exponent))
 
725
        {
 
726
                DEBUG("Failed to parse crypt info\n");
 
727
                return;
 
728
        }
 
729
        DEBUG("Generating client random\n");
 
730
        generate_random(client_random);
 
731
        sec_rsa_encrypt(sec->sec_crypted_random, client_random, SEC_RANDOM_SIZE,
 
732
                        sec->server_public_key_len, modulus, exponent);
 
733
        sec_generate_keys(sec, client_random, server_random, rc4_key_size);
 
734
}
 
735
 
 
736
 
 
737
/* Process SRV_INFO, find RDP version supported by server */
 
738
static void
 
739
sec_process_srv_info(rdpSec * sec, STREAM s)
 
740
{
 
741
        in_uint16_le(s, sec->server_rdp_version);
 
742
        DEBUG_RDP5("Server RDP version is %d\n", sec->server_rdp_version);
 
743
 
 
744
        if(sec->server_rdp_version == 1)
 
745
        {
 
746
                sec->rdp->settings->rdp_version = 4;
 
747
                sec->rdp->settings->server_depth = 8;
 
748
        }
 
749
        else if(sec->server_rdp_version == 4)
 
750
        {
 
751
                sec->rdp->settings->rdp_version = 5;
 
752
        }
 
753
        else
 
754
        {
 
755
                sec->rdp->settings->rdp_version = 5;
 
756
        }
 
757
}
 
758
 
 
759
 
 
760
/* Process connect response data blob */
 
761
void
 
762
sec_process_mcs_data(rdpSec * sec, STREAM s)
 
763
{
 
764
        uint16 tag, length;
 
765
        uint8 *next_tag;
 
766
        uint8 len;
 
767
 
 
768
        in_uint8s(s, 21);       /* header (T.124 ConferenceCreateResponse) */
 
769
        in_uint8(s, len);
 
770
        if (len & 0x80)
 
771
                in_uint8(s, len);
 
772
 
 
773
        while (s->p < s->end)
 
774
        {
 
775
                in_uint16_le(s, tag);
 
776
                in_uint16_le(s, length);
 
777
 
 
778
                if (length <= 4)
 
779
                        return;
 
780
 
 
781
                next_tag = s->p + length - 4;
 
782
 
 
783
                switch (tag)
 
784
                {
 
785
                        case UDH_SC_CORE:
 
786
                                sec_process_srv_info(sec, s);
 
787
                                break;
 
788
 
 
789
                        case UDH_SC_SECURITY:
 
790
                                sec_process_crypt_info(sec, s);
 
791
                                break;
 
792
 
 
793
                        case UDH_SC_NET:
 
794
                                /* FIXME: We should parse this information and
 
795
                                   use it to map RDP5 channels to MCS
 
796
                                   channels */
 
797
                                break;
 
798
 
 
799
                        default:
 
800
                                ui_unimpl(NULL, "response tag 0x%x\n", tag);
 
801
                }
 
802
 
 
803
                s->p = next_tag;
 
804
        }
 
805
}
 
806
 
 
807
/* Receive secure transport packet */
 
808
STREAM
 
809
sec_recv(rdpSec * sec, secRecvType * type)
 
810
{
 
811
        isoRecvType iso_type;
 
812
        uint32 sec_flags;
 
813
        uint16 channel;
 
814
        STREAM s;
 
815
 
 
816
        while ((s = mcs_recv(sec->mcs, &channel, &iso_type)) != NULL)
 
817
        {
 
818
                if ((iso_type == ISO_RECV_FAST_PATH) ||
 
819
                        (iso_type == ISO_RECV_FAST_PATH_ENCRYPTED))
 
820
                {
 
821
                        *type = SEC_RECV_FAST_PATH;
 
822
                        if (iso_type == ISO_RECV_FAST_PATH_ENCRYPTED)
 
823
                        {
 
824
                                in_uint8s(s, 8);        /* dataSignature */ /* TODO: Check signature! */
 
825
                                sec_decrypt(sec, s->p, s->end - s->p);
 
826
                        }
 
827
                        return s;
 
828
                }
 
829
                if (sec->rdp->settings->encryption || !(sec->licence->licence_issued))
 
830
                {
 
831
                        /* basicSecurityHeader: */
 
832
                        in_uint32_le(s, sec_flags);
 
833
 
 
834
                        if ((sec_flags & SEC_ENCRYPT) || (sec_flags & SEC_REDIRECTION_PKT))
 
835
                        {
 
836
                                in_uint8s(s, 8);        /* dataSignature */
 
837
                                sec_decrypt(sec, s->p, s->end - s->p);
 
838
                        }
 
839
 
 
840
                        if (sec_flags & SEC_LICENSE_PKT)
 
841
                        {
 
842
                                *type = SEC_RECV_LICENSE;
 
843
                                licence_process(sec->licence, s);
 
844
                                continue;
 
845
                        }
 
846
 
 
847
                        if (sec_flags & SEC_REDIRECTION_PKT)
 
848
                        {
 
849
                                *type = SEC_RECV_REDIRECT;
 
850
                                return s;
 
851
                        }
 
852
                }
 
853
 
 
854
                if (channel != MCS_GLOBAL_CHANNEL)
 
855
                {
 
856
                        vchan_process(sec->mcs->chan, s, channel);
 
857
                        *type = SEC_RECV_IOCHANNEL;
 
858
                        return s;
 
859
                }
 
860
                *type = SEC_RECV_SHARE_CONTROL;
 
861
                return s;
 
862
        }
 
863
 
 
864
        return NULL;
 
865
}
 
866
 
 
867
/* Establish a secure connection */
 
868
RD_BOOL
 
869
sec_connect(rdpSec * sec, char *server, char *username, int port)
 
870
{
 
871
        /* Don't forget to set this *before* iso_connect(), otherwise you'll bang your head on the wall */
 
872
        /* sec->tls = 1; */
 
873
        
 
874
        if (!iso_connect(sec->mcs->iso, server, username, port))
 
875
                return False;
 
876
 
 
877
#ifndef DISABLE_TLS
 
878
        
 
879
        if(sec->tls)
 
880
        {
 
881
                /* TLS with NLA was successfully negotiated */
 
882
 
 
883
                sec->ctx = tls_create_context();
 
884
                sec->ssl = tls_connect(sec->ctx, sec->mcs->iso->tcp->sock, server);
 
885
                ntlm_send_negotiate_message(sec);
 
886
                credssp_recv(sec);
 
887
                exit(0);
 
888
        }
 
889
        else
 
890
#endif
 
891
        {
 
892
                RD_BOOL success;
 
893
                struct stream connectdata;
 
894
 
 
895
                /* We exchange some RDP data during the MCS-Connect */
 
896
                connectdata.size = 512;
 
897
                connectdata.p = connectdata.data = (uint8 *) xmalloc(connectdata.size);
 
898
                sec_out_connectdata(sec, &connectdata);
 
899
                success = mcs_connect(sec->mcs, &connectdata);
 
900
                xfree(connectdata.data);
 
901
 
 
902
                if (success && sec->rdp->settings->encryption)
 
903
                        sec_establish_key(sec);
 
904
 
 
905
                return success;
 
906
        }
 
907
}
 
908
 
 
909
/* Reestablish a secure connection */
 
910
RD_BOOL
 
911
sec_reconnect(rdpSec * sec, char *server, int port)
 
912
{
 
913
        RD_BOOL success;
 
914
        struct stream connectdata;
 
915
 
 
916
        if (!iso_reconnect(sec->mcs->iso, server, port))
 
917
                return False;
 
918
 
 
919
        /* We exchange some RDP data during the MCS-Connect */
 
920
        connectdata.size = 512;
 
921
        connectdata.p = connectdata.data = (uint8 *) xmalloc(connectdata.size);
 
922
        sec_out_connectdata(sec, &connectdata);
 
923
        success = mcs_reconnect(sec->mcs, &connectdata);
 
924
        xfree(connectdata.data);
 
925
 
 
926
        if (success && sec->rdp->settings->encryption)
 
927
                sec_establish_key(sec);
 
928
 
 
929
        return success;
 
930
}
 
931
 
 
932
/* Disconnect a connection */
 
933
void
 
934
sec_disconnect(rdpSec * sec)
 
935
{
 
936
        mcs_disconnect(sec->mcs);
 
937
}
 
938
 
 
939
/* reset the state of the sec layer */
 
940
void
 
941
sec_reset_state(rdpSec * sec)
 
942
{
 
943
        sec->server_rdp_version = 0;
 
944
        sec->sec_encrypt_use_count = 0;
 
945
        sec->sec_decrypt_use_count = 0;
 
946
        mcs_reset_state(sec->mcs);
 
947
}
 
948
 
 
949
rdpSec *
 
950
sec_new(struct rdp_rdp * rdp)
 
951
{
 
952
        rdpSec * self;
 
953
 
 
954
        self = (rdpSec *) xmalloc(sizeof(rdpSec));
 
955
        if (self != NULL)
 
956
        {
 
957
                memset(self, 0, sizeof(rdpSec));
 
958
                self->rdp = rdp;
 
959
                self->mcs = mcs_new(self);
 
960
                self->licence = licence_new(self);
 
961
                
 
962
#ifndef DISABLE_TLS
 
963
                self->nla = nla_new(self);
 
964
#endif
 
965
                
 
966
        }
 
967
        return self;
 
968
}
 
969
 
 
970
void
 
971
sec_free(rdpSec * sec)
 
972
{
 
973
        if (sec != NULL)
 
974
        {
 
975
                licence_free(sec->licence);
 
976
                mcs_free(sec->mcs);
 
977
 
 
978
#ifndef DISABLE_TLS
 
979
                nla_free(sec->nla);
 
980
#endif
 
981
                
 
982
                xfree(sec);
 
983
        }
 
984
}