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