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

Legend:
Removed from v.24  
changed lines
  Added in v.200

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26