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

Annotation of /trunk/Src/wptKeygenDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide 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 twoaday 2 /* wptKeygenDlg.cpp - Key Generation dialog
2 twoaday 22 * Copyright (C) 2000-2005 Timo Schulz
3 twoaday 2 *
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 twoaday 20 ask_for_backup (HWND dlg)
51 twoaday 2 {
52     int id;
53     char * path = NULL, * keyring = NULL;
54     const char * name;
55    
56 twoaday 20 path = get_gnupg_path ();
57 twoaday 2 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 twoaday 22 keygen_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
130 twoaday 2 {
131 twoaday 20 static genkey_s *ctx;
132 twoaday 2 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 twoaday 20 char t[64], *expire = NULL, *fpr=NULL;
139 twoaday 2 int bits, use_comment, keytype = 0;
140     char * p;
141    
142     switch ( msg ) {
143     case WM_INITDIALOG:
144 twoaday 20 if (lparam != NULL)
145     ctx = (genkey_s *)lparam;
146 twoaday 2 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 twoaday 12 if (bits > DFAULT_KEYSIZE) {
207 twoaday 2 int id = msg_box (dlg, _("Do you really need such a large key?"),
208     _("Key Generation"), MB_YESNO);
209     if (id == IDNO)
210 twoaday 12 bits = DFAULT_KEYSIZE;
211 twoaday 2 }
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 twoaday 22 else if (check_passwd_quality (pwd, 0)) {
248 twoaday 2 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 twoaday 20 err = gpgme_op_genkey_auto (p, keygen_cb, &fpr);
301 twoaday 2 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 twoaday 20 safe_free (fpr);
311     msg_box (dlg, gpgme_strerror( err ), _("Key Generation"), MB_ERR);
312 twoaday 2 return FALSE;
313     }
314     status_box( dlg, _("Key Generation completed"), _("GnuPG Status") );
315 twoaday 20
316     keycache_update (0, fpr);
317     keycache_update (1, fpr);
318 twoaday 22 if (ctx->first_start == 0 && ctx != NULL)
319 twoaday 20 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 twoaday 2 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 twoaday 20 static genkey_s *ctx;
344 twoaday 2 static int pubkey_algo = GPGME_KEYGEN_DSA_ELG;
345     gpgme_error_t err;
346     char name[128], email[128];
347 twoaday 20 char * utf8_name, * p, *fpr=NULL;
348 twoaday 2 char * pass = NULL;
349     int cancel = 0;
350    
351    
352     switch( msg ) {
353     case WM_INITDIALOG:
354 twoaday 20 ctx = (genkey_s *)lparam;
355 twoaday 2 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 twoaday 20 _("Key Generation Wizard"), MB_WARN);
388 twoaday 2 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 twoaday 20 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 twoaday 22 pass = request_passphrase2 (_("Key Generation"), PASSDLG_STRICT, &cancel);
402 twoaday 2 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 twoaday 22 p = gpgme_genkey_params (pubkey_algo, DFAULT_KEYSIZE, utf8_name,
410 twoaday 2 NULL, email, NULL, pass);
411     free( utf8_name );
412     keygen_cb_dlg_create();
413 twoaday 20 err = gpgme_op_genkey_auto (p, keygen_cb, &fpr);
414 twoaday 2 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 twoaday 20 safe_free (fpr);
424 twoaday 2 return FALSE;
425     }
426     status_box( dlg, _("Key Generation completed"), _("GnuPG Status") );
427 twoaday 20
428     keycache_update (0, fpr);
429     keycache_update (1, fpr);
430 twoaday 22 if (ctx->first_start == 0 && ctx != NULL)
431 twoaday 20 get_pubkey (fpr, &ctx->newkey);
432     safe_free (fpr);
433    
434     ask_for_backup (dlg);
435     EndDialog (dlg, TRUE);
436 twoaday 2 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