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
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.
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.
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.
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>
29 extern char hostname[16];
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;
43 static RC4_KEY rc4_decrypt_key;
44 static RC4_KEY rc4_encrypt_key;
45 static RSA *server_public_key;
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];
56 uint16 g_server_rdp_version = 0;
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.
64 sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
72 for (i = 0; i < 3; i++)
74 memset(pad, salt + i, i + 1);
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);
84 MD5_Update(&md5, in, 48);
85 MD5_Update(&md5, shasig, 20);
86 MD5_Final(&out[i * 16], &md5);
91 * Weaker 16-byte transformation, also using two 32-byte salts, but
92 * only using a single round of MD5.
95 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
100 MD5_Update(&md5, in, 16);
101 MD5_Update(&md5, salt1, 32);
102 MD5_Update(&md5, salt2, 32);
103 MD5_Final(out, &md5);
106 /* Reduce key entropy from 64 to 40 bits */
108 sec_make_40bit(uint8 * key)
115 /* Generate a session key and RC4 keys, given client and server randoms */
117 sec_generate_keys(uint8 * client_key, uint8 * server_key, int rc4_key_size)
119 uint8 session_key[48];
123 /* Construct input data to hash */
124 memcpy(input, client_key, 24);
125 memcpy(input + 24, server_key, 24);
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);
131 /* Store first 16 bytes of session key, for generating signatures */
132 memcpy(sec_sign_key, session_key, 16);
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);
138 if (rc4_key_size == 1)
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);
148 DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
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);
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);
162 printf("sec_decrypt_key: ");
163 for (i = 0; i < 16; ++i)
164 printf("0x%02x ", sec_decrypt_key[i]);
167 printf("sec_encrypt_key: ");
168 for (i = 0; i < 16; ++i)
169 printf("0x%02x ", sec_encrypt_key[i]);
176 static uint8 pad_54[40] = {
177 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
179 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
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
190 /* Output a uint32 into a buffer (little-endian) */
192 buf_out_uint32(uint8 * buffer, uint32 value)
194 buffer[0] = (value) & 0xff;
195 buffer[1] = (value >> 8) & 0xff;
196 buffer[2] = (value >> 16) & 0xff;
197 buffer[3] = (value >> 24) & 0xff;
200 /* Generate a signature hash, using a combination of SHA1 and MD5 */
202 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
210 buf_out_uint32(lenhdr, datalen);
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);
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);
225 memcpy(signature, md5sig, siglen);
228 /* Update an encryption key - similar to the signing process */
230 sec_update(uint8 * key, uint8 * update_key)
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);
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);
249 RC4_set_key(&update, rc4_key_len, key);
250 RC4(&update, rc4_key_len, key, key);
252 if (rc4_key_len == 8)
256 /* Encrypt data using RC4 */
258 sec_encrypt(uint8 * data, int length)
260 static int use_count;
262 if (use_count == 4096)
264 sec_update(sec_decrypt_key, sec_decrypt_update_key);
265 RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
269 printf("RC4-ing %u bytes with DECRYPT, uc=%u\n", length, use_count);
271 RC4(&rc4_decrypt_key, length, data, data);
275 /* Decrypt data using RC4 */
277 sec_decrypt(uint8 * data, int length)
279 static int use_count;
281 if (use_count == 4096)
283 sec_update(sec_encrypt_key, sec_encrypt_update_key);
284 RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
288 RC4(&rc4_encrypt_key, length, data, data);
293 reverse(uint8 * p, int len)
298 for (i = 0, j = len - 1; i < j; i++, j--)
306 /* Perform an RSA public key encryption operation */
308 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
311 BIGNUM mod, exp, x, y;
312 uint8 inr[SEC_MODULUS_SIZE];
315 reverse(modulus, SEC_MODULUS_SIZE);
316 reverse(exponent, SEC_EXPONENT_SIZE);
317 memcpy(inr, in, len);
326 BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
327 BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
328 BN_bin2bn(inr, len, &x);
329 BN_mod_exp(&y, &x, &exp, &mod, ctx);
330 outlen = BN_bn2bin(&y, out);
331 reverse(out, outlen);
332 if (outlen < SEC_MODULUS_SIZE)
333 memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
342 /* Initialise secure transport packet */
344 sec_init(uint32 flags, int maxlen)
349 if (!g_licence_issued)
350 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
352 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
353 printf("HDRLEN is %u\n", hdrlen);
354 s = mcs_init(maxlen + hdrlen);
355 s_push_layer(s, sec_hdr, hdrlen);
360 /* Transmit secure transport packet over specified channel */
362 sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
366 // DEBUG(("sending packet to channel %u\n", channel));
368 s_pop_layer(s, sec_hdr);
369 if (!g_licence_issued || (flags & SEC_ENCRYPT)) {
370 out_uint32_le(s, flags);
373 if (flags & SEC_ENCRYPT)
375 flags &= ~SEC_ENCRYPT;
376 datalen = s->end - s->p - 8;
379 DEBUG(("Sending encrypted packet:\n"));
380 hexdump(s->p + 8, datalen);
383 sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, datalen);
384 printf("First byte of signature is 0x%x, at %p\n", (s->p)[0], s->p);
385 sec_encrypt(s->p + 8, datalen);
388 mcs_send_to_channel(s, channel);
391 /* Transmit secure transport packet */
394 sec_send(STREAM s, uint32 flags)
396 sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
400 /* Transfer the client random to the server */
402 sec_establish_key(void)
404 uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
405 uint32 flags = SEC_CLIENT_RANDOM;
408 s = sec_init(flags, 76);
410 out_uint32_le(s, length);
411 out_uint8p(s, sec_crypted_random, SEC_MODULUS_SIZE);
412 out_uint8s(s, SEC_PADDING_SIZE);
418 /* Parse a public key structure */
420 sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
422 uint32 magic, modulus_len;
424 in_uint32_le(s, magic);
425 if (magic != SEC_RSA_MAGIC)
427 error("RSA magic 0x%x\n", magic);
431 in_uint32_le(s, modulus_len);
432 if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
434 error("modulus len 0x%x\n", modulus_len);
438 in_uint8s(s, 8); /* modulus_bits, unknown */
439 in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);
440 in_uint8p(s, *modulus, SEC_MODULUS_SIZE);
441 in_uint8s(s, SEC_PADDING_SIZE);
447 sec_parse_x509_key(X509 * cert)
449 EVP_PKEY *epk = NULL;
450 /* By some reason, Microsoft sets the OID of the Public RSA key to
451 the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
453 Kudos to Richard Levitte for the following (. intiutive .)
454 lines of code that resets the OID and let's us extract the key. */
455 if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
457 DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
458 cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
460 epk = X509_get_pubkey(cert);
463 error("Failed to extract public key from certificate\n");
467 server_public_key = (RSA *) epk->pkey.ptr;
473 /* Parse a crypto information structure */
475 sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
476 uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
478 uint32 crypt_level, random_len, rsa_info_len;
479 uint32 cacert_len, cert_len, flags;
480 X509 *cacert, *server_cert;
482 uint8 *next_tag, *end;
484 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
485 in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
486 if (crypt_level == 0) /* no encryption */
488 in_uint32_le(s, random_len);
489 in_uint32_le(s, rsa_info_len);
491 if (random_len != SEC_RANDOM_SIZE)
493 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
497 in_uint8p(s, *server_random, random_len);
500 end = s->p + rsa_info_len;
504 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
507 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
508 in_uint8s(s, 8); /* unknown */
512 in_uint16_le(s, tag);
513 in_uint16_le(s, length);
515 next_tag = s->p + length;
520 if (!sec_parse_public_key(s, modulus, exponent))
522 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
527 /* Is this a Microsoft key that we just got? */
528 /* Care factor: zero! */
529 /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
530 key as a known key of the hostname. This would prevent some MITM-attacks. */
534 unimpl("crypt tag 0x%x\n", tag);
544 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
545 in_uint32_le(s, certcount); /* Number of certificates */
549 error("Server didn't send enough X509 certificates\n");
553 for(; certcount > 2; certcount--)
554 { /* ignore all the certificates between the root and the signing CA */
558 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
560 in_uint32_le(s, ignorelen);
561 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
562 ignorecert = d2i_X509(NULL, &(s->p), ignorelen);
564 if(ignorecert == NULL)
565 { /* XXX: error out? */
566 DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
569 #ifdef WITH_DEBUG_RDP5
570 DEBUG_RDP5(("cert #%d (ignored):\n",certcount));
571 X509_print_fp(stdout, ignorecert);
575 /* Do da funky X.509 stuffy
577 "How did I find out about this? I looked up and saw a
578 bright light and when I came to I had a scar on my forehead
579 and knew about X.500"
580 - Peter Gutman in a early version of
581 http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
584 in_uint32_le(s, cacert_len);
585 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
586 cacert = d2i_X509(NULL, &(s->p), cacert_len);
587 /* Note: We don't need to move s->p here - d2i_X509 is
588 "kind" enough to do it for us */
591 error("Couldn't load CA Certificate from server\n");
595 /* Currently, we don't use the CA Certificate.
597 *) Verify the server certificate (server_cert) with the
599 *) Store the CA Certificate with the hostname of the
600 server we are connecting to as key, and compare it
601 when we connect the next time, in order to prevent
605 in_uint32_le(s, cert_len);
606 DEBUG_RDP5(("Certificate length is %d\n", cert_len));
607 server_cert = d2i_X509(NULL, &(s->p), cert_len);
608 if (NULL == server_cert)
610 error("Couldn't load Certificate from server\n");
614 in_uint8s(s, 16); /* Padding */
616 /* Note: Verifying the server certificate must be done here,
617 before sec_parse_public_key since we'll have to apply
618 serious violence to the key after this */
620 if (!sec_parse_x509_key(server_cert))
622 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
625 return True; /* There's some garbage here we don't care about */
627 return s_check_end(s);
630 /* Process crypto information blob */
632 sec_process_crypt_info(STREAM s)
634 uint8 *server_random, *modulus, *exponent;
635 uint8 client_random[SEC_RANDOM_SIZE];
637 uint8 inr[SEC_MODULUS_SIZE];
639 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
641 DEBUG(("Failed to parse crypt info\n"));
645 DEBUG(("Generating client random\n"));
646 /* Generate a client random, and hence determine encryption keys */
647 /* This is what the MS client do: */
648 memset(inr, 0, SEC_RANDOM_SIZE);
649 /* *ARIGL!* Plaintext attack, anyone?
651 generate_random(inr);
652 ..but that generates connection errors now and then (yes,
653 "now and then". Something like 0 to 3 attempts needed before a
654 successful connection. Nice. Not!
657 generate_random(client_random);
658 if (NULL != server_public_key)
659 { /* Which means we should use
660 RDP5-style encryption */
662 memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
663 reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
665 RSA_public_encrypt(SEC_MODULUS_SIZE,
666 inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
668 reverse(sec_crypted_random, SEC_MODULUS_SIZE);
672 { /* RDP4-style encryption */
673 sec_rsa_encrypt(sec_crypted_random,
674 client_random, SEC_RANDOM_SIZE, modulus, exponent);
676 sec_generate_keys(client_random, server_random, rc4_key_size);
680 /* Process SRV_INFO, find RDP version supported by server */
682 sec_process_srv_info(STREAM s)
684 in_uint16_le(s, g_server_rdp_version);
685 DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
686 /* if (1 == g_server_rdp_version)
691 /* Process connect response data blob */
693 sec_process_mcs_data(STREAM s)
699 in_uint8s(s, 21); /* header (T.124 stuff, probably) */
704 while (s->p < s->end)
706 in_uint16_le(s, tag);
707 in_uint16_le(s, length);
712 next_tag = s->p + length - 4;
716 case SEC_TAG_SRV_INFO:
717 sec_process_srv_info(s);
720 case SEC_TAG_SRV_CRYPT:
721 sec_process_crypt_info(s);
724 case SEC_TAG_SRV_CHANNELS:
725 /* FIXME: We should parse this information and
726 use it to map RDP5 channels to MCS
731 unimpl("response tag 0x%x\n", tag);
738 extern unsigned char cacert[];
739 extern BOOL g_licence_issued;
741 unsigned char demand_license[] = {
742 0x01, 0x03, 0x86, 0x00, 0x9c, 0x6e, 0xef, 0x5a, 0x26, 0x45, 0x88, 0x86, 0x0e, 0xdf, 0xa4, 0x4a,
743 0x45, 0xc7, 0x5a, 0x4c, 0xec, 0x33, 0xff, 0x4c, 0xd8, 0x4b, 0xd2, 0x4e, 0xd2, 0x22, 0x16, 0xde,
744 0x1e, 0x5b, 0x06, 0x6e, 0x00, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x69, 0x00,
745 0x63, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00,
746 0x43, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00,
747 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x00, 0x30, 0x00,
748 0x32, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf6, 0x00, 0x00,
749 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
750 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x00
752 unsigned char result_license[] = {
753 0xff, 0x03, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa0, 0x5f, 0x00, 0x00
756 unsigned char demand_active[] = {
757 0x24, 0x01, 0x11, 0x00, 0xea, 0x03, 0xea, 0x03, 0x01, 0x00, 0x04, 0x00, 0x0e, 0x01, 0x52, 0x44,
758 0x50, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x08, 0x00, 0xea, 0x03, 0x40, 0xe4, 0x01, 0x00,
759 0x18, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x11, 0x04, 0x00, 0x00,
760 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0e, 0x00, 0x04, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x08, 0x00,
761 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x03, 0x58, 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
762 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00,
764 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
765 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
766 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42,
767 0x0f, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
768 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00,
769 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x58, 0x00, 0x35, 0x00, 0x00, 0x00,
770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xed, 0xbf, 0xa5, 0xcd, 0xb1, 0xae, 0xbe,
771 0x88, 0x35, 0x56, 0xe5, 0xc2, 0x01, 0xaf, 0xbe, 0xc8, 0xed, 0xbf, 0xa5, 0x8c, 0x33, 0x40, 0xe4,
772 0x08, 0x30, 0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x08, 0x30, 0x40, 0xe4, 0x00, 0x00, 0x00, 0x00,
773 0xc0, 0xed, 0xbf, 0xa5, 0x34, 0xf5, 0xae, 0xbe, 0x08, 0x30, 0x40, 0xe4, 0xb4, 0xed, 0xbf, 0xa5,
774 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00, 0x00, 0x00,
775 0x00, 0x00, 0x00, 0x00
778 #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); }
779 #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); }
780 #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); }
783 process_presented_license(STREAM s)
785 unsigned char client_license_random[SEC_RANDOM_SIZE];
786 unsigned char client_license_rsa_data[SEC_MODULUS_SIZE];
788 uint16 length, license_size;
790 uint8 *license, hwid[LICENCE_HWID_SIZE], signature[LICENCE_SIGNATURE_SIZE];
793 EXPECT8(2); // version
794 in_uint16_le(s, length);
796 EXPECT32(1); // unknown
800 in_uint8a(s, client_license_random, SEC_RANDOM_SIZE);
802 EXPECT16(SEC_MODULUS_SIZE + SEC_PADDING_SIZE);
803 in_uint8a(s, client_license_rsa_data, SEC_MODULUS_SIZE);
804 in_uint8s(s, SEC_PADDING_SIZE);
807 in_uint16_le(s, license_size);
809 license = (uint8 *)xmalloc(license_size);
810 in_uint8a(s, license, license_size);
812 printf("Received license:\n");
813 for (i = 0; i < license_size; ++i)
814 printf(" 0x%02x", license[i]);
818 EXPECT16(LICENCE_HWID_SIZE);
819 in_uint8a(s, hwid, LICENCE_HWID_SIZE);
821 printf("License hardware ID:\n");
822 for (i = 0; i < LICENCE_HWID_SIZE; ++i)
823 printf(" 0x%02x", hwid[i]);
826 in_uint8a(s, signature, LICENCE_SIGNATURE_SIZE);
828 if (!s_check_end(s)) {
829 printf("Unknown data at the end of presented license!");
832 // now we can generate the keys we need
833 licence_generate_keys(client_license_random, demand_license + 4, client_license_rsa_data);
837 /* Receive secure transport packet */
845 if ((s = mcs_recv(&channel)) != NULL)
847 if (/*g_encryption || !g_licence_issued*/ 1)
849 in_uint32_le(s, sec_flags);
850 printf("sec_flags=%x\n", sec_flags);
852 if (sec_flags & SEC_ENCRYPT)
855 in_uint8s(s, 8); /* signature */
856 sec_decrypt(s->p, s->end - s->p);
859 if (sec_flags & SEC_LICENCE_NEG)
863 printf("SEC_LICENSE_NEG tag %x\n", tag);
865 if (tag == LICENCE_TAG_PRESENT) {
866 process_presented_license(s);
870 s = sec_init(SEC_LICENCE_NEG, sizeof(result_license));
871 out_uint8p(s, result_license, sizeof(result_license));
873 sec_send(s, SEC_LICENCE_NEG);
878 printf("Sending DEMAND_ACTIVE (0x%x bytes)\n", sizeof(demand_active));
879 s = sec_init(SEC_ENCRYPT, sizeof(demand_active));
880 out_uint8p(s, demand_active, sizeof(demand_active));
882 sec_send(s, SEC_ENCRYPT);
889 if (sec_flags & SEC_LOGON_INFO)
891 printf("Received logon packet!\n");
892 rdp_get_logon_info(s);
898 s = sec_init(SEC_LICENCE_NEG, sizeof(demand_license));
899 out_uint8p(s, demand_license, sizeof(demand_license));
901 sec_send(s, SEC_LICENCE_NEG);
907 if (sec_flags & SEC_CLIENT_RANDOM) {
909 uint8 inr[SEC_MODULUS_SIZE];
912 printf("Receiving the client random!\n");
913 in_uint32_le(s, length);
914 if (length != SEC_MODULUS_SIZE + SEC_PADDING_SIZE) {
915 error("Client random was wrong size, %u bytes\n", length);
917 in_uint8a(s, sec_crypted_random, SEC_MODULUS_SIZE);
918 in_uint8s(s, SEC_PADDING_SIZE);
919 if (!s_check_end(s)) {
920 error("Junk after client random\n");
923 reverse(sec_crypted_random, SEC_MODULUS_SIZE);
925 RSA_private_decrypt(SEC_MODULUS_SIZE, sec_crypted_random, inr, privkey, RSA_NO_PADDING);
927 reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
929 printf("Unencrypted client random: ");
930 for (i = 0; i < SEC_RANDOM_SIZE; ++i) {
931 printf("0x%x ", inr[i + SEC_RANDOM_SIZE]);
935 // now we can generate the keys
936 sec_generate_keys(inr + SEC_RANDOM_SIZE, cacert, 1);
941 printf("Received MCS data on ch %u\n", channel);
942 if (channel != MCS_GLOBAL_CHANNEL)
944 channel_process(s, channel);
954 /* Disconnect a connection */