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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26