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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26