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

Contents of /trunk/Src/wptGPGME.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 214 - (show annotations)
Sun May 14 18:40:36 2006 UTC (18 years, 9 months ago) by twoaday
File size: 8666 byte(s)
2006-05-14  Timo Schulz  <ts@g10code.de>
                                                                                
        * wptKeyCache.cpp (gpg_keycache_update_attr): Parse
        preferred keyserver URL.
        * wptHTTP.cpp (extractHostInfo): Fix segv.
        * wptGPGUtil.cpp (gpg_find_key_subpacket): Ignore default
        gpg.conf.
        * wptKeyserverSearchDlg.cpp (search_hkp_keys): Do not
        assume an existing user id.
        * wptPassphraseCB.cpp (passphrase_cb): Automatic cancel
        if no passphrase is available.

(for complete list of changes, see Src/ChangeLog)

About to release 0.12.1


1 /* wptGPGME.cpp - WinPT GPGME interface
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
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (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 GNU
14 * 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 <sys/types.h>
25 #include <windows.h>
26
27 #include "resource.h"
28 #include "wptNLS.h"
29 #include "wptGPG.h"
30 #include "wptErrors.h"
31 #include "wptTypes.h"
32 #include "wptW32API.h"
33 #include "wptVersion.h"
34 #include "wptCommonCtl.h"
35 #include "wptContext.h"
36 #include "wptRegistry.h"
37 #include "wptDlgs.h"
38
39 #include "openpgp.h"
40
41 BOOL CALLBACK keycache_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam);
42 void progress_cleanup (progress_filter_s * pfx);
43
44 /* Global GPG key cache contexts. */
45 static gpg_keycache_t pub = NULL;
46 static gpg_keycache_t sec = NULL;
47 static char *gpg_secring = NULL;
48
49
50 /* Reload the key cache. */
51 void
52 keycache_reload (HWND dlg)
53 {
54 refresh_cache_s rcs;
55
56 memset (&rcs, 0, sizeof rcs);
57 rcs.kr_reload = rcs.kr_update = 1;
58 rcs.tr_update = 0;
59 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, dlg,
60 keycache_dlg_proc, (LPARAM)&rcs);
61 }
62
63
64 /* Release both key cache objects. If @cleanup is 1,
65 also release other global structs. */
66 void
67 keycache_release (int cleanup)
68 {
69 int n = gpg_keycache_get_size (pub);
70 char tmpbuf[64];
71
72 /* XXX: update the value when the cache has changed. */
73 sprintf (tmpbuf, "%d", n);
74 set_reg_key (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys", tmpbuf);
75
76 if (pub) {
77 gpg_keycache_release (pub);
78 pub = NULL;
79 }
80 if (sec) {
81 gpg_keycache_release (sec);
82 sec = NULL;
83 }
84 if (cleanup)
85 safe_free (gpg_secring);
86 }
87
88
89 /* Update the key with the keyid @keyid in the key cache.
90 If @is_sec is 1, the secret key cache is used. */
91 gpgme_error_t
92 keycache_update (int is_sec, const char *keyid)
93 {
94 gpg_keycache_t ctx = pub;
95 gpgme_error_t err;
96
97 if (is_sec)
98 ctx = sec;
99 err = gpg_keycache_update_key (ctx, is_sec, pub, keyid);
100 if (is_sec)
101 gpg_keycache_prepare_single (ctx, keyid, NULL, gpg_secring);
102 return err;
103 }
104
105
106 /* Initialize both cache contexts. Use @pubring for the public
107 keyring and @secring for the secret keyring. */
108 gpgme_error_t
109 keycache_init (const char *pubring, const char *secring)
110 {
111 struct progress_filter_s pfx;
112 gpgme_error_t err;
113 int val = 0;
114 char *p;
115
116 if (secring != NULL) {
117 free_if_alloc (gpg_secring);
118 gpg_secring = get_gnupg_keyring (0, NO_STRICT);
119 }
120
121 p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys");
122 if (p && *p != ' ') {
123 val = atoi (p);
124 free_if_alloc (p);
125 }
126
127 memset (&pfx, 0, sizeof (pfx));
128 /* Release old contexts first. */
129 keycache_release (0);
130
131 err = gpg_keycache_new (&pub);
132 if (err)
133 return err;
134 if (val != 0)
135 gpg_keycache_set_cb (pub, progress_callback, &pfx, val);
136 err = gpg_keycache_new (&sec);
137 if (!err)
138 err = gpg_keycache_init (pub, NULL, 0);
139 if (!err)
140 err = gpg_keycache_init (sec, NULL, 1);
141 if (!err && pubring && *pubring)
142 err = gpg_keycache_prepare (pub, pubring, NULL);
143 if (!err && secring && * secring)
144 err = gpg_keycache_prepare (sec, NULL, secring);
145 if (!err)
146 gpg_keycache_sync (pub, sec);
147 if (val != 0)
148 progress_cleanup (&pfx);
149 return err;
150 }
151
152
153 /* Return the public cache context if @is_pub is set
154 the secre cache context otherwise. */
155 gpg_keycache_t
156 keycache_get_ctx (int is_pub)
157 {
158 gpg_keycache_t ctx;
159
160 ctx = is_pub? pub : sec;
161 if (!ctx)
162 BUG (0);
163 return ctx;
164 }
165
166
167 /* Get the GPG key with keyid @keyid from the cache. Return it
168 in @r_key on success. */
169 static gpgme_error_t
170 get_key_from_cache (const char *keyid, gpgme_key_t *r_key,
171 struct keycache_s **c, int secret)
172 {
173 gpg_keycache_t cache;
174 gpgme_error_t err;
175 int mode = secret? KEYCACHE_PRV : KEYCACHE_PUB;
176
177 if (!keyid)
178 return gpg_error (GPG_ERR_INV_VALUE);
179 if (r_key)
180 *r_key = NULL;
181 cache = keycache_get_ctx (mode);
182 if (!c)
183 err = gpg_keycache_find_key (cache, keyid, 0, r_key);
184 else
185 err = gpg_keycache_find_key2 (cache, keyid, 0, r_key, c);
186 return err;
187 }
188
189
190 /* Get GPG key with keyid @keyid directly from GPG and return
191 it in @r_key on success. */
192 static gpgme_error_t
193 get_key_directly (const char *keyid, gpgme_key_t *r_key, int secret)
194 {
195 gpgme_ctx_t ctx;
196 gpgme_error_t err;
197
198 err = gpgme_new (&ctx);
199 if (err)
200 return err;
201 err = gpgme_get_key (ctx, keyid, r_key, secret);
202 gpgme_release (ctx);
203 return err;
204 }
205
206
207 /* Search the public key with @keyid as the keyid in the cache and
208 return the item in @k. */
209 gpgme_error_t
210 winpt_get_pubkey (const char *keyid, winpt_key_s *k)
211 {
212 gpgme_error_t err;
213
214 err = get_key_from_cache (keyid, &k->ctx, &k->ext, 0);
215 if (err)
216 return err;
217 k->is_v3 = k->ctx->subkeys->pubkey_algo == GPGME_PK_RSA &&
218 strlen (k->ctx->subkeys->fpr) == 32;
219 k->is_protected = k->ext->gloflags.is_protected;
220 k->keyid = k->ctx->subkeys->keyid+8;
221 k->uid = k->ext->uids->uid;
222 return 0;
223 }
224
225
226 gpgme_error_t
227 winpt_get_seckey (const char *keyid, winpt_key_s *k)
228 {
229 gpgme_error_t err;
230
231 err = get_key_from_cache (keyid, &k->ctx, &k->ext, 1);
232 if (err)
233 return err;
234 k->is_v3 = k->ctx->subkeys->pubkey_algo == GPGME_PK_RSA &&
235 strlen (k->ctx->subkeys->fpr) == 32;
236 k->is_protected = k->ext->gloflags.is_protected;
237 k->keyid = k->ctx->subkeys->keyid+8;
238 k->uid = k->ext->uids->uid;
239 return 0;
240 }
241
242
243 gpgme_error_t
244 get_pubkey (const char *keyid, gpgme_key_t *ret_key)
245 {
246 gpgme_error_t rc;
247
248 if (pub && sec)
249 rc = get_key_from_cache (keyid, ret_key, NULL, 0);
250 else
251 rc = get_key_directly (keyid, ret_key, 0);
252 return rc;
253 }
254
255
256 gpgme_error_t
257 get_seckey (const char *keyid, gpgme_key_t *ret_skey)
258 {
259 gpgme_error_t rc;
260
261 if (pub && sec)
262 rc = get_key_from_cache (keyid, ret_skey, NULL, 1);
263 else
264 rc = get_key_directly (keyid, ret_skey, 1);
265 return rc;
266 }
267
268
269 /* Search for insecure ElGamal keys and return the
270 number of founded keys. */
271 int
272 count_insecure_elgkeys (void)
273 {
274 gpg_keycache_t pc;
275 gpgme_key_t key;
276 int n=0;
277
278 pc = keycache_get_ctx (1);
279 while (!gpg_keycache_next_key (pc, 0, &key)) {
280 if (key->subkeys->pubkey_algo == GPGME_PK_ELG)
281 n++;
282 }
283 gpg_keycache_rewind (pc);
284 return n;
285 }
286
287
288
289 /* Map the signature summary in @sum to signature status table index.
290 Return value: index to table. */
291 static int
292 sigsum_to_index (gpgme_sigsum_t sum)
293 {
294 if ((sum & GPGME_SIGSUM_VALID) && (sum & GPGME_SIGSUM_KEY_REVOKED))
295 return 7;
296 if ((sum & GPGME_SIGSUM_VALID) && (sum & GPGME_SIGSUM_SIG_EXPIRED))
297 return 6;
298 if (sum & GPGME_SIGSUM_GREEN)
299 return 1;
300 else if (sum & GPGME_SIGSUM_RED)
301 return 2;
302 else if (sum & GPGME_SIGSUM_KEY_MISSING)
303 return 3;
304 return 0;
305 }
306
307
308 /* Return a humand readable description for the signature status @sum. */
309 const char*
310 get_gpg_sigstat (gpgme_sigsum_t sum)
311 {
312 const char *gpg_sigstat[] = {
313 _("Error during verification process."),
314 _("The signature is good."),
315 _("The signature is BAD!"),
316 _("The signature could not be checked due to a missing key."),
317 _("No valid OpenPGP signature."),
318 _("Signature Error"),
319 _("Good Signature (Expired Key)"),
320 _("Good Signature (Revoked Key)"),
321 NULL
322 };
323 const unsigned int mask = 8;
324
325 return gpg_sigstat[sigsum_to_index (sum) % mask];
326 }
327
328
329 /* Check if the secret keyring contains at least one
330 key with ultimate trust.
331 Return value: 0 on success. */
332 int
333 check_ultimate_trusted_key (void)
334 {
335 struct keycache_s *n;
336 int nkeys = 0;
337
338 for (n = sec->item; n; n = n->next) {
339 if (n->pubpart &&
340 n->pubpart->key->owner_trust == GPGME_VALIDITY_ULTIMATE)
341 return 0;
342 nkeys++;
343 }
344
345 /* if we do not have any secret keys, it does not make sense
346 to return an error. */
347 if (nkeys == 0)
348 return 0;
349 return -1;
350 }
351
352
353 bool
354 secret_key_available (void)
355 {
356 gpg_keycache_t _sec = keycache_get_ctx (0);
357 if (!_sec || gpg_keycache_get_size (_sec) == 0)
358 return false;
359 return true;
360 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26