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

Annotation of /trunk/Src/wptGPGME.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 271 - (hide annotations)
Sun Nov 5 08:57:45 2006 UTC (18 years, 3 months ago) by twoaday
File size: 7818 byte(s)


1 werner 36 /* wptGPGME.cpp - WinPT GPGME interface
2 twoaday 217 * Copyright (C) 2001-2006 Timo Schulz
3 werner 36 *
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 twoaday 270 /* Return 1 if no cache is available.
51     This can be the case if WinPT were run in command line mode. */
52 twoaday 217 int
53     keycache_not_available (void)
54     {
55     return pub == NULL;
56 werner 36 }
57    
58     /* Release both key cache objects. If @cleanup is 1,
59     also release other global structs. */
60     void
61     keycache_release (int cleanup)
62     {
63 twoaday 255 char tmpbuf[64];
64 werner 36 int n = gpg_keycache_get_size (pub);
65    
66     /* XXX: update the value when the cache has changed. */
67 twoaday 271 _snprintf (tmpbuf, DIM (tmpbuf)-1, "%d", n);
68 werner 36 set_reg_key (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys", tmpbuf);
69    
70     if (pub) {
71     gpg_keycache_release (pub);
72     pub = NULL;
73     }
74     if (sec) {
75     gpg_keycache_release (sec);
76     sec = NULL;
77     }
78 twoaday 211 if (cleanup)
79     safe_free (gpg_secring);
80 werner 36 }
81    
82    
83     /* Update the key with the keyid @keyid in the key cache.
84     If @is_sec is 1, the secret key cache is used. */
85     gpgme_error_t
86     keycache_update (int is_sec, const char *keyid)
87     {
88     gpg_keycache_t ctx = pub;
89     gpgme_error_t err;
90    
91     if (is_sec)
92     ctx = sec;
93     err = gpg_keycache_update_key (ctx, is_sec, pub, keyid);
94     if (is_sec)
95     gpg_keycache_prepare_single (ctx, keyid, NULL, gpg_secring);
96     return err;
97     }
98    
99    
100     /* Initialize both cache contexts. Use @pubring for the public
101     keyring and @secring for the secret keyring. */
102     gpgme_error_t
103     keycache_init (const char *pubring, const char *secring)
104     {
105     struct progress_filter_s pfx;
106     gpgme_error_t err;
107     int val = 0;
108     char *p;
109    
110     if (secring != NULL) {
111     free_if_alloc (gpg_secring);
112     gpg_secring = get_gnupg_keyring (0, NO_STRICT);
113 twoaday 270 log_debug ("keycache_init: secring path '%s'\r\n", gpg_secring);
114 werner 36 }
115 twoaday 150
116 werner 36 p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys");
117     if (p && *p != ' ') {
118     val = atoi (p);
119 twoaday 181 free_if_alloc (p);
120 werner 36 }
121    
122 twoaday 181 memset (&pfx, 0, sizeof (pfx));
123 twoaday 217 keycache_release (0); /* Release old contexts first. */
124 twoaday 150
125 werner 36 err = gpg_keycache_new (&pub);
126     if (err)
127     return err;
128     if (val != 0)
129     gpg_keycache_set_cb (pub, progress_callback, &pfx, val);
130     err = gpg_keycache_new (&sec);
131     if (!err)
132     err = gpg_keycache_init (pub, NULL, 0);
133     if (!err)
134 twoaday 175 err = gpg_keycache_init (sec, NULL, 1);
135     if (!err && pubring && *pubring)
136 twoaday 181 err = gpg_keycache_prepare (pub, pubring, NULL);
137 twoaday 175 if (!err && secring && * secring)
138     err = gpg_keycache_prepare (sec, NULL, secring);
139 werner 36 if (!err)
140     gpg_keycache_sync (pub, sec);
141     if (val != 0)
142     progress_cleanup (&pfx);
143     return err;
144     }
145    
146    
147     /* Return the public cache context if @is_pub is set
148     the secre cache context otherwise. */
149     gpg_keycache_t
150     keycache_get_ctx (int is_pub)
151     {
152 twoaday 208 gpg_keycache_t ctx;
153    
154     ctx = is_pub? pub : sec;
155     if (!ctx)
156     BUG (0);
157     return ctx;
158 werner 36 }
159    
160    
161     /* Get the GPG key with keyid @keyid from the cache. Return it
162     in @r_key on success. */
163 twoaday 211 static gpgme_error_t
164 twoaday 217 get_key_from_cache (const char *keyid, int secret, gpgme_key_t *r_key,
165     struct keycache_s **c)
166 werner 36 {
167     gpg_keycache_t cache;
168     gpgme_error_t err;
169     int mode = secret? KEYCACHE_PRV : KEYCACHE_PUB;
170    
171     if (!keyid)
172 twoaday 211 return gpg_error (GPG_ERR_INV_VALUE);
173 werner 36 if (r_key)
174     *r_key = NULL;
175     cache = keycache_get_ctx (mode);
176     if (!c)
177     err = gpg_keycache_find_key (cache, keyid, 0, r_key);
178     else
179     err = gpg_keycache_find_key2 (cache, keyid, 0, r_key, c);
180 twoaday 211 return err;
181 werner 36 }
182    
183    
184 twoaday 217 /* Release the internal key structure.
185     If allocated is 0, assume fixed cache item. */
186     void
187     winpt_release_pubkey (winpt_key_s *k)
188 werner 36 {
189 twoaday 217 /*log_box ("debug", 0, "alloc %d", k->allocated);*/
190     if (!k->allocated)
191     return;
192     gpg_keycache_item_release (k->ext);
193     k->ext = NULL;
194     k->allocated = 0;
195 werner 36 }
196    
197    
198     /* Search the public key with @keyid as the keyid in the cache and
199     return the item in @k. */
200 twoaday 211 gpgme_error_t
201 werner 36 winpt_get_pubkey (const char *keyid, winpt_key_s *k)
202     {
203 twoaday 217 gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
204 werner 36
205 twoaday 217 if (pub)
206     err = get_key_from_cache (keyid, 0, &k->ctx, &k->ext);
207     else
208     err = gpg_keycache_fetch_key (keyid, 0, &k->ctx, &k->ext);
209 twoaday 211 if (err)
210     return err;
211 werner 36 k->is_v3 = k->ctx->subkeys->pubkey_algo == GPGME_PK_RSA &&
212     strlen (k->ctx->subkeys->fpr) == 32;
213     k->is_protected = k->ext->gloflags.is_protected;
214 twoaday 212 k->keyid = k->ctx->subkeys->keyid+8;
215     k->uid = k->ext->uids->uid;
216 twoaday 217 k->allocated = pub? 0 : 1;
217 twoaday 211 return 0;
218 werner 36 }
219    
220    
221 twoaday 211 gpgme_error_t
222 werner 36 winpt_get_seckey (const char *keyid, winpt_key_s *k)
223     {
224 twoaday 211 gpgme_error_t err;
225    
226 twoaday 217 if (sec)
227     err = get_key_from_cache (keyid, 1, &k->ctx, &k->ext);
228     else
229     err = gpg_keycache_fetch_key (keyid, 1, &k->ctx, &k->ext);
230 twoaday 211 if (err)
231     return err;
232 werner 36 k->is_v3 = k->ctx->subkeys->pubkey_algo == GPGME_PK_RSA &&
233     strlen (k->ctx->subkeys->fpr) == 32;
234     k->is_protected = k->ext->gloflags.is_protected;
235 twoaday 212 k->keyid = k->ctx->subkeys->keyid+8;
236     k->uid = k->ext->uids->uid;
237 twoaday 219 k->allocated = sec? 0 : 1;
238 twoaday 211 return 0;
239 werner 36 }
240    
241    
242 twoaday 211 gpgme_error_t
243 werner 36 get_pubkey (const char *keyid, gpgme_key_t *ret_key)
244     {
245 twoaday 217 return get_key_from_cache (keyid, 0, ret_key, NULL);
246 werner 36 }
247    
248    
249 twoaday 211 gpgme_error_t
250 werner 36 get_seckey (const char *keyid, gpgme_key_t *ret_skey)
251     {
252 twoaday 217 return get_key_from_cache (keyid, 1, ret_skey, NULL);
253 werner 36 }
254    
255    
256 twoaday 109 /* Map the signature summary in @sum to signature status table index.
257     Return value: index to table. */
258     static int
259     sigsum_to_index (gpgme_sigsum_t sum)
260     {
261 twoaday 262 if (sum & GPGME_SIGSUM_RED)
262     return 2;
263     else if (sum & GPGME_SIGSUM_SIG_EXPIRED)
264 twoaday 260 return 8;
265 twoaday 262 else if (sum & GPGME_SIGSUM_KEY_REVOKED)
266 twoaday 109 return 7;
267 twoaday 262 else if (sum & GPGME_SIGSUM_KEY_EXPIRED)
268 twoaday 109 return 6;
269 twoaday 262 else if (sum & GPGME_SIGSUM_GREEN)
270 twoaday 109 return 1;
271     else if (sum & GPGME_SIGSUM_KEY_MISSING)
272     return 3;
273     return 0;
274     }
275    
276    
277 twoaday 262 /* Return a humand readable description for the signature status @sum.
278     Warning: this function does not consider the validity of the key. */
279 twoaday 109 const char*
280     get_gpg_sigstat (gpgme_sigsum_t sum)
281     {
282     const char *gpg_sigstat[] = {
283 twoaday 231 _("Error during verification process"),
284     _("The signature is good"),
285 twoaday 109 _("The signature is BAD!"),
286 twoaday 231 _("The signature could not be checked due to a missing key"),
287     _("No valid OpenPGP signature"),
288 twoaday 109 _("Signature Error"),
289 twoaday 260 _("Good signature (Expired Key)"),
290     _("Good signature (Revoked Key)"),
291     _("Good signature (Expired)"),
292 twoaday 109 NULL
293     };
294 twoaday 260 const unsigned int mask = 9;
295 twoaday 109
296     return gpg_sigstat[sigsum_to_index (sum) % mask];
297     }
298 twoaday 175
299    
300 twoaday 260 /* Return true if at least one secret key is available. */
301 twoaday 214 bool
302     secret_key_available (void)
303     {
304 twoaday 219 if (!sec || gpg_keycache_get_size (sec) == 0)
305 twoaday 214 return false;
306     return true;
307     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26