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

Legend:
Removed from v.23  
changed lines
  Added in v.77

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26