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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26