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 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 RC4(&rc4_decrypt_key, length, data, data);
273 /* Decrypt data using RC4 */
275 sec_decrypt(uint8 * data, int length)
277 static int use_count;
279 if (use_count == 4096)
281 sec_update(sec_encrypt_key, sec_encrypt_update_key);
282 RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
286 RC4(&rc4_encrypt_key, length, data, data);
291 reverse(uint8 * p, int len)
296 for (i = 0, j = len - 1; i < j; i++, j--)
304 /* Perform an RSA public key encryption operation */
306 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
309 BIGNUM mod, exp, x, y;
310 uint8 inr[SEC_MODULUS_SIZE];
313 reverse(modulus, SEC_MODULUS_SIZE);
314 reverse(exponent, SEC_EXPONENT_SIZE);
315 memcpy(inr, in, len);
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);
340 /* Initialise secure transport packet */
342 sec_init(uint32 flags, int maxlen)
347 if (!g_licence_issued)
348 hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
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);
358 /* Transmit secure transport packet over specified channel */
360 sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
364 // DEBUG(("sending packet to channel %u\n", channel));
366 s_pop_layer(s, sec_hdr);
367 if (!g_licence_issued || (flags & SEC_ENCRYPT)) {
368 out_uint32_le(s, flags);
371 if (flags & SEC_ENCRYPT)
373 flags &= ~SEC_ENCRYPT;
374 datalen = s->end - s->p - 8;
377 DEBUG(("Sending encrypted packet:\n"));
378 hexdump(s->p + 8, datalen);
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);
386 mcs_send_to_channel(s, channel);
389 /* Transmit secure transport packet */
392 sec_send(STREAM s, uint32 flags)
394 sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
398 /* Transfer the client random to the server */
400 sec_establish_key(void)
402 uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
403 uint32 flags = SEC_CLIENT_RANDOM;
406 s = sec_init(flags, 76);
408 out_uint32_le(s, length);
409 out_uint8p(s, sec_crypted_random, SEC_MODULUS_SIZE);
410 out_uint8s(s, SEC_PADDING_SIZE);
416 /* Parse a public key structure */
418 sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
420 uint32 magic, modulus_len;
422 in_uint32_le(s, magic);
423 if (magic != SEC_RSA_MAGIC)
425 error("RSA magic 0x%x\n", magic);
429 in_uint32_le(s, modulus_len);
430 if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
432 error("modulus len 0x%x\n", modulus_len);
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);
445 sec_parse_x509_key(X509 * cert)
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"
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)
455 DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
456 cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
458 epk = X509_get_pubkey(cert);
461 error("Failed to extract public key from certificate\n");
465 server_public_key = (RSA *) epk->pkey.ptr;
471 /* Parse a crypto information structure */
473 sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
474 uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
476 uint32 crypt_level, random_len, rsa_info_len;
477 uint32 cacert_len, cert_len, flags;
478 X509 *cacert, *server_cert;
480 uint8 *next_tag, *end;
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 */
486 in_uint32_le(s, random_len);
487 in_uint32_le(s, rsa_info_len);
489 if (random_len != SEC_RANDOM_SIZE)
491 error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
495 in_uint8p(s, *server_random, random_len);
498 end = s->p + rsa_info_len;
502 in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
505 DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
506 in_uint8s(s, 8); /* unknown */
510 in_uint16_le(s, tag);
511 in_uint16_le(s, length);
513 next_tag = s->p + length;
518 if (!sec_parse_public_key(s, modulus, exponent))
520 DEBUG_RDP5(("Got Public key, RDP4-style\n"));
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. */
532 unimpl("crypt tag 0x%x\n", tag);
542 DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
543 in_uint32_le(s, certcount); /* Number of certificates */
547 error("Server didn't send enough X509 certificates\n");
551 for(; certcount > 2; certcount--)
552 { /* ignore all the certificates between the root and the signing CA */
556 DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
558 in_uint32_le(s, ignorelen);
559 DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
560 ignorecert = d2i_X509(NULL, &(s->p), ignorelen);
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"));
567 #ifdef WITH_DEBUG_RDP5
568 DEBUG_RDP5(("cert #%d (ignored):\n",certcount));
569 X509_print_fp(stdout, ignorecert);
573 /* Do da funky X.509 stuffy
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
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 */
589 error("Couldn't load CA Certificate from server\n");
593 /* Currently, we don't use the CA Certificate.
595 *) Verify the server certificate (server_cert) with the
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
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)
608 error("Couldn't load Certificate from server\n");
612 in_uint8s(s, 16); /* Padding */
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 */
618 if (!sec_parse_x509_key(server_cert))
620 DEBUG_RDP5(("Didn't parse X509 correctly\n"));
623 return True; /* There's some garbage here we don't care about */
625 return s_check_end(s);
628 /* Process crypto information blob */
630 sec_process_crypt_info(STREAM s)
632 uint8 *server_random, *modulus, *exponent;
633 uint8 client_random[SEC_RANDOM_SIZE];
635 uint8 inr[SEC_MODULUS_SIZE];
637 if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
639 DEBUG(("Failed to parse crypt info\n"));
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?
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!
655 generate_random(client_random);
656 if (NULL != server_public_key)
657 { /* Which means we should use
658 RDP5-style encryption */
660 memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
661 reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
663 RSA_public_encrypt(SEC_MODULUS_SIZE,
664 inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
666 reverse(sec_crypted_random, SEC_MODULUS_SIZE);
670 { /* RDP4-style encryption */
671 sec_rsa_encrypt(sec_crypted_random,
672 client_random, SEC_RANDOM_SIZE, modulus, exponent);
674 sec_generate_keys(client_random, server_random, rc4_key_size);
678 /* Process SRV_INFO, find RDP version supported by server */
680 sec_process_srv_info(STREAM s)
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)
689 /* Process connect response data blob */
691 sec_process_mcs_data(STREAM s)
697 in_uint8s(s, 21); /* header (T.124 stuff, probably) */
702 while (s->p < s->end)
704 in_uint16_le(s, tag);
705 in_uint16_le(s, length);
710 next_tag = s->p + length - 4;
714 case SEC_TAG_SRV_INFO:
715 sec_process_srv_info(s);
718 case SEC_TAG_SRV_CRYPT:
719 sec_process_crypt_info(s);
722 case SEC_TAG_SRV_CHANNELS:
723 /* FIXME: We should parse this information and
724 use it to map RDP5 channels to MCS
729 unimpl("response tag 0x%x\n", tag);
736 extern unsigned char cacert[];
737 extern BOOL g_licence_issued;
739 unsigned char result_license[] = {
740 0xff, 0x03, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa0, 0x5f, 0x00, 0x00
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
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); }
769 /* Receive secure transport packet */
777 if ((s = mcs_recv(&channel)) != NULL)
779 if (/*g_encryption || !g_licence_issued*/ 1)
781 in_uint32_le(s, sec_flags);
783 if (sec_flags & SEC_ENCRYPT)
785 in_uint8s(s, 8); /* signature */
786 sec_decrypt(s->p, s->end - s->p);
789 if (sec_flags & SEC_LICENCE_NEG)
794 printf("License tag %x, unimplemented\n", tag);
799 if (sec_flags & SEC_LOGON_INFO)
801 rdp_get_logon_info(s);
803 // say "licensing is OK", then demand
807 s = sec_init(SEC_LICENCE_NEG, sizeof(result_license));
808 out_uint8p(s, result_license, sizeof(result_license));
810 sec_send(s, SEC_LICENCE_NEG);
815 s = sec_init(SEC_ENCRYPT, sizeof(demand_active));
816 out_uint8p(s, demand_active, sizeof(demand_active));
818 sec_send(s, SEC_ENCRYPT);
824 if (sec_flags & SEC_CLIENT_RANDOM) {
826 uint8 inr[SEC_MODULUS_SIZE];
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);
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");
839 reverse(sec_crypted_random, SEC_MODULUS_SIZE);
841 RSA_private_decrypt(SEC_MODULUS_SIZE, sec_crypted_random, inr, privkey, RSA_NO_PADDING);
843 reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
845 printf("Unencrypted client random: ");
846 for (i = 0; i < SEC_RANDOM_SIZE; ++i) {
847 printf("0x%x ", inr[i + SEC_RANDOM_SIZE]);
851 // now we can generate the keys
852 sec_generate_keys(inr + SEC_RANDOM_SIZE, cacert, 1);
857 printf("Received MCS data on ch %u\n", channel);
858 if (channel != MCS_GLOBAL_CHANNEL)
860 channel_process(s, channel);
870 /* Disconnect a connection */