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

Annotation of /trunk/Src/wptKeysignDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 333 - (hide annotations)
Tue Oct 13 10:51:21 2009 UTC (15 years, 4 months ago) by twoaday
File size: 12483 byte(s)


1 werner 36 /* wptKeysignDlg.cpp - Key signing dialog
2 twoaday 328 * Copyright (C) 2001-2006, 2008-2009 Timo Schulz
3 werner 36 *
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 werner 42 #ifdef HAVE_CONFIG_H
17     #include <config.h>
18     #endif
19    
20 werner 36 #include <windows.h>
21     #include <commctrl.h>
22 twoaday 181 #include <time.h>
23 twoaday 229 #include <assert.h>
24 werner 36
25 werner 47 #include "resource.h"
26 werner 36 #include "wptGPG.h"
27     #include "wptNLS.h"
28     #include "wptW32API.h"
29     #include "wptVersion.h"
30     #include "wptTypes.h"
31     #include "wptErrors.h"
32     #include "wptCommonCtl.h"
33     #include "wptContext.h"
34     #include "wptDlgs.h"
35     #include "wptUTF8.h"
36     #include "wptRegistry.h"
37 werner 47 #include "wptKeylist.h"
38 werner 36 #include "wptKeyEdit.h"
39 twoaday 278 #include "StringBuffer.h"
40 werner 36
41    
42 twoaday 328 int key_load_photo (winpt_key_t key,
43     char *photo_file, size_t photo_file_size,
44     gpgme_validity_t *r_valid);
45     int get_photo_tmpname (gpgme_key_t key, char *buf, size_t buflen);
46 twoaday 226
47 werner 36 /* Return a beautified printable fingerprint of @fpr. */
48     static const char*
49     get_printable_fpr (const char *fpr)
50     {
51 twoaday 328 static char pfpr[128];
52 werner 36 int pos = 0;
53     size_t i;
54    
55 twoaday 328 memset (pfpr, 0, sizeof (pfpr));
56 werner 36 for (i = 0; i < strlen (fpr); i += 4) {
57     pfpr[pos++] = fpr[i];
58     pfpr[pos++] = fpr[i+1];
59     pfpr[pos++] = fpr[i+2];
60     pfpr[pos++] = fpr[i+3];
61     pfpr[pos++] = ' ';
62     }
63     return pfpr;
64     }
65    
66    
67     /* Return human friendly information about the key @key. */
68 twoaday 225 const char*
69 werner 36 get_keyinfo (gpgme_key_t key)
70     {
71     static char buf[64+16];
72     struct winpt_key_s k;
73    
74     memset (&k, 0, sizeof (k));
75 twoaday 225 if (winpt_get_seckey (key->subkeys->keyid, &k))
76     BUG (0);
77     _snprintf (buf, DIM (buf)-1-16, _("%d-bit %s key, ID 0x%s"),
78     key->subkeys->length,
79     get_key_pubalgo (key->subkeys->pubkey_algo),
80     key->subkeys->keyid+8);
81 werner 36 if (k.ext->gloflags.divert_to_card)
82 twoaday 328 strcat (buf, _(" (Card)"));
83 werner 36 return buf;
84     }
85    
86    
87     /* Fill the secret key combo-box with all entries from the cache.
88     @dlg is the handle to the combo-box. @keyid show which key to skip.
89     Return value: 0 on success. */
90     static int
91     do_fill_seckeylist (HWND dlg, const char *keyid)
92     {
93     gpg_keycache_t sec;
94 twoaday 167 gpgme_key_t pk, defkey;
95 twoaday 278 const char *s;
96     char *uid;
97 twoaday 167 int i = 0, n = 0, curr_sel = 0;
98 werner 36
99     sec = keycache_get_ctx (0);
100 twoaday 167 gpg_keycache_get_default_key (sec, &defkey);
101 werner 36 gpg_keycache_rewind (sec);
102     while (!gpg_keycache_next_key (sec, 1, &pk)) {
103 twoaday 278 StringBuffer p;
104    
105 werner 36 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 twoaday 167 if (defkey && !strcmp (defkey->subkeys->keyid, pk->subkeys->keyid))
120     curr_sel = i;
121 twoaday 278
122 twoaday 187 uid = utf8_to_native (s);
123 twoaday 278 p = uid;
124     p = p + " (" + get_keyinfo (pk) + ")";
125 twoaday 167 SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
126 twoaday 278 CB_ADDSTRING, i, (LPARAM)(char *)p.getBuffer ());
127 twoaday 167 SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
128     CB_SETITEMDATA, i++, (LPARAM)(DWORD)pk);
129 twoaday 225 safe_free (uid);
130 werner 36 n++;
131     }
132 twoaday 167 SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
133     CB_SETCURSEL, (WPARAM)curr_sel, 0);
134 werner 36 if (!n)
135     return -1;
136     return 0;
137     }
138    
139    
140    
141     /* Dialog box procedure to choose the signature class. */
142     BOOL CALLBACK
143     sig_class_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
144     {
145 twoaday 229 HWND parent;
146 twoaday 328
147 werner 36 switch (msg) {
148     case WM_INITDIALOG:
149 twoaday 229 parent = (HWND)lparam;
150 werner 36 SetWindowText (dlg, _("Choose Signature Class"));
151 twoaday 225 SetDlgItemText (dlg, IDC_SIGCLASS_TITLEINF,
152     _("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\"."));
153     SetDlgItemText (dlg, IDC_SIGCLASS_CLASS0,
154     _("(0) I will not answer (default)"));
155     SetDlgItemText (dlg, IDC_SIGCLASS_CLASS1,
156     _("(1) I have not checked at all."));
157     SetDlgItemText (dlg, IDC_SIGCLASS_CLASS2,
158     _("(2) I have done causal checking."));
159     SetDlgItemText (dlg, IDC_SIGCLASS_CLASS3,
160 twoaday 248 _("(3) I have done very careful checking."));
161 werner 36 CheckDlgButton (dlg, IDC_SIGCLASS_CLASS0, BST_CHECKED);
162     SetForegroundWindow (dlg);
163 twoaday 229 center_window (dlg, parent? parent : NULL);
164 twoaday 328 return TRUE;
165 werner 36
166     case WM_COMMAND:
167 twoaday 170 switch (LOWORD (wparam)) {
168 werner 36 case IDOK:
169 twoaday 328 int sig_class;
170    
171 werner 36 if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS0))
172 twoaday 170 sig_class = 0;
173 werner 36 else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS1))
174 twoaday 170 sig_class = 1;
175 werner 36 else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS2))
176 twoaday 170 sig_class = 2;
177 werner 36 else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS3))
178 twoaday 170 sig_class = 3;
179 werner 36 else
180 twoaday 170 sig_class = 0;
181     EndDialog (dlg, sig_class);
182 twoaday 328 break;
183 twoaday 170
184     case IDCANCEL:
185     EndDialog (dlg, 0);
186 twoaday 328 break;
187 werner 36 }
188     break;
189     }
190    
191     return FALSE;
192     }
193    
194    
195     /* Return the humand friendly expiration date of @key. */
196     static const char*
197     get_expire_date (gpgme_key_t key)
198     {
199     u32 u = key->subkeys->expires;
200     if (!u)
201     return _("never");
202     return get_key_expire_date (u);
203     }
204    
205 twoaday 225
206 twoaday 181 /* Check if the given system time @st points to today. */
207     static int
208     date_is_today (SYSTEMTIME *st)
209     {
210     time_t t;
211     struct tm *tm;
212    
213     t = time (NULL);
214     tm = localtime (&t);
215     if (st->wDay == tm->tm_mday &&
216     st->wYear == tm->tm_year+1900 &&
217     st->wMonth == tm->tm_mon+1)
218     return -1;
219     return 0;
220     }
221    
222    
223 twoaday 255 /* Display all needed information about the key @key in the dialog @dlg. */
224     static void
225 twoaday 333 display_keyinfo (HWND dlg, listview_ctrl_t list, winpt_key_t key)
226 twoaday 255 {
227 twoaday 278 StringBuffer kinf;
228 twoaday 255 struct native_uid_s *u;
229 twoaday 333 char tmp[256];
230 twoaday 278
231 twoaday 271 _snprintf (tmp, DIM (tmp) -1,
232 twoaday 256 _("pub %d/0x%s created: %s expires: %s\n\n"
233 twoaday 328 "Key fingerprint:\n%s\n\n"),
234 twoaday 255 key->ctx->subkeys->length,
235     key->ctx->subkeys->keyid+8,
236     get_key_created (key->ctx->subkeys->timestamp),
237     get_expire_date (key->ctx),
238 twoaday 278 get_printable_fpr (key->ctx->subkeys->fpr));
239 twoaday 333 kinf = tmp;
240     SetDlgItemText (dlg, IDC_KEYSIGN_INFOS, kinf.getBuffer ());
241    
242     for (u = key->ext->uids; u; u = u->next) {
243 twoaday 256 if (u->revoked)
244     continue;
245 twoaday 333 listview_add_item (list, "");
246     listview_add_sub_item (list, 0, 0, u->name);
247     listview_add_sub_item (list, 0, 1, u->email);
248 twoaday 255 }
249     }
250    
251    
252 twoaday 328 void set_gpg_auto_passphrase_cb (passphrase_cb_s *cb, const char *title);
253     gpgme_error_t passphrase_cb (void *hook, const char *uid_hint,
254     const char *passphrase_info,
255     int prev_was_bad, int fd);
256    
257 twoaday 278 /* Perform the actual procedure to sign the key. */
258     static BOOL
259     on_click_ok (HWND dlg, winpt_key_t key)
260 werner 36 {
261 twoaday 278 gpgme_key_t k;
262 werner 36 gpgme_error_t err;
263     SYSTEMTIME st;
264 twoaday 278 GpgKeyEdit ke;
265     int sig_class = 0;
266 twoaday 328 char keymsg[64];
267 werner 36 int type, expires=0, idx;
268 twoaday 278
269     if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_ASKLEVEL))
270     sig_class = dialog_box_param (glob_hinst,
271     (LPCSTR)IDD_WINPT_SIGCLASS, dlg,
272     sig_class_dlg_proc, (LPARAM)dlg,
273     _("Choose Signature Class"),
274     IDS_WINPT_SIGCLASS);
275     type = IsDlgButtonChecked (dlg, IDC_KEYSIGN_LOCAL);
276     if (type)
277     type = GPG_EDITKEY_LSIGN;
278     else
279     type = GPG_EDITKEY_SIGN;
280 twoaday 328
281 twoaday 278 if (reg_prefs.expert && IsDlgButtonChecked (dlg, IDC_KEYSIGN_NREV)) {
282     type = GPG_EDITKEY_NRSIGN;
283     if (type == GPG_EDITKEY_LSIGN)
284     type = GPG_EDITKEY_NRLSIGN;
285     }
286    
287     if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG)) {
288     DateTime_GetSystemtime (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), &st);
289     if (date_is_today (&st)) {
290 twoaday 328 show_balloon_msg (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES),
291     _("You cannot select today as the expiration date."),
292     IDI_WARNING);
293 twoaday 278 return TRUE;
294     }
295     else
296     expires = 1;
297     _snprintf (keymsg, DIM (keymsg)-1, "%04d-%02d-%02d",
298 twoaday 333 st.wYear, st.wMonth, st.wDay);
299 twoaday 278 }
300    
301 twoaday 333 if (key->ctx->subkeys->keyid == NULL)
302     BUG (0); /* should be always true. */
303 twoaday 278 ke.setKeyID (key->ctx->subkeys->keyid);
304 twoaday 328
305     passphrase_cb_s cb;
306 twoaday 333 set_gpg_auto_passphrase_cb (&cb, _("Key Edit"));
307 twoaday 328 ke.setPassphraseCallback (passphrase_cb, (void*)&cb);
308    
309     HWND klist = GetDlgItem (dlg, IDC_KEYSIGN_KEYLIST);
310     idx = SendMessage (klist, CB_GETCURSEL, 0, 0);
311 twoaday 333 k = (gpgme_key_t)SendMessage (klist, CB_GETITEMDATA, (WPARAM)idx, 0);
312 twoaday 278 if (k != NULL)
313     ke.setLocalUser (k);
314    
315 twoaday 328 err = ke.signKey (type, sig_class, expires? keymsg : "0");
316     release_gpg_passphrase_cb (&cb);
317 twoaday 333 if (cb.cancel)
318     return TRUE;
319     else if (err) {
320 twoaday 278 msg_box (dlg, gpgme_strerror (err), _("Key Signing"), MB_ERR);
321     return TRUE;
322     }
323 twoaday 328 else if (ke.getResult () != 0) {
324     show_balloon_msg (klist, _("This key is already signed by your key"),
325 twoaday 333 IDI_INFORMATION);
326 twoaday 328 return TRUE;
327     }
328 twoaday 278 else {
329     status_box (dlg, _("Key successfully signed."), _("Key Signing"));
330 twoaday 333 key->update = 1;
331 twoaday 278 }
332     EndDialog (dlg, TRUE);
333     return TRUE;
334     }
335    
336    
337 twoaday 333 static listview_ctrl_t
338     init_uidlist (HWND dlg)
339     {
340     struct listview_column_s cols[] = {
341     {0, 190, (char *)_("Name")},
342     {1, 150, (char *)_("E-Mail")}};
343    
344     listview_ctrl_t list;
345     listview_new (&list, GetDlgItem (dlg, IDC_KEYSIGN_UIDLIST));
346     listview_add_column (list, &cols[0]);
347     listview_add_column (list, &cols[1]);
348     return list;
349     }
350    
351    
352 twoaday 278 /* Dialog box procedure to sign a key. */
353     BOOL CALLBACK
354     keysign_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
355     {
356     static winpt_key_t key;
357 twoaday 333 static listview_ctrl_t list;
358 twoaday 328 char buf[MAX_PATH+128+1];
359 twoaday 278 const char *s;
360    
361 twoaday 177 switch (msg) {
362 werner 36 case WM_INITDIALOG:
363     key = (winpt_key_t) lparam;
364 twoaday 225 if (!key)
365 twoaday 255 BUG (0);
366 werner 36 s = key->ctx->subkeys->keyid;
367     if (do_fill_seckeylist (dlg, s)) {
368 twoaday 328 msg_box (dlg, _("No valid secret key found."),
369     _("Key Signing"), MB_ERR);
370 werner 36 EndDialog (dlg, FALSE);
371 twoaday 225 return TRUE;
372 twoaday 333 }
373     list = init_uidlist (dlg);
374     display_keyinfo (dlg, list, key);
375 werner 36 SetDlgItemText (dlg, IDC_KEYSIGN_LOCAL, _("Sign local only (non exportable signature)"));
376     SetDlgItemText (dlg, IDC_KEYSIGN_EXPSIG, _("Signature expires on"));
377     SetDlgItemText (dlg, IDC_KEYSIGN_NREV, _("Sign non-revocably"));
378     SetDlgItemText (dlg, IDC_KEYSIGN_ASKLEVEL, _("&Ask for certification level"));
379 twoaday 328 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
380     SetDlgItemText (dlg, IDC_KEYSIGN_CONFIRMSIGN, _("Are you really sure that you want to sign this key with YOUR key?"));
381 twoaday 225 SetWindowText (dlg, _("Key Signing"));
382 werner 36 CheckDlgButton (dlg, IDC_KEYSIGN_LOCAL, BST_CHECKED);
383     CheckDlgButton (dlg, IDC_KEYSIGN_EXPSIG, BST_UNCHECKED);
384     CheckDlgButton (dlg, IDC_KEYSIGN_ASKLEVEL, BST_UNCHECKED);
385     EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), FALSE);
386     if (reg_prefs.expert == 0)
387     ShowWindow (GetDlgItem (dlg, IDC_KEYSIGN_NREV), SW_HIDE);
388 twoaday 41 if (!reg_prefs.gpg.ask_cert_level)
389     EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_ASKLEVEL), FALSE);
390 twoaday 181 if (!reg_prefs.gpg.ask_cert_expire)
391     EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPSIG), FALSE);
392 twoaday 328 if (key->ext && key->ext->attrib.len > 0)
393     key_load_photo (key, buf, DIM(buf)-1, NULL);
394 twoaday 177 CheckDlgButton (dlg, IDC_KEYSIGN_HIDE, BST_CHECKED);
395 werner 36 SetForegroundWindow (dlg);
396 twoaday 328 SetFocus (GetDlgItem (dlg, IDOK));
397 werner 36 return FALSE;
398    
399 twoaday 328 case WM_DESTROY:
400     balloon_msg_disable ();
401     if (key->ext && key->ext->attrib.len > 0) {
402     get_photo_tmpname (key->ctx, buf, DIM(buf)-1);
403     DeleteFile (buf);
404     }
405 twoaday 333 if (list != NULL) {
406     listview_release (list);
407     list = NULL;
408     }
409 twoaday 328 break;
410    
411     case WM_PAINT:
412     if (key->ext != NULL && key->ext->attrib.len > 0) {
413     POINT p;
414     p.x = p.y = 0;
415     get_photo_tmpname (key->ctx, buf, DIM (buf)-1);
416     if (jpg_show (GetDlgItem (dlg, IDC_SHOWPHOTO_IMG), &p, buf))
417     EndDialog (dlg, TRUE);
418     }
419     break;
420    
421 werner 36 case WM_COMMAND:
422 twoaday 177 if (HIWORD (wparam) == BN_CLICKED &&
423     LOWORD (wparam) == IDC_KEYSIGN_EXPSIG) {
424 werner 36 int enable = IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG);
425 twoaday 328 EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES),
426     enable? TRUE : FALSE);
427 werner 36 }
428 twoaday 225
429 twoaday 170 switch (LOWORD (wparam)) {
430 werner 36 case IDOK:
431 twoaday 328 balloon_msg_disable ();
432 twoaday 278 return on_click_ok (dlg, key);
433 werner 36
434     case IDCANCEL:
435     EndDialog (dlg, FALSE);
436     return TRUE;
437     }
438     break;
439     }
440    
441     return FALSE;
442     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26