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

Legend:
Removed from v.2  
changed lines
  Added in v.211

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26