ReactOS  0.4.12-dev-57-g7050ac4
secure.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 8 -*-
2  rdesktop: A Remote Desktop Protocol client.
3  Protocol services - RDP encryption and licensing
4  Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5  Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
6 
7  This program is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "precomp.h"
22 
23 void *
25 void
27 void
29 void
30 rdssl_sha1_transform(void * sha1_info, char * data, int len);
31 void
32 rdssl_sha1_complete(void * sha1_info, char * data);
33 void *
35 void
37 void *
39 void
41 void
43 void
44 rdssl_md5_transform(void * md5_info, char * data, int len);
45 void
46 rdssl_md5_complete(void * md5_info, char * data);
47 void *
49 void
50 rdssl_rc4_info_delete(void * rc4_info);
51 void
52 rdssl_rc4_set_key(void * rc4_info, char * key, int len);
53 void
54 rdssl_rc4_crypt(void * rc4_info, char * in_data, char * out_data, int len);
55 int
56 rdssl_mod_exp(char* out, int out_len, char* in, int in_len,
57  char* mod, int mod_len, char* exp, int exp_len);
58 int
59 rdssl_sign_ok(char* e_data, int e_len, char* n_data, int n_len,
60  char* sign_data, int sign_len, char* sign_data2, int sign_len2, char* testkey);
63 void
65 uint8 *
67 RD_BOOL
68 rdssl_certs_ok(PCCERT_CONTEXT server_cert, PCCERT_CONTEXT cacert);
69 int
70 rdssl_rkey_get_exp_mod(uint8 * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
71  uint32 max_mod_len);
72 void
73 rdssl_rkey_free(uint8 * rkey);
74 
75 extern char g_hostname[16];
76 extern int g_width;
77 extern int g_height;
78 extern unsigned int g_keylayout;
79 extern int g_keyboard_type;
80 extern int g_keyboard_subtype;
81 extern int g_keyboard_functionkeys;
82 extern RD_BOOL g_encryption;
88 extern int g_server_depth;
89 extern VCHANNEL g_channels[];
90 extern unsigned int g_num_channels;
92 
93 static int g_rc4_key_len;
94 static void * g_rc4_decrypt_key;
95 static void * g_rc4_encrypt_key;
97 
98 static uint8 g_sec_sign_key[16];
104 
106 
107 /* These values must be available to reset state - Session Directory */
108 static int g_sec_encrypt_use_count = 0;
109 static int g_sec_decrypt_use_count = 0;
110 
111 #define SEC_MODULUS_SIZE 64
112 
113 static uint8 g_testkey[176] =
114 {
115  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
116  0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x5c, 0x00,
117  0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00,
118  0x00, 0x02, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
119  0x01, 0x00, 0x01, 0x00, 0x79, 0x6f, 0xb4, 0xdf,
120  0xa6, 0x95, 0xb9, 0xa9, 0x61, 0xe3, 0xc4, 0x5e,
121  0xff, 0x6b, 0xd8, 0x81, 0x8a, 0x12, 0x4a, 0x93,
122  0x42, 0x97, 0x18, 0x93, 0xac, 0xd1, 0x3a, 0x38,
123  0x3c, 0x68, 0x50, 0x19, 0x31, 0xb6, 0x84, 0x51,
124  0x79, 0xfb, 0x1c, 0xe7, 0xe3, 0x99, 0x20, 0xc7,
125  0x84, 0xdf, 0xd1, 0xaa, 0xb5, 0x15, 0xef, 0x47,
126  0x7e, 0xfc, 0x88, 0xeb, 0x29, 0xc3, 0x27, 0x5a,
127  0x35, 0xf8, 0xfd, 0xaa, 0x00, 0x00, 0x00, 0x00,
128  0x00, 0x00, 0x00, 0x00,
129  0x08, 0x00, 0x48, 0x00,
130  0x32, 0x3b, 0xde, 0x6f, 0x18, 0x97, 0x1e, 0xc3,
131  0x6b, 0x2b, 0x2d, 0xe4, 0xfc, 0x2d, 0xa2, 0x8e,
132  0x32, 0x3c, 0xf3, 0x1b, 0x24, 0x90, 0x57, 0x4d,
133  0x8e, 0xe4, 0x69, 0xfc, 0x16, 0x8d, 0x41, 0x92,
134  0x78, 0xc7, 0x9c, 0xb4, 0x26, 0xff, 0xe8, 0x3e,
135  0xa1, 0x8a, 0xf5, 0x57, 0xc0, 0x7f, 0x3e, 0x21,
136  0x17, 0x32, 0x30, 0x6f, 0x79, 0xe1, 0x36, 0xcd,
137  0xb6, 0x8e, 0xbe, 0x57, 0x57, 0xd2, 0xa9, 0x36
138 };
139 
140 /*
141  * I believe this is based on SSLv3 with the following differences:
142  * MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
143  * MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
144  * key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
145  * key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
146  * encryption/decryption keys updated every 4096 packets
147  * See http://wp.netscape.com/eng/ssl3/draft302.txt
148  */
149 
150 /*
151  * 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
152  * Both SHA1 and MD5 algorithms are used.
153  */
154 void
155 sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
156 {
157  uint8 shasig[20];
158  uint8 pad[4];
159  void * sha;
160  void * md5;
161  int i;
162 
163  for (i = 0; i < 3; i++)
164  {
165  memset(pad, salt + i, i + 1);
166  sha = rdssl_sha1_info_create();
167  rdssl_sha1_clear(sha);
168  rdssl_sha1_transform(sha, (char *)pad, i + 1);
169  rdssl_sha1_transform(sha, (char *)in, 48);
170  rdssl_sha1_transform(sha, (char *)salt1, 32);
171  rdssl_sha1_transform(sha, (char *)salt2, 32);
172  rdssl_sha1_complete(sha, (char *)shasig);
174  md5 = rdssl_md5_info_create();
175  rdssl_md5_clear(md5);
176  rdssl_md5_transform(md5, (char *)in, 48);
177  rdssl_md5_transform(md5, (char *)shasig, 20);
178  rdssl_md5_complete(md5, (char *)out + i * 16);
180  }
181 }
182 
183 /*
184  * 16-byte transformation used to generate export keys (6.2.2).
185  */
186 void
187 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
188 {
189  void * md5;
190 
191  md5 = rdssl_md5_info_create();
192  rdssl_md5_clear(md5);
193  rdssl_md5_transform(md5, (char *)in, 16);
194  rdssl_md5_transform(md5, (char *)salt1, 32);
195  rdssl_md5_transform(md5, (char *)salt2, 32);
196  rdssl_md5_complete(md5, (char *)out);
198 }
199 
200 /*
201  * 16-byte sha1 hash
202  */
203 void
205 {
206  void * sha;
207  sha = rdssl_sha1_info_create();
208  rdssl_sha1_clear(sha);
209  rdssl_sha1_transform(&sha, (char *)in, 16);
210  rdssl_sha1_transform(&sha, (char *)salt1, 16);
211  rdssl_sha1_complete(&sha, (char *)out);
213 }
214 
215 /* create string from hash */
216 void
218 {
219  int k;
220  memset(out, 0, out_size);
221  for (k = 0; k < in_size; k++, out += 2)
222  {
223  sprintf(out, "%.2x", in[k]);
224  }
225 }
226 
227 /* Reduce key entropy from 64 to 40 bits */
228 static void
230 {
231  key[0] = 0xd1;
232  key[1] = 0x26;
233  key[2] = 0x9e;
234 }
235 
236 /* Generate encryption keys given client and server randoms */
237 static void
238 sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
239 {
240  uint8 pre_master_secret[48];
241  uint8 master_secret[48];
242  uint8 key_block[48];
243 
244  /* Construct pre-master secret */
245  memcpy(pre_master_secret, client_random, 24);
246  memcpy(pre_master_secret + 24, server_random, 24);
247 
248  /* Generate master secret and then key material */
249  sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
250  sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
251 
252  /* First 16 bytes of key material is MAC secret */
253  memcpy(g_sec_sign_key, key_block, 16);
254 
255  /* Generate export keys from next two blocks of 16 bytes */
256  sec_hash_16(g_sec_decrypt_key, &key_block[16], client_random, server_random);
257  sec_hash_16(g_sec_encrypt_key, &key_block[32], client_random, server_random);
258 
259  if (rc4_key_size == 1)
260  {
261  DEBUG(("40-bit encryption enabled\n"));
265  g_rc4_key_len = 8;
266  }
267  else
268  {
269  DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
270  g_rc4_key_len = 16;
271  }
272 
273  /* Save initial RC4 keys as update keys */
276 
277  /* Initialise RC4 state arrays */
278 
279  rdssl_rc4_info_delete(g_rc4_decrypt_key);
280  g_rc4_decrypt_key = rdssl_rc4_info_create();
281  rdssl_rc4_set_key(g_rc4_decrypt_key, (char *)g_sec_decrypt_key, g_rc4_key_len);
282 
283  rdssl_rc4_info_delete(g_rc4_encrypt_key);
284  g_rc4_encrypt_key = rdssl_rc4_info_create();
285  rdssl_rc4_set_key(g_rc4_encrypt_key, (char *)g_sec_encrypt_key, g_rc4_key_len);
286 }
287 
288 static uint8 pad_54[40] = {
289  54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
290  54, 54, 54,
291  54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
292  54, 54, 54
293 };
294 
295 static uint8 pad_92[48] = {
296  92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
297  92, 92, 92, 92, 92, 92, 92,
298  92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
299  92, 92, 92, 92, 92, 92, 92
300 };
301 
302 /* Output a uint32 into a buffer (little-endian) */
303 void
305 {
306  buffer[0] = (value) & 0xff;
307  buffer[1] = (value >> 8) & 0xff;
308  buffer[2] = (value >> 16) & 0xff;
309  buffer[3] = (value >> 24) & 0xff;
310 }
311 
312 /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
313 void
314 sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
315 {
316  uint8 shasig[20];
317  uint8 md5sig[16];
318  uint8 lenhdr[4];
319  void * sha;
320  void * md5;
321 
322  buf_out_uint32(lenhdr, datalen);
323 
324  sha = rdssl_sha1_info_create();
325  rdssl_sha1_clear(sha);
326  rdssl_sha1_transform(sha, (char *)session_key, keylen);
327  rdssl_sha1_transform(sha, (char *)pad_54, 40);
328  rdssl_sha1_transform(sha, (char *)lenhdr, 4);
329  rdssl_sha1_transform(sha, (char *)data, datalen);
330  rdssl_sha1_complete(sha, (char *)shasig);
332 
333  md5 = rdssl_md5_info_create();
334  rdssl_md5_clear(md5);
335  rdssl_md5_transform(md5, (char *)session_key, keylen);
336  rdssl_md5_transform(md5, (char *)pad_92, 48);
337  rdssl_md5_transform(md5, (char *)shasig, 20);
338  rdssl_md5_complete(md5, (char *)md5sig);
339  rdssl_md5_info_delete(md5);
340 
341  memcpy(signature, md5sig, siglen);
342 }
343 
344 /* Update an encryption key */
345 static void
346 sec_update(uint8 * key, uint8 * update_key)
347 {
348  uint8 shasig[20];
349  void * sha;
350  void * md5;
351  void * update;
352 
353  sha = rdssl_sha1_info_create();
354  rdssl_sha1_clear(sha);
355  rdssl_sha1_transform(sha, (char *)update_key, g_rc4_key_len);
356  rdssl_sha1_transform(sha, (char *)pad_54, 40);
357  rdssl_sha1_transform(sha, (char *)key, g_rc4_key_len);
358  rdssl_sha1_complete(sha, (char *)shasig);
360 
361  md5 = rdssl_md5_info_create();
362  rdssl_md5_clear(md5);
363  rdssl_md5_transform(md5, (char *)update_key, g_rc4_key_len);
364  rdssl_md5_transform(md5, (char *)pad_92, 48);
365  rdssl_md5_transform(md5, (char *)shasig, 20);
366  rdssl_md5_complete(md5, (char *)key);
368 
369 
370  update = rdssl_rc4_info_create();
371  rdssl_rc4_set_key(update, (char *)key, g_rc4_key_len);
372  rdssl_rc4_crypt(update, (char *)key, (char *)key, g_rc4_key_len);
373  rdssl_rc4_info_delete(update);
374 
375  if (g_rc4_key_len == 8)
376  sec_make_40bit(key);
377 }
378 
379 /* Encrypt data using RC4 */
380 static void
382 {
383  if (g_sec_encrypt_use_count == 4096)
384  {
386  rdssl_rc4_set_key(g_rc4_encrypt_key, (char *)g_sec_encrypt_key, g_rc4_key_len);
388  }
389 
390  rdssl_rc4_crypt(g_rc4_encrypt_key, (char *)data, (char *)data, length);
392 }
393 
394 /* Decrypt data using RC4 */
395 void
397 {
398  if (g_sec_decrypt_use_count == 4096)
399  {
401  rdssl_rc4_set_key(g_rc4_decrypt_key, (char *)g_sec_decrypt_key, g_rc4_key_len);
403  }
404 
405  rdssl_rc4_crypt(g_rc4_decrypt_key,(char *)data, (char *)data, length);
407 }
408 
409 /* Perform an RSA public key encryption operation */
410 static void
411 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
412  uint8 * exponent)
413 {
414  rdssl_mod_exp((char *)out, 64, (char *)in, 32, (char *)modulus, 64, (char *)exponent, 4);
415 }
416 
417 /* Initialise secure transport packet */
418 STREAM
419 sec_init(uint32 flags, int maxlen)
420 {
421  int hdrlen;
422  STREAM s;
423 
425  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
426  else
427  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
428  s = mcs_init(maxlen + hdrlen);
429  s_push_layer(s, sec_hdr, hdrlen);
430 
431  return s;
432 }
433 
434 /* Transmit secure transport packet over specified channel */
435 void
437 {
438  int datalen;
439 
440 #ifdef WITH_SCARD
442 #endif
443 
444  s_pop_layer(s, sec_hdr);
445  if ((!g_licence_issued && !g_licence_error_result) || (flags & SEC_ENCRYPT))
446  out_uint32_le(s, flags);
447 
448  if (flags & SEC_ENCRYPT)
449  {
450  flags &= ~SEC_ENCRYPT;
451  datalen = s->end - s->p - 8;
452 
453 #ifdef WITH_DEBUG
454  DEBUG(("Sending encrypted packet:\n"));
455  hexdump(s->p + 8, datalen);
456 #endif
457 
458  sec_sign(s->p, 8, g_sec_sign_key, g_rc4_key_len, s->p + 8, datalen);
459  sec_encrypt(s->p + 8, datalen);
460  }
461 
462  mcs_send_to_channel(s, channel);
463 
464 #ifdef WITH_SCARD
466 #endif
467 }
468 
469 /* Transmit secure transport packet */
470 
471 void
473 {
475 }
476 
477 
478 /* Transfer the client random to the server */
479 static void
481 {
484  STREAM s;
485 
486  s = sec_init(flags, length + 4);
487 
488  out_uint32_le(s, length);
490  out_uint8s(s, SEC_PADDING_SIZE);
491 
492  s_mark_end(s);
493  sec_send(s, flags);
494 }
495 
496 /* Output connect initial data blob */
497 static void
498 sec_out_mcs_data(STREAM s, uint32 selected_protocol)
499 {
500  int hostlen = 2 * strlen(g_hostname);
501  int length = 162 + 76 + 12 + 4;
502  unsigned int i;
503  uint32 cluster_flags = 0;
504 
505  if (g_num_channels > 0)
506  length += g_num_channels * 12 + 8;
507 
508  if (hostlen > 30)
509  hostlen = 30;
510 
511  /* Generic Conference Control (T.124) ConferenceCreateRequest */
512  out_uint16_be(s, 5);
513  out_uint16_be(s, 0x14);
514  out_uint8(s, 0x7c);
515  out_uint16_be(s, 1);
516 
517  out_uint16_be(s, (length | 0x8000)); /* remaining length */
518 
519  out_uint16_be(s, 8); /* length? */
520  out_uint16_be(s, 16);
521  out_uint8(s, 0);
522  out_uint16_le(s, 0xc001);
523  out_uint8(s, 0);
524 
525  out_uint32_le(s, 0x61637544); /* OEM ID: "Duca", as in Ducati. */
526  out_uint16_be(s, ((length - 14) | 0x8000)); /* remaining length */
527 
528  /* Client information */
530  out_uint16_le(s, 216); /* length */
531  out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 4 : 1); /* RDP version. 1 == RDP4, 4 >= RDP5 to RDP8 */
532  out_uint16_le(s, 8);
535  out_uint16_le(s, 0xca01);
536  out_uint16_le(s, 0xaa03);
538  out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
539 
540  /* Unicode name of client, padded to 32 bytes */
541  rdp_out_unistr(s, g_hostname, hostlen);
542  out_uint8s(s, 30 - hostlen);
543 
544  /* See
545  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceddk40/html/cxtsksupportingremotedesktopprotocol.asp */
549  out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
550  out_uint16_le(s, 0xca01); /* colour depth? */
551  out_uint16_le(s, 1);
552 
553  out_uint32(s, 0);
555  out_uint16_le(s, 0x0700);
556  out_uint8(s, 0);
557  out_uint32_le(s, 1);
558  out_uint8s(s, 64);
559  out_uint32_le(s, selected_protocol); /* End of client info */
560 
561  /* Write a Client Cluster Data (TS_UD_CS_CLUSTER) */
562  out_uint16_le(s, SEC_TAG_CLI_CLUSTER); /* header.type */
563  out_uint16_le(s, 12); /* length */
564 
565  cluster_flags |= SEC_CC_REDIRECTION_SUPPORTED;
566  cluster_flags |= (SEC_CC_REDIRECT_VERSION_3 << 2);
567 
569  cluster_flags |= SEC_CC_REDIRECT_SESSIONID_FIELD_VALID;
570 
571  out_uint32_le(s, cluster_flags);
573 
574  /* Client encryption settings */
576  out_uint16_le(s, 12); /* length */
577  out_uint32_le(s, g_encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
578  out_uint32(s, 0); /* Unknown */
579 
580  DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
581  if (g_num_channels > 0)
582  {
584  out_uint16_le(s, g_num_channels * 12 + 8); /* length */
585  out_uint32_le(s, g_num_channels); /* number of virtual channels */
586  for (i = 0; i < g_num_channels; i++)
587  {
588  DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
589  out_uint8a(s, g_channels[i].name, 8);
590  out_uint32_be(s, g_channels[i].flags);
591  }
592  }
593 
594  s_mark_end(s);
595 }
596 
597 /* Parse a public key structure */
598 static RD_BOOL
600 {
601  uint32 magic, modulus_len;
602 
603  in_uint32_le(s, magic);
604  if (magic != SEC_RSA_MAGIC)
605  {
606  error("RSA magic 0x%x\n", magic);
607  return False;
608  }
609 
610  in_uint32_le(s, modulus_len);
611  modulus_len -= SEC_PADDING_SIZE;
612  if ((modulus_len < SEC_MODULUS_SIZE) || (modulus_len > SEC_MAX_MODULUS_SIZE))
613  {
614  error("Bad server public key size (%u bits)\n", modulus_len * 8);
615  return False;
616  }
617 
618  in_uint8s(s, 8); /* modulus_bits, unknown */
619  in_uint8a(s, exponent, SEC_EXPONENT_SIZE);
620  in_uint8a(s, modulus, modulus_len);
622  g_server_public_key_len = modulus_len;
623 
624  return s_check(s);
625 }
626 
627 /* Parse a public signature structure */
628 static RD_BOOL
630 {
631  uint8 signature[SEC_MAX_MODULUS_SIZE];
632  uint8 signature_[SEC_MAX_MODULUS_SIZE];
633  uint32 sig_len;
634 
635  if (len != 72)
636  {
637  return True;
638  }
639  memset(signature, 0, sizeof(signature));
640  sig_len = len - 8;
641  in_uint8a(s, signature, sig_len);
642  if(rdssl_sign_ok((char *)exponent, SEC_EXPONENT_SIZE, (char *)modulus, g_server_public_key_len,
643  (char *)signature_, SEC_MODULUS_SIZE, (char *)signature, sig_len, (char *)g_testkey))
644  {
645  DEBUG_RDP5(("key signature doesn't match test key\n"));
646  }
647  return s_check(s);
648 }
649 
650 /* Parse a crypto information structure */
651 static RD_BOOL
653  uint8 ** server_random, uint8 * modulus, uint8 * exponent)
654 {
655  uint32 crypt_level, random_len, rsa_info_len;
656  uint32 cacert_len, cert_len, flags;
657  PCCERT_CONTEXT cacert, server_cert;
658  BYTE *server_public_key;
659  uint16 tag, length;
660  uint8 *next_tag, *end;
661 
662  in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
663  in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
664  if (crypt_level == 0)
665  {
666  /* no encryption */
667  return False;
668  }
669 
670  in_uint32_le(s, random_len);
671  in_uint32_le(s, rsa_info_len);
672 
673  if (random_len != SEC_RANDOM_SIZE)
674  {
675  error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
676  return False;
677  }
678 
679  in_uint8p(s, *server_random, random_len);
680 
681  /* RSA info */
682  end = s->p + rsa_info_len;
683  if (end > s->end)
684  return False;
685 
686  in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
687  if (flags & 1)
688  {
689  DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
690  in_uint8s(s, 8); /* unknown */
691 
692  while (s->p < end)
693  {
694  in_uint16_le(s, tag);
695  in_uint16_le(s, length);
696 
697  next_tag = s->p + length;
698 
699  switch (tag)
700  {
701  case SEC_TAG_PUBKEY:
702  if (!sec_parse_public_key(s, modulus, exponent))
703  return False;
704  DEBUG_RDP5(("Got Public key, RDP4-style\n"));
705 
706  break;
707 
708  case SEC_TAG_KEYSIG:
709  if (!sec_parse_public_sig(s, length, modulus, exponent))
710  return False;
711  break;
712 
713  default:
714  unimpl("crypt tag 0x%x\n", tag);
715  }
716 
717  s->p = next_tag;
718  }
719  }
720  else
721  {
722  uint32 certcount;
723 
724  DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
725  in_uint32_le(s, certcount); /* Number of certificates */
726  if (certcount < 2)
727  {
728  error("Server didn't send enough X509 certificates\n");
729  return False;
730  }
731  for (; certcount > 2; certcount--)
732  { /* ignore all the certificates between the root and the signing CA */
733  uint32 ignorelen;
734  PCCERT_CONTEXT ignorecert;
735 
736  DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
737  in_uint32_le(s, ignorelen);
738  DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
739  ignorecert = rdssl_cert_read(s->p, ignorelen);
740  in_uint8s(s, ignorelen);
741  if (ignorecert == NULL)
742  { /* XXX: error out? */
743  DEBUG_RDP5(("got a bad cert: this will probably screw up the rest of the communication\n"));
744  }
745 
746 #ifdef WITH_DEBUG_RDP5
747  DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
748  rdssl_cert_print_fp(stdout, ignorecert);
749 #endif
750  }
751  /* Do da funky X.509 stuffy
752 
753  "How did I find out about this? I looked up and saw a
754  bright light and when I came to I had a scar on my forehead
755  and knew about X.500"
756  - Peter Gutman in a early version of
757  http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
758  */
759  in_uint32_le(s, cacert_len);
760  DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
761  cacert = rdssl_cert_read(s->p, cacert_len);
762  in_uint8s(s, cacert_len);
763  if (NULL == cacert)
764  {
765  error("Couldn't load CA Certificate from server\n");
766  return False;
767  }
768  in_uint32_le(s, cert_len);
769  DEBUG_RDP5(("Certificate length is %d\n", cert_len));
770  server_cert = rdssl_cert_read(s->p, cert_len);
771  in_uint8s(s, cert_len);
772  if (NULL == server_cert)
773  {
774  rdssl_cert_free(cacert);
775  error("Couldn't load Certificate from server\n");
776  return False;
777  }
778  if (!rdssl_certs_ok(server_cert, cacert))
779  {
780  rdssl_cert_free(server_cert);
781  rdssl_cert_free(cacert);
782  error("Security error CA Certificate invalid\n");
783  return False;
784  }
785  rdssl_cert_free(cacert);
786  in_uint8s(s, 16); /* Padding */
787  server_public_key = rdssl_cert_to_rkey(server_cert, &g_server_public_key_len);
788  if (NULL == server_public_key)
789  {
790  DEBUG_RDP5(("Didn't parse X509 correctly\n"));
791  rdssl_cert_free(server_cert);
792  return False;
793  }
794  rdssl_cert_free(server_cert);
797  {
798  error("Bad server public key size (%u bits)\n",
800  rdssl_rkey_free(server_public_key);
801  return False;
802  }
803  if (rdssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
804  modulus, SEC_MAX_MODULUS_SIZE) != 0)
805  {
806  error("Problem extracting RSA exponent, modulus");
807  rdssl_rkey_free(server_public_key);
808  return False;
809  }
810  rdssl_rkey_free(server_public_key);
811  return True; /* There's some garbage here we don't care about */
812  }
813  return s_check_end(s);
814 }
815 
816 /* Process crypto information blob */
817 static void
819 {
820  uint8 *server_random = NULL;
822  uint8 exponent[SEC_EXPONENT_SIZE];
823  uint32 rc4_key_size;
824 
825  memset(modulus, 0, sizeof(modulus));
826  memset(exponent, 0, sizeof(exponent));
827  if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, modulus, exponent))
828  {
829  DEBUG(("Failed to parse crypt info\n"));
830  return;
831  }
832  DEBUG(("Generating client random\n"));
835  g_server_public_key_len, modulus, exponent);
836  sec_generate_keys(g_client_random, server_random, rc4_key_size);
837 }
838 
839 
840 /* Process SRV_INFO, find RDP version supported by server */
841 static void
843 {
845  DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
846  if (1 == g_server_rdp_version)
847  {
849  g_server_depth = 8;
850  }
851 }
852 
853 
854 /* Process connect response data blob */
855 void
857 {
858  uint16 tag, length;
859  uint8 *next_tag;
860  uint8 len;
861 
862  in_uint8s(s, 21); /* header (T.124 ConferenceCreateResponse) */
863  in_uint8(s, len);
864  if (len & 0x80)
865  in_uint8(s, len);
866 
867  while (s->p < s->end)
868  {
869  in_uint16_le(s, tag);
870  in_uint16_le(s, length);
871 
872  if (length <= 4)
873  return;
874 
875  next_tag = s->p + length - 4;
876 
877  switch (tag)
878  {
879  case SEC_TAG_SRV_INFO:
881  break;
882 
883  case SEC_TAG_SRV_CRYPT:
885  break;
886 
888  /* FIXME: We should parse this information and
889  use it to map RDP5 channels to MCS
890  channels */
891  break;
892 
893  default:
894  unimpl("response tag 0x%x\n", tag);
895  }
896 
897  s->p = next_tag;
898  }
899 }
900 
901 /* Receive secure transport packet */
902 STREAM
903 sec_recv(uint8 * rdpver)
904 {
905  uint16 sec_flags;
906  /* uint16 sec_flags_hi; */
907  uint16 channel;
908  STREAM s;
909 
910  while ((s = mcs_recv(&channel, rdpver)) != NULL)
911  {
912  if (rdpver != NULL)
913  {
914  if (*rdpver != 3)
915  {
916  if (*rdpver & 0x80)
917  {
918  in_uint8s(s, 8); /* signature */
919  sec_decrypt(s->p, s->end - s->p);
920  }
921  return s;
922  }
923  }
925  {
926  /* TS_SECURITY_HEADER */
927  in_uint16_le(s, sec_flags);
928  in_uint8s(s, 2); /* sec_flags_hi */
929 
930  if (g_encryption)
931  {
932  if (sec_flags & SEC_ENCRYPT)
933  {
934  in_uint8s(s, 8); /* signature */
935  sec_decrypt(s->p, s->end - s->p);
936  }
937 
938  if (sec_flags & SEC_LICENSE_PKT)
939  {
940  licence_process(s);
941  continue;
942  }
943 
944  if (sec_flags & SEC_REDIRECTION_PKT) /* SEC_REDIRECT_ENCRYPT */
945  {
946  uint8 swapbyte;
947 
948  in_uint8s(s, 8); /* signature */
949  sec_decrypt(s->p, s->end - s->p);
950 
951  /* Check for a redirect packet, starts with 00 04 */
952  if (s->p[0] == 0 && s->p[1] == 4)
953  {
954  /* for some reason the PDU and the length seem to be swapped.
955  This isn't good, but we're going to do a byte for byte
956  swap. So the first four values appear as: 00 04 XX YY,
957  where XX YY is the little endian length. We're going to
958  use 04 00 as the PDU type, so after our swap this will look
959  like: XX YY 04 00 */
960  swapbyte = s->p[0];
961  s->p[0] = s->p[2];
962  s->p[2] = swapbyte;
963 
964  swapbyte = s->p[1];
965  s->p[1] = s->p[3];
966  s->p[3] = swapbyte;
967 
968  swapbyte = s->p[2];
969  s->p[2] = s->p[3];
970  s->p[3] = swapbyte;
971  }
972 #ifdef WITH_DEBUG
973  /* warning! this debug statement will show passwords in the clear! */
974  hexdump(s->p, s->end - s->p);
975 #endif
976  }
977  }
978  else
979  {
980  if (sec_flags & SEC_LICENSE_PKT)
981  {
982  licence_process(s);
983  continue;
984  }
985  s->p -= 4;
986  }
987  }
988 
989  if (channel != MCS_GLOBAL_CHANNEL)
990  {
991  channel_process(s, channel);
992  if (rdpver != NULL)
993  *rdpver = 0xff;
994  return s;
995  }
996 
997  return s;
998  }
999 
1000  return NULL;
1001 }
1002 
1003 /* Establish a secure connection */
1004 RD_BOOL
1005 sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
1006 {
1007  uint32 selected_proto;
1008  struct stream mcs_data;
1009 
1010  /* Start a MCS connect sequence */
1011  if (!mcs_connect_start(server, username, domain, password, reconnect, &selected_proto))
1012  return False;
1013 
1014  /* We exchange some RDP data during the MCS-Connect */
1015  mcs_data.size = 512;
1016  mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
1017  sec_out_mcs_data(&mcs_data, selected_proto);
1018 
1019  /* finalize the MCS connect sequence */
1020  if (!mcs_connect_finalize(&mcs_data))
1021  return False;
1022 
1023  /* sec_process_mcs_data(&mcs_data); */
1024  if (g_encryption)
1026  xfree(mcs_data.data);
1027  return True;
1028 }
1029 
1030 /* Disconnect a connection */
1031 void
1033 {
1034  mcs_disconnect();
1035 }
1036 
1037 /* reset the state of the sec layer */
1038 void
1040 {
1044  g_licence_issued = 0;
1046  mcs_reset_state();
1047 }
static const WCHAR sha[]
Definition: oid.c:1055
void rdssl_rkey_free(uint8 *rkey)
Definition: ssl_calls.c:1777
#define SEC_CC_REDIRECT_VERSION_3
Definition: constants.h:135
#define out_uint16_le(s, v)
Definition: parse.h:58
void buf_out_uint32(uint8 *buffer, uint32 value)
Definition: secure.c:304
#define out_uint8p(s, v, n)
Definition: parse.h:93
Definition: get.c:139
#define SEC_TAG_CLI_INFO
Definition: constants.h:119
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:100
#define SEC_TAG_CLI_CRYPT
Definition: constants.h:120
#define SEC_TAG_CLI_CLUSTER
Definition: constants.h:122
#define SEC_RSA_MAGIC
Definition: constants.h:127
static rfbScreenInfoPtr server
Definition: vnc.c:74
void rdssl_rc4_crypt(void *rc4_info, char *in_data, char *out_data, int len)
Definition: ssl_calls.c:173
#define error(str)
Definition: mkdosfs.c:1605
Definition: http.c:6587
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define out_uint8a(s, v, n)
Definition: parse.h:94
static RD_BOOL sec_parse_crypt_info(STREAM s, uint32 *rc4_key_size, uint8 **server_random, uint8 *modulus, uint8 *exponent)
Definition: secure.c:652
void mcs_send_to_channel(STREAM s, uint16 channel)
Definition: mcs.c:254
void sec_reset_state(void)
Definition: secure.c:1039
RD_BOOL g_licence_issued
Definition: licence.c:44
int g_keyboard_functionkeys
Definition: uimain.c:47
void sec_process_mcs_data(STREAM s)
Definition: secure.c:856
unsigned int uint32
Definition: types.h:32
void rdssl_md5_info_delete(void *md5_info)
Definition: ssl_calls.c:421
char g_hostname[16]
Definition: uimain.c:26
RD_BOOL g_console_session
Definition: uimain.c:48
#define SEC_TAG_PUBKEY
Definition: constants.h:124
static int g_rc4_key_len
Definition: secure.c:93
static void sec_make_40bit(uint8 *key)
Definition: secure.c:229
#define SEC_MODULUS_SIZE
Definition: secure.c:111
RD_BOOL mcs_connect_start(char *server, char *username, char *domain, char *password, RD_BOOL reconnect, uint32 *selected_protocol)
Definition: mcs.c:311
#define out_uint32_le(s, v)
Definition: parse.h:59
u32_t magic(void)
#define SEC_MAX_MODULUS_SIZE
Definition: constants.h:93
RDP_VERSION g_rdp_version
Definition: uimain.c:74
GLuint buffer
Definition: glext.h:5915
int g_keyboard_subtype
Definition: uimain.c:46
RD_BOOL rdssl_certs_ok(PCCERT_CONTEXT server_cert, PCCERT_CONTEXT cacert)
Definition: ssl_calls.c:1743
void channel_process(STREAM s, uint16 mcs_channel)
Definition: channels.c:138
static void sec_rsa_encrypt(uint8 *out, uint8 *in, int len, uint32 modulus_size, uint8 *modulus, uint8 *exponent)
Definition: secure.c:411
GLuint GLuint end
Definition: gl.h:1545
unsigned char * data
Definition: parse.h:26
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1027
void * rdssl_md5_info_create(void)
Definition: ssl_calls.c:414
void rdssl_md5_clear(void *md5_info)
Definition: ssl_calls.c:428
#define in_uint8p(s, v, n)
Definition: parse.h:89
void rdssl_sha1_clear(void *sha1_info)
Definition: ssl_calls.c:393
int rdssl_rkey_get_exp_mod(uint8 *rkey, uint8 *exponent, uint32 max_exp_len, uint8 *modulus, uint32 max_mod_len)
Definition: ssl_calls.c:1762
void sec_decrypt(uint8 *data, int length)
Definition: secure.c:396
FILE * stdout
void rdssl_md5_complete(void *md5_info, char *data)
Definition: ssl_calls.c:442
#define s_check(s)
Definition: parse.h:42
static RD_BOOL sec_parse_public_key(STREAM s, uint8 *modulus, uint8 *exponent)
Definition: secure.c:599
#define SEC_TAG_CLI_CHANNELS
Definition: constants.h:121
#define MCS_GLOBAL_CHANNEL
Definition: constants.h:87
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define out_uint8(s, v)
Definition: parse.h:92
void mcs_reset_state(void)
Definition: mcs.c:363
GLenum GLclampf GLint i
Definition: glfuncs.h:14
void sec_sign(uint8 *signature, int siglen, uint8 *session_key, int keylen, uint8 *data, int datalen)
Definition: secure.c:314
void sec_send(STREAM s, uint32 flags)
Definition: secure.c:472
void rdssl_sha1_info_delete(void *sha1_info)
Definition: ssl_calls.c:386
void * xmalloc(int size)
Definition: uimain.c:747
#define sha1_info
Definition: compat-1.3.h:2234
void rdssl_sha1_transform(void *sha1_info, char *data, int len)
Definition: ssl_calls.c:400
static uint32 g_server_public_key_len
Definition: secure.c:96
RD_BOOL g_encryption
Definition: uimain.c:40
uint16 g_server_rdp_version
Definition: secure.c:105
uint32 g_redirect_session_id
Definition: uimain.c:67
#define s_pop_layer(s, h)
Definition: parse.h:40
static uint8 g_sec_sign_key[16]
Definition: secure.c:98
smooth NULL
Definition: ftsmooth.c:416
#define SEC_LICENSE_PKT
Definition: constants.h:105
VCHANNEL g_channels[]
Definition: channels.c:32
#define in_uint8s(s, n)
Definition: parse.h:91
void * rdssl_sha1_info_create(void)
Definition: ssl_calls.c:379
static BYTE cert[]
Definition: msg.c:1437
#define SEC_ENCRYPT
Definition: constants.h:101
int RD_BOOL
Definition: types.h:21
#define out_uint8s(s, n)
Definition: parse.h:95
void sec_hash_to_string(char *out, int out_size, uint8 *in, int in_size)
Definition: secure.c:217
static uint8 g_sec_encrypt_key[16]
Definition: secure.c:100
#define s_check_end(s)
Definition: parse.h:44
static int g_sec_decrypt_use_count
Definition: secure.c:109
static WCHAR username[]
Definition: url.c:32
static void sec_process_srv_info(STREAM s)
Definition: secure.c:842
#define SEC_TAG_SRV_CHANNELS
Definition: constants.h:117
#define True
Definition: types.h:24
static void pad(Char *s)
Definition: bzip2.c:908
#define False
Definition: types.h:25
void xfree(void *mem)
Definition: uimain.c:758
#define SEC_EXPONENT_SIZE
Definition: constants.h:95
Definition: types.h:44
static void sec_establish_key(void)
Definition: secure.c:480
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
void rdssl_sha1_complete(void *sha1_info, char *data)
Definition: ssl_calls.c:407
#define SEC_RANDOM_SIZE
Definition: constants.h:91
static void sec_out_mcs_data(STREAM s, uint32 selected_protocol)
Definition: secure.c:498
static FILE * out
Definition: regtests2xml.c:44
unsigned char * end
Definition: parse.h:25
void scard_unlock(int lock)
STREAM sec_recv(uint8 *rdpver)
Definition: secure.c:903
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG in_size
Definition: file.c:100
unsigned char uint8
Definition: types.h:28
static uint8 pad_54[40]
Definition: secure.c:288
static uint8 pad_92[48]
Definition: secure.c:295
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
int g_server_depth
Definition: uimain.c:41
RD_BOOL sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
Definition: secure.c:1005
unsigned int g_keylayout
Definition: uimain.c:44
STREAM mcs_init(int length)
Definition: mcs.c:242
void rdssl_rc4_info_delete(void *rc4_info)
Definition: ssl_calls.c:90
static void sec_update(uint8 *key, uint8 *update_key)
Definition: secure.c:346
unsigned int size
Definition: parse.h:27
Definition: parse.h:22
T1_FIELD_DICT_PRIVATE password
Definition: t1tokens.h:64
#define SEC_PADDING_SIZE
Definition: constants.h:94
#define SEC_CC_REDIRECT_SESSIONID_FIELD_VALID
Definition: constants.h:131
enum _RDP_VERSION RDP_VERSION
STREAM mcs_recv(uint16 *channel, uint8 *rdpver)
Definition: mcs.c:280
#define SEC_CC_REDIRECTION_SUPPORTED
Definition: constants.h:130
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
static uint8 g_sec_decrypt_key[16]
Definition: secure.c:99
static int g_sec_encrypt_use_count
Definition: secure.c:108
static uint8 g_sec_encrypt_update_key[16]
Definition: secure.c:102
void rdssl_cert_free(PCCERT_CONTEXT context)
Definition: ssl_calls.c:1656
Definition: types.h:43
GLsizei const GLfloat * value
Definition: glext.h:6069
static uint8 g_sec_crypted_random[SEC_MAX_MODULUS_SIZE]
Definition: secure.c:103
static void * g_rc4_encrypt_key
Definition: secure.c:95
unsigned int g_num_channels
Definition: channels.c:33
static uint8 g_testkey[176]
Definition: secure.c:113
#define SCARD_LOCK_SEC
Definition: constants.h:580
unsigned char BYTE
Definition: ntddk_ex.h:96
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
RD_BOOL mcs_connect_finalize(STREAM mcs_data)
Definition: mcs.c:318
#define SEC_TAG_KEYSIG
Definition: constants.h:125
#define in_uint8a(s, v, n)
Definition: parse.h:90
#define out_uint32_be(s, v)
Definition: parse.h:78
static void sec_encrypt(uint8 *data, int length)
Definition: secure.c:381
static void sec_generate_keys(uint8 *client_random, uint8 *server_random, int rc4_key_size)
Definition: secure.c:238
#define s_push_layer(s, h, n)
Definition: parse.h:39
void hexdump(unsigned char *p, unsigned int len)
Definition: shimdbg.c:234
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
#define SEC_TAG_SRV_CRYPT
Definition: constants.h:116
int g_width
Definition: uimain.c:42
void scard_lock(int lock)
int g_height
Definition: uimain.c:43
#define SEC_REDIRECTION_PKT
Definition: constants.h:108
void sec_disconnect(void)
Definition: secure.c:1032
void sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2)
Definition: secure.c:187
void * rdssl_rc4_info_create(void)
Definition: ssl_calls.c:51
unsigned short uint16
Definition: types.h:30
void rdp_out_unistr(STREAM s, char *string, int len)
Definition: rdp.c:188
#define in_uint8(s, v)
Definition: parse.h:88
void rdssl_md5_transform(void *md5_info, char *data, int len)
Definition: ssl_calls.c:435
static void sec_process_crypt_info(STREAM s)
Definition: secure.c:818
static uint8 g_sec_decrypt_update_key[16]
Definition: secure.c:101
unsigned char * p
Definition: parse.h:24
#define out_uint16_be(s, v)
Definition: parse.h:77
static void * g_rc4_decrypt_key
Definition: secure.c:94
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
Definition: secure.c:436
unsigned char * sec_hdr
Definition: parse.h:32
void generate_random(uint8 *random)
Definition: uimain.c:709
static RD_BOOL sec_parse_public_sig(STREAM s, uint32 len, uint8 *modulus, uint8 *exponent)
Definition: secure.c:629
Definition: name.c:36
#define md5_info
Definition: compat-1.3.h:2007
#define SEC_EXCHANGE_PKT
Definition: constants.h:98
uint8 * rdssl_cert_to_rkey(PCCERT_CONTEXT cert, uint32 *key_len)
Definition: ssl_calls.c:1663
DWORD exp
Definition: msg.c:15681
void sec_hash_sha1_16(uint8 *out, uint8 *in, uint8 *salt1)
Definition: secure.c:204
#define out_uint32(s, v)
Definition: parse.h:85
#define md5
Definition: compat-1.3.h:2003
void unimpl(char *format,...)
Definition: uimain.c:801
PCCERT_CONTEXT rdssl_cert_read(uint8 *data, uint32 len)
Definition: ssl_calls.c:1639
#define DEBUG(args)
Definition: rdesktop.h:129
int g_keyboard_type
Definition: uimain.c:45
void rdssl_rc4_set_key(void *rc4_info, char *key, int len)
Definition: ssl_calls.c:123
#define s_mark_end(s)
Definition: parse.h:41
int rdssl_sign_ok(char *e_data, int e_len, char *n_data, int n_len, char *sign_data, int sign_len, char *sign_data2, int sign_len2, char *testkey)
Definition: ssl_calls.c:1594
STREAM sec_init(uint32 flags, int maxlen)
Definition: secure.c:419
#define in_uint32_le(s, v)
Definition: parse.h:56
void sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt)
Definition: secure.c:155
#define SEC_TAG_SRV_INFO
Definition: constants.h:115
uint8 g_client_random[SEC_RANDOM_SIZE]
Definition: uimain.c:78
int rdssl_mod_exp(char *out, int out_len, char *in, int in_len, char *mod, int mod_len, char *exp, int exp_len)
Definition: ssl_calls.c:1485
#define memset(x, y, z)
Definition: compat.h:39
void mcs_disconnect(void)
Definition: mcs.c:356
int k
Definition: mpi.c:3369
void licence_process(STREAM s)
Definition: licence.c:378
RD_BOOL g_licence_error_result
Definition: licence.c:45
#define in_uint16_le(s, v)
Definition: parse.h:55
Definition: path.c:42
static int mod
Definition: i386-dis.c:1273
char * tag
Definition: main.c:59