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

Legend:
Removed from v.35  
changed lines
  Added in v.36

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26