/[winpt]/trunk/MyGPGME/keycache.c
ViewVC logotype

Contents of /trunk/MyGPGME/keycache.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 17 - (show annotations)
Fri May 20 08:38:32 2005 UTC (19 years, 9 months ago) by twoaday
File MIME type: text/plain
File size: 7519 byte(s)
2005-05-20      Timo Schulz  <twoaday@freakmail.de>
 
        * gpgme.h: s/cliptype/pgptype. Suggested by Kurt Fitzner.
        s/CLIP/PGP. Likewise.
        * w32-io.c (_gpgme_io_select): Increment the right loop variable.
        Kudos to Kurt.
        * keylist.c (gpgme_op_keylist_getkey): New. Handy function to
        retrieve a single key.
        * verify.c (gpgme_get_sig_key): Use it here.
        * keycache.c (gpgme_keycache_update_key): Update a single key.
 


1 /* keycache.c - Caching for the pub- and the secring
2 * Copyright (C) 2001-2004 Timo Schulz
3 *
4 * This file is part of MyGPGME.
5 *
6 * MyGPGME is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * MyGPGME 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "context.h"
25 #include "ops.h"
26 #include "key.h"
27 #include "util.h"
28
29
30 gpgme_error_t
31 gpgme_keycache_new( gpgme_keycache_t *r_ctx )
32 {
33 gpgme_keycache_t ctx;
34
35 if( !r_ctx )
36 return mk_error( Invalid_Value );
37 ctx = calloc( 1, sizeof *ctx );
38 if( !ctx )
39 return mk_error( Out_Of_Core );
40 ctx->secret = 0;
41 ctx->pos = 0;
42 *r_ctx = ctx;
43 return 0;
44 } /* gpgme_keycache_new */
45
46
47 void
48 gpgme_keycache_release (gpgme_keycache_t ctx)
49 {
50 struct keycache_s * c, * c2;
51
52 if (!ctx)
53 return;
54
55 for( c = ctx->item; c; c = c2 ) {
56 c2 = c->next;
57 gpgme_key_release( c->key );
58 c->key = NULL;
59 safe_free( c );
60 }
61 safe_free( ctx );
62 } /* gpgme_keycache_release */
63
64
65 void
66 gpgme_keycache_set_cb (gpgme_keycache_t ctx,
67 void (*cb)(void *, const char *, int, unsigned, unsigned),
68 void * cb_value1, int cb_value2)
69 {
70 if (!ctx)
71 return;
72 ctx->cb = cb;
73 ctx->cb_value = cb_value1;
74 ctx->cb_value2 = cb_value2;
75 }
76
77
78 int
79 gpgme_keycache_add_key( gpgme_keycache_t ctx, gpgme_key_t key )
80 {
81 struct keycache_s * c, * n1;
82
83 if( !ctx )
84 return mk_error(Invalid_Value);
85
86 c = calloc( 1, sizeof *c );
87 if( !c )
88 return mk_error( Out_Of_Core );
89 c->key = key;
90 if( !ctx->item )
91 ctx->item = c;
92 else {
93 for( n1 = ctx->item; n1 && n1->next; n1 = n1->next )
94 ;
95 n1->next = c;
96 }
97 return 0;
98 } /* gpgme_keycache_add_key */
99
100
101 #define is_deleted_item(c) (((c)->flags & 0x01))
102 #define has_keyid_len(pattern) (\
103 strlen (pattern) == 8 || strlen (pattern) == 10 || \
104 strlen (pattern) == 16 || strlen (pattern) == 18)
105
106
107 static gpgme_error_t
108 keycache_find_key (gpgme_keycache_t ctx, const char * pattern, int flags,
109 gpgme_key_t * r_key, struct keycache_s ** r_item)
110 {
111 struct keycache_s * c;
112 struct subkey_s * s;
113 struct user_id_s * u;
114 const char *kid;
115
116 if (!ctx || !r_key)
117 return mk_error (Invalid_Value);
118
119 if (strstr (pattern, "0x"))
120 pattern += 2;
121 /* XXX: this code is very slow, revamp it and use hash tables whenever
122 it is possible. */
123 for (c = ctx->item; c; c = c->next) {
124 if (is_deleted_item (c))
125 continue;
126 for (s = &c->key->keys; s; s = s->next) {
127 for (u = c->key->uids; u; u = u->next) {
128 if (u->name && memistr (u->name, strlen (u->name), pattern)) {
129 if (r_item)
130 *r_item = c;
131 *r_key = flags? c->pubpart : c->key;
132 return 0;
133 }
134 }
135 if (has_keyid_len (pattern))
136 kid = s->keyid;
137 else
138 kid = s->fingerprint;
139
140 if (kid && memistr (kid, strlen (kid), pattern)) {
141 if (r_item)
142 *r_item = c;
143 *r_key = flags? c->pubpart : c->key;
144 return 0;
145 }
146 }
147 }
148 *r_key = NULL;
149 return mk_error (General_Error);
150 } /* keycache_find_key */
151
152
153 gpgme_error_t
154 gpgme_keycache_find_key (gpgme_keycache_t ctx, const char * pattern,
155 int flags, gpgme_key_t * r_key)
156 {
157 return keycache_find_key (ctx, pattern, flags, r_key, NULL);
158 } /* gpgme_keycache_find_key */
159
160
161 gpgme_error_t
162 gpgme_keycache_update_key (gpgme_keycache_t ctx, const char *keyid)
163 {
164 struct keycache_s *c = NULL;
165 gpgme_key_t key=NULL, fndkey=NULL;
166 gpgme_error_t err;
167
168 err = gpgme_op_keylist_getkey (0, keyid, &key);
169 if (err)
170 return err;
171 err = keycache_find_key (ctx, keyid, 0, &fndkey, &c);
172 if (err)
173 return err;
174 if (c != NULL) {
175 gpgme_key_release (c->key);
176 c->key = key;
177 c->flags = 0;
178 }
179 return 0;
180 }
181
182 gpgme_error_t
183 gpgme_keycache_delete_key (gpgme_keycache_t ctx, const char * pattern)
184 {
185 struct keycache_s *c = NULL;
186 gpgme_key_t key;
187 gpgme_error_t rc;
188
189 if (!ctx)
190 return mk_error (Invalid_Value);
191 rc = keycache_find_key (ctx, pattern, 0, &key, &c);
192 if (!rc)
193 c->flags |= 1;
194 return rc;
195 } /* gpgme_keycache_delete_key */
196
197
198 gpgme_error_t
199 gpgme_keycache_init (gpgme_keycache_t ctx, const char *pattern, int secret)
200 {
201 gpgme_error_t err;
202 gpgme_ctx_t c;
203 gpgme_key_t key;
204
205 if (!ctx)
206 return mk_error( Invalid_Value );
207
208 err = gpgme_new (&c);
209 if (err)
210 return err;
211 if (ctx->cb)
212 {
213 gpgme_control (c, GPGME_CTRL_CB_VAL, ctx->cb_value2);
214 gpgme_set_progress_cb (c, ctx->cb, ctx->cb_value);
215 }
216 gpgme_control (c, GPGME_CTRL_LOGGING, 1);
217 err = gpgme_op_keylist_start( c, pattern, secret );
218 while(!err)
219 {
220 err = gpgme_op_keylist_next (c, &key);
221 if (!err)
222 err = gpgme_keycache_add_key (ctx, key);
223 }
224 if (err == GPGME_EOF)
225 err = 0;
226 if (gpgme_get_process_rc (c))
227 err = gpgme_check_logging (c);
228 gpgme_release (c);
229 return err;
230 } /* gpgme_keycache_init */
231
232
233 gpgme_error_t
234 gpgme_keycache_sync (gpgme_keycache_t pub, gpgme_keycache_t sec)
235 {
236 struct keycache_s * c;
237 const char * s;
238 gpgme_key_t key;
239
240 if (!pub || !sec)
241 return mk_error (Invalid_Value);
242 /* The GPG secret key listing does not contain much information
243 so we add some information to the public key cache. */
244 for (c=sec->item; c; c=c->next) {
245 s = gpgme_key_get_string_attr (c->key, GPGME_ATTR_KEYID, NULL, 0);
246 if (!gpgme_keycache_find_key (pub, s, 0, &key)) {
247 key->gloflags.is_protected = c->key->gloflags.is_protected;
248 key->gloflags.divert_to_card = c->key->gloflags.divert_to_card;
249 c->pubpart = key;
250 }
251 }
252 return 0;
253 }
254
255
256 void
257 gpgme_keycache_rewind (gpgme_keycache_t ctx)
258 {
259 if (ctx)
260 ctx->pos = 0;
261 } /* gpgme_keycache_rewind */
262
263
264 int
265 gpgme_keycache_count (gpgme_keycache_t ctx)
266 {
267 struct keycache_s *c;
268 int count = 0;
269
270 if (!ctx)
271 return 0;
272 for (c = ctx->item; c; c = c->next) {
273 if (is_deleted_item (c))
274 continue;
275 count++;
276 }
277 return count;
278 } /* gpgme_keycache_count */
279
280
281 gpgme_error_t
282 gpgme_keycache_next_key (gpgme_keycache_t ctx, int flags, gpgme_key_t * r_key)
283 {
284 if (!ctx || !r_key)
285 return mk_error (Invalid_Value);
286
287 if (!ctx->pos)
288 ctx->tmp = ctx->item;
289
290 if (!ctx->tmp || !ctx->tmp->key) {
291 ctx->pos = 0;
292 *r_key = NULL;
293 return mk_error (Invalid_Value);
294 }
295
296 *r_key = flags? ctx->tmp->pubpart : ctx->tmp->key;
297
298 ctx->tmp = ctx->tmp->next;
299 ctx->pos++;
300
301 return 0;
302 } /* gpgme_keycache_next_key */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26