1 /**
2 * xrdp: A Remote Desktop Protocol server.
3 *
4 * Copyright (C) Jay Sorg 2004-2014
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * rsa key generator for xrdp
19 */
20
21 /*
22 references:
23
24 http://www.securiteam.com/windowsntfocus/5EP010KG0G.html
25
26 */
27
28 #if defined(HAVE_CONFIG_H)
29 #include <config_ac.h>
30 #endif
31
32 #include "os_calls.h"
33 #include "string_calls.h"
34 #include "ssl_calls.h"
35 #include "arch.h"
36 #include "list.h"
37 #include "file.h"
38
39 /* this is the signature size in bytes */
40 #define TSSK_KEY_LENGTH 64
41
42 /* default to 2048 bit key size, can set changed, set */
43 static int g_key_size_bits = 2048;
44
45 static tui8 g_exponent[4] =
46 {
47 0x01, 0x00, 0x01, 0x00
48 };
49
50 /* 4 bytes public exponent */
51 static tui8 g_ppk_e[4] =
52 {
53 0x5B, 0x7B, 0x88, 0xC0
54 };
55
56 /* 64 byte modulus */
57 static tui8 g_ppk_n[72] = /* 64 bytes + 8 bytes pad */
58 {
59 0x3D, 0x3A, 0x5E, 0xBD, 0x72, 0x43, 0x3E, 0xC9,
60 0x4D, 0xBB, 0xC1, 0x1E, 0x4A, 0xBA, 0x5F, 0xCB,
61 0x3E, 0x88, 0x20, 0x87, 0xEF, 0xF5, 0xC1, 0xE2,
62 0xD7, 0xB7, 0x6B, 0x9A, 0xF2, 0x52, 0x45, 0x95,
63 0xCE, 0x63, 0x65, 0x6B, 0x58, 0x3A, 0xFE, 0xEF,
64 0x7C, 0xE7, 0xBF, 0xFE, 0x3D, 0xF6, 0x5C, 0x7D,
65 0x6C, 0x5E, 0x06, 0x09, 0x1A, 0xF5, 0x61, 0xBB,
66 0x20, 0x93, 0x09, 0x5F, 0x05, 0x6D, 0xEA, 0x87,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
68 };
69
70 /* 64 bytes private exponent */
71 static tui8 g_ppk_d[108] = /* 64 bytes + 44 bytes pad */
72 {
73 0x87, 0xA7, 0x19, 0x32, 0xDA, 0x11, 0x87, 0x55,
74 0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xF8,
75 0x24, 0x3E, 0xE6, 0xFA, 0xE9, 0x67, 0x49, 0x94,
76 0xCF, 0x92, 0xCC, 0x33, 0x99, 0xE8, 0x08, 0x60,
77 0x17, 0x9A, 0x12, 0x9F, 0x24, 0xDD, 0xB1, 0x24,
78 0x99, 0xC7, 0x3A, 0xB8, 0x0A, 0x7B, 0x0D, 0xDD,
79 0x35, 0x07, 0x79, 0x17, 0x0B, 0x51, 0x9B, 0xB3,
80 0xC7, 0x10, 0x01, 0x13, 0xE7, 0x3F, 0xF3, 0x5F,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00
87 };
88
89 /* 512 bit proprietary certificate
90 dwVersion 0 4 bytes always 0x00000001
91 dwSigAlgId 4 4 bytes always 0x00000001
92 dwKeyAlgId 8 4 bytes always 0x00000001
93 wPublicKeyBlobType 12 2 bytes always 0x0006
94 wPublicKeyBlobLen 14 2 bytes 0x005C 92 bytes
95 magic 16 4 bytes always 0x31415352
96 keylen 20 4 bytes 0x0048 72 bytes
97 bitlen 24 4 bytes 0x0200 512 bits
98 datalen 28 4 bytes 0x003F 63 bytes
99 pubExp 32 4 bytes 0x00010001
100 modulus 36 72 bytes
101 wSignatureBlobType 108 2 bytes always 0x0008
102 wSignatureBlobLen 110 2 bytes 0x0048 72 bytes
103 SignatureBlob 112 72 bytes */
104
105 static tui8 g_testkey512[184] = /* 512 bit test key */
106 {
107 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* 0 */
108 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x5c, 0x00,
109 0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00,
110 0x00, 0x02, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
111 0x01, 0x00, 0x01, 0x00, 0x79, 0x6f, 0xb4, 0xdf, /* 32 */
112 0xa6, 0x95, 0xb9, 0xa9, 0x61, 0xe3, 0xc4, 0x5e,
113 0xff, 0x6b, 0xd8, 0x81, 0x8a, 0x12, 0x4a, 0x93,
114 0x42, 0x97, 0x18, 0x93, 0xac, 0xd1, 0x3a, 0x38,
115 0x3c, 0x68, 0x50, 0x19, 0x31, 0xb6, 0x84, 0x51, /* 64 */
116 0x79, 0xfb, 0x1c, 0xe7, 0xe3, 0x99, 0x20, 0xc7,
117 0x84, 0xdf, 0xd1, 0xaa, 0xb5, 0x15, 0xef, 0x47,
118 0x7e, 0xfc, 0x88, 0xeb, 0x29, 0xc3, 0x27, 0x5a,
119 0x35, 0xf8, 0xfd, 0xaa, 0x00, 0x00, 0x00, 0x00, /* 96 */
120 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x00,
121 0x32, 0x3b, 0xde, 0x6f, 0x18, 0x97, 0x1e, 0xc3,
122 0x6b, 0x2b, 0x2d, 0xe4, 0xfc, 0x2d, 0xa2, 0x8e,
123 0x32, 0x3c, 0xf3, 0x1b, 0x24, 0x90, 0x57, 0x4d, /* 128 */
124 0x8e, 0xe4, 0x69, 0xfc, 0x16, 0x8d, 0x41, 0x92,
125 0x78, 0xc7, 0x9c, 0xb4, 0x26, 0xff, 0xe8, 0x3e,
126 0xa1, 0x8a, 0xf5, 0x57, 0xc0, 0x7f, 0x3e, 0x21,
127 0x17, 0x32, 0x30, 0x6f, 0x79, 0xe1, 0x36, 0xcd, /* 160 */
128 0xb6, 0x8e, 0xbe, 0x57, 0x57, 0xd2, 0xa9, 0x36,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
130 };
131
132 /* 2048 bit proprietary certificate
133 dwVersion 0 4 bytes always 0x00000001
134 dwSigAlgId 4 4 bytes always 0x00000001
135 dwKeyAlgId 8 4 bytes always 0x00000001
136 wPublicKeyBlobType 12 2 bytes always 0x0006
137 wPublicKeyBlobLen 14 2 bytes 0x011C 284 bytes
138 magic 16 4 bytes always 0x31415352
139 keylen 20 4 bytes 0x0108 264 bytes
140 bitlen 24 4 bytes 0x0800 2048 bits
141 datalen 28 4 bytes 0x00FF 255 bytes
142 pubExp 32 4 bytes 0x00010001
143 modulus 36 264 bytes
144 wSignatureBlobType 300 2 bytes always 0x0008
145 wSignatureBlobLen 302 2 bytes 0x0048 72 bytes
146 SignatureBlob 304 72 bytes */
147
148 static tui8 g_testkey2048[376] = /* 2048 bit test key */
149 {
150 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* 0 */
151 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x1c, 0x01,
152 0x52, 0x53, 0x41, 0x31, 0x08, 0x01, 0x00, 0x00,
153 0x00, 0x08, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
154 0x01, 0x00, 0x01, 0x00, 0x13, 0x77, 0x6d, 0xd8, /* 32 */
155 0x7b, 0x6e, 0x6f, 0xb4, 0x27, 0x6d, 0x70, 0x3a,
156 0x97, 0x5f, 0xcb, 0x50, 0x9b, 0x13, 0x6b, 0xc7,
157 0xba, 0xdf, 0x73, 0x54, 0x17, 0x35, 0xf0, 0x09,
158 0x9e, 0x9d, 0x0b, 0x6a, 0x2c, 0x9f, 0xd1, 0x0c, /* 64 */
159 0xc6, 0x47, 0x83, 0xde, 0xca, 0x90, 0x20, 0xac,
160 0x70, 0x63, 0x9b, 0xb7, 0x49, 0x07, 0x0b, 0xf5,
161 0xf2, 0x38, 0x2a, 0x40, 0xff, 0xf1, 0xba, 0x97,
162 0x79, 0x3e, 0xd4, 0xd1, 0xf3, 0x41, 0x0f, 0x91, /* 96 */
163 0xfe, 0x1a, 0x86, 0xf4, 0x1b, 0xef, 0xcc, 0x29,
164 0xa3, 0x35, 0x6f, 0x60, 0xfa, 0x98, 0x53, 0x51,
165 0x80, 0x57, 0x15, 0x2f, 0xe1, 0x8b, 0xd7, 0x86,
166 0x15, 0x2d, 0xb5, 0xec, 0x7a, 0xdd, 0xc5, 0x1d, /* 128 */
167 0x1b, 0x88, 0x53, 0x67, 0x86, 0xe1, 0x6e, 0xcd,
168 0x4e, 0x2e, 0xfd, 0xd2, 0x49, 0x04, 0xfb, 0x1d,
169 0x95, 0xf0, 0xe9, 0x7f, 0x97, 0xa3, 0x1b, 0xb2,
170 0x92, 0x2e, 0x62, 0x2a, 0x96, 0xd4, 0xea, 0x18, /* 160 */
171 0x8e, 0x99, 0x41, 0xea, 0x83, 0xb5, 0xf1, 0x0e,
172 0xea, 0x53, 0x70, 0x99, 0xd7, 0x9e, 0x0c, 0x65,
173 0x2b, 0xf4, 0xdc, 0x0e, 0xe7, 0x9e, 0xce, 0x04,
174 0x25, 0x01, 0x88, 0xc4, 0xc1, 0xd2, 0xa4, 0x18, /* 192 */
175 0xc2, 0x8a, 0x52, 0x0f, 0x01, 0xb2, 0x71, 0x30,
176 0x44, 0x3f, 0x5b, 0x11, 0x2e, 0xe7, 0x53, 0xa0,
177 0xc8, 0x1f, 0x77, 0xaf, 0xb5, 0xbb, 0xaf, 0x12,
178 0xe8, 0x19, 0x0c, 0xf6, 0x1f, 0xa8, 0x3e, 0x11, /* 224 */
179 0x34, 0xe4, 0xac, 0x1c, 0x1c, 0x00, 0xbb, 0xb9,
180 0x2f, 0xbb, 0x81, 0x76, 0x4e, 0x46, 0xda, 0x73,
181 0x00, 0x82, 0x71, 0xa4, 0x62, 0xc3, 0xd4, 0x3f,
182 0xda, 0x34, 0x54, 0x27, 0xe3, 0xd0, 0x3a, 0x73, /* 256 */
183 0x2f, 0x99, 0xc4, 0x91, 0x56, 0x12, 0x98, 0xa8,
184 0x3b, 0x8d, 0x61, 0x83, 0x62, 0xb7, 0x20, 0x61,
185 0x4d, 0xc9, 0x41, 0xd1, 0x40, 0x02, 0x11, 0x4b,
186 0x63, 0x46, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00, /* 288 */
187 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x00,
188 0x00, 0x50, 0xb7, 0x75, 0xf3, 0x77, 0x99, 0xb2,
189 0xd3, 0xdd, 0xcd, 0x83, 0x6e, 0xdb, 0x0a, 0x29,
190 0x88, 0x05, 0xb5, 0x8a, 0x49, 0xd5, 0xa8, 0x5a, /* 320 */
191 0xc3, 0xb7, 0x18, 0xc2, 0x3c, 0x1e, 0xde, 0xd3,
192 0x8f, 0xdd, 0x21, 0x27, 0x84, 0xa0, 0xc8, 0x8d,
193 0x65, 0xce, 0x5d, 0x3d, 0x46, 0x65, 0x88, 0xfc,
194 0x35, 0x0a, 0x04, 0xa0, 0xda, 0xc1, 0xab, 0xbf, /* 352 */
195 0xcd, 0xf1, 0x7e, 0x71, 0x7b, 0xf8, 0x4a, 0x78,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
197 };
198
199 /*****************************************************************************/
200 static int
out_params(void)201 out_params(void)
202 {
203 g_writeln("%s", "");
204 g_writeln("xrdp rsa key gen utility examples");
205 g_writeln(" xrdp-keygen xrdp ['path and file name' | auto] [512 or 2048]");
206 g_writeln(" xrdp-keygen test");
207 g_writeln("%s", "");
208 return 0;
209 }
210
211 /*****************************************************************************/
212 /* this is the special key signing algorithm */
213 static int
sign_key(const char * e_data,int e_len,const char * n_data,int n_len,char * sign_data,int sign_len)214 sign_key(const char *e_data, int e_len, const char *n_data, int n_len,
215 char *sign_data, int sign_len)
216 {
217 char *key;
218 char *md5_final;
219 void *md5;
220
221 if ((e_len != 4) || ((n_len != 64) && (n_len != 256)) || (sign_len != 64))
222 {
223 return 1;
224 }
225
226 if (n_len == 64)
227 {
228 key = (char *)g_malloc(184, 0);
229 md5_final = (char *)g_malloc(64, 0);
230 md5 = ssl_md5_info_create();
231 /* copy the test key */
232 g_memcpy(key, g_testkey512, 184);
233 /* replace e and n */
234 g_memcpy(key + 32, e_data, e_len);
235 g_memcpy(key + 36, n_data, n_len);
236 ssl_md5_clear(md5);
237 /* the first 108 bytes */
238 ssl_md5_transform(md5, key, 108);
239 /* set the whole thing with 0xff */
240 g_memset(md5_final, 0xff, 64);
241 /* digest 16 bytes */
242 ssl_md5_complete(md5, md5_final);
243 /* set non 0xff array items */
244 md5_final[16] = 0;
245 md5_final[62] = 1;
246 md5_final[63] = 0;
247 /* encrypt */
248 ssl_mod_exp(sign_data, sign_len, md5_final, 64, (char *)g_ppk_n, 64,
249 (char *)g_ppk_d, 64);
250 /* cleanup */
251 ssl_md5_info_delete(md5);
252 g_free(key);
253 g_free(md5_final);
254 }
255 else if (n_len == 256)
256 {
257 key = (char *)g_malloc(376, 0);
258 md5_final = (char *)g_malloc(64, 0);
259 md5 = ssl_md5_info_create();
260 /* copy the test key */
261 g_memcpy(key, g_testkey2048, 376);
262 /* replace e and n */
263 g_memcpy(key + 32, e_data, e_len);
264 g_memcpy(key + 36, n_data, n_len);
265 ssl_md5_clear(md5);
266 /* the first 300 bytes */
267 ssl_md5_transform(md5, key, 300);
268 /* set the whole thing with 0xff */
269 g_memset(md5_final, 0xff, 64);
270 /* digest 16 bytes */
271 ssl_md5_complete(md5, md5_final);
272 /* set non 0xff array items */
273 md5_final[16] = 0;
274 md5_final[62] = 1;
275 md5_final[63] = 0;
276 /* encrypt */
277 ssl_mod_exp(sign_data, sign_len, md5_final, 64, (char *)g_ppk_n, 64,
278 (char *)g_ppk_d, 64);
279 /* cleanup */
280 ssl_md5_info_delete(md5);
281 g_free(key);
282 g_free(md5_final);
283 }
284
285 return 0;
286 }
287
288 /*****************************************************************************/
289 static int
write_out_line(int fd,const char * name,const char * data,int len)290 write_out_line(int fd, const char *name, const char *data, int len)
291 {
292 int max;
293 int error;
294 int index;
295 int data_item;
296 int buf_pos;
297 char *buf;
298 char *text;
299
300 text = (char *)g_malloc(256, 0);
301 max = len;
302 max = max * 10;
303 buf_pos = g_strlen(name);
304 max = max + buf_pos + 16;
305 buf = (char *)g_malloc(max, 0);
306 g_strncpy(buf, name, max - 1);
307 buf[buf_pos] = '=';
308 buf_pos++;
309
310 for (index = 0; index < len; index++)
311 {
312 data_item = (tui8)(data[index]);
313 g_snprintf(text, 255, "0x%2.2x", data_item);
314
315 if (index != 0)
316 {
317 buf[buf_pos] = ',';
318 buf_pos++;
319 }
320
321 buf[buf_pos] = text[0];
322 buf_pos++;
323 buf[buf_pos] = text[1];
324 buf_pos++;
325 buf[buf_pos] = text[2];
326 buf_pos++;
327 buf[buf_pos] = text[3];
328 buf_pos++;
329 }
330
331 buf[buf_pos] = '\n';
332 buf_pos++;
333 buf[buf_pos] = 0;
334 error = g_file_write(fd, buf, buf_pos) == -1;
335 g_free(buf);
336 g_free(text);
337 return error;
338 }
339
340 /*****************************************************************************/
341 static int
save_all(const char * e_data,int e_len,const char * n_data,int n_len,const char * d_data,int d_len,const char * sign_data,int sign_len,const char * path_and_file_name)342 save_all(const char *e_data, int e_len, const char *n_data, int n_len,
343 const char *d_data, int d_len, const char *sign_data, int sign_len,
344 const char *path_and_file_name)
345 {
346 int fd;
347 char filename[256];
348
349 if (path_and_file_name == 0)
350 {
351 g_strncpy(filename, "rsakeys.ini", 255);
352 }
353 else
354 {
355 g_strncpy(filename, path_and_file_name, 255);
356 }
357
358 g_writeln("saving to %s", filename);
359 g_writeln("%s", "");
360
361 if (g_file_exist(filename))
362 {
363 if (g_file_delete(filename) == 0)
364 {
365 g_writeln("problem deleting %s, maybe no rights", filename);
366 return 1;
367 }
368 }
369
370 fd = g_file_open(filename);
371
372 if (fd != -1)
373 {
374 if (g_file_write(fd, "[keys]\n", 7) == -1)
375 {
376 g_writeln("problem writing to %s, maybe no rights", filename);
377 g_file_close(fd);
378 return 1;
379 }
380
381 write_out_line(fd, "pub_exp", e_data, e_len);
382 write_out_line(fd, "pub_mod", n_data, n_len);
383 write_out_line(fd, "pub_sig", sign_data, sign_len);
384 write_out_line(fd, "pri_exp", d_data, d_len);
385 }
386 else
387 {
388 g_writeln("problem opening %s, maybe no rights", filename);
389 return 1;
390 }
391
392 g_file_close(fd);
393 return 0;
394 }
395
396 /*****************************************************************************/
397 static int
key_gen(const char * path_and_file_name)398 key_gen(const char *path_and_file_name)
399 {
400 char *e_data;
401 char *n_data;
402 char *d_data;
403 char *sign_data;
404 int e_len;
405 int n_len;
406 int d_len;
407 int sign_len;
408 int error;
409
410 e_data = (char *)g_exponent;
411 n_data = (char *)g_malloc(256, 0);
412 d_data = (char *)g_malloc(256, 0);
413 sign_data = (char *)g_malloc(64, 0);
414 e_len = 4;
415 n_len = g_key_size_bits / 8;
416 d_len = n_len;
417 sign_len = 64;
418 error = 0;
419 g_writeln("%s", "");
420 g_writeln("Generating %d bit rsa key...", g_key_size_bits);
421 g_writeln("%s", "");
422
423 if (error == 0)
424 {
425 error = ssl_gen_key_xrdp1(g_key_size_bits, e_data, e_len, n_data, n_len,
426 d_data, d_len);
427 if (error != 0)
428 {
429 g_writeln("error %d in key_gen, ssl_gen_key_xrdp1", error);
430 }
431 }
432
433 if (error == 0)
434 {
435 g_writeln("ssl_gen_key_xrdp1 ok");
436 g_writeln("%s", "");
437 error = sign_key(e_data, e_len, n_data, n_len, sign_data, sign_len);
438
439 if (error != 0)
440 {
441 g_writeln("error %d in key_gen, sign_key", error);
442 }
443 }
444
445 if (error == 0)
446 {
447 error = save_all(e_data, e_len, n_data, n_len, d_data, d_len,
448 sign_data, sign_len, path_and_file_name);
449
450 if (error != 0)
451 {
452 g_writeln("error %d in key_gen, save_all", error);
453 }
454 }
455
456 g_free(n_data);
457 g_free(d_data);
458 g_free(sign_data);
459 return error;
460 }
461
462 /*****************************************************************************/
463 static int
key_gen_auto(void)464 key_gen_auto(void)
465 {
466 return key_gen("/etc/xrdp/rsakeys.ini");
467 }
468
469 /*****************************************************************************/
470 static int
key_test512(void)471 key_test512(void)
472 {
473 char *md5_final;
474 char *sig;
475 void *md5;
476
477 md5_final = (char *)g_malloc(64, 0);
478 sig = (char *)g_malloc(64, 0);
479 md5 = ssl_md5_info_create();
480 g_writeln("original key is:");
481 g_hexdump((char *)g_testkey512, 184);
482 g_writeln("original exponent is:");
483 g_hexdump((char *)g_testkey512 + 32, 4);
484 g_writeln("original modulus is:");
485 g_hexdump((char *)g_testkey512 + 36, 64);
486 g_writeln("original signature is:");
487 g_hexdump((char *)g_testkey512 + 112, 64);
488 ssl_md5_clear(md5);
489 ssl_md5_transform(md5, (char *)g_testkey512, 108);
490 g_memset(md5_final, 0xff, 64);
491 ssl_md5_complete(md5, md5_final);
492 g_writeln("md5 hash of first 108 bytes of this key is:");
493 g_hexdump(md5_final, 16);
494 md5_final[16] = 0;
495 md5_final[62] = 1;
496 md5_final[63] = 0;
497 ssl_mod_exp(sig, 64, md5_final, 64, (char *)g_ppk_n, 64, (char *)g_ppk_d, 64);
498 g_writeln("produced signature(this should match original "
499 "signature above) is:");
500 g_hexdump(sig, 64);
501 g_memset(md5_final, 0, 64);
502 ssl_mod_exp(md5_final, 64, (char *)g_testkey512 + 112, 64, (char *)g_ppk_n, 64,
503 (char *)g_ppk_e, 4);
504 g_writeln("decrypted hash of first 108 bytes of this key is:");
505 g_hexdump(md5_final, 64);
506 ssl_md5_info_delete(md5);
507 g_free(md5_final);
508 g_free(sig);
509 return 0;
510 }
511
512 /*****************************************************************************/
513 static int
key_test2048(void)514 key_test2048(void)
515 {
516 char *md5_final;
517 char *sig;
518 void *md5;
519
520 md5_final = (char *)g_malloc(64, 0);
521 sig = (char *)g_malloc(64, 0);
522 md5 = ssl_md5_info_create();
523 g_writeln("original key is:");
524 g_hexdump((char *)g_testkey2048, 376);
525 g_writeln("original exponent is:");
526 g_hexdump((char *)g_testkey2048 + 32, 4);
527 g_writeln("original modulus is:");
528 g_hexdump((char *)g_testkey2048 + 36, 256);
529 g_writeln("original signature is:");
530 g_hexdump((char *)g_testkey2048 + 304, 64);
531 ssl_md5_clear(md5);
532 ssl_md5_transform(md5, (char *)g_testkey2048, 300);
533 g_memset(md5_final, 0xff, 64);
534 ssl_md5_complete(md5, md5_final);
535 g_writeln("md5 hash of first 300 bytes of this key is:");
536 g_hexdump(md5_final, 16);
537 md5_final[16] = 0;
538 md5_final[62] = 1;
539 md5_final[63] = 0;
540 ssl_mod_exp(sig, 64, md5_final, 64, (char *)g_ppk_n, 64, (char *)g_ppk_d, 64);
541 g_writeln("produced signature(this should match original "
542 "signature above) is:");
543 g_hexdump(sig, 64);
544 g_memset(md5_final, 0, 64);
545 ssl_mod_exp(md5_final, 64, (char *)g_testkey2048 + 304, 64, (char *)g_ppk_n, 64,
546 (char *)g_ppk_e, 4);
547 g_writeln("decrypted hash of first 108 bytes of this key is:");
548 g_hexdump(md5_final, 64);
549 ssl_md5_info_delete(md5);
550 g_free(md5_final);
551 g_free(sig);
552 return 0;
553 }
554
555 /*****************************************************************************/
556 int
main(int argc,char ** argv)557 main(int argc, char **argv)
558 {
559 if (argc > 1)
560 {
561 if (g_strcasecmp(argv[1], "xrdp") == 0)
562 {
563 if (argc > 2)
564 {
565 if (argc > 3)
566 {
567 g_key_size_bits = g_atoi(argv[3]);
568 if ((g_key_size_bits != 512) && (g_key_size_bits != 2048))
569 {
570 out_params();
571 return 0;
572 }
573 }
574 if (g_strcasecmp(argv[2], "auto") == 0)
575 {
576 if (g_getuid() != 0)
577 {
578 g_writeln("must run as root");
579 return 0;
580 }
581
582 return key_gen_auto();
583 }
584 else
585 {
586 return key_gen(argv[2]);
587 }
588 }
589 else
590 {
591 return key_gen(0);
592 }
593 }
594 else if (g_strcasecmp(argv[1], "test") == 0)
595 {
596 g_writeln("%s", "");
597 g_writeln("testing 512 bit key");
598 key_test512();
599 g_writeln("%s", "");
600 g_writeln("testing 2048 bit key");
601 key_test2048();
602 return 0;
603 }
604 }
605
606 out_params();
607 return 0;
608 }
609