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

Contents of /trunk/Src/wptKeysignDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File size: 10773 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


1 /* wptKeysignDlg.cpp - Key signing dialog
2 * Copyright (C) 2001-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
21 #include <windows.h>
22 #include <commctrl.h>
23
24 #include "../resource.h"
25 #include "wptGPG.h"
26 #include "wptNLS.h"
27 #include "wptW32API.h"
28 #include "wptVersion.h"
29 #include "wptTypes.h"
30 #include "wptErrors.h"
31 #include "wptCommonCtl.h"
32 #include "wptContext.h"
33 #include "wptDlgs.h"
34 #include "wptUTF8.h"
35 #include "wptRegistry.h"
36 #include "wptKeyList.h"
37 #include "wptKeyEdit.h"
38
39 static int sig_class_choice = 0;
40
41 /* Return a beautified printable fingerprint of @fpr. */
42 static const char*
43 get_printable_fpr (const char *fpr)
44 {
45 static char pfpr[64];
46 int pos = 0;
47 size_t i;
48
49 for (i = 0; i < strlen (fpr); i += 4) {
50 pfpr[pos++] = fpr[i];
51 pfpr[pos++] = fpr[i+1];
52 pfpr[pos++] = fpr[i+2];
53 pfpr[pos++] = fpr[i+3];
54 pfpr[pos++] = ' ';
55 }
56 return pfpr;
57 }
58
59
60 /* Return human friendly information about the key @key. */
61 static const char*
62 get_keyinfo (gpgme_key_t key)
63 {
64 static char buf[64+16];
65
66 _snprintf (buf, DIM (buf)-1-16, "%d-bit %s key, ID %s",
67 key->subkeys->length,
68 key->subkeys->pubkey_algo,
69 key->subkeys->keyid+8);
70 // XXX
71 //if (gpgme_key_get_ulong_attr (key, GPGME_ATTR_DIVERT_CARD, NULL, 0))
72 // strcat (buf, " (Card)");
73 return buf;
74 }
75
76
77 /* Fill the secret key combo-box with all entries from the cache.
78 @dlg is the handle to the combo-box. @keyid show which key to skip.
79 Return value: 0 on success. */
80 static int
81 do_fill_seckeylist (HWND dlg, const char *keyid)
82 {
83 gpgme_keycache_t sec;
84 gpgme_key_t pk;
85 const char * s;
86 char * uid, * p;
87 int i = 0, n=0;
88
89 sec = keycache_get_ctx (0);
90 if (!sec)
91 BUG (0);
92 gpgme_keycache_rewind (sec);
93 while (!gpgme_keycache_next_key (sec, 1, &pk)) {
94 if (!pk)
95 continue;
96 s = pk->subkeys->keyid;
97 if (!strcmp (s, keyid))
98 continue;
99 /* skip all ElGamal sign+encrypt keys */
100 if (pk->subkeys->pubkey_algo == GPGME_PK_ELG)
101 continue;
102 /* make sure the public key is okay not: revoked, expired or disabled. */
103 if (pk->expired ||pk->revoked || pk->disabled)
104 continue;
105 s = pk->uids->name;
106 if (!s)
107 continue;
108 uid = utf8_to_wincp (s, strlen (s));
109 p = new char[strlen (uid) + 64];
110 if (!p)
111 BUG (NULL);
112 _snprintf (p, strlen (uid) + 63, "%s (%s)", uid, get_keyinfo (pk));
113 SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_ADDSTRING, i, (LPARAM)(char *)p);
114 SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_SETITEMDATA, i++, (LPARAM)(DWORD)pk);
115 free_if_alloc (p);
116 free (uid);
117 n++;
118 }
119 SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_SETCURSEL, 0, 0);
120 if (!n)
121 return -1;
122 return 0;
123 }
124
125
126 /* Check if the selected key is protected and en- or disable the
127 passphrase control. */
128 static void
129 do_check_protection (HWND dlg)
130 {
131 int idx, protec;
132 gpgme_key_t key;
133 struct winpt_key_s k;
134
135 idx = SendDlgItemMessage( dlg, IDC_KEYSIGN_KEYLIST, CB_GETCURSEL, 0, 0 );
136 key = (gpgme_key_t)SendDlgItemMessage( dlg, IDC_KEYSIGN_KEYLIST, CB_GETITEMDATA, (WPARAM)idx, 0 );
137 if (key) {
138 winpt_get_seckey (key->subkeys->keyid, &k);
139 protec = k.is_protected;
140 if (!protec)
141 protec = k.ext->gloflags.divert_to_card;
142 EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_PASSPHRASE), protec? TRUE : FALSE);
143 }
144 }
145
146
147 /* Dialog box procedure to choose the signature class. */
148 BOOL CALLBACK
149 sig_class_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
150 {
151 switch (msg) {
152 case WM_INITDIALOG:
153 SetWindowText (dlg, _("Choose Signature Class"));
154 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\"."));
155 SetDlgItemText (dlg, IDC_SIGCLASS_CLASS0, _("(0) I will not answer (default)"));
156 SetDlgItemText (dlg, IDC_SIGCLASS_CLASS1, _("(1) I have not checked at all."));
157 SetDlgItemText (dlg, IDC_SIGCLASS_CLASS2, _("(2) I have done causal checking."));
158 SetDlgItemText (dlg, IDC_SIGCLASS_CLASS3, _("(3) I have done very careful checkings."));
159 CheckDlgButton (dlg, IDC_SIGCLASS_CLASS0, BST_CHECKED);
160 SetForegroundWindow (dlg);
161 center_window (dlg, NULL);
162 return TRUE;
163
164 case WM_COMMAND:
165 switch( LOWORD( wparam ) ) {
166 case IDOK:
167 if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS0))
168 sig_class_choice = 0;
169 else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS1))
170 sig_class_choice = 1;
171 else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS2))
172 sig_class_choice = 2;
173 else if (IsDlgButtonChecked (dlg, IDC_SIGCLASS_CLASS3))
174 sig_class_choice = 3;
175 else
176 sig_class_choice = 0;
177 EndDialog (dlg, TRUE);
178 return TRUE;
179 }
180 break;
181 }
182
183 return FALSE;
184 }
185
186
187 /* Return the humand friendly expiration date of @key. */
188 static const char*
189 get_expire_date (gpgme_key_t key)
190 {
191 static char tmp[64];
192
193 u32 u = key->subkeys->expires;
194 if (!u)
195 return "never";
196 return get_key_expire_date (u);
197 }
198
199
200 /* Dialog box procedure to sign a key. */
201 BOOL CALLBACK
202 keysign_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
203 {
204 static winpt_key_t key;
205 GpgKeyEdit *ke;
206 gpgme_error_t err;
207 gpgme_key_t k;
208 SYSTEMTIME st;
209 HWND h;
210 char keymsg[4096], pwd[256], *uid = NULL;
211 const char *keyid, *s;
212 u32 created;
213 int type, expires=0, idx;
214
215 switch ( msg ) {
216 case WM_INITDIALOG:
217 if (lparam == NULL)
218 dlg_fatal_error (dlg, "Could not get dialog param.");
219 #ifndef LANG_DE
220 SetWindowText (dlg, _("Key Signing"));
221 #endif
222 key = (winpt_key_t) lparam;
223 created = key->ctx->subkeys->timestamp;
224 s = key->ctx->uids->uid;
225 if (s)
226 uid = utf8_to_wincp (s, strlen (s));
227 _snprintf (keymsg, sizeof keymsg -1,
228 _("pub %d/%s created: %s expires: %s\n\n"
229 "Primary key fingerprint: %s\n\n"
230 "\t%s\n\n"
231 "\nAre you really sure that you want to sign this key with YOUR key?\n"),
232 key->ctx->subkeys->length,
233 key->ctx->subkeys->keyid+8,
234 get_key_created (key->ctx->subkeys->timestamp),
235 get_expire_date (key->ctx),
236 get_printable_fpr (key->ctx->subkeys->fpr),
237 uid);
238 free (uid);
239 s = key->ctx->subkeys->keyid;
240 if (do_fill_seckeylist (dlg, s)) {
241 msg_box( dlg, _("No valid secret key found."), _("Key Signing"), MB_ERR );
242 EndDialog( dlg, FALSE );
243 }
244 SetDlgItemText (dlg, IDC_KEYSIGN_INFOS, keymsg);
245 #ifndef LANG_DE
246 SetDlgItemText (dlg, IDC_KEYSIGN_LOCAL, _("Sign local only (non exportable signature)"));
247 SetDlgItemText (dlg, IDC_KEYSIGN_EXPSIG, _("Signature expires on"));
248 SetDlgItemText (dlg, IDC_KEYSIGN_NREV, _("Sign non-revocably"));
249 #endif
250 CheckDlgButton (dlg, IDC_KEYSIGN_LOCAL, BST_CHECKED);
251 CheckDlgButton (dlg, IDC_KEYSIGN_EXPSIG, BST_UNCHECKED);
252 CheckDlgButton (dlg, IDC_KEYSIGN_ASKLEVEL, BST_UNCHECKED);
253 EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), FALSE);
254 if (reg_prefs.expert == 0)
255 ShowWindow (GetDlgItem (dlg, IDC_KEYSIGN_NREV), SW_HIDE);
256 SetForegroundWindow( dlg );
257 h = GetDlgItem( dlg, IDC_KEYSIGN_PASSPHRASE );
258 SetFocus( h );
259 return FALSE;
260
261 case WM_DESTROY:
262 sig_class_choice = 0;
263 break;
264
265 case WM_SYSCOMMAND:
266 if( LOWORD( wparam ) == SC_CLOSE ) {
267 SetDlgItemText( dlg, IDC_KEYSIGN_PASSPHRASE, "" );
268 EndDialog( dlg, TRUE );
269 }
270 return FALSE;
271
272 case WM_COMMAND:
273 if( HIWORD( wparam ) == CBN_SELCHANGE ) {
274 do_check_protection( dlg );
275 break;
276 }
277 if (HIWORD (wparam) == BN_CLICKED && LOWORD (wparam) == IDC_KEYSIGN_EXPSIG) {
278 int enable = IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG);
279 EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), enable? TRUE : FALSE);
280 }
281
282 switch( LOWORD( wparam ) ) {
283 case IDOK:
284 if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_ASKLEVEL))
285 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_SIGCLASS, dlg,
286 sig_class_dlg_proc, (LPARAM)NULL,
287 _("Choose Signature Class"), IDS_WINPT_SIGCLASS);
288 type = IsDlgButtonChecked (dlg, IDC_KEYSIGN_LOCAL);
289 if (type)
290 type = GPG_EDITKEY_LSIGN;
291 else
292 type = GPG_EDITKEY_SIGN;
293
294 if (reg_prefs.expert && IsDlgButtonChecked (dlg, IDC_KEYSIGN_NREV)) {
295 type = GPG_EDITKEY_NRSIGN;
296 if (type == GPG_EDITKEY_LSIGN)
297 type = GPG_EDITKEY_NRLSIGN;
298 }
299 if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG)) {
300 expires = 1;
301 DateTime_GetSystemtime (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), &st);
302 sprintf (keymsg, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
303 }
304
305 GetDlgItemText( dlg, IDC_KEYSIGN_PASSPHRASE, pwd, DIM (pwd)-1);
306 keyid = key->ctx->subkeys->keyid;
307 if( !keyid ) {
308 msg_box( dlg, _("Could not get Key ID from key."), _("Key Signing"), MB_ERR );
309 return TRUE;
310 }
311 ke = new GpgKeyEdit (keyid);
312 if (!ke)
313 BUG (NULL);
314 ke->setPassphrase (pwd);
315 idx = SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST, CB_GETCURSEL, 0, 0);
316 k = (gpgme_key_t)SendDlgItemMessage (dlg, IDC_KEYSIGN_KEYLIST,
317 CB_GETITEMDATA, (WPARAM)idx, 0);
318 if (k)
319 ke->setLocalUser (k);
320
321 err = ke->signKey (type, sig_class_choice, expires? keymsg : NULL);
322 memset (&pwd, 0, sizeof pwd);
323 delete ke;
324 if (err) {
325 msg_box (dlg, gpgme_strerror (err), _("Key Signing"), MB_ERR);
326 return TRUE;
327 }
328 status_box (dlg, _("Key successfully signed."), PGM_NAME);
329 key->update = 1;
330 EndDialog (dlg, TRUE);
331 return TRUE;
332
333 case IDCANCEL:
334 EndDialog (dlg, FALSE);
335 return TRUE;
336 }
337 break;
338 }
339
340 return FALSE;
341 }
342

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26