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

Diff of /trunk/Src/wptKeygenDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 12 by twoaday, Thu Apr 14 12:56:25 2005 UTC revision 225 by twoaday, Tue Jun 6 13:37:59 2006 UTC
# Line 1  Line 1 
 /* wptKeygenDlg.cpp - Key Generation dialog  
  *      Copyright (C) 2000-2004 Timo Schulz  
  *  
  * This file is part of WinPT.  
  *  
  * WinPT is free software; you can redistribute it and/or modify  
  * it under the terms of the GNU General Public License as published by  
  * the Free Software Foundation; either version 2 of the License, or  
  * (at your option) any later version.  
  *  
  * WinPT is distributed in the hope that it will be useful,  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
  * GNU General Public License for more details.  
  *  
  * You should have received a copy of the GNU General Public License  
  * along with WinPT; if not, write to the Free Software Foundation,  
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA  
  */  
   
 #include <windows.h>  
   
 #include "../resource.h"  
 #include "wptTypes.h"  
 #include "wptNLS.h"  
 #include "wptGPG.h"  
 #include "wptCommonCtl.h"  
 #include "wptContext.h" /* for passphrase_s */  
 #include "wptDlgs.h"  
 #include "wptW32API.h"  
 #include "wptVersion.h"  
 #include "wptErrors.h"  
 #include "wptUTF8.h"  
   
   
 static void  
 clear_dlg_fields( HWND dlg )  
 {  
     SetDlgItemText( dlg, IDC_KEYGEN_SUBKEYBITS, "" );  
     SetDlgItemText( dlg, IDC_KEYGEN_NAME, "" );  
     SetDlgItemText( dlg, IDC_KEYGEN_EMAIL, "" );  
     SetDlgItemText( dlg, IDC_KEYGEN_COMMENT, "" );  
     SetDlgItemText( dlg, IDC_KEYGEN_EXPDATE, "" );  
     SetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, "" );  
     SetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, "" );  
 } /* clear_dlg_fields */  
   
   
 static void  
 ask_for_backup( HWND dlg )  
 {  
     int id;  
     char * path = NULL, * keyring = NULL;  
     const char * name;  
       
     path = get_gnupg_path( );  
     if( !path )  
         BUG( dlg );  
     id = msg_box( dlg,  
                  _("It is STRONGLY recommend that you backup your keyrings because they both "  
                    "contain VERY important data.\nRemember that your hard disk can crash or the "  
                    "files can be deleted by accident; so it is a good\nidea to store them on "  
                    "a different mass stoarge like a floppy or CDR!\n\n"  
                    "Backup your keyrings now?"),  
                  _("WARNING - Important hint" ), MB_YESNO );  
     if( id == IDYES ) {  
         name = get_filename_dlg( dlg, 1, _("Destination for Public Keyring"), NULL, "pubring.gpg" );  
         if( name ) {  
             keyring = make_filename( path, "pubring", "gpg" );  
             if( !CopyFile( keyring, name, FALSE ) )  
                 log_box( _("Key Generation"), MB_ERR,  
                          _("Could not copy %s -> %s"), keyring, name );      
             free_if_alloc( keyring );  
         }  
         name = get_filename_dlg( dlg, 1, _("Destination for Secret Keyring"), NULL, "secring.gpg" );  
         if( name ) {  
             keyring = make_filename( path, "secring", "gpg" );  
             if( !CopyFile( keyring, name, FALSE ) )  
                 log_box( _("Key Generation"), MB_ERR,  
                          _("Could not copy %s -> %s"), keyring, name );  
             free_if_alloc( keyring );  
         }  
     }  
     free_if_alloc( path );  
 } /* ask_for_backup */  
   
   
 static void  
 fill_keytype_box( HWND dlg )  
 {  
     HWND cb = GetDlgItem( dlg, IDC_KEYGEN_KEYTYPE );  
   
 #define addstr( cb, str ) \  
     SendMessage( (cb), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)(str) )  
     addstr( cb, _("DSA and ELG (default)") );  
     addstr( cb, _("DSA and RSA") );  
     addstr( cb, _("DSA sign only") );  
     addstr( cb, _("RSA sign only") );  
     addstr( cb, _("RSA sign and encrypt") );  
     addstr( cb, _("RSA and RSA (PGP)") );  
     SendMessage( cb, CB_SETCURSEL, 0, 0 );  
 #undef addstr  
 } /* fill_keytype_box */  
   
   
 static inline int  
 get_keytype( HWND dlg )  
 {  
     HWND cb = GetDlgItem( dlg, IDC_KEYGEN_KEYTYPE );  
     return SendMessage( cb, CB_GETCURSEL, 0, 0 ) + 1;  
 } /* get_keytype */  
   
   
 int  
 keygen_check_date( SYSTEMTIME *st )  
 {        
     SYSTEMTIME t;  
           
     GetSystemTime( &t );  
     if( st->wYear > t.wYear || st->wMonth > t.wMonth )  
         return 1;  
     else if( st->wYear < t.wYear || st->wMonth < t.wMonth || st->wDay < t.wDay)  
         return 0;        
     return 1;  
 } /* keygen_check_date */  
   
   
 BOOL CALLBACK  
 keygen_dlg_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )  
 {  
     static int hide = 1;  
     static int act_expdate = 0;  
     SYSTEMTIME st;  
     gpgme_error_t err;  
     char name[128] = {0}, email[128] = {0}, comment[128] = {0};  
     char pwd[128], pwd2[128];  
     char t[64], *expire = NULL;  
     int bits, use_comment, keytype = 0;      
     char * p;    
       
     switch ( msg ) {  
     case WM_INITDIALOG:  
         hide = 1;  
 #ifndef LANG_DE  
         SetWindowText( dlg, _("Key Generation") );  
         SetDlgItemText( dlg, IDC_KEYGEN_INFO,  
                         _("NOTE: Key generation can be a lengthy process! Please wait until "  
                           "you get the message that key generation was finished.") );  
         SetDlgItemText( dlg, IDC_KEYGEN_SUBKEYINF, _("Subkey size in &bits"));  
         SetDlgItemText( dlg, IDC_KEYGEN_NAMEINF, _("&Real name") );  
         SetDlgItemText( dlg, IDC_KEYGEN_COMMINF, _("&Comment (optional)") );  
         SetDlgItemText( dlg, IDC_KEYGEN_EMAILINF, _("Email &address") );  
         SetDlgItemText( dlg, IDC_KEYGEN_EXPINF, _("Key &expiration") );  
         SetDlgItemText( dlg, IDC_KEYGEN_PWDINF, _("&Passphrase") );  
         SetDlgItemText( dlg, IDC_KEYGEN_REPWDINF, _("&Repeat passphrase") );  
         SetDlgItemText( dlg, IDC_KEYGEN_KEYTYPEINF, _("Key &type") );  
         SetDlgItemText (dlg, IDC_KEYGEN_CLEAR, _("&Never"));  
         SetDlgItemText (dlg, IDC_KEYGEN_HIDEPWD, _("&Hide Typing"));  
 #endif  
         SetDlgItemInt( dlg, IDC_KEYGEN_SUBKEYBITS, 2048, FALSE );  
         CheckDlgButton (dlg, IDC_KEYGEN_HIDEPWD, BST_CHECKED);  
         CheckDlgButton (dlg, IDC_KEYGEN_EXPNEVER, BST_CHECKED);  
         EnableWindow (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), FALSE);  
         fill_keytype_box( dlg );  
         center_window( dlg );  
         SetForegroundWindow( dlg );  
         return TRUE;  
           
     case WM_SYSCOMMAND:  
         if( LOWORD( wparam ) == SC_CLOSE ) {  
             SetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, "" );  
             SetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, "" );  
             EndDialog( dlg, TRUE );  
         }  
         return FALSE;  
           
     case WM_COMMAND:  
         if (HIWORD (wparam) == BN_CLICKED &&  
             LOWORD (wparam) == IDC_KEYGEN_EXPNEVER) {  
             act_expdate ^= 1;  
             EnableWindow (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), act_expdate);  
         }  
         if( HIWORD( wparam ) == BN_CLICKED  
             && LOWORD( wparam ) == IDC_KEYGEN_HIDEPWD ) {  
             HWND hwnd_a = GetDlgItem( dlg, IDC_KEYGEN_PASSPHRASE );  
             HWND hwnd_b = GetDlgItem( dlg, IDC_KEYGEN_PWDCHECK );  
             hide ^= 1;  
             SendMessage( hwnd_a, EM_SETPASSWORDCHAR, hide? '*' : 0, 0 );  
             SetFocus( hwnd_a );  
             SendMessage( hwnd_b, EM_SETPASSWORDCHAR, hide? '*' : 0, 0 );  
             SetFocus( hwnd_b );  
   
         }  
   
         switch( LOWORD( wparam ) ) {  
         case IDOK:  
             bits = GetDlgItemInt (dlg, IDC_KEYGEN_SUBKEYBITS, NULL, FALSE);  
             if (bits < 1024 || bits > 4096) {  
                 msg_box (dlg, _("Invalid value. Allowed values 1024-4096 bits."),  
                          _("Key Generation"), MB_ERR);  
                 return FALSE;  
             }  
             if (bits > DFAULT_KEYSIZE) {  
                 int id = msg_box (dlg, _("Do you really need such a large key?"),  
                                   _("Key Generation"), MB_YESNO);  
                 if (id == IDNO)  
                     bits = DFAULT_KEYSIZE;  
             }  
             if( !GetDlgItemText( dlg, IDC_KEYGEN_NAME, name, sizeof name - 1 ) ) {  
                 msg_box( dlg, _("Please enter the name."), _("Key Generation"), MB_ERR );  
                 return FALSE;  
             }  
             if (strchr (name, '@')) {  
                 msg_box (dlg, _("Please do not enter the email address in the name field."),  
                          _("Key Generation"), MB_INFO);  
                 return FALSE;  
             }  
             if( !GetDlgItemText(dlg, IDC_KEYGEN_EMAIL, email, sizeof email -1 )  
                 || !strchr( email, '@') ) {  
                 msg_box( dlg, _("Please enter a valid email address."),  
                          _("Key Generation"), MB_ERR );  
                 return FALSE;  
             }  
             use_comment = GetDlgItemText( dlg, IDC_KEYGEN_COMMENT, comment, sizeof comment -1 );  
             if( use_comment > 0 && strchr( comment, '@' ) ) {  
                 msg_box( dlg, _("Please do NOT enter the email address in the comment field."),  
                          _("Key Generation"), MB_INFO );  
                 return FALSE;  
             }  
             keytype = get_keytype( dlg );  
             if (IsDlgButtonChecked (dlg, IDC_KEYGEN_EXPNEVER))  
                 expire = NULL;  
             else {  
                 DateTime_GetSystemtime (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), &st);  
                 _snprintf (t, DIM (t)-1, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);  
                 expire = t;  
             }  
               
             if( !GetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, pwd, sizeof pwd -1 ) ) {  
                 msg_box( dlg, _("Please enter the passphrase."),  
                          _("Key Generation"), MB_ERR );  
                 return FALSE;  
             }  
             else if( strlen( pwd ) < 8 ) {  
                 int id = msg_box( dlg, _("Your passphrase should be at least 8 characters"  
                                          " long\nand should contain non-alphabetic characters."  
                                          "\n\nStill proceed?"),  
                                     _("Key Generation"), MB_ICONWARNING|MB_YESNO );  
                 if( id == IDNO ) {  
                     SetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, "" );  
                     SetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, "" );  
                     return FALSE;  
                 }  
             }  
             if( !GetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, pwd2, sizeof pwd2 -1 ) ) {  
                 msg_box( dlg, _("Please repeat the passphrase."),  
                          _("Key Generation"), MB_ERR );  
                 return FALSE;  
             }  
             if( strcmp( pwd, pwd2 ) ) {  
                 msg_box( dlg,  _("Passphrases are NOT identical!" ),  
                          _("Key Generation"), MB_ERR );  
                 memset( pwd, 0, sizeof pwd );  
                 memset( pwd2, 0, sizeof pwd2 );  
                 return FALSE;  
             }  
             if( is_8bit_string( pwd ) ) {  
                 msg_box( dlg, _("The passphrase contains 8-bit characters.\n"  
                                 "It is not suggested to use charset specific characters."),  
                          _("Key Generation"), MB_ERR );  
                 memset( pwd, 0, sizeof pwd );  
                 memset( pwd2, 0, sizeof pwd2 );  
                 SetDlgItemText( dlg, IDC_KEYGEN_PASSPHRASE, "" );  
                 SetDlgItemText( dlg, IDC_KEYGEN_PWDCHECK, "" );  
                 return FALSE;  
             }  
                                   
             if( !use_comment && !strlen( comment ) ) {  
                 char *utf8_name;  
                 utf8_name = wincp_to_utf8 (name, strlen (name));  
                 if( !utf8_name )  
                     BUG( dlg );  
                 p = gpgme_genkey_params( keytype, bits, utf8_name, NULL, email, expire, pwd );  
                 free( utf8_name );  
             }  
             else {  
                 char *utf8_name, *utf8_comment;  
                 utf8_name = wincp_to_utf8 (name, strlen (name));  
                 utf8_comment = wincp_to_utf8 (comment, strlen (comment));                
                 if( !utf8_name || !utf8_comment )  
                     BUG( dlg );  
                 p = gpgme_genkey_params( keytype, bits, utf8_name, utf8_comment, email, expire, pwd );  
                 free( utf8_name );  
                 free( utf8_comment );  
             }  
             keygen_cb_dlg_create( );  
             err = gpgme_op_genkey_auto( p, keygen_cb, NULL );  
             memset( pwd, 0, sizeof pwd );  
             memset( pwd2, 0, sizeof pwd2 );  
             if( p ) {  
                 memset( p, 0, strlen( p ) ); /* burn the passphrase! */  
                 free( p );  
             }  
             keygen_cb_dlg_destroy( );  
             keygen_cb( NULL, NULL, 0, 0, 0 ); /* flush */  
             if( err ) {  
                 msg_box( dlg, gpgme_strerror( err ), _("Key Generation"), MB_ERR );  
                 return FALSE;  
             }  
             status_box( dlg, _("Key Generation completed"), _("GnuPG Status") );  
             keycache_set_reload( 1 );  
             clear_dlg_fields( dlg );  
             ask_for_backup( dlg );  
             EndDialog( dlg, TRUE );  
             return TRUE;  
               
         case IDCANCEL:  
             SetDlgItemText (dlg, IDC_KEYGEN_PASSPHRASE, "");  
             SetDlgItemText (dlg, IDC_KEYGEN_PWDCHECK, "");  
             EndDialog (dlg, FALSE);  
             return FALSE;  
         }  
         break;  
     }  
       
     return FALSE;  
 } /* keygen_dlg_proc */  
   
   
 BOOL CALLBACK  
 keygen_wizard_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  
 {  
     static key_wizard_s * ctx;  
     static int pubkey_algo = GPGME_KEYGEN_DSA_ELG;  
     gpgme_error_t err;  
     char name[128], email[128];  
     char * utf8_name, * p;  
     char * pass = NULL;  
     int cancel = 0;  
       
   
     switch( msg ) {  
     case WM_INITDIALOG:  
         ctx = (key_wizard_s *)lparam;  
         if (!ctx || (ctx && ctx->interactive == 0))  
             EnableWindow (GetDlgItem (dlg, IDC_KEYWIZARD_EXPERT), FALSE);  
         SetDlgItemText (dlg, IDC_KEYWIZARD_USERSA, _("&Prefer RSA keys"));  
         SetDlgItemText (dlg, IDC_KEYWIZARD_NAMEINF, _("Real name:"));  
         SetDlgItemText (dlg, IDC_KEYWIZARD_EMAILINF, _("Email address:"));  
         SetDlgItemText (dlg, IDC_KEYWIZARD_TITLEINF, _("Name and E-Mail Assignment"));  
         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."));  
         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."));  
         SetForegroundWindow (dlg);  
         center_window (dlg);  
         break;  
   
     case WM_SYSCOMMAND:  
         if( LOWORD( wparam ) == SC_CLOSE )  
             EndDialog( dlg, FALSE );  
   
     case WM_COMMAND:  
         switch( LOWORD( wparam ) ) {  
         case IDC_KEYWIZARD_EXPERT:  
             DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYGEN, dlg,  
                             keygen_dlg_proc, NULL);  
             EndDialog (dlg, TRUE);  
             break;  
   
         case IDOK:  
             if( !GetDlgItemText( dlg, IDC_KEYWIZARD_NAME, name, sizeof name-1 ) ) {  
                 msg_box( dlg, _("Please enter the name."),  
                          _("Key Generation Wizard"), MB_ERR );  
                 return FALSE;  
             }  
             if (strchr (name, '@')) {  
                 msg_box (dlg, _("Please do not enter the email address in the name field."),  
                          _("Key Generation Wizard"), MB_ERR);  
                 return FALSE;  
             }  
             if( !GetDlgItemText( dlg, IDC_KEYWIZARD_EMAIL, email, sizeof email-1 )  
                 || !strchr( email, '@' ) ) {  
                 msg_box( dlg, _("Please enter a valid email address."),  
                          _("Key Generation Wizard"), MB_ERR );  
                 return FALSE;  
             }  
             pass = request_passphrase2 (_("Key Generation"), &cancel);  
             if (cancel)  
                 return FALSE;  
             utf8_name = wincp_to_utf8 (name, strlen (name));  
             if( !utf8_name )  
                 BUG( NULL );  
             if (IsDlgButtonChecked (dlg, IDC_KEYWIZARD_USERSA))  
                 pubkey_algo = GPGME_KEYGEN_DSA_RSA;  
             p = gpgme_genkey_params (pubkey_algo, 2048, utf8_name,  
                                      NULL, email, NULL, pass);  
             free( utf8_name );  
             keygen_cb_dlg_create();  
             err = gpgme_op_genkey_auto( p, keygen_cb, NULL );  
             keygen_cb_dlg_destroy();  
             keygen_cb( NULL, NULL, 0, 0, 0 );  
             if( p ) {  
                 memset( p, 0, strlen( p ) );  
                 free( p );  
             }  
             sfree_if_alloc (pass);  
             if( err ) {  
                 msg_box( dlg, gpgme_strerror( err ), _("Key Generation Wizard"), MB_ERR );  
                 return FALSE;  
             }  
             status_box( dlg, _("Key Generation completed"), _("GnuPG Status") );  
             keycache_set_reload( 1 );  
             EndDialog( dlg, TRUE );  
             break;  
   
         case IDCANCEL:  
             EndDialog( dlg, FALSE );  
             break;  
         }  
         break;  
     }  
     return FALSE;  
 }  
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    #ifdef HAVE_CONFIG_H
21    #include <config.h>
22    #endif
23    
24    #include <windows.h>
25    #include <time.h>
26    
27    #include "resource.h"
28    #include "wptTypes.h"
29    #include "wptNLS.h"
30    #include "wptGPG.h"
31    #include "wptCommonCtl.h"
32    #include "wptContext.h" /* for passphrase_s */
33    #include "wptDlgs.h"
34    #include "wptW32API.h"
35    #include "wptVersion.h"
36    #include "wptErrors.h"
37    
38    
39    /* All valid key generation combination. */
40    enum gpg_keytype_t {
41        GPG_KEYGEN_NONE    = 0,
42        GPG_KEYGEN_DSA_ELG = 1,
43        GPG_KEYGEN_DSA_RSA = 2,
44        GPG_KEYGEN_DSA_SIG = 3,
45        GPG_KEYGEN_RSA_SIG = 4,    
46        GPG_KEYGEN_RSA     = 5,
47        GPG_KEYGEN_RSA_RSA = 6 /*PGP*/
48    };
49    
50    
51    static const char key_params[] =
52            "<GnupgKeyParms format=\"internal\">\n"
53            "Key-Type: %s\n"
54            "Key-Usage: sign\n"
55            "Key-Length: %d\n"
56            "Subkey-Type: %s\n"
57            "Subkey-Length: %d\n"
58            "Name-Real: %s\n"      
59            "Name-Email: %s\n"
60            "Expire-Date: %s\n"
61            "Passphrase: %s\n"
62            "</GnupgKeyParms>\n";
63    
64    static const char key_params_with_comment[] =
65            "<GnupgKeyParms format=\"internal\">\n"
66            "Key-Type: %s\n"
67            "Key-Usage: sign\n"
68            "Key-Length: %d\n"
69            "Subkey-Type: %s\n"
70            "Subkey-Length: %d\n"
71            "Name-Real: %s\n"
72            "Name-Comment: %s\n"
73            "Name-Email: %s\n"
74            "Expire-Date: %s\n"
75            "Passphrase: %s\n"
76            "</GnupgKeyParms>\n";
77    
78    static const char key_params_one[] =
79            "<GnupgKeyParms format=\"internal\">\n"
80            "Key-Type: %s\n"
81            "Key-Length: %d\n"
82            "Key-Usage: %s\n"      
83            "Name-Real: %s\n"      
84            "Name-Email: %s\n"
85            "Expire-Date: %s\n"
86            "Passphrase: %s\n"
87            "</GnupgKeyParms>\n";
88    
89    static const char key_params_one_with_comment[] =
90            "<GnupgKeyParms format=\"internal\">\n"
91            "Key-Type: %s\n"
92            "Key-Length: %d\n"
93            "Key-Usage: %s\n"      
94            "Name-Real: %s\n"      
95            "Name-Comment: %s\n"
96            "Name-Email: %s\n"
97            "Expire-Date: %s\n"
98            "Passphrase: %s\n"
99            "</GnupgKeyParms>\n";
100    
101    
102    /* Generate the GPG specific genkey params with the given information.
103       @keytype: See valid combinations.
104       @bits: Length in bits.
105       @user: user-ID name
106       @comment: comment for the user-ID.
107       @email: email address.
108       @expdata: date of expiration or NULL.
109       @passphrase: the actual passphrase.
110       Return value: the gen. params. */
111    static char*
112    gpg_genkey_params (int keytype, int bits,
113                       const char *user, const char *comment, const char *email,
114                       const char *expdate, const char *passphrase)
115    {
116        char *p = NULL;
117        int addsize = strlen ("sign encrypt");
118        int size = 0;
119        
120        if (keytype == GPG_KEYGEN_NONE)
121            return NULL;
122        
123        size = strlen (user) + strlen (email) + strlen (passphrase) + addsize + 48;
124        if (comment && *comment)
125            size += strlen (key_params_with_comment) + strlen (comment);
126        else
127            size += strlen (key_params);
128        if (expdate)
129            size += strlen (expdate) + 1;
130        p = new char[size+1];
131        if (!p)
132            BUG (0);
133        /* XXX: simply the whole switch-case code. */
134        if (comment && *comment) {
135            switch( keytype ) {
136            case GPG_KEYGEN_DSA_ELG:
137                sprintf (p, key_params_with_comment,
138                         "DSA", 1024, "ELG-E", bits, user, comment, email,
139                         expdate ? expdate : "0", passphrase);
140                break;
141                
142            case GPG_KEYGEN_DSA_RSA:
143                sprintf( p, key_params_with_comment,
144                         "DSA", 1024, "RSA", bits, user, comment, email,
145                         expdate ? expdate : "0", passphrase );
146                break;
147                
148            case GPG_KEYGEN_DSA_SIG:
149                sprintf( p, key_params_one_with_comment,
150                         "DSA", 1024, "sign",
151                         user, comment, email,
152                         expdate ? expdate : "0", passphrase );
153                break;
154                
155            case GPG_KEYGEN_RSA_SIG:
156                sprintf( p, key_params_one_with_comment,
157                         "RSA", bits, "sign",
158                         user, comment, email,
159                         expdate ? expdate : "0", passphrase );
160                break;
161                
162            case GPG_KEYGEN_RSA:
163                sprintf( p, key_params_one_with_comment,
164                        "RSA", bits, "sign encrypt",
165                        user, comment, email,
166                        expdate ? expdate : "0", passphrase );
167                break;
168    
169            case GPG_KEYGEN_RSA_RSA:
170                sprintf( p, key_params_with_comment,
171                         "RSA", bits, "RSA", bits, user, comment, email,
172                         expdate? expdate : "0", passphrase );
173                break;
174                
175            default:
176                free_if_alloc (p);
177                break;
178            }
179        }
180        else {
181            switch ( keytype ) {
182            case GPG_KEYGEN_DSA_ELG:
183                sprintf( p, key_params,
184                        "DSA", 1024, "ELG-E", bits, user, email,
185                        expdate ? expdate : "0", passphrase );
186                break;
187                
188            case GPG_KEYGEN_DSA_RSA:
189                sprintf( p, key_params,
190                        "DSA", 1024, "RSA", bits, user, email,
191                        expdate ? expdate : "0", passphrase );
192                break;
193                
194            case GPG_KEYGEN_DSA_SIG:
195                sprintf( p, key_params_one,
196                        "DSA", 1024, "sign",
197                        user, email,
198                        expdate ? expdate : "0", passphrase );
199                break;
200                
201            case GPG_KEYGEN_RSA_SIG:
202                sprintf( p, key_params_one,
203                        "RSA", bits, "sign",
204                        user, email,
205                        expdate ? expdate : "0", passphrase );
206                break;
207                
208            case GPG_KEYGEN_RSA:
209                sprintf( p, key_params_one,
210                        "RSA", bits, "sign encrypt",
211                        user, email,
212                        expdate ? expdate : "0", passphrase );
213                break;
214    
215            case GPG_KEYGEN_RSA_RSA:
216                sprintf( p, key_params,
217                         "RSA", bits, "RSA", bits, user, email,
218                         expdate? expdate : "0", passphrase );
219                break;
220                
221            default:
222                free_if_alloc (p);
223                break;
224            }
225        }
226        return p;
227    }
228    
229    
230    /* Generate a key with the given params @params. @prog_cb is a user defined
231       progress callback which is called during the generation.
232       @fpr will store the fingerprint of the generated key.
233       Return value: 0 on success. */
234    gpgme_error_t
235    gpg_genkey (const char *params, gpgme_progress_cb_t prog_cb, char **fpr)
236    {
237        gpgme_error_t err = 0;
238        gpgme_ctx_t ctx;
239        gpgme_genkey_result_t res;
240        
241        err = gpgme_new(&ctx);
242        if (err)
243            return err;
244        if (prog_cb)
245            gpgme_set_progress_cb (ctx, prog_cb, NULL);
246        err = gpgme_op_genkey (ctx, params, NULL, NULL);
247        if (!err) {
248            res = gpgme_op_genkey_result (ctx);
249            *fpr = res && res->fpr? m_strdup (res->fpr) : NULL;
250        }
251        gpgme_release (ctx);
252        return err;
253    }
254    
255    
256    
257    /* Clear all dialog fields. */
258    static void
259    clear_dlg_fields (HWND dlg)
260    {
261        SetDlgItemText (dlg, IDC_KEYGEN_SUBKEYBITS, "");
262        SetDlgItemText (dlg, IDC_KEYGEN_NAME, "");
263        SetDlgItemText (dlg, IDC_KEYGEN_EMAIL, "");
264        SetDlgItemText (dlg, IDC_KEYGEN_COMMENT, "");
265        SetDlgItemText (dlg, IDC_KEYGEN_EXPDATE, "");
266        SetDlgItemText (dlg, IDC_KEYGEN_PASSPHRASE, "");
267        SetDlgItemText (dlg, IDC_KEYGEN_PWDCHECK, "");
268    }
269    
270    
271    /* Ask the user if a keyring backup is wanted and if so,
272       backup both keyrings to the selected folder. @dlg is
273       the handle of the parent window.*/
274    static void
275    backup_keyrings (HWND dlg)
276    {
277        const char *name;
278        char *path = NULL;
279        char *keyring = NULL;
280        int id;
281        
282        path = get_gnupg_path ();
283        if (!path)
284            BUG (dlg);
285        id = msg_box (dlg,
286                     _("It is STRONGLY recommend that you backup your keyrings because they both "
287                       "contain VERY important data.\nRemember that your hard disk can crash or the "
288                       "files can be deleted by accident; so it is a good\nidea to store them on "
289                       "a different mass stoarge like a floppy or CDR!\n\n"
290                       "Backup your keyrings now?"),
291                     _("WARNING - Important hint" ), MB_YESNO);
292        if (id == IDYES) {
293            name = get_filesave_dlg (dlg, _("Destination for Public Keyring"),
294                                     NULL, "pubring.gpg");
295            if( name ) {
296                keyring = make_filename (path, "pubring", "gpg");
297                if( !CopyFile (keyring, name, FALSE))
298                    log_box (_("Key Generation"), MB_ERR,
299                             _("Could not copy %s -> %s"), keyring, name);
300                free_if_alloc (keyring);
301            }
302            name = get_filesave_dlg (dlg, _("Destination for Secret Keyring"),
303                                     NULL, "secring.gpg");
304            if (name) {
305                keyring = make_filename (path, "secring", "gpg");
306                if (!CopyFile (keyring, name, FALSE))
307                    log_box (_("Key Generation"), MB_ERR,
308                             _("Could not copy %s -> %s"), keyring, name);
309                free_if_alloc (keyring);
310            }
311        }
312        free_if_alloc (path);
313    }
314    
315    
316    /* Fill in all valid GPG algorithms. */
317    static void
318    fill_keytype_box (HWND dlg)
319    {
320        HWND cb = GetDlgItem (dlg, IDC_KEYGEN_KEYTYPE);
321    
322    #define addstr(cb, str) \
323        SendMessage ((cb), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)(str))
324        addstr (cb, _("DSA and ELG (default)"));
325        addstr (cb, _("DSA and RSA"));
326        addstr (cb, _("DSA sign only"));
327        addstr (cb, _("RSA sign only"));
328        addstr (cb, _("RSA sign and encrypt"));
329        addstr (cb, _("RSA and RSA (PGP)") );
330        SendMessage (cb, CB_SETCURSEL, 0, 0);
331    #undef addstr
332    }
333    
334    
335    time_t w32_mktime (SYSTEMTIME *st);
336    
337    /* Check that the given date lies not in the past.
338       Return value: 1 on success. */
339    int
340    keygen_check_date (SYSTEMTIME *st)
341    {      
342        time_t dat, now;
343            
344        dat = w32_mktime (st);
345        now = time (NULL);
346        if (dat >= now)
347            return 1;
348        return 0;
349    }
350    
351    
352    /* Dialog box procedure for key generation. */
353    BOOL CALLBACK
354    keygen_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
355    {
356        static genkey_s *ctx;
357        SYSTEMTIME st;
358        gpgme_error_t err;
359        char *utf8_name =NULL, *utf8_comment = NULL;
360        char email[128];
361        char *pwd;
362        char t[64], *expire = NULL, *fpr=NULL;
363        int bits, use_comment, keytype = 0;
364        int cancel = 0;
365        char *p;
366        
367        switch (msg) {
368        case WM_INITDIALOG:
369            if (lparam != 0)
370                ctx = (genkey_s *)lparam;
371            SetWindowText (dlg, _("Key Generation"));
372            SetDlgItemText(dlg, IDC_KEYGEN_INFO,
373                            _("NOTE: Key generation can be a lengthy process! Please wait until "
374                              "you get the message that key generation was finished."));
375            SetDlgItemText (dlg, IDC_KEYGEN_SUBKEYINF, _("Subkey size in &bits"));
376            SetDlgItemText (dlg, IDC_KEYGEN_NAMEINF, _("&Real name"));
377            SetDlgItemText (dlg, IDC_KEYGEN_COMMINF, _("&Comment (optional)"));
378            SetDlgItemText (dlg, IDC_KEYGEN_EMAILINF, _("Email &address"));
379            SetDlgItemText (dlg, IDC_KEYGEN_EXPINF, _("&Expire date"));
380            SetDlgItemText (dlg, IDC_KEYGEN_KEYTYPEINF, _("Key &type"));
381            SetDlgItemText (dlg, IDC_KEYGEN_EXPNEVER, _("&Never"));
382            SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
383    
384            SetDlgItemInt (dlg, IDC_KEYGEN_SUBKEYBITS, DFAULT_KEYSIZE, FALSE);
385            CheckDlgButton (dlg, IDC_KEYGEN_HIDEPWD, BST_CHECKED);
386            CheckDlgButton (dlg, IDC_KEYGEN_EXPNEVER, BST_CHECKED);
387            EnableWindow (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), FALSE);
388            fill_keytype_box (dlg);
389            center_window (dlg, NULL);
390            SetForegroundWindow (dlg);
391            return TRUE;
392            
393        case WM_SYSCOMMAND:
394            if (LOWORD (wparam) == SC_CLOSE)
395                EndDialog (dlg, TRUE);
396            return FALSE;
397            
398        case WM_COMMAND:
399            if (HIWORD (wparam) == BN_CLICKED &&
400                LOWORD (wparam) == IDC_KEYGEN_EXPNEVER) {
401                int never = IsDlgButtonChecked (dlg, IDC_KEYGEN_EXPNEVER);
402                EnableWindow (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), !never);
403            }
404    
405            switch (LOWORD (wparam)) {
406            case IDOK:
407                bits = GetDlgItemInt (dlg, IDC_KEYGEN_SUBKEYBITS, NULL, FALSE);
408                if (bits < 1024 || bits > 4096) {
409                    msg_box (dlg, _("Invalid value. Allowed values 1024-4096 bits."),
410                             _("Key Generation"), MB_ERR);
411                    return FALSE;
412                }
413                if (bits > DFAULT_KEYSIZE) {
414                    int id = msg_box (dlg, _("Do you really need such a large key?"),
415                                      _("Key Generation"), MB_YESNO);
416                    if (id == IDNO)
417                        bits = DFAULT_KEYSIZE;
418                }
419                if (!GetDlgItemText_utf8 (dlg, IDC_KEYGEN_NAME, &utf8_name)) {
420                    msg_box (dlg, _("Please enter the name."), _("Key Generation"), MB_ERR);
421                    return FALSE;
422                }
423                if (strchr (utf8_name, '@')) {
424                    msg_box (dlg, _("Please do not enter the email address in the name field."),
425                             _("Key Generation"), MB_INFO);
426                    free_if_alloc (utf8_name);
427                    return FALSE;
428                }
429                if (!GetDlgItemText (dlg, IDC_KEYGEN_EMAIL, email, sizeof (email) -1)
430                    || check_email_address (email)) {
431                    msg_box (dlg, _("Please enter a valid email address."),
432                             _("Key Generation"), MB_ERR);
433                    free_if_alloc (utf8_name);
434                    return FALSE;
435                }
436                use_comment = GetDlgItemText_utf8 (dlg, IDC_KEYGEN_COMMENT,
437                                                   &utf8_comment);
438                if (use_comment > 0 && strchr (utf8_comment, '@')) {
439                    msg_box (dlg, _("Please do NOT enter the email address in the comment field."),
440                             _("Key Generation"), MB_INFO);
441                    free_if_alloc (utf8_name);
442                    free_if_alloc (utf8_comment);
443                    return TRUE;
444                }
445                keytype = SendDlgItemMessage (dlg, IDC_KEYGEN_KEYTYPE, CB_GETCURSEL, 0, 0) + 1;
446                if (IsDlgButtonChecked (dlg, IDC_KEYGEN_EXPNEVER))
447                    expire = NULL;
448                else {
449                    DateTime_GetSystemtime (GetDlgItem (dlg, IDC_KEYGEN_EXPDATE), &st);
450                    if (!keygen_check_date (&st)) {
451                        free_if_alloc (utf8_name);
452                        free_if_alloc (utf8_comment);
453                        msg_box (dlg, _("The date you have chosen lies in the past."),
454                                 _("Key Generation"), MB_ERR);
455                        return TRUE;
456                    }
457                    _snprintf (t, DIM (t)-1, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
458                    expire = t;
459                }
460    
461                pwd = request_passphrase2 (_("Key Generation"), PASSDLG_STRICT, &cancel);
462                if (cancel) {
463                    sfree_if_alloc (pwd);
464                    free_if_alloc (utf8_name);
465                    free_if_alloc (utf8_comment);
466                    return FALSE;
467                }
468                if (!pwd) {
469                    msg_box (dlg, _("Please enter the passphrase."),
470                             _("Key Generation"), MB_ERR);
471                    free_if_alloc (utf8_name);
472                    free_if_alloc (utf8_comment);
473                    return FALSE;
474                }
475    
476                if (!use_comment && !utf8_comment)
477                    p = gpg_genkey_params (keytype, bits, utf8_name, NULL,
478                                           email, expire, pwd);
479                else
480                    p = gpg_genkey_params (keytype, bits, utf8_name, utf8_comment,
481                                           email, expire, pwd);
482                free_if_alloc (utf8_name);
483                free_if_alloc (utf8_comment);
484                keygen_cb_dlg_create ();
485                err = gpg_genkey (p, keygen_cb, &fpr);
486                sfree_if_alloc (pwd);
487                sfree_if_alloc (p); /* burn the passphrase! */
488                keygen_cb_dlg_destroy (1);
489                if (err) {
490                    free_if_alloc (fpr);
491                    msg_box (dlg, gpgme_strerror (err), _("Key Generation"), MB_ERR);
492                    return FALSE;
493                }
494                status_box (dlg, _("Key Generation completed"), _("GnuPG Status"));
495                
496                keycache_update (0, fpr);
497                keycache_update (1, fpr);
498                free_if_alloc (fpr);            
499    
500                clear_dlg_fields (dlg);
501                backup_keyrings (dlg);
502                if (ctx)
503                    ctx->cancel = 0;
504                EndDialog (dlg, TRUE);
505                return TRUE;
506                
507            case IDCANCEL:
508                if (ctx)
509                    ctx->cancel = 1;
510                EndDialog (dlg, FALSE);        
511                return FALSE;
512            }
513            break;
514        }
515        
516        return FALSE;
517    }
518    
519    
520    BOOL CALLBACK
521    keygen_wizard_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
522    {
523        static genkey_s *ctx;
524        static int pubkey_algo = GPG_KEYGEN_DSA_ELG;
525        gpgme_error_t err;
526        char email[128];
527        char *utf8_name=NULL, * p, *fpr=NULL;
528        char * pass = NULL;
529        int cancel = 0;
530        
531    
532        switch( msg ) {
533        case WM_INITDIALOG:
534            ctx = (genkey_s *)lparam;
535            if (!ctx || (ctx && ctx->interactive == 0))
536                EnableWindow (GetDlgItem (dlg, IDC_KEYWIZARD_EXPERT), FALSE);
537            SetDlgItemText (dlg, IDC_KEYWIZARD_USERSA, _("&Prefer RSA keys"));
538            SetDlgItemText (dlg, IDC_KEYWIZARD_NAMEINF, _("Real name:"));
539            SetDlgItemText (dlg, IDC_KEYWIZARD_EMAILINF, _("Email address:"));
540            SetDlgItemText (dlg, IDC_KEYWIZARD_TITLEINF, _("Name and E-Mail Assignment"));
541            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."));
542            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."));
543            SetWindowText (dlg, _("Key Generation Wizard"));
544            SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
545            SetDlgItemText (dlg, IDC_KEYWIZARD_EXPERT, _("E&xpert"));
546            SetForegroundWindow (dlg);
547            center_window (dlg, NULL);
548            break;
549    
550        case WM_COMMAND:
551            switch (LOWORD( wparam)) {
552            case IDC_KEYWIZARD_EXPERT:
553                DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYGEN, dlg,
554                                keygen_dlg_proc, 0);
555                EndDialog (dlg, TRUE);
556                break;
557    
558            case IDOK:
559                if (!GetDlgItemText_utf8 (dlg, IDC_KEYWIZARD_NAME, &utf8_name)) {
560                    msg_box (dlg, _("Please enter the name."),
561                             _("Key Generation Wizard"), MB_ERR);
562                    return FALSE;
563                }
564                if (strchr (utf8_name, '@')) {
565                    msg_box (dlg, _("Please do not enter the email address in the name field."),
566                             _("Key Generation Wizard"), MB_WARN);
567                    free_if_alloc (utf8_name);
568                    return FALSE;
569                }
570                if (!GetDlgItemText(dlg, IDC_KEYWIZARD_EMAIL, email, sizeof email-1 )
571                    || check_email_address (email)) {
572                    msg_box (dlg, _("Please enter a valid email address."),
573                             _("Key Generation Wizard"), MB_ERR);
574                    free_if_alloc (utf8_name);
575                    return FALSE;
576                }
577                if (strchr (email, '<') || strchr (email, '>')) {
578                    msg_box (dlg, _("Please do not add '<' or '>' to the email address."),
579                             _("Key Generation Wizard"), MB_WARN);
580                    free_if_alloc (utf8_name);
581                    return FALSE;
582                }
583                pass = request_passphrase2 (_("Key Generation"), PASSDLG_STRICT, &cancel);
584                if (cancel) {
585                    free_if_alloc (utf8_name);
586                    return FALSE;
587                }
588                if (IsDlgButtonChecked (dlg, IDC_KEYWIZARD_USERSA))
589                    pubkey_algo = GPG_KEYGEN_DSA_RSA;
590                p = gpg_genkey_params (pubkey_algo, DFAULT_KEYSIZE, utf8_name,
591                                         NULL, email, NULL, pass);
592                free_if_alloc (utf8_name);
593                keygen_cb_dlg_create();
594                err = gpg_genkey (p, keygen_cb, &fpr);
595                keygen_cb_dlg_destroy (1);
596                sfree_if_alloc (p);
597                sfree_if_alloc (pass);
598                if (err) {
599                    msg_box (dlg, gpgme_strerror( err ), _("Key Generation Wizard"), MB_ERR);
600                    free_if_alloc (fpr);
601                    return FALSE;
602                }
603                status_box (dlg, _("Key Generation completed"), _("GnuPG Status"));
604                keycache_update (0, fpr);
605                keycache_update (1, fpr);
606                free_if_alloc (fpr);
607    
608                backup_keyrings (dlg);
609                if (ctx)
610                    ctx->cancel = 0;            
611                EndDialog (dlg, TRUE);
612                break;
613    
614            case IDCANCEL:
615                if (ctx)
616                    ctx->cancel = 1;
617                EndDialog (dlg, FALSE);
618                break;
619            }
620            break;
621        }
622        return FALSE;
623    }

Legend:
Removed from v.12  
changed lines
  Added in v.225

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26