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

Diff of /trunk/Src/wptKeysignDlg.cpp

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

revision 33 by twoaday, Tue Oct 25 07:46:20 2005 UTC revision 256 by twoaday, Sat Aug 5 10:31:06 2006 UTC
# Line 1  Line 1 
1  /* wptKeysignDlg.cpp - Key signing dialog  /* wptKeysignDlg.cpp - Key signing dialog
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2006 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
6   * WinPT is free software; you can redistribute it and/or modify   * 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   * 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   * the Free Software Foundation; either version 2 of the License, or
9   * (at your option) any later version.   * (at your option) any later version.
10   *   *
11   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
15   *   *
16   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19   */   */
20    #ifdef HAVE_CONFIG_H
21  #include <windows.h>  #include <config.h>
22  #include <commctrl.h>  #endif
   
 #include "../resource.h"  
 #include "wptGPG.h"  
 #include "wptNLS.h"  
 #include "wptW32API.h"  
 #include "wptVersion.h"  
 #include "wptTypes.h"  
 #include "wptErrors.h"  
 #include "wptCommonCtl.h"  
 #include "wptContext.h"  
 #include "wptDlgs.h"  
 #include "wptUTF8.h"  
 #include "wptRegistry.h"  
 #include "wptKeyList.h"  
 #include "wptKeyEdit.h"  
   
 static int sig_class_choice = 0;  
   
 /* Return a beautified printable fingerprint of @fpr. */  
 static const char*  
 get_printable_fpr (const char *fpr)  
 {  
     static char pfpr[64];      
     int pos = 0;  
     size_t i;  
   
     for (i = 0; i < strlen (fpr); i += 4) {  
         pfpr[pos++] = fpr[i];  
         pfpr[pos++] = fpr[i+1];  
         pfpr[pos++] = fpr[i+2];  
         pfpr[pos++] = fpr[i+3];  
         pfpr[pos++] = ' ';  
     }  
     return pfpr;  
 }  
   
   
 /* Return human friendly information about the key @key. */  
 static const char*  
 get_keyinfo (gpgme_key_t key)  
 {  
     static char buf[64+16];  
     struct winpt_key_s k;  
   
     memset (&k, 0, sizeof (k));  
     winpt_get_seckey (key->subkeys->keyid, &k);  
     _snprintf (buf, DIM (buf)-1-16, "%d-bit %s key, ID %s",  
         key->subkeys->length,  
         get_key_pubalgo (key->subkeys->pubkey_algo),  
         key->subkeys->keyid+8);  
     if (k.ext->gloflags.divert_to_card)  
         strcat (buf, " (Card)");  
     return buf;  
 }  
   
   
 /* Fill the secret key combo-box with all entries from the cache.  
    @dlg is the handle to the combo-box. @keyid show which key to skip.  
    Return value: 0 on success. */  
 static int  
 do_fill_seckeylist (HWND dlg, const char *keyid)  
 {  
     gpg_keycache_t sec;  
     gpgme_key_t pk;  
     const char * s;  
     char * uid, * p;      
     int i = 0, n=0;  
   
     sec = keycache_get_ctx (0);  
     if (!sec)  
         BUG (0);  
     gpg_keycache_rewind (sec);  
     while (!gpg_keycache_next_key (sec, 1, &pk)) {  
         if (!pk)  
             continue;  
         s = pk->subkeys->keyid;  
         if (!strcmp (s, keyid))  
             continue;  
         /* skip all ElGamal sign+encrypt keys */  
         if (pk->subkeys->pubkey_algo == GPGME_PK_ELG)  
             continue;  
         /* make sure the public key is okay not: revoked, expired or disabled. */  
         if (pk->expired ||pk->revoked || pk->disabled)  
             continue;  
         s = pk->uids->name;  
         if (!s)  
             continue;  
         uid = utf8_to_wincp (s, strlen (s));  
         p = new char[strlen (uid) + 64];  
         if (!p)  
             BUG (NULL);  
         _snprintf (p, strlen (uid) + 63, "%s (%s)", uid, get_keyinfo (pk));  
         SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_ADDSTRING, i, (LPARAM)(char *)p);  
         SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_SETITEMDATA, i++, (LPARAM)(DWORD)pk);  
         free_if_alloc (p);  
         free (uid);  
         n++;  
     }  
     SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_SETCURSEL, 0, 0);  
     if (!n)  
         return -1;  
     return 0;  
 }  
   
   
 /* Check if the selected key is protected and en- or disable the  
    passphrase control. */  
 static void  
 do_check_protection (HWND dlg)  
 {  
     int idx, protec;  
     gpgme_key_t key;  
     struct winpt_key_s k;  
   
     idx = SendDlgItemMessage( dlg, IDC_KEYSIGN_KEYLIST, CB_GETCURSEL, 0, 0 );  
     key = (gpgme_key_t)SendDlgItemMessage( dlg, IDC_KEYSIGN_KEYLIST, CB_GETITEMDATA, (WPARAM)idx, 0 );  
     if (key) {  
         winpt_get_seckey (key->subkeys->keyid, &k);  
         protec = k.is_protected;  
         if (!protec)  
             protec = k.ext->gloflags.divert_to_card;  
         EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_PASSPHRASE), protec? TRUE : FALSE);  
     }  
 }  
   
   
 /* Dialog box procedure to choose the signature class. */  
 BOOL CALLBACK  
 sig_class_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  
 {  
     switch (msg) {  
     case WM_INITDIALOG:  
         SetWindowText (dlg, _("Choose Signature Class"));  
         SetDlgItemText (dlg, IDC_SIGCLASS_TITLEINF, _("How carefully have you verified the key you are about to sign actually belongs to the person? If you don't know what to anwser, use \"0\"."));  
         SetDlgItemText (dlg, IDC_SIGCLASS_CLASS0, _("(0) I will not answer (default)"));  
         SetDlgItemText (dlg, IDC_SIGCLASS_CLASS1, _("(1) I have not checked at all."));  
         SetDlgItemText (dlg, IDC_SIGCLASS_CLASS2, _("(2) I have done causal checking."));  
         SetDlgItemText (dlg, IDC_SIGCLASS_CLASS3, _("(3) I have done very careful checkings."));  
         CheckDlgButton (dlg, IDC_SIGCLASS_CLASS0, BST_CHECKED);  
         SetForegroundWindow (dlg);  
         center_window (dlg, NULL);  
         return TRUE;  
   
     case WM_COMMAND:  
         switch( LOWORD( wparam ) ) {  
         case IDOK:  
             if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS0))  
                 sig_class_choice = 0;  
             else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS1))  
                 sig_class_choice = 1;  
             else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS2))  
                 sig_class_choice = 2;  
             else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS3))  
                 sig_class_choice = 3;  
             else  
                 sig_class_choice = 0;  
             EndDialog (dlg, TRUE);  
             return TRUE;  
         }  
         break;  
     }  
   
     return FALSE;  
 }  
   
   
 /* Return the humand friendly expiration date of @key. */  
 static const char*  
 get_expire_date (gpgme_key_t key)  
 {  
     static char tmp[64];  
   
     u32 u = key->subkeys->expires;  
     if (!u)  
         return _("never");  
     return get_key_expire_date (u);  
 }  
   
 /* Display photo of key @key in a separate window. */  
 static void  
 show_photo (winpt_key_t key)  
 {  
     /* XXX: fill it with life. */  
 }  
   
   
 /* Dialog box procedure to sign a key. */  
 BOOL CALLBACK  
 keysign_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  
 {  
     static winpt_key_t key;  
     GpgKeyEdit *ke;  
     gpgme_error_t err;  
     gpgme_key_t k;  
     SYSTEMTIME st;  
     HWND h;  
     char keymsg[2048], pwd[256];  
     char *uid = NULL;  
     const char *keyid, *s;  
     int type, expires=0, idx;  
       
     switch ( msg )  {  
     case WM_INITDIALOG:  
         if (lparam == NULL)  
             dlg_fatal_error (dlg, "Could not get dialog param.");  
         #ifndef LANG_DE  
         SetWindowText (dlg, _("Key Signing"));  
         #endif  
         key = (winpt_key_t) lparam;  
         s = key->ctx->uids->uid;  
         uid = utf8_to_wincp (s, strlen (s));  
         _snprintf (keymsg, sizeof keymsg -1,  
                    _("pub %d/%s  created: %s    expires: %s\n\n"  
                      "Primary key fingerprint: %s\n\n"  
                      "\t%s\n\n"  
                      "\nAre you really sure that you want to sign this key with YOUR key?\n"),  
                    key->ctx->subkeys->length,  
                    key->ctx->subkeys->keyid+8,  
                    get_key_created (key->ctx->subkeys->timestamp),  
                    get_expire_date (key->ctx),  
                    get_printable_fpr (key->ctx->subkeys->fpr),  
                    uid);  
         free (uid);  
         s = key->ctx->subkeys->keyid;  
         if (do_fill_seckeylist (dlg, s)) {  
             msg_box (dlg, _("No valid secret key found."), _("Key Signing"), MB_ERR);  
             EndDialog (dlg, FALSE);  
         }  
         SetDlgItemText (dlg, IDC_KEYSIGN_INFOS, keymsg);  
         #ifndef LANG_DE  
         SetDlgItemText (dlg, IDC_KEYSIGN_LOCAL, _("Sign local only (non exportable signature)"));  
         SetDlgItemText (dlg, IDC_KEYSIGN_EXPSIG, _("Signature expires on"));  
         SetDlgItemText (dlg, IDC_KEYSIGN_NREV, _("Sign non-revocably"));  
         SetDlgItemText (dlg, IDC_KEYSIGN_ASKLEVEL, _("&Ask for certification level"));  
         SetDlgItemText (dlg, IDC_KEYSIGN_PWDINF, _("Passphrase"));  
         #endif  
         CheckDlgButton (dlg, IDC_KEYSIGN_LOCAL, BST_CHECKED);  
         CheckDlgButton (dlg, IDC_KEYSIGN_EXPSIG, BST_UNCHECKED);  
         CheckDlgButton (dlg, IDC_KEYSIGN_ASKLEVEL, BST_UNCHECKED);  
         EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), FALSE);  
         if (reg_prefs.expert == 0)  
             ShowWindow (GetDlgItem (dlg, IDC_KEYSIGN_NREV), SW_HIDE);  
         if (key->ext && key->ext->attrib.len > 0)  
             EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_SHOWIMG), TRUE);  
         SetForegroundWindow (dlg);  
         h = GetDlgItem (dlg, IDC_KEYSIGN_PASSPHRASE);  
         SetFocus (h);  
         return FALSE;  
       
     case WM_DESTROY:  
         sig_class_choice = 0;  
         break;  
   
     case WM_SYSCOMMAND:  
         if( LOWORD( wparam ) == SC_CLOSE ) {  
             SetDlgItemText( dlg, IDC_KEYSIGN_PASSPHRASE, "" );  
             EndDialog( dlg, TRUE );  
         }  
         return FALSE;  
           
     case WM_COMMAND:  
         if (HIWORD( wparam ) == CBN_SELCHANGE) {  
             do_check_protection (dlg);  
             break;  
         }  
         if (HIWORD (wparam) == BN_CLICKED && LOWORD (wparam) == IDC_KEYSIGN_EXPSIG) {  
             int enable = IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG);  
             EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), enable? TRUE : FALSE);  
         }  
   
         switch( LOWORD( wparam ) ) {  
         case IDOK:  
             if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_ASKLEVEL))  
                 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_SIGCLASS, dlg,  
                                   sig_class_dlg_proc, (LPARAM)NULL,  
                                   _("Choose Signature Class"),  IDS_WINPT_SIGCLASS);  
             type = IsDlgButtonChecked (dlg, IDC_KEYSIGN_LOCAL);  
             if (type)  
                 type = GPG_EDITKEY_LSIGN;  
             else  
                 type = GPG_EDITKEY_SIGN;  
   
             if (reg_prefs.expert && IsDlgButtonChecked (dlg, IDC_KEYSIGN_NREV)) {  
                 type = GPG_EDITKEY_NRSIGN;  
                 if (type == GPG_EDITKEY_LSIGN)  
                     type = GPG_EDITKEY_NRLSIGN;  
             }  
             if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG)) {  
                 expires = 1;  
                 DateTime_GetSystemtime (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), &st);  
                 sprintf (keymsg, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);  
             }  
   
             /* XXX: check for --ask-cert-level and --ask-cert-expire in the gpg.conf  
                     if an advanced button is checked and offer to add it to the config  
                     file. */  
   
             GetDlgItemText( dlg, IDC_KEYSIGN_PASSPHRASE, pwd, DIM (pwd)-1);  
             keyid = key->ctx->subkeys->keyid;  
             if( !keyid ) {  
                 msg_box( dlg, _("Could not get Key ID from key."), _("Key Signing"), MB_ERR );  
                 return TRUE;  
             }  
             ke = new GpgKeyEdit (keyid);  
             if (!ke)  
                 BUG (NULL);  
             ke->setPassphrase (pwd);  
             idx = SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_GETCURSEL, 0, 0);  
             k = (gpgme_key_t)SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,  
                                                  CB_GETITEMDATA, (WPARAM)idx, 0);  
             if (k)  
                 ke->setLocalUser (k);  
   
             err = ke->signKey (type, sig_class_choice, expires? keymsg : "0");  
             memset (&pwd, 0, sizeof pwd);            
             if (err) {  
                 delete ke;  
                 msg_box (dlg, gpgme_strerror (err), _("Key Signing"), MB_ERR);  
                 return TRUE;  
             }  
             if (ke->getResult () != 0)  
                 msg_box (dlg, _("This key is already signed by your key"), _("Key Signing"), MB_INFO);  
             else {  
                 status_box (dlg, _("Key successfully signed."), PGM_NAME);  
                 key->update = 1;  
             }  
             delete ke;  
             EndDialog (dlg, TRUE);  
             return TRUE;  
               
         case IDCANCEL:  
             EndDialog (dlg, FALSE);  
             return TRUE;  
   
         case IDC_KEYSIGN_SHOWIMG:  
             show_photo (key);  
             return TRUE;  
         }  
         break;  
     }  
       
     return FALSE;  
 }  
23    
24    #include <windows.h>
25    #include <commctrl.h>
26    #include <time.h>
27    #include <assert.h>
28    
29    #include "resource.h"
30    #include "wptGPG.h"
31    #include "wptNLS.h"
32    #include "wptW32API.h"
33    #include "wptVersion.h"
34    #include "wptTypes.h"
35    #include "wptErrors.h"
36    #include "wptCommonCtl.h"
37    #include "wptContext.h"
38    #include "wptDlgs.h"
39    #include "wptUTF8.h"
40    #include "wptRegistry.h"
41    #include "wptKeylist.h"
42    #include "wptKeyEdit.h"
43    
44    
45    void key_unload_photo (HWND dlg);
46    int  key_load_photo (HWND dlg, gpgme_key_t key, gpgme_validity_t *r_valid);
47    const char* get_photo_tmpname (HWND dlg);
48    
49    /* Return a beautified printable fingerprint of @fpr. */
50    static const char*
51    get_printable_fpr (const char *fpr)
52    {
53        static char pfpr[64];
54        int pos = 0;
55        size_t i;
56    
57        for (i = 0; i < strlen (fpr); i += 4) {
58            pfpr[pos++] = fpr[i];
59            pfpr[pos++] = fpr[i+1];
60            pfpr[pos++] = fpr[i+2];
61            pfpr[pos++] = fpr[i+3];
62            pfpr[pos++] = ' ';
63        }
64        return pfpr;
65    }
66    
67    
68    /* Return human friendly information about the key @key. */
69    const char*
70    get_keyinfo (gpgme_key_t key)
71    {
72        static char buf[64+16];
73        struct winpt_key_s k;
74    
75        memset (&k, 0, sizeof (k));
76        if (winpt_get_seckey (key->subkeys->keyid, &k))
77            BUG (0);
78        _snprintf (buf, DIM (buf)-1-16, _("%d-bit %s key, ID 0x%s"),
79                   key->subkeys->length,
80                   get_key_pubalgo (key->subkeys->pubkey_algo),
81                   key->subkeys->keyid+8);
82        if (k.ext->gloflags.divert_to_card)
83            strcat (buf, " (Card)");
84        return buf;
85    }
86    
87    
88    /* Fill the secret key combo-box with all entries from the cache.
89       @dlg is the handle to the combo-box. @keyid show which key to skip.
90       Return value: 0 on success. */
91    static int
92    do_fill_seckeylist (HWND dlg, const char *keyid)
93    {
94        gpg_keycache_t sec;
95        gpgme_key_t pk, defkey;
96        const char *s, *inf;
97        char *uid, *p;
98        int i = 0, n = 0, curr_sel = 0;
99        int len = 0;
100    
101        sec = keycache_get_ctx (0);
102        gpg_keycache_get_default_key (sec, &defkey);
103        gpg_keycache_rewind (sec);
104        while (!gpg_keycache_next_key (sec, 1, &pk)) {
105            if (!pk)
106                continue;
107            s = pk->subkeys->keyid;
108            if (!strcmp (s, keyid))
109                continue;
110            /* skip all ElGamal sign+encrypt keys */
111            if (pk->subkeys->pubkey_algo == GPGME_PK_ELG)
112                continue;
113            /* make sure the public key is okay not: revoked, expired or disabled. */
114            if (pk->expired ||pk->revoked || pk->disabled)
115                continue;
116            s = pk->uids->name;
117            if (!s)
118                continue;
119            if (defkey && !strcmp (defkey->subkeys->keyid, pk->subkeys->keyid))
120                curr_sel = i;
121            uid = utf8_to_native (s);
122            inf = get_keyinfo (pk);
123            len = strlen (uid) + strlen (inf) + 8;
124            p = new char[len+1];
125            if (!p)
126                BUG (NULL);
127            _snprintf (p, len, "%s (%s)", uid, inf);
128            SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
129                                CB_ADDSTRING, i, (LPARAM)(char *)p);
130            SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
131                                CB_SETITEMDATA, i++, (LPARAM)(DWORD)pk);
132            free_if_alloc (p);
133            safe_free (uid);
134            n++;
135        }
136        SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
137                            CB_SETCURSEL, (WPARAM)curr_sel, 0);
138        if (!n)
139            return -1;
140        return 0;
141    }
142    
143    
144    /* Check if the selected key is protected and en- or disable the
145       passphrase control. */
146    static void
147    do_check_protection (HWND dlg)
148    {
149        gpgme_key_t key;
150        struct winpt_key_s k;
151        int idx, protec;    
152    
153        idx = SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_GETCURSEL, 0, 0);
154        key = (gpgme_key_t)SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
155                                               CB_GETITEMDATA, (WPARAM)idx, 0);
156        if (key) {
157            if (winpt_get_seckey (key->subkeys->keyid, &k))
158                BUG (0);
159            protec = k.is_protected;
160            if (!protec)
161                protec = k.ext->gloflags.divert_to_card;
162            EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_PASSPHRASE), protec? TRUE : FALSE);
163        }
164    }
165    
166    
167    /* Show the photographic ID of the key in a separate dialog window. */
168    BOOL CALLBACK
169    showphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
170    {
171        static winpt_key_t key;
172        char buf[200];
173    
174        switch (msg) {
175        case WM_INITDIALOG:
176            key = (winpt_key_t)lparam;
177            if (!key)
178                BUG (0);
179            key_load_photo (dlg, key->ctx, NULL);
180            _snprintf (buf, sizeof (buf)-1, _("Photo of %s"), key->uid);
181            SetWindowText (dlg, buf);
182            SetForegroundWindow (dlg);
183            break;
184    
185        case WM_PAINT:
186            if (key->ext && key->ext->attrib.len > 0) {
187                POINT p;
188                p.x = p.y = 0;
189                PTD_jpg_show (GetDlgItem (dlg, IDC_SHOWPHOTO_IMG),
190                                &p, get_photo_tmpname (dlg));
191            }
192            break;
193    
194        case WM_DESTROY:
195            key_unload_photo (dlg);
196            break;
197    
198        case WM_COMMAND:
199            switch (LOWORD (wparam)) {
200            case IDCANCEL:
201            case IDOK:
202                EndDialog (dlg, TRUE);
203                break;
204            }
205            break;
206        }
207    
208        return FALSE;
209    }
210    
211    
212    /* Dialog box procedure to choose the signature class. */
213    BOOL CALLBACK
214    sig_class_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
215    {
216        HWND parent;
217        int sig_class = 0;
218    
219        switch (msg) {
220        case WM_INITDIALOG:
221            parent = (HWND)lparam;
222            SetWindowText (dlg, _("Choose Signature Class"));
223            SetDlgItemText (dlg, IDC_SIGCLASS_TITLEINF,
224                            _("How carefully have you verified the key you are about to sign actually belongs to the person? If you don't know what to anwser, use \"0\"."));
225            SetDlgItemText (dlg, IDC_SIGCLASS_CLASS0,
226                            _("(0) I will not answer (default)"));
227            SetDlgItemText (dlg, IDC_SIGCLASS_CLASS1,
228                            _("(1) I have not checked at all."));
229            SetDlgItemText (dlg, IDC_SIGCLASS_CLASS2,
230                            _("(2) I have done causal checking."));
231            SetDlgItemText (dlg, IDC_SIGCLASS_CLASS3,
232                            _("(3) I have done very careful checking."));
233            CheckDlgButton (dlg, IDC_SIGCLASS_CLASS0, BST_CHECKED);
234            SetForegroundWindow (dlg);
235            center_window (dlg, parent? parent : NULL);
236            return TRUE;
237    
238        case WM_COMMAND:
239            switch (LOWORD (wparam)) {
240            case IDOK:
241                if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS0))
242                    sig_class = 0;
243                else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS1))
244                    sig_class = 1;
245                else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS2))
246                    sig_class = 2;
247                else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS3))
248                    sig_class = 3;
249                else
250                    sig_class = 0;
251                EndDialog (dlg, sig_class);
252                return TRUE;
253    
254            case IDCANCEL:
255                EndDialog (dlg, 0);
256                return TRUE;
257            }
258            break;
259        }
260    
261        return FALSE;
262    }
263    
264    
265    /* Return the humand friendly expiration date of @key. */
266    static const char*
267    get_expire_date (gpgme_key_t key)
268    {
269        u32 u = key->subkeys->expires;
270        if (!u)
271            return _("never");
272        return get_key_expire_date (u);
273    }
274    
275    
276    /* Check if the given system time @st points to today. */
277    static int
278    date_is_today (SYSTEMTIME *st)
279    {
280        time_t t;
281        struct tm *tm;
282    
283        t = time (NULL);
284        tm = localtime (&t);
285        if (st->wDay == tm->tm_mday &&
286            st->wYear == tm->tm_year+1900 &&
287            st->wMonth == tm->tm_mon+1)
288            return -1;
289        return 0;
290    }
291    
292    
293    /* Display all needed information about the key @key in the dialog @dlg. */
294    static void
295    display_keyinfo (HWND dlg, winpt_key_t key)
296    {
297        gpgme_data_t kinf;
298        struct native_uid_s *u;
299        char tmp[256], *p;
300        size_t len;
301    
302        gpgme_data_new (&kinf);
303        _snprintf (tmp, sizeof (tmp) -1,
304                       _("pub %d/0x%s   created: %s    expires: %s\n\n"
305                         "Primary key fingerprint: %s\n\n"),
306                       key->ctx->subkeys->length,
307                       key->ctx->subkeys->keyid+8,
308                       get_key_created (key->ctx->subkeys->timestamp),
309                       get_expire_date (key->ctx),
310                       get_printable_fpr (key->ctx->subkeys->fpr));
311        gpgme_data_write (kinf, tmp, strlen (tmp));
312        for (len=0, u = key->ext->uids; u; u = u->next) {
313            if (u->revoked)
314                continue;
315            if (len++ > 2)
316                break;
317            gpgme_data_write (kinf, "\t\"", 2);
318            gpgme_data_write (kinf, u->uid, strlen (u->uid));
319            gpgme_data_write (kinf, "\"\n", 2);
320        }
321        p = (char*)_("\n\nAre you really sure that you want to sign this key with YOUR key?\n");
322        gpgme_data_write (kinf, p, strlen (p));
323        gpgme_data_write (kinf, "\0", 1);
324        p = gpgme_data_release_and_get_mem (kinf, &len);
325        SetDlgItemText (dlg, IDC_KEYSIGN_INFOS, p);
326        gpgme_free (p);
327    }
328    
329    
330    /* Dialog box procedure to sign a key. */
331    BOOL CALLBACK
332    keysign_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
333    {
334        static winpt_key_t key;
335        GpgKeyEdit *ke;
336        gpgme_error_t err;
337        gpgme_key_t k;
338        SYSTEMTIME st;
339        char keymsg[64], *pwd;
340        const char *keyid, *s;
341        int type, expires=0, idx;
342        int sig_class = 0;
343        
344        switch (msg)  {
345        case WM_INITDIALOG:
346            key = (winpt_key_t) lparam;
347            if (!key)
348                BUG (0);        
349            s = key->ctx->subkeys->keyid;
350            if (do_fill_seckeylist (dlg, s)) {
351                msg_box (dlg, _("No valid secret key found."), _("Key Signing"), MB_ERR);
352                EndDialog (dlg, FALSE);
353                return TRUE;
354            }
355            do_check_protection (dlg);
356            display_keyinfo (dlg, key);
357            SetDlgItemText (dlg, IDC_KEYSIGN_LOCAL, _("Sign local only (non exportable signature)"));
358            SetDlgItemText (dlg, IDC_KEYSIGN_EXPSIG, _("Signature expires on"));
359            SetDlgItemText (dlg, IDC_KEYSIGN_NREV, _("Sign non-revocably"));
360            SetDlgItemText (dlg, IDC_KEYSIGN_ASKLEVEL, _("&Ask for certification level"));
361            SetDlgItemText (dlg, IDC_KEYSIGN_PWDINF, _("Passphrase"));
362            SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
363            SetDlgItemText (dlg, IDC_KEYSIGN_SHOWIMG, _("&Show photo"));
364            SetDlgItemText (dlg, IDC_KEYSIGN_HIDE, _("&Hide Typing"));
365            SetWindowText (dlg, _("Key Signing"));
366            CheckDlgButton (dlg, IDC_KEYSIGN_LOCAL, BST_CHECKED);
367            CheckDlgButton (dlg, IDC_KEYSIGN_EXPSIG, BST_UNCHECKED);
368            CheckDlgButton (dlg, IDC_KEYSIGN_ASKLEVEL, BST_UNCHECKED);
369            EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), FALSE);
370            if (reg_prefs.expert == 0)
371                ShowWindow (GetDlgItem (dlg, IDC_KEYSIGN_NREV), SW_HIDE);
372            if (key->ext && key->ext->attrib.len == 0)
373                ShowWindow (GetDlgItem (dlg, IDC_KEYSIGN_SHOWIMG), SW_HIDE);
374            if (!reg_prefs.gpg.ask_cert_level)
375                EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_ASKLEVEL), FALSE);
376            if (!reg_prefs.gpg.ask_cert_expire)
377                EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPSIG), FALSE);
378            CheckDlgButton (dlg, IDC_KEYSIGN_HIDE, BST_CHECKED);
379            SetForegroundWindow (dlg);
380            SetFocus (GetDlgItem (dlg, IDC_KEYSIGN_PASSPHRASE));
381            return FALSE;
382            
383        case WM_COMMAND:
384            if (HIWORD (wparam) == CBN_SELCHANGE) {
385                do_check_protection (dlg);
386                break;
387            }
388            if (HIWORD (wparam) == BN_CLICKED &&
389                LOWORD (wparam) == IDC_KEYSIGN_EXPSIG) {
390                int enable = IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG);
391    
392                EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), enable? TRUE : FALSE);
393            }
394            if (HIWORD (wparam) == BN_CLICKED &&
395                LOWORD (wparam) == IDC_KEYSIGN_HIDE) {
396                HWND hwnd = GetDlgItem (dlg, IDC_KEYSIGN_PASSPHRASE);
397                int hide = IsDlgButtonChecked (dlg, IDC_KEYSIGN_HIDE);
398    
399                SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
400                SetFocus (hwnd);
401            }
402    
403            switch (LOWORD (wparam)) {
404            case IDOK:
405                if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_ASKLEVEL))
406                    sig_class = dialog_box_param (glob_hinst,
407                                                  (LPCSTR)IDD_WINPT_SIGCLASS, dlg,
408                                                  sig_class_dlg_proc, (LPARAM)dlg,
409                                                  _("Choose Signature Class"),
410                                                  IDS_WINPT_SIGCLASS);
411                type = IsDlgButtonChecked (dlg, IDC_KEYSIGN_LOCAL);
412                if (type)
413                    type = GPG_EDITKEY_LSIGN;
414                else
415                    type = GPG_EDITKEY_SIGN;
416    
417                if (reg_prefs.expert && IsDlgButtonChecked (dlg, IDC_KEYSIGN_NREV)) {
418                    type = GPG_EDITKEY_NRSIGN;
419                    if (type == GPG_EDITKEY_LSIGN)
420                        type = GPG_EDITKEY_NRLSIGN;
421                }
422                if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG)) {
423                    DateTime_GetSystemtime (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), &st);
424                    if (date_is_today (&st)) {
425                        msg_box (dlg, _("You cannot select today as the expiration date."),
426                                 _("Key Signing"), MB_INFO);
427                        return TRUE;
428                    }
429                    else
430                        expires = 1;
431                    _snprintf (keymsg, sizeof (keymsg)-1, "%04d-%02d-%02d",
432                               st.wYear, st.wMonth, st.wDay);
433                }
434    
435                /* XXX: check for --ask-cert-level and --ask-cert-expire in the gpg.conf
436                        if an advanced button is checked and offer to add it to the config
437                        file. */
438    
439                GetDlgItemText_utf8 (dlg, IDC_KEYSIGN_PASSPHRASE, &pwd);
440                keyid = key->ctx->subkeys->keyid;
441                assert (keyid != NULL); /* should be always true. */
442                ke = new GpgKeyEdit (keyid);
443                if (!ke)
444                    BUG (NULL);
445                ke->setPassphrase (pwd);
446                idx = SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_GETCURSEL, 0, 0);
447                k = (gpgme_key_t)SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
448                                                     CB_GETITEMDATA, (WPARAM)idx, 0);
449                if (k)
450                    ke->setLocalUser (k);
451    
452                err = ke->signKey (type, sig_class, expires? keymsg : "0");
453                sfree_if_alloc (pwd);
454                if (err) {
455                    delete ke;
456                    msg_box (dlg, gpgme_strerror (err), _("Key Signing"), MB_ERR);
457                    return TRUE;
458                }
459                if (ke->getResult () != 0) {
460                    msg_box (dlg, _("This key is already signed by your key"),
461                             _("Key Signing"), MB_INFO);
462                    delete ke;
463                    return TRUE;
464                }
465                else {
466                    status_box (dlg, _("Key successfully signed."), _("Key Signing"));
467                    key->update = 1;
468                }
469                delete ke;
470                EndDialog (dlg, TRUE);
471                return TRUE;
472                
473            case IDCANCEL:
474                EndDialog (dlg, FALSE);
475                return TRUE;
476    
477            case IDC_KEYSIGN_SHOWIMG:
478                DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_SHOWPHOTO,
479                                dlg, showphoto_dlg_proc, (LPARAM)key);
480                return TRUE;
481            }
482            break;
483        }
484        
485        return FALSE;
486    }

Legend:
Removed from v.33  
changed lines
  Added in v.256

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26