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

Annotation of /trunk/Src/wptGPGME.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 211 - (hide annotations)
Sun May 7 12:36:48 2006 UTC (18 years, 9 months ago) by twoaday
File size: 8335 byte(s)


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 twoaday 211 /* Global GPG key cache contexts. */
45 werner 36 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 twoaday 211 if (cleanup)
85     safe_free (gpg_secring);
86 werner 36 }
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 twoaday 150
121 werner 36 p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys");
122     if (p && *p != ' ') {
123     val = atoi (p);
124 twoaday 181 free_if_alloc (p);
125 werner 36 }
126    
127 twoaday 181 memset (&pfx, 0, sizeof (pfx));
128 twoaday 150 /* Release old contexts first. */
129     keycache_release (0);
130    
131 werner 36 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 twoaday 175 err = gpg_keycache_init (sec, NULL, 1);
141     if (!err && pubring && *pubring)
142 twoaday 181 err = gpg_keycache_prepare (pub, pubring, NULL);
143 twoaday 175 if (!err && secring && * secring)
144     err = gpg_keycache_prepare (sec, NULL, secring);
145 werner 36 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 twoaday 208 gpg_keycache_t ctx;
159    
160     ctx = is_pub? pub : sec;
161     if (!ctx)
162     BUG (0);
163     return ctx;
164 werner 36 }
165    
166    
167     /* Get the GPG key with keyid @keyid from the cache. Return it
168     in @r_key on success. */
169 twoaday 211 static gpgme_error_t
170 werner 36 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 twoaday 211 return gpg_error (GPG_ERR_INV_VALUE);
179 werner 36 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 twoaday 211 return err;
187 werner 36 }
188    
189    
190     /* Get GPG key with keyid @keyid directly from GPG and return
191     it in @r_key on success. */
192 twoaday 211 static gpgme_error_t
193 werner 36 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 twoaday 211 return err;
201 werner 36 err = gpgme_get_key (ctx, keyid, r_key, secret);
202     gpgme_release (ctx);
203 twoaday 211 return err;
204 werner 36 }
205    
206    
207     /* Search the public key with @keyid as the keyid in the cache and
208     return the item in @k. */
209 twoaday 211 gpgme_error_t
210 werner 36 winpt_get_pubkey (const char *keyid, winpt_key_s *k)
211     {
212 twoaday 211 gpgme_error_t err;
213 werner 36
214 twoaday 211 err = get_key_from_cache (keyid, &k->ctx, &k->ext, 0);
215     if (err)
216     return err;
217 werner 36 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;
221     k->uid = k->ctx->uids->uid;
222 twoaday 211 return 0;
223 werner 36 }
224    
225    
226 twoaday 211 gpgme_error_t
227 werner 36 winpt_get_seckey (const char *keyid, winpt_key_s *k)
228     {
229 twoaday 211 gpgme_error_t err;
230    
231     err = get_key_from_cache (keyid, &k->ctx, &k->ext, 1);
232     if (err)
233     return err;
234 werner 36 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;
238     k->uid = k->ctx->uids->uid;
239 twoaday 211 return 0;
240 werner 36 }
241    
242    
243 twoaday 211 gpgme_error_t
244 werner 36 get_pubkey (const char *keyid, gpgme_key_t *ret_key)
245     {
246 twoaday 211 gpgme_error_t rc;
247 werner 36
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 twoaday 211 gpgme_error_t
257 werner 36 get_seckey (const char *keyid, gpgme_key_t *ret_skey)
258     {
259 twoaday 211 gpgme_error_t rc;
260 werner 36
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 twoaday 109
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 twoaday 175
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    
337     for (n = sec->item; n; n = n->next) {
338     if (n->pubpart &&
339     n->pubpart->key->owner_trust == GPGME_VALIDITY_ULTIMATE)
340     return 0;
341     }
342     return -1;
343     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26