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

Contents of /trunk/Src/wptGPGME.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 208 - (show annotations)
Mon May 1 12:22:18 2006 UTC (18 years, 10 months ago) by twoaday
File size: 8322 byte(s)
See ChangeLog.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26