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;
42 static int rc4_key_len;
43 static RC4_KEY rc4_decrypt_key;
44 static RC4_KEY rc4_encrypt_key;
45 static RSA *server_public_key;
47 static 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]);
174 static uint8 pad_54[40] = {
175 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
177 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
181 static uint8 pad_92[48] = {
182 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
183 92, 92, 92, 92, 92, 92, 92,
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
188 /* Output a uint32 into a buffer (little-endian) */
190 buf_out_uint32(uint8 * buffer, uint32 value)
192 buffer[0] = (value) & 0xff;
193 buffer[1] = (value >> 8) & 0xff;
194 buffer[2] = (value >> 16) & 0xff;
195 buffer[3] = (value >> 24) & 0xff;
198 /* Generate a signature hash, using a combination of SHA1 and MD5 */
200 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
208 buf_out_uint32(lenhdr, datalen);
211 SHA1_Update(&sha, session_key, keylen);
212 SHA1_Update(&sha, pad_54, 40);
213 SHA1_Update(&sha, lenhdr, 4);
214 SHA1_Update(&sha, data, datalen);
215 SHA1_Final(shasig, &sha);
218 MD5_Update(&md5, session_key, keylen);
219 MD5_Update(&md5, pad_92, 48);
220 MD5_Update(&md5, shasig, 20);
221 MD5_Final(md5sig, &md5);
223 memcpy(signature, md5sig, siglen);
226 /* Update an encryption key - similar to the signing process */
228 sec_update(uint8 * key, uint8 * update_key)
236 SHA1_Update(&sha, update_key, rc4_key_len);
237 SHA1_Update(&sha, pad_54, 40);
238 SHA1_Update(&sha, key, rc4_key_len);
239 SHA1_Final(shasig, &sha);
242 MD5_Update(&md5, update_key, rc4_key_len);
243 MD5_Update(&md5, pad_92, 48);
244 MD5_Update(&md5, shasig, 20);
245 MD5_Final(key, &md5);
247 RC4_set_key(&update, rc4_key_len, key);
248 RC4(&update, rc4_key_len, key, key);
250 if (rc4_key_len == 8)
254 /* Encrypt data using RC4 */
256 sec_encrypt(uint8 * data, int length)
258 static int use_count;
260 if (use_count == 4096)
262 sec_update(sec_decrypt_key, sec_decrypt_update_key);
263 RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
267 RC4(&rc4_decrypt_key, length, data, data);
271 /* Decrypt data using RC4 */
273 sec_decrypt(uint8 * data, int length)
275 static int use_count;
277 if (use_count == 4096)
279 sec_update(sec_encrypt_key, sec_encrypt_update_key);
280 RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
284 RC4(&rc4_encrypt_key, length, data, data);
289 reverse(uint8 * p, int len)
294 for (i = 0, j = len - 1; i < j; i++, j--)
302 /* Perform an RSA public key encryption operation */
304 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
307 BIGNUM mod, exp, x, y;
308 uint8 inr[SEC_MODULUS_SIZE];
311 reverse(modulus, SEC_MODULUS_SIZE);
312 reverse(exponent, SEC_EXPONENT_SIZE);
313 memcpy(inr, in, len);
322 BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
323 BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
324 BN_bin2bn(inr, len, &x);
325 BN_mod_exp(&y, &x, &exp, &mod, ctx);
326 outlen = BN_bn2bin(&y, out);
327 reverse(out, outlen);
328 if (outlen < SEC_MODULUS_SIZE)
329 memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
338 /* Initialise secure transport packet */
340 sec_init(uint32 flags, int maxlen)
345 if (!g_licence_issued)
346 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
348 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
349 s = mcs_init(maxlen + hdrlen);
350 s_push_layer(s, sec_hdr, hdrlen);
355 /* Transmit secure transport packet over specified channel */
357 sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
361 // DEBUG(("sending packet to channel %u\n", channel));
363 s_pop_layer(s, sec_hdr);
364 if (!g_licence_issued || (flags & SEC_ENCRYPT)) {
365 out_uint32_le(s, flags);
368 if (flags & SEC_ENCRYPT)
370 flags &= ~SEC_ENCRYPT;
371 datalen = s->end - s->p - 8;
374 DEBUG(("Sending encrypted packet:\n"));
375 hexdump(s->p + 8, datalen);
378 sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, datalen);
379 printf("First byte of signature is 0x%x, at %p\n", (s->p)[0], s->p);
380 sec_encrypt(s->p + 8, datalen);
383 mcs_send_to_channel(s, channel);
386 /* Transmit secure transport packet */
389 sec_send(STREAM s, uint32 flags)
391 sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
395 /* Transfer the client random to the server */
397 sec_establish_key(void)
399 uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
400 uint32 flags = SEC_CLIENT_RANDOM;
403 s = sec_init(flags, 76);
405 out_uint32_le(s, length);
406 out_uint8p(s, sec_crypted_random, SEC_MODULUS_SIZE);
407 out_uint8s(s, SEC_PADDING_SIZE);
413 /* Parse a public key structure */
415 sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
417 uint32 magic, modulus_len;
419 in_uint32_le(s, magic);
420 if (magic != SEC_RSA_MAGIC)
422 error("RSA magic 0x%x\n", magic);
426 in_uint32_le(s, modulus_len);
427 if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
429 error("modulus len 0x%x\n", modulus_len);
433 in_uint8s(s, 8); /* modulus_bits, unknown */
434 in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);
435 in_uint8p(s, *modulus, SEC_MODULUS_SIZE);
436 in_uint8s(s, SEC_PADDING_SIZE);
442 sec_parse_x509_key(X509 * cert)
444 EVP_PKEY *epk = NULL;
445 /* By some reason, Microsoft sets the OID of the Public RSA key to
446 the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
448 Kudos to Richard Levitte for the following (. intiutive .)
449 lines of code that resets the OID and let's us extract the key. */
450 if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
452 DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
453 cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
455 epk = X509_get_pubkey(cert);
458 error("Failed to extract public key from certificate\n");
462 server_public_key = (RSA *) epk->pkey.ptr;
468 /* Parse a crypto information structure */
470 sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
471 uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
473 uint32 crypt_level, random_len, rsa_info_len;
474 uint32 cacert_len, cert_len, flags;
475 X509 *cacert, *server_cert;
477 uint8 *next_tag, *end;
479 in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
480 in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
481 if (crypt_level == 0) /* no encryption */
483 in_uint32_le(s, random_len);
484 in_uint32_le(s, rsa_info_len);
486 if (random_len != SEC_RANDOM_SIZE)
488 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
492 in_uint8p(s, *server_random, random_len);
495 end = s->p + rsa_info_len;
499 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
502 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
503 in_uint8s(s, 8); /* unknown */
507 in_uint16_le(s, tag);
508 in_uint16_le(s, length);
510 next_tag = s->p + length;
515 if (!sec_parse_public_key(s, modulus, exponent))
517 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
522 /* Is this a Microsoft key that we just got? */
523 /* Care factor: zero! */
524 /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
525 key as a known key of the hostname. This would prevent some MITM-attacks. */
529 unimpl("crypt tag 0x%x\n", tag);
539 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
540 in_uint32_le(s, certcount); /* Number of certificates */
544 error("Server didn't send enough X509 certificates\n");
548 for(; certcount > 2; certcount--)
549 { /* ignore all the certificates between the root and the signing CA */
553 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
555 in_uint32_le(s, ignorelen);
556 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
557 ignorecert = d2i_X509(NULL, &(s->p), ignorelen);
559 if(ignorecert == NULL)
560 { /* XXX: error out? */
561 DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
564 #ifdef WITH_DEBUG_RDP5
565 DEBUG_RDP5(("cert #%d (ignored):\n",certcount));
566 X509_print_fp(stdout, ignorecert);
570 /* Do da funky X.509 stuffy
572 "How did I find out about this? I looked up and saw a
573 bright light and when I came to I had a scar on my forehead
574 and knew about X.500"
575 - Peter Gutman in a early version of
576 http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
579 in_uint32_le(s, cacert_len);
580 DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
581 cacert = d2i_X509(NULL, &(s->p), cacert_len);
582 /* Note: We don't need to move s->p here - d2i_X509 is
583 "kind" enough to do it for us */
586 error("Couldn't load CA Certificate from server\n");
590 /* Currently, we don't use the CA Certificate.
592 *) Verify the server certificate (server_cert) with the
594 *) Store the CA Certificate with the hostname of the
595 server we are connecting to as key, and compare it
596 when we connect the next time, in order to prevent
600 in_uint32_le(s, cert_len);
601 DEBUG_RDP5(("Certificate length is %d\n", cert_len));
602 server_cert = d2i_X509(NULL, &(s->p), cert_len);
603 if (NULL == server_cert)
605 error("Couldn't load Certificate from server\n");
609 in_uint8s(s, 16); /* Padding */
611 /* Note: Verifying the server certificate must be done here,
612 before sec_parse_public_key since we'll have to apply
613 serious violence to the key after this */
615 if (!sec_parse_x509_key(server_cert))
617 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
620 return True; /* There's some garbage here we don't care about */
622 return s_check_end(s);
625 /* Process crypto information blob */
627 sec_process_crypt_info(STREAM s)
629 uint8 *server_random, *modulus, *exponent;
630 uint8 client_random[SEC_RANDOM_SIZE];
632 uint8 inr[SEC_MODULUS_SIZE];
634 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
636 DEBUG(("Failed to parse crypt info\n"));
640 DEBUG(("Generating client random\n"));
641 /* Generate a client random, and hence determine encryption keys */
642 /* This is what the MS client do: */
643 memset(inr, 0, SEC_RANDOM_SIZE);
644 /* *ARIGL!* Plaintext attack, anyone?
646 generate_random(inr);
647 ..but that generates connection errors now and then (yes,
648 "now and then". Something like 0 to 3 attempts needed before a
649 successful connection. Nice. Not!
652 generate_random(client_random);
653 if (NULL != server_public_key)
654 { /* Which means we should use
655 RDP5-style encryption */
657 memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
658 reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
660 RSA_public_encrypt(SEC_MODULUS_SIZE,
661 inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
663 reverse(sec_crypted_random, SEC_MODULUS_SIZE);
667 { /* RDP4-style encryption */
668 sec_rsa_encrypt(sec_crypted_random,
669 client_random, SEC_RANDOM_SIZE, modulus, exponent);
671 sec_generate_keys(client_random, server_random, rc4_key_size);
675 /* Process SRV_INFO, find RDP version supported by server */
677 sec_process_srv_info(STREAM s)
679 in_uint16_le(s, g_server_rdp_version);
680 DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
681 /* if (1 == g_server_rdp_version)
686 /* Process connect response data blob */
688 sec_process_mcs_data(STREAM s)
694 in_uint8s(s, 21); /* header (T.124 stuff, probably) */
699 while (s->p < s->end)
701 in_uint16_le(s, tag);
702 in_uint16_le(s, length);
707 next_tag = s->p + length - 4;
711 case SEC_TAG_SRV_INFO:
712 sec_process_srv_info(s);
715 case SEC_TAG_SRV_CRYPT:
716 sec_process_crypt_info(s);
719 case SEC_TAG_SRV_CHANNELS:
720 /* FIXME: We should parse this information and
721 use it to map RDP5 channels to MCS
726 unimpl("response tag 0x%x\n", tag);
733 extern unsigned char cacert[];
734 extern BOOL g_licence_issued;
736 unsigned char demand_license[] = {
737 0x01, 0x03, 0x86, 0x00, 0x9c, 0x6e, 0xef, 0x5a, 0x26, 0x45, 0x88, 0x86, 0x0e, 0xdf, 0xa4, 0x4a,
738 0x45, 0xc7, 0x5a, 0x4c, 0xec, 0x33, 0xff, 0x4c, 0xd8, 0x4b, 0xd2, 0x4e, 0xd2, 0x22, 0x16, 0xde,
739 0x1e, 0x5b, 0x06, 0x6e, 0x00, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x69, 0x00,
740 0x63, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00,
741 0x43, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00,
742 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x00, 0x30, 0x00,
743 0x32, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xf6, 0x00, 0x00,
744 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
745 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x00
747 unsigned char result_license[] = {
748 0xff, 0x03, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa0, 0x5f, 0x00, 0x00
751 unsigned char demand_active[] = {
752 0x24, 0x01, 0x11, 0x00, 0xea, 0x03, 0xea, 0x03, 0x01, 0x00, 0x04, 0x00, 0x0e, 0x01, 0x52, 0x44,
753 0x50, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x08, 0x00, 0xea, 0x03, 0x40, 0xe4, 0x01, 0x00,
754 0x18, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x11, 0x04, 0x00, 0x00,
755 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0e, 0x00, 0x04, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x08, 0x00,
756 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x03, 0x58, 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
757 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00,
759 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
760 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
761 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42,
762 0x0f, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
763 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00,
764 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x58, 0x00, 0x35, 0x00, 0x00, 0x00,
765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xed, 0xbf, 0xa5, 0xcd, 0xb1, 0xae, 0xbe,
766 0x88, 0x35, 0x56, 0xe5, 0xc2, 0x01, 0xaf, 0xbe, 0xc8, 0xed, 0xbf, 0xa5, 0x8c, 0x33, 0x40, 0xe4,
767 0x08, 0x30, 0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x08, 0x30, 0x40, 0xe4, 0x00, 0x00, 0x00, 0x00,
768 0xc0, 0xed, 0xbf, 0xa5, 0x34, 0xf5, 0xae, 0xbe, 0x08, 0x30, 0x40, 0xe4, 0xb4, 0xed, 0xbf, 0xa5,
769 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00, 0x00, 0x00,
770 0x00, 0x00, 0x00, 0x00
773 #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); }
774 #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); }
775 #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); }
778 process_presented_license(STREAM s)
780 unsigned char client_license_random[SEC_RANDOM_SIZE];
781 unsigned char client_license_rsa_data[SEC_MODULUS_SIZE];
783 uint16 length, license_size;
785 uint8 *license, hwid[LICENCE_HWID_SIZE], signature[LICENCE_SIGNATURE_SIZE];
788 EXPECT8(2); // version
789 in_uint16_le(s, length);
791 EXPECT32(1); // unknown
795 in_uint8a(s, client_license_random, SEC_RANDOM_SIZE);
797 EXPECT16(SEC_MODULUS_SIZE + SEC_PADDING_SIZE);
798 in_uint8a(s, client_license_rsa_data, SEC_MODULUS_SIZE);
799 in_uint8s(s, SEC_PADDING_SIZE);
802 in_uint16_le(s, license_size);
804 license = (uint8 *)xmalloc(license_size);
805 in_uint8a(s, license, license_size);
807 printf("Received license:\n");
808 for (i = 0; i < license_size; ++i)
809 printf(" 0x%02x", license[i]);
813 EXPECT16(LICENCE_HWID_SIZE);
814 in_uint8a(s, hwid, LICENCE_HWID_SIZE);
816 printf("License hardware ID:\n");
817 for (i = 0; i < LICENCE_HWID_SIZE; ++i)
818 printf(" 0x%02x", hwid[i]);
821 in_uint8a(s, signature, LICENCE_SIGNATURE_SIZE);
823 if (!s_check_end(s)) {
824 printf("Unknown data at the end of presented license!");
827 // now we can generate the keys we need
828 licence_generate_keys(client_license_random, demand_license + 4, client_license_rsa_data);
832 /* Receive secure transport packet */
840 while ((s = mcs_recv(&channel)) != NULL)
842 if (/*g_encryption || !g_licence_issued*/ 1)
844 in_uint32_le(s, sec_flags);
845 printf("sec_flags=%x\n", sec_flags);
847 if (sec_flags & SEC_ENCRYPT)
850 in_uint8s(s, 8); /* signature */
851 sec_decrypt(s->p, s->end - s->p);
854 if (sec_flags & SEC_LICENCE_NEG)
858 printf("SEC_LICENSE_NEG tag %x\n", tag);
860 if (tag == LICENCE_TAG_PRESENT) {
861 process_presented_license(s);
863 s = sec_init(sizeof(result_license), SEC_LICENCE_NEG);
864 out_uint8p(s, result_license, sizeof(result_license));
866 sec_send(s, SEC_LICENCE_NEG);
868 //g_licence_issued = 1;
870 printf("Sending DEMAND_ACTIVE (0x%x bytes)\n", sizeof(demand_active));
871 s = sec_init(sizeof(demand_active), SEC_ENCRYPT);
872 out_uint8p(s, demand_active, sizeof(demand_active));
874 sec_send(s, SEC_ENCRYPT);
880 if (sec_flags & SEC_LOGON_INFO)
882 printf("Received logon packet!\n");
883 rdp_get_logon_info(s);
889 s = sec_init(sizeof(demand_license), SEC_LICENCE_NEG);
890 out_uint8p(s, demand_license, sizeof(demand_license));
892 sec_send(s, SEC_LICENCE_NEG);
898 if (sec_flags & SEC_CLIENT_RANDOM) {
900 uint8 inr[SEC_MODULUS_SIZE];
903 printf("Receiving the client random!\n");
904 in_uint32_le(s, length);
905 if (length != SEC_MODULUS_SIZE + SEC_PADDING_SIZE) {
906 error("Client random was wrong size, %u bytes\n", length);
908 in_uint8a(s, sec_crypted_random, SEC_MODULUS_SIZE);
909 in_uint8s(s, SEC_PADDING_SIZE);
910 if (!s_check_end(s)) {
911 error("Junk after client random\n");
914 reverse(sec_crypted_random, SEC_MODULUS_SIZE);
916 RSA_private_decrypt(SEC_MODULUS_SIZE, sec_crypted_random, inr, privkey, RSA_NO_PADDING);
918 reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
920 printf("Unencrypted client random: ");
921 for (i = 0; i < SEC_RANDOM_SIZE; ++i) {
922 printf("0x%x ", inr[i + SEC_RANDOM_SIZE]);
926 // now we can generate the keys
927 sec_generate_keys(inr + SEC_RANDOM_SIZE, cacert, 1);
932 printf("Received MCS data on ch %u\n", channel);
933 if (channel != MCS_GLOBAL_CHANNEL)
935 channel_process(s, channel);
945 /* Disconnect a connection */