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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26