/[winpt]/trunk/Src/wptKeygenDlg.cpp
ViewVC logotype

Contents of /trunk/Src/wptKeygenDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 16386 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


1 /* wptKeygenDlg.cpp - Key Generation dialog
2 * Copyright (C) 2000-2005 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT 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.
10 *
11 * WinPT 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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include <windows.h>
22
23 #include "../resource.h"
24 #include "wptTypes.h"
25 #include "wptNLS.h"
26 #include "wptGPG.h"
27 #include "wptCommonCtl.h"
28 #include "wptContext.h" /* for passphrase_s */
29 #include "wptDlgs.h"
30 #include "wptW32API.h"
31 #include "wptVersion.h"
32 #include "wptErrors.h"
33 #include "wptUTF8.h"
34
35
36 static void
37 clear_dlg_fields( HWND dlg )
38 {
39 SetDlgItemText( dlg, IDC_KEYGEN_SUBKEYBITS, "" );
40 SetDlgItemText( dlg, IDC_KEYGEN_NAME, "" );
41 SetDlgItemText( dlg, IDC_KEYGEN_EMAIL, "" );
42 SetDlgItemText( dlg, IDC_KEYGEN_COMMENT, "" );
43 SetDlgItemText( dlg, IDC_KEYGEN_EXPDATE, "" );
44 SetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, "" );
45 SetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, "" );
46 } /* clear_dlg_fields */
47
48
49 static void
50 ask_for_backup (HWND dlg)
51 {
52 int id;
53 char * path = NULL, * keyring = NULL;
54 const char * name;
55
56 path = get_gnupg_path ();
57 if( !path )
58 BUG( dlg );
59 id = msg_box( dlg,
60 _("It is STRONGLY recommend that you backup your keyrings because they both "
61 "contain VERY important data.\nRemember that your hard disk can crash or the "
62 "files can be deleted by accident; so it is a good\nidea to store them on "
63 "a different mass stoarge like a floppy or CDR!\n\n"
64 "Backup your keyrings now?"),
65 _("WARNING - Important hint" ), MB_YESNO );
66 if( id == IDYES ) {
67 name = get_filename_dlg( dlg, 1, _("Destination for Public Keyring"), NULL, "pubring.gpg" );
68 if( name ) {
69 keyring = make_filename( path, "pubring", "gpg" );
70 if( !CopyFile( keyring, name, FALSE ) )
71 log_box( _("Key Generation"), MB_ERR,
72 _("Could not copy %s -> %s"), keyring, name );
73 free_if_alloc( keyring );
74 }
75 name = get_filename_dlg( dlg, 1, _("Destination for Secret Keyring"), NULL, "secring.gpg" );
76 if( name ) {
77 keyring = make_filename( path, "secring", "gpg" );
78 if( !CopyFile( keyring, name, FALSE ) )
79 log_box( _("Key Generation"), MB_ERR,
80 _("Could not copy %s -> %s"), keyring, name );
81 free_if_alloc( keyring );
82 }
83 }
84 free_if_alloc( path );
85 } /* ask_for_backup */
86
87
88 static void
89 fill_keytype_box( HWND dlg )
90 {
91 HWND cb = GetDlgItem( dlg, IDC_KEYGEN_KEYTYPE );
92
93 #define addstr( cb, str ) \
94 SendMessage( (cb), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)(str) )
95 addstr( cb, _("DSA and ELG (default)") );
96 addstr( cb, _("DSA and RSA") );
97 addstr( cb, _("DSA sign only") );
98 addstr( cb, _("RSA sign only") );
99 addstr( cb, _("RSA sign and encrypt") );
100 addstr( cb, _("RSA and RSA (PGP)") );
101 SendMessage( cb, CB_SETCURSEL, 0, 0 );
102 #undef addstr
103 } /* fill_keytype_box */
104
105
106 static inline int
107 get_keytype( HWND dlg )
108 {
109 HWND cb = GetDlgItem( dlg, IDC_KEYGEN_KEYTYPE );
110 return SendMessage( cb, CB_GETCURSEL, 0, 0 ) + 1;
111 } /* get_keytype */
112
113
114 int
115 keygen_check_date( SYSTEMTIME *st )
116 {
117 SYSTEMTIME t;
118
119 GetSystemTime( &t );
120 if( st->wYear > t.wYear || st->wMonth > t.wMonth )
121 return 1;
122 else if( st->wYear < t.wYear || st->wMonth < t.wMonth || st->wDay < t.wDay)
123 return 0;
124 return 1;
125 } /* keygen_check_date */
126
127
128 BOOL CALLBACK
129 keygen_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
130 {
131 static genkey_s *ctx;
132 static int hide = 1;
133 static int act_expdate = 0;
134 SYSTEMTIME st;
135 gpgme_error_t err;
136 char name[128] = {0}, email[128] = {0}, comment[128] = {0};
137 char pwd[128], pwd2[128];
138 char t[64], *expire = NULL, *fpr=NULL;
139 int bits, use_comment, keytype = 0;
140 char * p;
141
142 switch ( msg ) {
143 case WM_INITDIALOG:
144 if (lparam != NULL)
145 ctx = (genkey_s *)lparam;
146 hide = 1;
147 #ifndef LANG_DE
148 SetWindowText( dlg, _("Key Generation") );
149 SetDlgItemText( dlg, IDC_KEYGEN_INFO,
150 _("NOTE: Key generation can be a lengthy process! Please wait until "
151 "you get the message that key generation was finished.") );
152 SetDlgItemText( dlg, IDC_KEYGEN_SUBKEYINF, _("Subkey size in &bits"));
153 SetDlgItemText( dlg, IDC_KEYGEN_NAMEINF, _("&Real name") );
154 SetDlgItemText( dlg, IDC_KEYGEN_COMMINF, _("&Comment (optional)") );
155 SetDlgItemText( dlg, IDC_KEYGEN_EMAILINF, _("Email &address") );
156 SetDlgItemText( dlg, IDC_KEYGEN_EXPINF, _("Key &expiration") );
157 SetDlgItemText( dlg, IDC_KEYGEN_PWDINF, _("&Passphrase") );
158 SetDlgItemText( dlg, IDC_KEYGEN_REPWDINF, _("&Repeat passphrase") );
159 SetDlgItemText( dlg, IDC_KEYGEN_KEYTYPEINF, _("Key &type") );
160 SetDlgItemText (dlg, IDC_KEYGEN_CLEAR, _("&Never"));
161 SetDlgItemText (dlg, IDC_KEYGEN_HIDEPWD, _("&Hide Typing"));
162 #endif
163 SetDlgItemInt( dlg, IDC_KEYGEN_SUBKEYBITS, 2048, FALSE );
164 CheckDlgButton (dlg, IDC_KEYGEN_HIDEPWD, BST_CHECKED);
165 CheckDlgButton (dlg, IDC_KEYGEN_EXPNEVER, BST_CHECKED);
166 EnableWindow (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), FALSE);
167 fill_keytype_box( dlg );
168 center_window( dlg );
169 SetForegroundWindow( dlg );
170 return TRUE;
171
172 case WM_SYSCOMMAND:
173 if( LOWORD( wparam ) == SC_CLOSE ) {
174 SetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, "" );
175 SetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, "" );
176 EndDialog( dlg, TRUE );
177 }
178 return FALSE;
179
180 case WM_COMMAND:
181 if (HIWORD (wparam) == BN_CLICKED &&
182 LOWORD (wparam) == IDC_KEYGEN_EXPNEVER) {
183 act_expdate ^= 1;
184 EnableWindow (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), act_expdate);
185 }
186 if( HIWORD( wparam ) == BN_CLICKED
187 && LOWORD( wparam ) == IDC_KEYGEN_HIDEPWD ) {
188 HWND hwnd_a = GetDlgItem( dlg, IDC_KEYGEN_PASSPHRASE );
189 HWND hwnd_b = GetDlgItem( dlg, IDC_KEYGEN_PWDCHECK );
190 hide ^= 1;
191 SendMessage( hwnd_a, EM_SETPASSWORDCHAR, hide? '*' : 0, 0 );
192 SetFocus( hwnd_a );
193 SendMessage( hwnd_b, EM_SETPASSWORDCHAR, hide? '*' : 0, 0 );
194 SetFocus( hwnd_b );
195
196 }
197
198 switch( LOWORD( wparam ) ) {
199 case IDOK:
200 bits = GetDlgItemInt (dlg, IDC_KEYGEN_SUBKEYBITS, NULL, FALSE);
201 if (bits < 1024 || bits > 4096) {
202 msg_box (dlg, _("Invalid value. Allowed values 1024-4096 bits."),
203 _("Key Generation"), MB_ERR);
204 return FALSE;
205 }
206 if (bits > DFAULT_KEYSIZE) {
207 int id = msg_box (dlg, _("Do you really need such a large key?"),
208 _("Key Generation"), MB_YESNO);
209 if (id == IDNO)
210 bits = DFAULT_KEYSIZE;
211 }
212 if( !GetDlgItemText( dlg, IDC_KEYGEN_NAME, name, sizeof name - 1 ) ) {
213 msg_box( dlg, _("Please enter the name."), _("Key Generation"), MB_ERR );
214 return FALSE;
215 }
216 if (strchr (name, '@')) {
217 msg_box (dlg, _("Please do not enter the email address in the name field."),
218 _("Key Generation"), MB_INFO);
219 return FALSE;
220 }
221 if( !GetDlgItemText(dlg, IDC_KEYGEN_EMAIL, email, sizeof email -1 )
222 || !strchr( email, '@') ) {
223 msg_box( dlg, _("Please enter a valid email address."),
224 _("Key Generation"), MB_ERR );
225 return FALSE;
226 }
227 use_comment = GetDlgItemText( dlg, IDC_KEYGEN_COMMENT, comment, sizeof comment -1 );
228 if( use_comment > 0 && strchr( comment, '@' ) ) {
229 msg_box( dlg, _("Please do NOT enter the email address in the comment field."),
230 _("Key Generation"), MB_INFO );
231 return FALSE;
232 }
233 keytype = get_keytype( dlg );
234 if (IsDlgButtonChecked (dlg, IDC_KEYGEN_EXPNEVER))
235 expire = NULL;
236 else {
237 DateTime_GetSystemtime (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), &st);
238 _snprintf (t, DIM (t)-1, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
239 expire = t;
240 }
241
242 if( !GetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, pwd, sizeof pwd -1 ) ) {
243 msg_box( dlg, _("Please enter the passphrase."),
244 _("Key Generation"), MB_ERR );
245 return FALSE;
246 }
247 else if (check_passwd_quality (pwd, 0)) {
248 int id = msg_box( dlg, _("Your passphrase should be at least 8 characters"
249 " long\nand should contain non-alphabetic characters."
250 "\n\nStill proceed?"),
251 _("Key Generation"), MB_ICONWARNING|MB_YESNO );
252 if( id == IDNO ) {
253 SetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, "" );
254 SetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, "" );
255 return FALSE;
256 }
257 }
258 if( !GetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, pwd2, sizeof pwd2 -1 ) ) {
259 msg_box( dlg, _("Please repeat the passphrase."),
260 _("Key Generation"), MB_ERR );
261 return FALSE;
262 }
263 if( strcmp( pwd, pwd2 ) ) {
264 msg_box( dlg, _("Passphrases are NOT identical!" ),
265 _("Key Generation"), MB_ERR );
266 memset( pwd, 0, sizeof pwd );
267 memset( pwd2, 0, sizeof pwd2 );
268 return FALSE;
269 }
270 if( is_8bit_string( pwd ) ) {
271 msg_box( dlg, _("The passphrase contains 8-bit characters.\n"
272 "It is not suggested to use charset specific characters."),
273 _("Key Generation"), MB_ERR );
274 memset( pwd, 0, sizeof pwd );
275 memset( pwd2, 0, sizeof pwd2 );
276 SetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, "" );
277 SetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, "" );
278 return FALSE;
279 }
280
281 if( !use_comment && !strlen( comment ) ) {
282 char *utf8_name;
283 utf8_name = wincp_to_utf8 (name, strlen (name));
284 if( !utf8_name )
285 BUG( dlg );
286 p = gpgme_genkey_params( keytype, bits, utf8_name, NULL, email, expire, pwd );
287 free( utf8_name );
288 }
289 else {
290 char *utf8_name, *utf8_comment;
291 utf8_name = wincp_to_utf8 (name, strlen (name));
292 utf8_comment = wincp_to_utf8 (comment, strlen (comment));
293 if( !utf8_name || !utf8_comment )
294 BUG( dlg );
295 p = gpgme_genkey_params( keytype, bits, utf8_name, utf8_comment, email, expire, pwd );
296 free( utf8_name );
297 free( utf8_comment );
298 }
299 keygen_cb_dlg_create( );
300 err = gpgme_op_genkey_auto (p, keygen_cb, &fpr);
301 memset( pwd, 0, sizeof pwd );
302 memset( pwd2, 0, sizeof pwd2 );
303 if( p ) {
304 memset( p, 0, strlen( p ) ); /* burn the passphrase! */
305 free( p );
306 }
307 keygen_cb_dlg_destroy( );
308 keygen_cb( NULL, NULL, 0, 0, 0 ); /* flush */
309 if( err ) {
310 safe_free (fpr);
311 msg_box (dlg, gpgme_strerror( err ), _("Key Generation"), MB_ERR);
312 return FALSE;
313 }
314 status_box( dlg, _("Key Generation completed"), _("GnuPG Status") );
315
316 keycache_update (0, fpr);
317 keycache_update (1, fpr);
318 if (ctx->first_start == 0 && ctx != NULL)
319 get_pubkey (fpr, &ctx->newkey);
320 safe_free (fpr);
321
322 clear_dlg_fields (dlg);
323 ask_for_backup (dlg);
324 EndDialog (dlg, TRUE);
325 return TRUE;
326
327 case IDCANCEL:
328 SetDlgItemText (dlg, IDC_KEYGEN_PASSPHRASE, "");
329 SetDlgItemText (dlg, IDC_KEYGEN_PWDCHECK, "");
330 EndDialog (dlg, FALSE);
331 return FALSE;
332 }
333 break;
334 }
335
336 return FALSE;
337 } /* keygen_dlg_proc */
338
339
340 BOOL CALLBACK
341 keygen_wizard_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
342 {
343 static genkey_s *ctx;
344 static int pubkey_algo = GPGME_KEYGEN_DSA_ELG;
345 gpgme_error_t err;
346 char name[128], email[128];
347 char * utf8_name, * p, *fpr=NULL;
348 char * pass = NULL;
349 int cancel = 0;
350
351
352 switch( msg ) {
353 case WM_INITDIALOG:
354 ctx = (genkey_s *)lparam;
355 if (!ctx || (ctx && ctx->interactive == 0))
356 EnableWindow (GetDlgItem (dlg, IDC_KEYWIZARD_EXPERT), FALSE);
357 SetDlgItemText (dlg, IDC_KEYWIZARD_USERSA, _("&Prefer RSA keys"));
358 SetDlgItemText (dlg, IDC_KEYWIZARD_NAMEINF, _("Real name:"));
359 SetDlgItemText (dlg, IDC_KEYWIZARD_EMAILINF, _("Email address:"));
360 SetDlgItemText (dlg, IDC_KEYWIZARD_TITLEINF, _("Name and E-Mail Assignment"));
361 SetDlgItemText (dlg, IDC_KEYWIZARD_TEXT1INF, _("Every key pair must have a name associated with it. The name and\nemail address let your correspondents that your public key they are\nusing belongs to us."));
362 SetDlgItemText (dlg, IDC_KEYWIZARD_TEXT2INF, _("By accosiating an email address with your key pair, you will enable WinPT to assist your correspondents in selecting the correct public\nkey when communicating with you."));
363 SetForegroundWindow (dlg);
364 center_window (dlg);
365 break;
366
367 case WM_SYSCOMMAND:
368 if( LOWORD( wparam ) == SC_CLOSE )
369 EndDialog( dlg, FALSE );
370
371 case WM_COMMAND:
372 switch( LOWORD( wparam ) ) {
373 case IDC_KEYWIZARD_EXPERT:
374 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYGEN, dlg,
375 keygen_dlg_proc, NULL);
376 EndDialog (dlg, TRUE);
377 break;
378
379 case IDOK:
380 if( !GetDlgItemText( dlg, IDC_KEYWIZARD_NAME, name, sizeof name-1 ) ) {
381 msg_box( dlg, _("Please enter the name."),
382 _("Key Generation Wizard"), MB_ERR );
383 return FALSE;
384 }
385 if (strchr (name, '@')) {
386 msg_box (dlg, _("Please do not enter the email address in the name field."),
387 _("Key Generation Wizard"), MB_WARN);
388 return FALSE;
389 }
390 if( !GetDlgItemText( dlg, IDC_KEYWIZARD_EMAIL, email, sizeof email-1 )
391 || !strchr( email, '@' ) ) {
392 msg_box( dlg, _("Please enter a valid email address."),
393 _("Key Generation Wizard"), MB_ERR );
394 return FALSE;
395 }
396 if (strchr (email, '<') || strchr (email, '>')) {
397 msg_box (dlg, _("Please do not add '<' or '>' to the email address."),
398 _("Key Generation Wizard"), MB_WARN);
399 return FALSE;
400 }
401 pass = request_passphrase2 (_("Key Generation"), PASSDLG_STRICT, &cancel);
402 if (cancel)
403 return FALSE;
404 utf8_name = wincp_to_utf8 (name, strlen (name));
405 if( !utf8_name )
406 BUG( NULL );
407 if (IsDlgButtonChecked (dlg, IDC_KEYWIZARD_USERSA))
408 pubkey_algo = GPGME_KEYGEN_DSA_RSA;
409 p = gpgme_genkey_params (pubkey_algo, DFAULT_KEYSIZE, utf8_name,
410 NULL, email, NULL, pass);
411 free( utf8_name );
412 keygen_cb_dlg_create();
413 err = gpgme_op_genkey_auto (p, keygen_cb, &fpr);
414 keygen_cb_dlg_destroy();
415 keygen_cb( NULL, NULL, 0, 0, 0 );
416 if( p ) {
417 memset( p, 0, strlen( p ) );
418 free( p );
419 }
420 sfree_if_alloc (pass);
421 if( err ) {
422 msg_box( dlg, gpgme_strerror( err ), _("Key Generation Wizard"), MB_ERR );
423 safe_free (fpr);
424 return FALSE;
425 }
426 status_box( dlg, _("Key Generation completed"), _("GnuPG Status") );
427
428 keycache_update (0, fpr);
429 keycache_update (1, fpr);
430 if (ctx->first_start == 0 && ctx != NULL)
431 get_pubkey (fpr, &ctx->newkey);
432 safe_free (fpr);
433
434 ask_for_backup (dlg);
435 EndDialog (dlg, TRUE);
436 break;
437
438 case IDCANCEL:
439 EndDialog( dlg, FALSE );
440 break;
441 }
442 break;
443 }
444 return FALSE;
445 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26