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

Diff of /trunk/Src/wptGPGME.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 19 by twoaday, Fri May 20 08:39:15 2005 UTC revision 32 by twoaday, Mon Oct 24 08:03:48 2005 UTC
# Line 1  Line 1 
1  /* wptGPGME.cpp - WinPT GPGME interface  /* wptGPGME.cpp - WinPT GPGME interface
2   *      Copyright (C) 2001-2004 Timo Schulz   *      Copyright (C) 2001-2005 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 38  Line 38 
38  BOOL CALLBACK  keycache_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam);  BOOL CALLBACK  keycache_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam);
39  void progress_cleanup (progress_filter_s * pfx);  void progress_cleanup (progress_filter_s * pfx);
40    
41  static gpgme_keycache_t pub = NULL;  static gpg_keycache_t pub = NULL;
42  static gpgme_keycache_t sec = NULL;  static gpg_keycache_t sec = NULL;
43  static unsigned int reload = 0;  static unsigned int reload = 0;
44    static char *gpg_secring = NULL;
45    
46    
47    /* Reload the key cache. */
48  void  void
49  keycache_reload (HWND dlg)  keycache_reload (HWND dlg)
50  {        {      
51      refresh_cache_s rcs = {0};      refresh_cache_s rcs;
52    
53        memset (&rcs, 0, sizeof rcs);
54      rcs.kr_reload = rcs.kr_update = 1;      rcs.kr_reload = rcs.kr_update = 1;
55      rcs.tr_update = 1;      rcs.tr_update = 0;
56      DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, dlg,                                              DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, dlg,                                        
57                      keycache_dlg_proc, (LPARAM)&rcs );                      keycache_dlg_proc, (LPARAM)&rcs);
58  } /* keycache_reload */  }
59    
60    
61    /* Release both key cache objects. If @cleanup is 1,
62       also release other global structs. */
63  void  void
64  keycache_release (void)  keycache_release (int cleanup)
65  {  {
66      int n = gpgme_keycache_count (pub);      int n = gpg_keycache_get_size (pub);
67      char tmpbuf[64];      char tmpbuf[64];
68    
69        /* XXX: update the value when the cache has changed. */
70      sprintf (tmpbuf, "%d", n);      sprintf (tmpbuf, "%d", n);
71      set_reg_key (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys", tmpbuf);      set_reg_key (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys", tmpbuf);
72    
73      if (pub) {      if (pub) {
74          gpgme_keycache_release( pub );          gpg_keycache_release (pub);
75          pub = NULL;          pub = NULL;
76      }      }
77      if (sec) {      if (sec) {
78          gpgme_keycache_release( sec );          gpg_keycache_release (sec);
79          sec = NULL;          sec = NULL;
80      }      }
81  } /* keycache_release */      if (cleanup) {
82            if (gpg_secring)
83                free (gpg_secring);
84            gpg_secring = NULL;
85        }
86    }
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  gpgme_error_t
92  keycache_update (const char *keyid)  keycache_update (int is_sec, const char *keyid)
93  {  {
94      return gpgme_keycache_update_key (pub, keyid);      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    /* XXX: cache_keyring_names must be called then the GPG homedir changes! */
106    
107    /* Initialize both cache contexts. Use @pubring for the public
108       keyring and @secring for the secret keyring. */
109  gpgme_error_t  gpgme_error_t
110  keycache_init (const char *pubring, const char * secring)  keycache_init (const char *pubring, const char *secring)
111  {  {
112      struct progress_filter_s pfx;      struct progress_filter_s pfx;
113      gpgme_error_t err;      gpgme_error_t err;
114      int val = 0;      int val = 0;
115      char * p;      char *p;
116    
117        if (secring != NULL) {
118            free_if_alloc (gpg_secring);
119            gpg_secring = get_gnupg_keyring (0, NO_STRICT);
120        }
121    
122      if (reload) {      if (reload) {
123          keycache_release ();          keycache_release (0);
124          reload = 0;          reload = 0;
125      }      }
126      p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys");      p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys");
127      if (p && *p != ' ') {      if (p && *p != ' ') {
128          val = atoi (p);          val = atoi (p);
129          free_if_alloc (p);          free_if_alloc (p);
130          memset (&pfx, 0, sizeof pfx);          memset (&pfx, 0, sizeof (pfx));
131      }      }
132    
133      err = gpgme_keycache_new (&pub);      err = gpg_keycache_new (&pub);
134      if (err)      if (err)
135          return err;          return err;
136      if (val != 0)      if (val != 0)
137          gpgme_keycache_set_cb (pub, progress_callback, &pfx, val);          gpg_keycache_set_cb (pub, progress_callback, &pfx, val);
138      err = gpgme_keycache_new (&sec);      err = gpg_keycache_new (&sec);
139      if (!err)      if (!err)
140          err = gpgme_keycache_init (pub, NULL, 0);          err = gpg_keycache_init (pub, NULL, 0);
141      if (!err)      if (!err)
142          err = gpgme_keycache_init( sec, NULL, 1 );          err = gpg_keycache_init( sec, NULL, 1 );
143      if( !err && pubring && *pubring )      if( !err && pubring && *pubring )
144          err = gpgme_keycache_prepare( pub, pubring, NULL );          err = gpg_keycache_prepare( pub, pubring, NULL );
145      if( !err && secring && * secring )      if( !err && secring && * secring )
146          err = gpgme_keycache_prepare( sec, NULL, secring );          err = gpg_keycache_prepare( sec, NULL, secring );
147      if (!err)      if (!err)
148          gpgme_keycache_sync (pub, sec);          gpg_keycache_sync (pub, sec);
149      if (val != 0)      if (val != 0)
150          progress_cleanup (&pfx);          progress_cleanup (&pfx);
151      return err;      return err;
152  } /* keycache_init */  }
153    
154    
155    /* If @val = 1 indicate to reload the cache. */
156  void  void
157  keycache_set_reload( int yes )  keycache_set_reload (int val)
158  {  {
159      reload = yes;      reload = val;
160  } /* keycache_set_reload */  }
161    
162    
163    /* Return the reload cache flag. */
164  int  int
165  keycache_get_reload( void )  keycache_get_reload (void)
166  {  {
167      return reload;      return reload;
168  } /* keycache_get_reload */  }
169    
170    
171  gpgme_keycache_t  /* Return the public cache context if @is_pub is set
172  keycache_get_ctx( int is_pub )     the secre cache context otherwise. */
173    gpg_keycache_t
174    keycache_get_ctx (int is_pub)
175  {  {
176      return is_pub? pub : sec;      return is_pub? pub : sec;
177  } /* keycache_get_ctx */  }
178    
179    
180    /* Get the GPG key with keyid @keyid from the cache. Return it
181       in @r_key on success. */
182  static int  static int
183  get_key( const char *keyid, gpgme_key_t *r_key, int secret )  get_key_from_cache (const char *keyid, gpgme_key_t *r_key,
184                        struct keycache_s **c, int secret)
185  {  {
186      gpgme_keycache_t cache;      gpg_keycache_t cache;
187      gpgme_error_t err;      gpgme_error_t err;
188      int mode = secret? KEYCACHE_PRV : KEYCACHE_PUB;      int mode = secret? KEYCACHE_PRV : KEYCACHE_PUB;
189    
190      if( !keyid )      if (!keyid)
191          return WPTERR_GENERAL;          return WPTERR_GENERAL;
192      if( r_key )      if (r_key)
193          *r_key = NULL;          *r_key = NULL;
194      cache = keycache_get_ctx( mode );      cache = keycache_get_ctx (mode);
195      if( !cache )      if (!cache)
196          BUG( NULL );          BUG( NULL );
197      err = gpgme_keycache_find_key( cache, keyid, 0, r_key );      if (!c)
198      if( err )          err = gpg_keycache_find_key (cache, keyid, 0, r_key);
199          return WPTERR_GENERAL;      else
200      return 0;          err = gpg_keycache_find_key2 (cache, keyid, 0, r_key, c);
201  } /* get_key */      return err? WPTERR_GENERAL : 0;
202    }
203    
204    
205    /* Get GPG key with keyid @keyid directly from GPG and return
206       it in @r_key on success. */
207  static int  static int
208  get_key2( const char * keyid, gpgme_key_t * r_key, int secret )  get_key_directly (const char *keyid, gpgme_key_t *r_key, int secret)
209  {  {
210      gpg_iobuf_t inp;      gpgme_ctx_t ctx;
211      char * p;      gpgme_error_t err;
     int rc;  
212    
213      p = get_gnupg_keyring (1, !NO_STRICT);      err = gpgme_new (&ctx);
214      if( !p )      if (err)
215          BUG( NULL );          return WPTERR_GENERAL;
216        err = gpgme_get_key (ctx, keyid, r_key, secret);
217        gpgme_release (ctx);
218        return err? WPTERR_GENERAL : 0;
219    }
220    
221    
222    /* Search the public key with @keyid as the keyid in the cache and
223       return the item in @k. */
224    int
225    winpt_get_pubkey (const char *keyid, winpt_key_s *k)
226    {
227        int rc;
228        
229        rc = get_key_from_cache (keyid, &k->ctx, &k->ext, 0);
230        if (rc)
231            return rc;
232        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        k->keyid = k->ctx->subkeys->keyid;
236        k->uid = k->ctx->uids->uid;
237        return rc;
238    }
239    
     inp = gpg_iobuf_open( p );  
     if( !inp ) {  
         const char *s = winpt_strerror( WPTERR_FILE_OPEN );  
         log_box( _("WinPT Error"), 0, "%s: %s", p, s );  
         free_if_alloc( p );  
         return NULL;  
     }  
     gpg_iobuf_ioctl( inp, 3, 1, NULL ); /* disable cache */  
     rc = gpgme_getkey_bykeyid( inp, keyid, r_key );  
240    
241      gpg_iobuf_close( inp );  int
242      free_if_alloc( p );  winpt_get_seckey (const char *keyid, winpt_key_s *k)
243    {
244        int rc;
245        rc = get_key_from_cache (keyid, &k->ctx, &k->ext, 1);
246        if (rc)
247            return rc;
248        k->is_v3 = k->ctx->subkeys->pubkey_algo == GPGME_PK_RSA &&
249                    strlen (k->ctx->subkeys->fpr) == 32;
250        k->is_protected = k->ext->gloflags.is_protected;
251        k->keyid = k->ctx->subkeys->keyid;
252        k->uid = k->ctx->uids->uid;
253      return rc;      return rc;
254  } /* get_key2 */  }
255    
256    
257  int  int
258  get_pubkey( const char *keyid, gpgme_key_t *ret_key )  get_pubkey (const char *keyid, gpgme_key_t *ret_key)
259  {  {
260      int rc = 0;      int rc;
261    
262      if( pub && sec )      if (pub && sec)
263          rc = get_key( keyid, ret_key, 0 );          rc = get_key_from_cache (keyid, ret_key, NULL, 0);
264      else      else
265          rc = get_key2( keyid, ret_key, 0 );          rc = get_key_directly (keyid, ret_key, 0);
266      return rc;      return rc;
267  } /* get_pubkey */  }
268    
269    
270  int  int
271  get_seckey( const char *keyid, gpgme_key_t *ret_skey )  get_seckey (const char *keyid, gpgme_key_t *ret_skey)
272  {  {
273      int rc = 0;      int rc;
274    
275      if( pub && sec )      if (pub && sec)
276          rc = get_key( keyid, ret_skey, 1 );          rc = get_key_from_cache (keyid, ret_skey, NULL, 1);
277      else      else
278          rc = get_key2( keyid, ret_skey, 1 );          rc = get_key_directly (keyid, ret_skey, 1);
279      return rc;      return rc;
280  } /* get_seckey */  }
281    
282    
283    /* Search for insecure ElGamal keys and return the
284       number of founded keys. */
285  int  int
286  count_insecure_elgkeys (void)  count_insecure_elgkeys (void)
287  {  {
288      gpgme_keycache_t pc;      gpg_keycache_t pc;
289      gpgme_key_t key;      gpgme_key_t key;
290      int n=0;      int n=0;
291    
292      pc = keycache_get_ctx (1);      pc = keycache_get_ctx (1);
293      if (!pc)      if (!pc)
294          BUG (0);          BUG (0);
295      while (!gpgme_keycache_next_key (pc, 0, &key)) {      while (!gpg_keycache_next_key (pc, 0, &key)) {
296          if (gpgme_key_get_ulong_attr (key, GPGME_ATTR_ALGO, NULL, 0)          if (key->subkeys->pubkey_algo == GPGME_PK_ELG)
             == GPGME_PK_ELG_ES)  
297              n++;              n++;
298      }      }
299      gpgme_keycache_rewind (pc);      gpg_keycache_rewind (pc);
300      return n;      return n;
301  }  }

Legend:
Removed from v.19  
changed lines
  Added in v.32

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26