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

Annotation of /trunk/Src/wptGPGME.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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


1 werner 36 /* 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 werner 47 #include "resource.h"
28 werner 36 #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 twoaday 150
123 werner 36 p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys");
124     if (p && *p != ' ') {
125     val = atoi (p);
126 twoaday 181 free_if_alloc (p);
127 werner 36 }
128    
129 twoaday 181 memset (&pfx, 0, sizeof (pfx));
130 twoaday 150 /* Release old contexts first. */
131     keycache_release (0);
132    
133 werner 36 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 twoaday 175 err = gpg_keycache_init (sec, NULL, 1);
143     if (!err && pubring && *pubring)
144 twoaday 181 err = gpg_keycache_prepare (pub, pubring, NULL);
145 twoaday 175 if (!err && secring && * secring)
146     err = gpg_keycache_prepare (sec, NULL, secring);
147 werner 36 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 twoaday 208 gpg_keycache_t ctx;
161    
162     ctx = is_pub? pub : sec;
163     if (!ctx)
164     BUG (0);
165     return ctx;
166 werner 36 }
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 twoaday 181 BUG (0);
186 werner 36 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 twoaday 109
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 twoaday 175
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