]> git.sesse.net Git - rdpsrv/blob - secure.c
Debug message cleanup.
[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 extern 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 demand_license[] = {
740         0x01, 0x03, 0x86, 0x00, 0x9c, 0x6e, 0xef, 0x5a, 0x26, 0x45, 0x88, 0x86, 0x0e, 0xdf, 0xa4, 0x4a,
741         0x45, 0xc7, 0x5a, 0x4c, 0xec, 0x33, 0xff, 0x4c, 0xd8, 0x4b, 0xd2, 0x4e, 0xd2, 0x22, 0x16, 0xde,
742         0x1e, 0x5b, 0x06, 0x6e, 0x00, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x69, 0x00,
743         0x63, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00,
744         0x43, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00,
745         0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x00, 0x30, 0x00,
746         0x32, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf6, 0x00, 0x00,
747         0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
748         0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x00 
749 };
750 unsigned char result_license[] = {
751         0xff, 0x03, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa0, 0x5f, 0x00, 0x00
752 };
753
754 unsigned char demand_active[] = {
755         0x24, 0x01, 0x11, 0x00, 0xea, 0x03, 0xea, 0x03, 0x01, 0x00, 0x04, 0x00, 0x0e, 0x01, 0x52, 0x44,
756         0x50, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x08, 0x00, 0xea, 0x03, 0x40, 0xe4, 0x01, 0x00,
757         0x18, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x11, 0x04, 0x00, 0x00,
758         0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0e, 0x00, 0x04, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x08, 0x00,
759         0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x03, 0x58, 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
760         0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
761         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00,
762         0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
763         0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
764         0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42,
765         0x0f, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
766         0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00,
767         0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x58, 0x00, 0x35, 0x00, 0x00, 0x00,
768         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xed, 0xbf, 0xa5, 0xcd, 0xb1, 0xae, 0xbe,
769         0x88, 0x35, 0x56, 0xe5, 0xc2, 0x01, 0xaf, 0xbe, 0xc8, 0xed, 0xbf, 0xa5, 0x8c, 0x33, 0x40, 0xe4,
770         0x08, 0x30, 0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x08, 0x30, 0x40, 0xe4, 0x00, 0x00, 0x00, 0x00,
771         0xc0, 0xed, 0xbf, 0xa5, 0x34, 0xf5, 0xae, 0xbe, 0x08, 0x30, 0x40, 0xe4, 0xb4, 0xed, 0xbf, 0xa5,
772         0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00, 0x00, 0x00,
773         0x00, 0x00, 0x00, 0x00
774 };
775
776 #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); }
777 #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); }
778 #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); }
779
780 void
781 process_presented_license(STREAM s)
782 {
783         unsigned char client_license_random[SEC_RANDOM_SIZE];
784         unsigned char client_license_rsa_data[SEC_MODULUS_SIZE];
785
786         uint16 length, license_size;
787         uint32 unknown;
788         uint8 *license, hwid[LICENCE_HWID_SIZE], signature[LICENCE_SIGNATURE_SIZE];
789         int i;
790         
791         EXPECT8(2);                   // version
792         in_uint16_le(s, length);
793
794         EXPECT32(1);                  // unknown
795         EXPECT16(0);
796         EXPECT16(0x0201);
797
798         in_uint8a(s, client_license_random, SEC_RANDOM_SIZE);
799         EXPECT16(0);
800         EXPECT16(SEC_MODULUS_SIZE + SEC_PADDING_SIZE);
801         in_uint8a(s, client_license_rsa_data, SEC_MODULUS_SIZE);
802         in_uint8s(s, SEC_PADDING_SIZE);
803
804         EXPECT16(1);
805         in_uint16_le(s, license_size);
806
807         license = (uint8 *)xmalloc(license_size);
808         in_uint8a(s, license, license_size);
809
810         printf("Received license:\n");
811         for (i = 0; i < license_size; ++i)
812                 printf(" 0x%02x", license[i]);
813         printf("\n");
814
815         EXPECT16(1);
816         EXPECT16(LICENCE_HWID_SIZE);
817         in_uint8a(s, hwid, LICENCE_HWID_SIZE);
818
819         printf("License hardware ID:\n");
820         for (i = 0; i < LICENCE_HWID_SIZE; ++i)
821                 printf(" 0x%02x", hwid[i]);
822         printf("\n");
823
824         in_uint8a(s, signature, LICENCE_SIGNATURE_SIZE);
825
826         if (!s_check_end(s)) {
827                 printf("Unknown data at the end of presented license!");
828         }
829
830         // now we can generate the keys we need
831         licence_generate_keys(client_license_random, demand_license + 4, client_license_rsa_data);
832 //      send_authreq();
833 }
834
835 /* Receive secure transport packet */
836 STREAM
837 sec_recv(void)
838 {
839         uint32 sec_flags;
840         uint16 channel;
841         STREAM s;
842
843         if ((s = mcs_recv(&channel)) != NULL)
844         {
845                 if (/*g_encryption || !g_licence_issued*/ 1)
846                 {
847                         in_uint32_le(s, sec_flags);
848                         
849                         if (sec_flags & SEC_ENCRYPT)
850                         {
851                                 in_uint8s(s, 8);        /* signature */
852                                 sec_decrypt(s->p, s->end - s->p);
853                         }
854
855                         if (sec_flags & SEC_LICENCE_NEG)
856                         {
857                                 uint8 tag;
858                                 in_uint8(s, tag);
859                                 
860                                 if (tag == LICENCE_TAG_PRESENT) {
861                                         process_presented_license(s);
862
863                                         {
864                                                 STREAM s;
865                                                 s = sec_init(SEC_LICENCE_NEG, sizeof(result_license));
866                                                 out_uint8p(s, result_license, sizeof(result_license));
867                                                 s_mark_end(s);
868                                                 sec_send(s, SEC_LICENCE_NEG);
869                                         }
870                                         
871                                         {
872                                                 STREAM s;
873                                                 s = sec_init(SEC_ENCRYPT, sizeof(demand_active));
874                                                 out_uint8p(s, demand_active, sizeof(demand_active));
875                                                 s_mark_end(s);
876                                                 sec_send(s, SEC_ENCRYPT);
877                                         }
878                                 }
879                                 
880                                 return NULL;
881                         }
882
883                         if (sec_flags & SEC_LOGON_INFO) 
884                         {
885                                 rdp_get_logon_info(s);
886                         
887                                 // demand a license
888                                 {
889                                         STREAM s;
890
891                                         s = sec_init(SEC_LICENCE_NEG, sizeof(demand_license));
892                                         out_uint8p(s, demand_license, sizeof(demand_license));
893                                         s_mark_end(s);
894                                         sec_send(s, SEC_LICENCE_NEG);
895                                 }
896                                 
897                                 return NULL;
898                         }
899
900                         if (sec_flags & SEC_CLIENT_RANDOM) {
901                                 uint32 length;
902                                 uint8 inr[SEC_MODULUS_SIZE];
903                                 int i;
904                                 
905                                 in_uint32_le(s, length);
906                                 if (length != SEC_MODULUS_SIZE + SEC_PADDING_SIZE) {
907                                         error("Client random was wrong size, %u bytes\n", length);
908                                 }
909                                 in_uint8a(s, sec_crypted_random, SEC_MODULUS_SIZE);
910                                 in_uint8s(s, SEC_PADDING_SIZE);
911                                 if (!s_check_end(s)) {
912                                         error("Junk after client random\n");
913                                 }
914                                 
915                                 reverse(sec_crypted_random, SEC_MODULUS_SIZE);
916
917                                 RSA_private_decrypt(SEC_MODULUS_SIZE, sec_crypted_random, inr, privkey, RSA_NO_PADDING);
918                         
919                                 reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
920                                 
921                                 printf("Unencrypted client random: ");
922                                 for (i = 0; i < SEC_RANDOM_SIZE; ++i) {
923                                         printf("0x%x ", inr[i + SEC_RANDOM_SIZE]);
924                                 }
925                                 printf("\n");
926
927                                 // now we can generate the keys
928                                 sec_generate_keys(inr + SEC_RANDOM_SIZE, cacert, 1);
929                                 return NULL;
930                         }
931                 }
932
933                 printf("Received MCS data on ch %u\n", channel);
934                 if (channel != MCS_GLOBAL_CHANNEL)
935                 {
936                         channel_process(s, channel);
937                         return NULL;
938                 }
939
940                 return s;
941         }
942
943         return NULL;
944 }
945
946 /* Disconnect a connection */
947 void
948 sec_disconnect(void)
949 {
950         mcs_disconnect();
951 }