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