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

Diff of /trunk/Src/wptKeyEdit.cpp

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

revision 23 by twoaday, Fri Sep 30 10:10:16 2005 UTC revision 205 by twoaday, Thu Apr 27 12:46:03 2006 UTC
# Line 1  Line 1 
1  /* wptKeyEdit.cpp - GPG key edit abstraction  /* wptKeyEdit.cpp - GPG key edit abstraction
2   *      Copyright (C) 2005 Timo Schulz   *      Copyright (C) 2005, 2006 Timo Schulz
3   *   *      Copyright (C) 2005 g10 Code GmbH
4   * This file is part of WinPT.   *
5   *   * This file is part of WinPT.
6   * WinPT is free software; you can redistribute it and/or   *
7   * modify it under the terms of the GNU General Public License   * WinPT is free software; you can redistribute it and/or
8   * as published by the Free Software Foundation; either version 2   * modify it under the terms of the GNU General Public License
9   * of the License, or (at your option) any later version.   * as published by the Free Software Foundation; either version 2
10   *     * of the License, or (at your option) any later version.
11   * WinPT is distributed in the hope that it will be useful,   *  
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * WinPT is distributed in the hope that it will be useful,
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * General Public License for more details.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   *   * General Public License for more details.
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,   * You should have received a copy of the GNU General Public License
18   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   * along with WinPT; if not, write to the Free Software Foundation,
19   */   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21  #include <windows.h>  
22    #ifdef HAVE_CONFIG_H
23  #include "w32gpgme.h"  #include <config.h>
24  #include "wptCommonCtl.h"  #endif
25  #include "wptContext.h"  #include <time.h>
26  #include "wptKeyEdit.h"  #include <windows.h>
27  #include "wptTypes.h"  
28  #include "wptW32API.h"  #include "gpgme.h"
29  #include "wptGPG.h"  #include "wptCommonCtl.h"
30    #include "wptContext.h"
31  /* Parse the colon status information of @line and store  #include "wptKeyEdit.h"
32     the information in @rev.  #include "wptTypes.h"
33     Return value: 0 on success. */  #include "wptW32API.h"
34  static gpgme_error_t  #include "wptGPG.h"
35  rev_key_colon_handler (gpg_desig_rev_t *rev, char *line)  #include "wptErrors.h"
36  {  #include "wptUTF8.h"
37      char *p, *pend;  
38      gpg_desig_rev_t r, t;  
39      int field = 0;  /* Parse the colon status information of @line and store
40       the information in @rev.
41      if (!line || strlen (line) < 3 || strncmp (line, "rvk", 3))     Return value: 0 on success. */
42          return gpg_error (GPG_ERR_EOF);  static gpgme_error_t
43    rev_key_colon_handler (gpg_desig_rev_t *rev, char *line)
44      r = (gpg_desig_rev_t)calloc (1, sizeof *r);  {
45      if (!r)      char *p, *pend;
46          return gpg_error (GPG_ERR_ENOMEM);      gpg_desig_rev_t r, t;
47      if (!*rev)      int field = 0;
48          *rev = r;  
49      else {      if (!line || strlen (line) < 3)
50          for (t=*rev; t->next; t=t->next)          return gpg_error (GPG_ERR_EOF);
51              ;      if (strncmp (line, "rvk", 3))
52          t->next = r;          return 0; /* skip this line. */
53      }  
54        log_debug ("rev_key: line=%s\r\n", line);
55      p = strdup (line);  
56      if (!p)      r = (gpg_desig_rev_t)calloc (1, sizeof *r);
57          return gpg_error (GPG_ERR_ENOMEM);      if (!r)
58            return gpg_error (GPG_ERR_ENOMEM);
59      for (;;) {      if (!*rev)
60          field++;          *rev = r;
61          pend = strsep (&p, ":");      else {
62          if (pend == NULL)          for (t=*rev; t->next; t=t->next)
63              break;              ;
64          switch (field) {          t->next = r;
65          case 3: r->pubkey_algo = (gpgme_pubkey_algo_t)atol (pend); break;      }
66          case 9: strncpy (r->fpr, pend, 40); r->fpr[40] = 0; break;  
67          }      p = strdup (line);
68      }      if (!p)
69      if (p)          return gpg_error (GPG_ERR_ENOMEM);
70          free (p);  
71      return 0;      for (;;) {
72  }          field++;
73            pend = strsep (&p, ":");
74            if (pend == NULL)
75  /* Parse the colon data output of edit key from @line and              break;
76     store the information in the @inf context.          switch (field) {
77     Return value: 0 on success. */          case  4: r->pubkey_algo = (gpgme_pubkey_algo_t)atol (pend); break;
78  static gpgme_error_t          case 10: strncpy (r->fpr, pend, 40); r->fpr[40] = 0; break;
79  uid_inf_colon_handler (gpg_uid_info_t *inf, char *line)          }      
80  {      }
81      char *p, *pend;      if (p)
82      int field = 0, len = 0;          free (p);
83      gpg_uid_info_t i, t;      return 0;
84    }
85      if (!line || strlen (line) < 3 || strncmp (line, "uid", 3))  
86          return gpg_error (GPG_ERR_EOF);  
87    /* Parse the colon data output of edit key from @line and
88      i = (gpg_uid_info_t)calloc (1, sizeof *i);     store the information in the @inf context.
89      if (!i)     Return value: 0 on success. */
90          return gpg_error (GPG_ERR_ENOMEM);  static gpgme_error_t
91      if (!*inf)  uid_inf_colon_handler (gpg_uid_info_t *inf, char *line)
92          *inf = i;  {
93      else {      gpg_uid_info_t i, t;
94          for (t=*inf; t->next; t=t->next)      char *p, *pend;
95              ;      char *name;
96          t->next = i;      int field = 0, len = 0;
97      }  
98        if (!line || strlen (line) < 3 || strncmp (line, "uid", 3))
99      p = strdup (line);          return gpg_error (GPG_ERR_EOF);
100      if (!p)  
101          return gpg_error (GPG_ERR_ENOMEM);;      i = (gpg_uid_info_t)calloc (1, sizeof *i);
102      for (;;) {      if (!i)
103          field++;          return gpg_error (GPG_ERR_ENOMEM);
104          pend = strsep (&p, ":");      if (!*inf)
105          if (pend == NULL)          *inf = i;
106              break;      else {
107            for (t=*inf; t->next; t=t->next)
108          switch (field) {              ;
109          case 2: /* trust info */          t->next = i;
110              break;      }
111    
112          case 10: /* user ID */      p = strdup (line);
113              i->name = (char *)calloc (1, strlen (pend)+1);      if (!p)
114              if (!i->name)          return gpg_error (GPG_ERR_ENOMEM);;
115                  return gpg_error (GPG_ERR_ENOMEM);;      for (;;) {
116              /* XXX _gpgme_decode_c_string (pend, &i->name, strlen (pend)+ 1); */          field++;
117              strcpy (i->name, pend);          pend = strsep (&p, ":");
118              if (strchr (pend, '<') != NULL && strchr (pend, '>') != NULL) {          if (pend == NULL)
119                  int pos = strchr (i->name, '<')- i->name + 1;              break;
120                  int end = strchr (i->name, '>') - i->name;  
121                  i->email = (char*) calloc (1, end-pos+2);          switch (field) {
122                  if (!i->email)          case 2: /* trust info */
123                      return gpg_error (GPG_ERR_ENOMEM);;              break;
124                  memcpy (i->email, i->name+pos, (end-pos));  
125              }          case 10: /* user ID */
126              break;              name = (char *)calloc (1, strlen (pend)+1);
127                if (!name)
128          case 13: /* preferences */                  return gpg_error (GPG_ERR_ENOMEM);;
129              if (strstr (pend, "mdc")) {              gpg_decode_c_string (pend, &name, strlen (pend)+ 1);
130                  len = strlen (pend) - 4; /* ,mdc */              i->name = utf8_to_native (name);
131                  if (strstr (pend, "no-ks-modify")) {              safe_free (name);
132                      i->flags.no_ks_modify = 1;              if (strchr (pend, '<') != NULL && strchr (pend, '>') != NULL) {
133                      len -= 13; /* ,no-ks-modify */                  int pos = strchr (i->name, '<')- i->name + 1;
134                  }                  int end = strchr (i->name, '>') - i->name;
135                  i->prefs = (char*)calloc (1, len+1);                  i->email = (char*) calloc (1, end-pos+2);
136                  if (!i->prefs)                  if (!i->email)
137                      return gpg_error (GPG_ERR_ENOMEM);                      return gpg_error (GPG_ERR_ENOMEM);;
138                  memcpy (i->prefs, pend, len);                  memcpy (i->email, i->name+pos, (end-pos));
139                  i->prefs[len] = '\0';              }
140                  i->flags.mdc = 1;              break;
141              }  
142              else {          case 13: /* preferences */
143                  i->prefs = strdup (pend);              if (strstr (pend, "mdc")) {
144                  if (!i->prefs)                  len = strlen (pend) - 4; /* ,mdc */
145                      return gpg_error (GPG_ERR_ENOMEM);                  if (strstr (pend, "no-ks-modify")) {
146                  i->flags.mdc = 0;                                    i->flags.no_ks_modify = 1;
147              }                      len -= 13; /* ,no-ks-modify */
148              break;                  }
149                    i->prefs = (char*)calloc (1, len+1);
150          case 14: /* index/flags */                  if (!i->prefs)
151              i->index = atol (pend);                      return gpg_error (GPG_ERR_ENOMEM);
152              if (strchr (pend, 'r'))                  memcpy (i->prefs, pend, len);
153                  i->flags.revoked = 1;                  i->prefs[len] = '\0';
154              if (strchr (pend, 'p'))                  i->flags.mdc = 1;
155                  i->flags.primary = 1;              }
156              break;              else {
157          }                  i->prefs = strdup (pend);
158      }                  if (!i->prefs)
159      if (p)                      return gpg_error (GPG_ERR_ENOMEM);
160          free (p);                  i->flags.mdc = 0;              
161      return 0;              }
162  }              break;
163    
164            case 14: /* index/flags */
165  /* Release the context in @inf. */              i->index = atol (pend);
166  void              if (strchr (pend, 'r'))
167  gpg_uid_info_release (gpg_uid_info_t list)                  i->flags.revoked = 1;
168  {              if (strchr (pend, 'p'))
169      gpg_uid_info_t i;                  i->flags.primary = 1;
170                  break;
171      while (list) {          }
172          i = list->next;      }
173          if (list->name) {      if (p)
174              if (list->name)                    free (p);
175                  free (list->name);      return 0;
176              list->name = NULL;  }
177          }  
178          if (list->prefs) {  
179              if (list->prefs)  /* Release the context in @inf. */
180                  free (list->prefs);  void
181              list->prefs = NULL;  gpg_uid_info_release (gpg_uid_info_t list)
182          }        {
183          free (list);      gpg_uid_info_t i;
184          list = i;    
185      }      while (list) {
186  }          i = list->next;
187            if (list->name) {
188                if (list->name)          
189  /* Release the context in @rev. */                  free (list->name);
190  void              list->name = NULL;
191  gpg_desig_rev_release (gpg_desig_rev_t rev)          }
192  {          if (list->prefs) {
193      gpg_desig_rev_t r;              if (list->prefs)
194                    free (list->prefs);
195      while (rev) {              list->prefs = NULL;
196          r = rev->next;          }      
197          free (rev);          free (list);
198          rev = r;          list = i;
199      }      }
200  }  }
201    
202    
203  /* Return all designated revokers for this key. If no revoker  /* Release the context in @rev. */
204     was set, @r_rev is NULL.  void
205     Return value: 0 on success. */  gpg_desig_rev_release (gpg_desig_rev_t rev)
206  gpgme_error_t  {
207  GpgKeyEdit::getDesignatedRevoker (gpg_desig_rev_t *r_rev)      gpg_desig_rev_t r;
208  {  
209      gpgme_data_t out=NULL;      while (rev) {
210      gpg_desig_rev_t rev = NULL;          r = rev->next;
211      gpgme_error_t err;          free (rev);
212      char buf[200];          rev = r;
213        }
214      if (!this->key)  }
215          return gpg_error (GPG_ERR_INV_OBJ);  
216    
217      err = gpgme_data_new (&out);  static gpgme_error_t
218      if (err)  list2_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)
219          goto leave;  {
220        DWORD n;
221      err = gpgme_op_edit (ctx, key, NULL, NULL, out);      const char *s;
222      if (err)  
223          goto leave;      if (!strcmp (key, "keyedit.prompt")) {
224            s = "quit\n";
225      while (gpg_data_readline (out, buf, 199))          WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
226          rev_key_colon_handler (&rev, buf);      }    
227      *r_rev = rev;      return 0;
228    }
229  leave:  
230      if (out)  
231          gpgme_data_release (out);  /* Dummy handler to get the colon data and then quit. */
232      if (err) {  static gpgme_error_t
233          gpg_desig_rev_release (rev);  list_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)
234          *r_rev = NULL;  {
235      }      static int step=0;
236      return err;      const char *s="";
237  }      DWORD n;
238    
239  /* Retrieve all user ID information of the key set via setKey      if (!strcmp (key, "keyedit.prompt") && step == 0) {
240     in @r_inf. The result also contains the user ID number which          step = 1;
241     is needed to securely delete the user-ID. */          s = "list\n";
242  gpgme_error_t          WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
243  GpgKeyEdit::getUseridInfo (gpg_uid_info_t *r_uinf)      }
244  {      else if (!strcmp (key, "keyedit.prompt") && step == 1) {
245      gpgme_data_t out = NULL;              step = 0;
246      gpgme_error_t err;          s = "quit\n";
247      gpg_uid_info_t inf = NULL;          WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
248      char buf[200];      }
249    
250      if (!this->key)      return 0;
251          return gpg_error (GPG_ERR_INV_OBJ);  }
252    
253      err = gpgme_data_new (&out);  
254      if (err)  /* Return all designated revokers for this key. If no revoker
255          goto leave;     was set, @r_rev is NULL.
256       Return value: 0 on success. */
257      err = gpgme_op_edit (ctx, key, NULL, NULL, out);  gpgme_error_t
258      if (err)  GpgKeyEdit::getDesignatedRevoker (gpg_desig_rev_t *r_rev)
259          goto leave;  {
260            gpgme_data_t out = NULL;
261      while (gpg_data_readline (out, buf, sizeof buf -1))      gpg_desig_rev_t rev = NULL;
262          uid_inf_colon_handler (&inf, buf);      gpgme_error_t err;
263        char buf[256];
264      *r_uinf = inf;  
265        if (!this->key)
266  leave:          return gpg_error (GPG_ERR_INV_OBJ);
267      if (out)  
268          gpgme_data_release (out);      err = gpgme_data_new (&out);
269      if (err) {      if (err)
270          gpg_uid_info_release (inf);          goto leave;
271          *r_uinf = NULL;  
272      }      err = gpgme_op_edit (ctx, key, list2_handler, NULL, out);
273      return err;      if (err)
274  }          goto leave;
275        
276        gpgme_data_rewind (out);
277  /* Construct an object with the given key in @key. */      while (gpg_data_readline (out, buf, sizeof (buf)-1) > 0)
278  GpgKeyEdit::GpgKeyEdit (gpgme_key_t key)          rev_key_colon_handler (&rev, buf);
279  {      *r_rev = rev;
280      this->key = key;  
281      pass = NULL;  leave:
282      type = 0;      if (out)
283      name = NULL;          gpgme_data_release (out);
284      cmt = NULL;      if (err) {
285      email = NULL;          gpg_desig_rev_release (rev);
286      gpgme_new (&ctx); /* FIXME */          *r_rev = NULL;
287  }      }
288        return err;
289  /* Construct an object and fetch the key with the keyid @keyid. */  }
290  GpgKeyEdit::GpgKeyEdit (const char *keyid)  
291  {  
292      get_pubkey (keyid, &this->key);  /* Retrieve all user ID information of the key set via setKey
293      pass = NULL;     in @r_inf. The result also contains the user ID number which
294      type = 0;     is needed to securely delete the user-ID. */
295      name = NULL;  gpgme_error_t
296      cmt = NULL;  GpgKeyEdit::getUseridInfo (gpg_uid_info_t *r_uinf)
297      email = NULL;  {
298      gpgme_new (&ctx); /* FIXME */      gpgme_data_t out = NULL;    
299  }      gpgme_error_t err;
300        gpg_uid_info_t inf = NULL;
301  /* Delete the given object. */      char buf[256];
302  GpgKeyEdit::~GpgKeyEdit (void)  
303  {      if (!this->key)
304      free_if_alloc (name);          return gpg_error (GPG_ERR_INV_OBJ);
305      free_if_alloc (cmt);  
306      free_if_alloc (email);      err = gpgme_data_new (&out);
307      gpgme_release (ctx);      if (err)
308  }          goto leave;
309    
310        err = gpgme_op_edit (ctx, key, list_handler, NULL, out);
311  /* Return true if type has a non-zero value. */      if (err)
312  bool          goto leave;
313  GpgKeyEdit::isValid (void)      
314  {      gpgme_data_rewind (out);
315      return type != 0;      while (gpg_data_readline (out, buf, sizeof (buf) -1) > 0)
316  }          uid_inf_colon_handler (&inf, buf);
317    
318        *r_uinf = inf;
319  /* Return the GPGME key. */  
320  gpgme_key_t  leave:
321  GpgKeyEdit::getKey (void)      if (out)
322  {          gpgme_data_release (out);
323      return key;      if (err) {
324  }          gpg_uid_info_release (inf);
325            *r_uinf = NULL;
326        }
327  /* Set the GPGME callback to @cb. The hook value can be      return err;
328     given in @cb_value. */  }
329  void  
330  GpgKeyEdit::setCallback (gpgme_progress_cb_t cb, void *cb_value)  
331  {  /* Clear object. */
332      gpgme_set_progress_cb (ctx, cb, cb_value);  void
333  }  GpgKeyEdit::clear (void)
334    {
335  /* Set the passphrase to @pass. */      pass = NULL;    
336  void      name = NULL;
337  GpgKeyEdit::setPassphrase (const char *pass)      cmt = NULL;
338  {      email = NULL;
339      this->pass = pass;      type = 0;
340  }      cnt = 0;
341        cmd_sent = 0;
342  /* Set the current key to @key. */      resval = 0;
343  void      uid_index = sig_index = key_index = -1;
344  GpgKeyEdit::setKey (gpgme_key_t key)      key_has_passwd = true;
345  {  }
346      this->key = key;  
347  }  
348    /* Construct an object with the given key in @key. */
349  void  GpgKeyEdit::GpgKeyEdit (gpgme_key_t _key)
350  GpgKeyEdit::setKeyID (const char *keyid)  {
351  {      clear ();
352      if (!keyid)      this->key = _key;
353          return;      gpgme_new (&ctx); /* FIXME */
354      get_pubkey (keyid, &this->key);  }
355  }  
356    /* Construct an object and fetch the key with the keyid @keyid. */
357    GpgKeyEdit::GpgKeyEdit (const char *_keyid)
358  void  {
359  GpgKeyEdit::setLocalUser (gpgme_key_t locusr)      clear ();
360  {      get_pubkey (_keyid, &this->key);
361      gpgme_signers_add (ctx, locusr);      gpgme_new (&ctx); /* FIXME */    
362  }  }
363    
364    /* Delete the given object. */
365  /* Sign the key stored in the object with the  GpgKeyEdit::~GpgKeyEdit (void)
366     signing mode @mode and the signature class @sig_class.  {
367     Return value: 0 on success. */      free_if_alloc (name);
368  gpgme_error_t      free_if_alloc (cmt);
369  GpgKeyEdit::signKey (int mode, int sig_class, const char *exp_date)      free_if_alloc (email);
370  {      gpgme_release (ctx);
371      if (!this->key || !this->pass)  }
372          return gpg_error (GPG_ERR_INV_OBJ);  
373    
374      type = mode;  /* Reset the state of the object. */
375      this->exp_date = exp_date;  void
376      this->sig_class = sig_class;  GpgKeyEdit::reset (void)
377      return gpg_editkey (this->ctx, this->key, this);  {
378  }      cmd_sent = 0;
379        cnt = 0;
380  /* Set the ownertrust of the key stored in the object      //resval = 0;
381     to the trust value @trust.  }
382     Return value: 0 on success. */  
383  gpgme_error_t  
384  GpgKeyEdit::setTrust (gpgme_validity_t trust)  /* Return true if type has a non-zero value. */
385  {  bool
386      if (!this->key)  GpgKeyEdit::isValid (void)
387          return gpg_error (GPG_ERR_INV_OBJ);  {
388        return type != 0;
389      type = GPG_EDITKEY_TRUST;  }
390      this->trust_id = (int)trust;  
391      return gpg_editkey (this->ctx, this->key, this);  
392  }  /* Return the GPGME key. */
393    gpgme_key_t
394  /* Add a user ID to the given key with the @name as the  GpgKeyEdit::getKey (void)
395     name, @cmt as the comment (or NULL) and @email as the email.  {
396     Return value: 0 on success. */      return key;
397  gpgme_error_t  }
398  GpgKeyEdit::addUserid (const char *name, const char *cmt, const char *email)  
399  {  
400      if (!this->key || !this->pass)  /* Set the GPGME callback to @cb. The hook value can be
401          return gpg_error (GPG_ERR_INV_OBJ);     given in @cb_value. */
402    void
403      type = GPG_EDITKEY_ADDUID;  GpgKeyEdit::setCallback (gpgme_progress_cb_t cb, void *cb_value)
404      free_if_alloc (this->name);  {
405      this->name = m_strdup (name);      gpgme_set_progress_cb (ctx, cb, cb_value);
406      free_if_alloc (this->cmt);  }
407      this->cmt = m_strdup (cmt);  
408      free_if_alloc (this->email);  
409      this->email = m_strdup (email);  /* Clear the stored passphrase. */
410      if (!this->email || !this->name || !this->cmt)  void
411          BUG (NULL);  GpgKeyEdit::clearPassphrase (void)
412      return gpg_editkey (this->ctx, this->key, this);  {
413  }      if (pass)
414            pass = NULL;
415  /* Delete the user-ID with the index @uid_index of the given key.  }
416     Return value: 0 on success. */  
417  gpgme_error_t  
418  GpgKeyEdit::delUserid (int uid_index)  
419  {  /* Inidicate that a key is protected by  a passphrase or not. */
420      if (!this->key)  void
421          return gpg_error (GPG_ERR_INV_OBJ);  GpgKeyEdit::setNoPassphrase (bool val)
422    {
423      type = GPG_EDITKEY_DELUID;      key_has_passwd = !val;
424      this->uid_index = uid_index;  }
425      return gpg_editkey (this->ctx, this->key, this);  
426  }  /* Set the passphrase to @pass. */
427    void
428  /* Delete the subkey with the index @key_index.  GpgKeyEdit::setPassphrase (const char *_pass)
429     Return value: 0 on success. */  {
430  gpgme_error_t      this->pass = _pass;
431  GpgKeyEdit::delKey (int key_index)  }
432  {  
433      if (!this->key)  /* Set the current key to @key. */
434          return gpg_error (GPG_ERR_INV_OBJ);  void
435    GpgKeyEdit::setKey (gpgme_key_t _key)
436      type = GPG_EDITKEY_DELKEY;  {
437      this->key_index = key_index;      this->key = _key;
438      return gpg_editkey (this->ctx, this->key, this);  }
439  }  
440    /* Set the keyid of the destination key to @keyid. */
441  /* Add a new subkey to the given key.  void
442     The new key will have @pubkey_algo as the algorithm  GpgKeyEdit::setKeyID (const char *_keyid)
443     and a size of @pubkey_size bits. If valid > 0, the  {
444     key expires in @valid days.      if (!_keyid)
445     Return value: 0 on success. */          return;
446  gpgme_error_t      get_pubkey (_keyid, &this->key);
447  GpgKeyEdit::addSubkey (gpgme_pubkey_algo_t pubkey_algo, unsigned int pubkey_size,  }
448                         long valid)  
449  {  
450      if (!this->key || !this->pass)  /* Set the local user for the operation to @locusr. */
451          return gpg_error (GPG_ERR_INV_OBJ);  void
452    GpgKeyEdit::setLocalUser (gpgme_key_t locusr)
453      type = GPG_EDITKEY_ADDKEY;  {
454      this->pubkey_algo = pubkey_algo;      gpgme_signers_add (ctx, locusr);
455      this->pubkey_size = pubkey_size;  }
456      this->valid = valid;  
457      return gpg_editkey (this->ctx, this->key, this);  /* Set the result of the operation to @val. */
458  }  void
459    GpgKeyEdit::setResult (int val)
460  /* Change the passphrase of the given key to @new_pass.  {
461     If allow_empty != 0, it is allowed to provide an empty passphrase.      resval |= val;
462     Return value: 0 on success. */  }
463  gpgme_error_t  
464  GpgKeyEdit::changePassphrase (const char *new_pass, int allow_empty)  
465  {  /* Return the result of the operation. */
466      if (!this->key || !this->pass)  int
467          return gpg_error (GPG_ERR_INV_OBJ);  GpgKeyEdit::getResult(void)
468        {
469      type = GPG_EDITKEY_PASSWD;      return resval;
470      this->new_pass = new_pass;  }
471      this->flags = allow_empty? 1 : 0;  
472      return gpg_editkey (this->ctx, this->key, this);  
473  }  /* Return the amount of days the key is valid. */
474    int
475  /* Set the primary user-ID of the given key to user-ID with  GpgKeyEdit::getValidDays (void)
476     the index @uid_index.  {
477     Return value: 0 on success. */      return valid;
478  gpgme_error_t  }
479  GpgKeyEdit::setPrimaryUserid (int uid_index)  
480  {  
481      if (!this->key || !this->pass)  int
482          return gpg_error (GPG_ERR_INV_OBJ);  GpgKeyEdit::getType (void)
483    {
484      type = GPG_EDITKEY_PRIMARY;      return type;
485      this->uid_index = uid_index;  }
486      return gpg_editkey (this->ctx, this->key, this);  
487  }  
488    /* Add the notation data from @notation to the user ID
489  /* Set the expire date of the subkey with the index @key_index.     with the index @_uid_idx.
490     @exp_timestamp is used to calculate the days the key is valid.     Return value: 0 on success.  */
491     Return value: 0 on success. */  gpgme_error_t
492  gpgme_error_t  GpgKeyEdit::addNotation (int _uid_idx, const char *_notation)
493  GpgKeyEdit::setKeyExpireDate (int key_index, long exp_timestamp)  {
494  {      if (!key)
495      if (!this->key || !this->pass)          return gpg_error (GPG_ERR_INV_OBJ);
496          return gpg_error (GPG_ERR_INV_OBJ);      if (key_has_passwd && !this->pass)
497      if (exp_timestamp > 0 && exp_timestamp < time (NULL))          return gpg_error (GPG_ERR_INV_PASSPHRASE);
498          return gpg_error (GPG_ERR_INV_ARG);  
499        type = GPG_EDITKEY_NOTATION;
500      valid = 0;      this->uid_index = _uid_idx;
501      if (exp_timestamp > 0) {      this->notation = (char*)_notation;
502          valid = exp_timestamp - time (NULL);      return gpg_editkey (this->ctx, this->key, this);
503          valid /= 86400;  }
504          type = GPG_EDITKEY_EXPIRE;  
505      }  
506      this->key_index = key_index;  /* Sign the key stored in the object with the
507      return gpg_editkey (this->ctx, this->key, this);     signing mode @mode and the signature class @sig_class.
508  }     Return value: 0 on success. */
509    gpgme_error_t
510    GpgKeyEdit::signKey (int mode, int _sig_class, const char *_exp_date)
511  /* Revoke a signature on the user-ID with the index @uid_index  {
512     and the signature index @sig_index.      if (!this->key)
513     Return value: 0 on success. */          return gpg_error (GPG_ERR_INV_OBJ);
514  gpgme_error_t      if (key_has_passwd && !this->pass)
515  GpgKeyEdit::revokeSignature (int uid_index, int sig_index)          return gpg_error (GPG_ERR_INV_PASSPHRASE);
516  {  
517      if (!this->key || !this->pass)      type = mode;
518          return gpg_error (GPG_ERR_INV_OBJ);      this->exp_date = _exp_date;
519        this->sig_class = _sig_class;
520      type = GPG_EDITKEY_REVSIG;      return gpg_editkey (this->ctx, this->key, this);
521      this->uid_index = uid_index;  }
522      this->sig_index = sig_index;  
523      return gpg_editkey (this->ctx, this->key, this);  
524  }  /* Sign a single user-id with the index @_uid_index.
525       All other parameters are equal to signKey().
526       Return value: 0 on success. */
527  /* Revoke the subkey with the index @key_index. Optionally  gpgme_error_t
528     a reason can be provided in @reason with a text to describe  GpgKeyEdit::signUserid (int _uid_idx, int mode, int _sig_class,
529     more details in @cmt.                          const char *_exp_date)
530     Return value: 0 on success. */  {
531  gpgme_error_t      if (!this->key)
532  GpgKeyEdit::revokeSubkey (int key_index, int reason, const char *cmt)          return gpg_error (GPG_ERR_INV_OBJ);
533  {      if (key_has_passwd && !this->pass)
534      if (!this->key || !this->pass)          return gpg_error (GPG_ERR_INV_PASSPHRASE);
535          return gpg_error (GPG_ERR_INV_OBJ);  
536        this->uid_index = _uid_idx;
537      type = GPG_EDITKEY_REVKEY;      type = mode;
538      this->key_index = key_index;      this->exp_date = _exp_date;
539      this->reason = reason;      this->sig_class = _sig_class;
540      free_if_alloc (this->cmt);      return gpg_editkey (this->ctx, this->key, this);
541      this->cmt = m_strdup (cmt);  }
542      return gpg_editkey (this->ctx, this->key, this);  
543  }  
544    /* Set the ownertrust of the key stored in the object
545       to the trust value @trust.
546  /* Revoke an entire key. With the reason given in @reason     Return value: 0 on success. */
547     and the description in @cmt.  gpgme_error_t
548     Return value: 0 on success. */  GpgKeyEdit::setTrust (gpgme_validity_t trust)
549  gpgme_error_t  {
550  GpgKeyEdit::revokeKey (int reason, const char *cmt)      if (!this->key)
551  {          return gpg_error (GPG_ERR_INV_OBJ);
552      if (!this->key || !this->pass)  
553          return gpg_error (GPG_ERR_INV_OBJ);      type = GPG_EDITKEY_TRUST;
554        this->trust_id = (int)trust;
555      type = GPG_EDITKEY_REVOKE;      return gpg_editkey (this->ctx, this->key, this);
556      this->reason = reason;  }
557      free_if_alloc (this->cmt);  
558      this->cmt = m_strdup (cmt);  /* Add a user ID to the given key with the @name as the
559      return gpg_editkey (this->ctx, this->key, this);     name, @cmt as the comment (or NULL) and @email as the email.
560  }     Return value: 0 on success. */
561    gpgme_error_t
562    GpgKeyEdit::addUserid (const char *_name, const char *_cmt, const char *_email)
563  /* Add a designated revoker to the key. @uid stores  {
564     the user-ID of the key who is allowed to be a      if (!this->key)
565     designated revoker.          return gpg_error (GPG_ERR_INV_OBJ);
566     Return value: 0 on success. */      if (key_has_passwd && !this->pass)
567  gpgme_error_t          return gpg_error (GPG_ERR_INV_PASSPHRASE);
568  GpgKeyEdit::addDesignatedRevoker (const char *uid)  
569  {      type = GPG_EDITKEY_ADDUID;
570      if (!this->key || !this->pass)      free_if_alloc (this->name);
571          return gpg_error (GPG_ERR_INV_OBJ);      this->name = m_strdup (_name);
572        free_if_alloc (this->cmt);
573      type = GPG_EDITKEY_ADDREV;      this->cmt = NULL;
574      free_if_alloc (this->name);      if (_cmt != NULL)
575      this->name = m_strdup (uid);          this->cmt = m_strdup (_cmt);    
576      return gpg_editkey (this->ctx, this->key, this);      free_if_alloc (this->email);
577  }      this->email = m_strdup (_email);
578        if (!this->email || !this->name)
579  /* Add a photo-ID to the key. The JPG image is given          BUG (NULL);
580     in the file with the name @jpg_file.      return gpg_editkey (this->ctx, this->key, this);
581     Return value: 0 on success. */  }
582  gpgme_error_t  
583  GpgKeyEdit::addPhotoid (const char *jpg_file)  /* Delete the user-ID with the index @uid_index of the given key.
584  {     Return value: 0 on success. */
585      if (!this->key || !this->pass)  gpgme_error_t
586          return gpg_error (GPG_ERR_INV_OBJ);  GpgKeyEdit::delUserid (int _uid_index)
587    {
588      type = GPG_EDITKEY_ADDPHOTO;      if (!this->key)
589      this->url = jpg_file;          return gpg_error (GPG_ERR_INV_OBJ);
590      return gpg_editkey (this->ctx, this->key, this);  
591  }      type = GPG_EDITKEY_DELUID;
592        this->uid_index = _uid_index;
593  /* Enable the given key. */      return gpg_editkey (this->ctx, this->key, this);
594  gpgme_error_t  }
595  GpgKeyEdit::enable (void)  
596  {  /* Delete the subkey with the index @key_index.
597      if (!this->key)     Return value: 0 on success. */
598          return gpg_error (GPG_ERR_INV_OBJ);  gpgme_error_t
599      type = GPG_EDITKEY_ENABLE;  GpgKeyEdit::delKey (int _key_index)
600      return gpg_editkey (this->ctx, this->key, this);  {
601  }      if (!this->key)
602            return gpg_error (GPG_ERR_INV_OBJ);
603  /* Disable the given key. */  
604  gpgme_error_t      type = GPG_EDITKEY_DELKEY;
605  GpgKeyEdit::disable (void)      this->key_index = _key_index;
606  {      return gpg_editkey (this->ctx, this->key, this);
607      if (!this->key)  }
608          return gpg_error (GPG_ERR_INV_OBJ);  
609      type = GPG_EDITKEY_DISABLE;  /* Add a new subkey to the given key.
610      return gpg_editkey (this->ctx, this->key, this);     The new key will have @pubkey_algo as the algorithm
611  }     and a size of @pubkey_size bits. If valid > 0, the
612       key expires in @valid days.
613       Return value: 0 on success. */
614  /* Update the user-ID preferences of the user-ID with the  gpgme_error_t
615     index @uid_index to the prefs given in @new_prefs.  GpgKeyEdit::addSubkey (gpgme_pubkey_algo_t _pubkey_algo,
616     Return value: 0 on success. */                         unsigned int _pubkey_size, long _valid)
617  gpgme_error_t  {
618  GpgKeyEdit::setUseridPreferences (int uid_index, const char *new_prefs)      if (!this->key)
619  {          return gpg_error (GPG_ERR_INV_OBJ);
620      if (!this->key || !this->pass)      if (key_has_passwd && !this->pass)
621          return gpg_error (GPG_ERR_INV_OBJ);          return gpg_error (GPG_ERR_INV_PASSPHRASE);
622      return GPG_ERR_NO_ERROR;  
623  }      type = GPG_EDITKEY_ADDKEY;
624        this->pubkey_algo = _pubkey_algo;
625        this->pubkey_size = _pubkey_size;
626  /* Delete a signature from the user-ID with the index @uid_index.      this->valid = _valid;
627     The index of the signature is given in @sig_index.      return gpg_editkey (this->ctx, this->key, this);
628     Return value: 0 on success. */  }
629  gpgme_error_t  
630  GpgKeyEdit::deleteUseridSignature (int uid_index, int sig_index)  /* Change the passphrase of the given key to @new_pass.
631  {     If allow_empty != 0, it is allowed to provide an empty passphrase.
632      if (!this->key)     Return value: 0 on success. */
633          return gpg_error (GPG_ERR_INV_OBJ);  gpgme_error_t
634      type = GPG_EDITKEY_DELSIG;  GpgKeyEdit::changePassphrase (const char *_new_pass, int allow_empty)
635      this->uid_index = uid_index;  {
636      this->sig_index = sig_index;      if (!this->key)
637      return gpg_editkey (this->ctx, this->key, this);          return gpg_error (GPG_ERR_INV_OBJ);
638  }      if (key_has_passwd && !this->pass)
639            return gpg_error (GPG_ERR_INV_PASSPHRASE);
640  /* Set the preferred keyserver for the given key to @url.      
641     Return value: 0 on success. */      type = GPG_EDITKEY_PASSWD;
642  gpgme_error_t      this->new_pass = _new_pass;
643  GpgKeyEdit::setPreferredKeyserver (int uid_index, const char *url)      this->flags = allow_empty? 1 : 0;
644  {      return gpg_editkey (this->ctx, this->key, this);
645      if (!this->key || !this->pass)  }
646          return gpg_error (GPG_ERR_INV_OBJ);  
647      if (!url)  /* Set the primary user-ID of the given key to user-ID with
648          return gpg_error (GPG_ERR_INV_ARG);     the index @uid_index.
649      type = GPG_EDITKEY_KEYSERV;     Return value: 0 on success. */
650      this->url = url;  gpgme_error_t
651      this->uid_index = uid_index;  GpgKeyEdit::setPrimaryUserid (int _uid_index)
652      return gpg_editkey (this->ctx, this->key, this);  {
653  }      if (!this->key)
654            return gpg_error (GPG_ERR_INV_OBJ);
655        if (key_has_passwd && !this->pass)
656            return gpg_error (GPG_ERR_INV_PASSPHRASE);
657    
658        type = GPG_EDITKEY_PRIMARY;
659        this->uid_index = _uid_index;
660        return gpg_editkey (this->ctx, this->key, this);
661    }
662    
663    /* Set the expire date of the subkey with the index @key_index.
664       @exp_timestamp is used to calculate the days the key is valid.
665       if @exp_days is true, exp_timestamp is already converted to days.
666       Return value: 0 on success. */
667    gpgme_error_t
668    GpgKeyEdit::setKeyExpireDate (int _key_index, long exp_timestamp,
669                                  bool exp_days)
670    {
671        if (!this->key)
672            return gpg_error (GPG_ERR_INV_OBJ);
673        if (key_has_passwd && !this->pass)
674            return gpg_error (GPG_ERR_INV_PASSPHRASE);
675        if (!exp_days && exp_timestamp > 0 && exp_timestamp < time (NULL))
676            return gpg_error (GPG_ERR_INV_ARG);
677        
678        type = GPG_EDITKEY_EXPIRE;
679        if (!exp_days && exp_timestamp > 0) {
680            valid = exp_timestamp - time (NULL);
681            valid /= 86400;
682        }
683        else
684            valid = exp_timestamp;
685        this->key_index = _key_index;
686        return gpg_editkey (this->ctx, this->key, this);
687    }
688    
689    /* Revoke the userid given by the index @uid_index.
690       Return value: 0 on success. */
691    gpgme_error_t
692    GpgKeyEdit::revokeUserid (int _uid_index)
693    {
694        if (!this->key)
695            return gpg_error (GPG_ERR_INV_OBJ);
696        if (key_has_passwd && !this->pass)
697            return gpg_error (GPG_ERR_INV_PASSPHRASE);
698    
699        type = GPG_EDITKEY_REVUID;
700        this->uid_index = _uid_index;
701        return gpg_editkey (this->ctx, this->key, this);
702    }
703    
704    
705    /* Revoke a signature on the user-ID with the index @uid_index
706       and the signature index @sig_index.
707       Return value: 0 on success. */
708    gpgme_error_t
709    GpgKeyEdit::revokeSignature (int _uid_index, int _sig_index)
710    {
711        if (!this->key)
712            return gpg_error (GPG_ERR_INV_OBJ);
713        if (key_has_passwd && !this->pass)
714            return gpg_error (GPG_ERR_INV_PASSPHRASE);
715    
716        type = GPG_EDITKEY_REVSIG;
717        this->uid_index = _uid_index;
718        this->sig_index = _sig_index;
719        return gpg_editkey (this->ctx, this->key, this);
720    }
721    
722    
723    /* Revoke the subkey with the index @key_index. Optionally
724       a reason can be provided in @reason with a text to describe
725       more details in @cmt.
726       Return value: 0 on success. */
727    gpgme_error_t
728    GpgKeyEdit::revokeSubkey (int _key_index, int _reason, const char *_cmt)
729    {
730        if (!this->key)
731            return gpg_error (GPG_ERR_INV_OBJ);
732        if (key_has_passwd && !this->pass)
733            return gpg_error (GPG_ERR_INV_PASSPHRASE);
734    
735        type = GPG_EDITKEY_REVKEY;
736        this->key_index = _key_index;
737        this->reason = _reason;
738        free_if_alloc (this->cmt);
739        this->cmt = NULL;
740        if (_cmt)
741            this->cmt = m_strdup (_cmt);
742        return gpg_editkey (this->ctx, this->key, this);
743    }
744    
745    
746    /* Add a designated revoker to the key. @uid stores
747       the user-ID of the key who is allowed to be a
748       designated revoker.
749       Return value: 0 on success. */
750    gpgme_error_t
751    GpgKeyEdit::addDesignatedRevoker (const char *uid)
752    {
753        if (!this->key)
754            return gpg_error (GPG_ERR_INV_OBJ);
755        if (key_has_passwd && !this->pass)
756            return gpg_error (GPG_ERR_INV_PASSPHRASE);
757    
758        type = GPG_EDITKEY_ADDREV;
759        free_if_alloc (this->name);
760        this->name = m_strdup (uid);
761        return gpg_editkey (this->ctx, this->key, this);
762    }
763    
764    /* Add a photo-ID to the key. The JPG image is given
765       in the file with the name @jpg_file.
766       Return value: 0 on success. */
767    gpgme_error_t
768    GpgKeyEdit::addPhotoid (const char *jpg_file)
769    {
770        if (!this->key)
771            return gpg_error (GPG_ERR_INV_OBJ);
772        if (key_has_passwd && !this->pass)
773            return gpg_error (GPG_ERR_INV_PASSPHRASE);
774    
775        type = GPG_EDITKEY_ADDPHOTO;
776        this->url = jpg_file;
777        return gpg_editkey (this->ctx, this->key, this);
778    }
779    
780    /* Enable the given key. */
781    gpgme_error_t
782    GpgKeyEdit::enable (void)
783    {
784        if (!this->key)
785            return gpg_error (GPG_ERR_INV_OBJ);
786        type = GPG_EDITKEY_ENABLE;
787        return gpg_editkey (this->ctx, this->key, this);
788    }
789    
790    /* Disable the given key. */
791    gpgme_error_t
792    GpgKeyEdit::disable (void)
793    {
794        if (!this->key)
795            return gpg_error (GPG_ERR_INV_OBJ);
796        type = GPG_EDITKEY_DISABLE;
797        return gpg_editkey (this->ctx, this->key, this);
798    }
799    
800    
801    /* Remove unusable parts from a key. */
802    gpgme_error_t
803    GpgKeyEdit::cleanKey (void)
804    {
805        if (!this->key)
806            return gpg_error (GPG_ERR_INV_OBJ);
807        type = GPG_EDITKEY_CLEAN;
808        return gpg_editkey (this->ctx, this->key, this);
809    }
810    
811    
812    /* Update the user-ID preferences of the user-ID with the
813       index @uid_index to the prefs given in @new_prefs.
814       Return value: 0 on success. */
815    gpgme_error_t
816    GpgKeyEdit::setUseridPreferences (int _uid_index, const char *new_prefs)
817    {
818        if (!this->key)
819            return gpg_error (GPG_ERR_INV_OBJ);
820        if (key_has_passwd && !this->pass)
821            return gpg_error (GPG_ERR_INV_PASSPHRASE);
822        return 0;
823    }
824    
825    
826    /* Delete a signature from the user-ID with the index @uid_index.
827       The index of the signature is given in @sig_index.
828       Return value: 0 on success. */
829    gpgme_error_t
830    GpgKeyEdit::delUseridSignature (int _uid_index, int _sig_index)
831    {
832        if (!this->key)
833            return gpg_error (GPG_ERR_INV_OBJ);
834        type = GPG_EDITKEY_DELSIG;
835        this->uid_index = _uid_index;
836        this->sig_index = _sig_index;
837        return gpg_editkey (this->ctx, this->key, this);
838    }
839    
840    /* Set the preferred keyserver for the given key to @url.
841       If @_uid_index is -1, set the keyserver for all user-ids.
842       Return value: 0 on success. */
843    gpgme_error_t
844    GpgKeyEdit::setPreferredKeyserver (int _uid_index, const char *_url)
845    {
846        if (!this->key)
847            return gpg_error (GPG_ERR_INV_OBJ);
848        if (key_has_passwd && !this->pass)
849            return gpg_error (GPG_ERR_INV_PASSPHRASE);
850        if (!_url)
851            return gpg_error (GPG_ERR_INV_ARG);
852    
853        type = GPG_EDITKEY_KEYSERV;
854        this->url = _url;
855        this->uid_index = _uid_index;
856        return gpg_editkey (this->ctx, this->key, this);
857    }
858    
859    
860    /* Return the saved user-id index. */
861    int
862    GpgKeyEdit::getUseridIndex (void)
863    {
864        return uid_index;
865    }
866    
867    
868    /* Return the saved key index. */  
869    int
870    GpgKeyEdit::getKeyIndex (void)
871    {
872        return key_index;
873    }
874    
875    
876    /* Return the saved sig index. */
877    int
878    GpgKeyEdit::getSigIndex (void)
879    {
880        return sig_index;
881    }

Legend:
Removed from v.23  
changed lines
  Added in v.205

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26