/[winpt]/trunk/Src/wptCardEdit.cpp
ViewVC logotype

Diff of /trunk/Src/wptCardEdit.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 36 by werner, Thu Oct 27 15:25:13 2005 UTC
# Line 1  Line 1 
1  /* wptCardEdit.cpp - OpenPGP editing interface  /* wptCardEdit.cpp - OpenPGP editing interface
2   *      Copyright (C) 2005 Timo Schulz   *      Copyright (C) 2005 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
6   * WinPT is free software; you can redistribute it and/or modify   * WinPT is free software; you can redistribute it and/or modify
7   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
8   * the Free Software Foundation; either version 2 of the License, or   * the Free Software Foundation; either version 2 of the License, or
9   * (at your option) any later version.   * (at your option) any later version.
10   *   *
11   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
15   *   *
16   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19   */   */
20    
21  #include <windows.h>  #ifdef HAVE_CONFIG_H
22  #include <io.h>  #include <config.h>
23  #include "w32gpgme.h"  #endif
24  #include "wptCardEdit.h"  
25    #include <windows.h>
26    #include <windows.h>
27  /* Create a new Smartcard context. */  #include <time.h>
28  static gpgme_error_t  
29  gpg_card_new (gpg_card_t * ret_card)  #include "gpgme.h"
30  {  #include "wptCard.h"
31      gpg_card_t c;  #include "wptCardEdit.h"
32    #include "wptGPG.h"
33      if (!ret_card)  #include "wptErrors.h"
34          return gpg_error (GPG_ERR_INV_ARG);  
35      *ret_card = NULL;  /* Create a new Smartcard context. */
36      c = (gpg_card_t)calloc (1, sizeof *c);  static gpgme_error_t
37      if( !c )  gpg_card_new (gpg_card_t *ret_card)
38          return gpg_error (GPG_ERR_ENOMEM);  {
39      *ret_card = c;      gpg_card_t c;
40      return 0;  
41  }      if (!ret_card)
42            return gpg_error (GPG_ERR_INV_ARG);
43        *ret_card = NULL;
44  /* Release an existing Smartcard context. @card. */      c = (gpg_card_t)calloc (1, sizeof *c);
45  void      if (!c)
46  gpg_card_release (gpg_card_t card)          return gpg_error (GPG_ERR_ENOMEM);
47  {      *ret_card = c;
48      int i;      return 0;
49    }
50      if (!card)  
51          return;  
52      if (card->aid)  /* Release an existing Smartcard context. @card. */
53          free (card->aid);    void
54      if (card->version)  gpg_card_release (gpg_card_t card)
55          free (card->version);  {
56      if (card->lang)      int i;
57          free (card->lang);  
58      if (card->login)      if (!card)
59          free (card->login);          return;
60            if (card->aid)
61      for (i=0; i < 3; i++) {          free (card->aid);  
62          if (card->fpr[i])      if (card->version)
63              free (card->fpr[i]);          free (card->version);
64      }      if (card->lang)
65      if (card->surname)          free (card->lang);
66          free (card->surname);      if (card->login)
67      if (card->givenname)          free (card->login);
68          free (card->givenname);      for (i=0; i < 3; i++) {
69      if (card->serial)          if (card->fpr[i])
70          free (card->serial);              free (card->fpr[i]);
71      if (card->vendor)          if (card->ca_fpr[i])
72          free (card->vendor);              free (card->ca_fpr[i]);
73      if (card->url)          if (card->fpr_created_str[i])
74          free (card->url);              free (card->fpr_created_str[i]);
75      free (card);      }
76        if (card->surname)
77  }          free (card->surname);
78        if (card->givenname)
79            free (card->givenname);
80  /* Colon handler for parsing the GPG card colon output. */      if (card->serial)
81  static gpgme_error_t          free (card->serial);
82  statuscard_colon_handler (gpg_card_t *ctx, char * line, int *cnt)      if (card->vendor)
83  {          free (card->vendor);
84      enum rectype_t {      if (card->url)
85          CARD_None = 0,          free (card->url);
86          CARD_AID,      if (card->card_type)
87          CARD_Version,          free (card->card_type);
88          CARD_Vendor,      free (card);
89          CARD_Serial,  
90          CARD_Name,  }
91          CARD_Lang,  
92          CARD_Sex,  
93          CARD_Url,  /* Parse the timestamp @long_ts and return a string
94          CARD_Login,     representation of it (format: YYYY-DD-MM HH:MM:SS). */
95          CARD_MaxPinLen,  static char*
96          CARD_SigCount,  get_str_timestamp (long long_ts)
97          CARD_Fpr  {
98      };          struct tm *tm;
99      enum rectype_t rectype;          char *p, *fmt;
100      gpgme_error_t err;  
101      gpg_card_t card;      tm = localtime (&long_ts);
102      char *p, *pend;      fmt = "%04d-%02d-%02d %02d:%02d:%02d";
103      int field = 0;      p = (char*)calloc (1, strlen (fmt)+32);
104        if (!p)
105      if (!line)          abort ();
106          return gpg_error (GPG_ERR_EOF);      sprintf (p, fmt,
107                     tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
108      if (!*ctx) {               tm->tm_hour, tm->tm_min, tm->tm_sec);
109          err = gpg_card_new (ctx);      return p;
110          return err;  }
111      }  
112      card = *ctx;  
113    /* Colon handler for parsing the GPG card colon output. */
114      for( p = line; p; p = pend ) {  static gpgme_error_t
115          field++;  statuscard_colon_handler (gpg_card_t card, char * line)
116          pend = strchr (p, ':');  {
117          if (pend)      enum rectype_t {
118              *pend++ = 0;          CARD_None = 0,
119            CARD_AID,
120          if (field == 1) {          CARD_Version,
121              if (!strcmp (p, "AID"))          CARD_Vendor,
122                  rectype = CARD_AID;          CARD_Serial,
123              else if( !strcmp( p, "version" ) )          CARD_Name,
124                  rectype = CARD_Version;          CARD_Lang,
125              else if( !strcmp( p, "vendor" ) )          CARD_Sex,
126                  rectype = CARD_Vendor;          CARD_Url,
127              else if( !strcmp( p, "serial" ) )          CARD_Login,
128                  rectype = CARD_Serial;          CARD_MaxPinLen,
129              else if( !strcmp( p, "name" ) )          CARD_SigCount,
130                  rectype = CARD_Name;          CARD_CAFpr,
131              else if( !strcmp( p, "lang" ) )          CARD_Fpr,
132                  rectype = CARD_Lang;          CARD_FprTime
133              else if( !strcmp( p, "sex" ) )      };
134                  rectype = CARD_Sex;      enum rectype_t rectype;    
135              else if( !strcmp( p, "url" ) )      char *p, *pend;
136                  rectype = CARD_Url;      int field = 0;
137              else if( !strcmp( p, "login" ) )  
138                  rectype = CARD_Login;      if (!line)
139              else if( !strcmp( p, "maxpinlen" ) )          return gpg_error (GPG_ERR_EOF);
140                  rectype = CARD_MaxPinLen;  
141              else if( !strcmp( p, "sigcount" ) )      for (p = line; p; p = pend) {
142                  rectype = CARD_SigCount;          field++;
143              else if( !strcmp( p, "fpr" ) )          pend = strchr (p, ':');
144                  rectype = CARD_Fpr;          if (pend)
145              else              *pend++ = 0;
146                  rectype = CARD_None;  
147          }          if (field == 1) {
148          switch( rectype ) {              if (!strcmp (p, "AID"))
149          case CARD_AID:                  rectype = CARD_AID;
150              if( field == 2 ) {              else if( !strcmp( p, "version" ) )
151                  card->aid = strdup (p);                  rectype = CARD_Version;
152                  if (!card->aid)              else if( !strcmp( p, "vendor" ) )
153                      return gpg_error (GPG_ERR_ENOMEM);                  rectype = CARD_Vendor;
154              }              else if( !strcmp( p, "serial" ) )
155              break;                  rectype = CARD_Serial;
156          case CARD_Version:              else if( !strcmp( p, "name" ) )
157              if( field == 2 ) {                  rectype = CARD_Name;
158                  card->version = strdup (p);              else if( !strcmp( p, "lang" ) )
159                  if (!card->version)                  rectype = CARD_Lang;
160                      return gpg_error (GPG_ERR_ENOMEM);              else if( !strcmp( p, "sex" ) )
161              }                  rectype = CARD_Sex;
162              break;              else if( !strcmp( p, "url" ) )
163          case CARD_Vendor:                  rectype = CARD_Url;
164              if( field == 3 ) {              else if( !strcmp( p, "login" ) )
165                  card->vendor = strdup( p );                  rectype = CARD_Login;
166                  if (!card->vendor)              else if( !strcmp( p, "maxpinlen" ) )
167                      return gpg_error (GPG_ERR_ENOMEM);                  rectype = CARD_MaxPinLen;
168              }              else if( !strcmp( p, "sigcount" ) )
169              break;                  rectype = CARD_SigCount;
170          case CARD_Serial:              else if (!strcmp (p, "cafpr"))
171              if( field == 2 ) {                  rectype = CARD_CAFpr;
172                  card->serial = strdup( p );              else if (!strcmp (p, "fpr"))
173                  if (!card->serial)                  rectype = CARD_Fpr;        
174                      return gpg_error (GPG_ERR_ENOMEM);              else if (!strcmp (p, "fprtime"))
175              }                  rectype = CARD_FprTime;
176              break;              else
177          case CARD_Name:                  rectype = CARD_None;
178              if( field == 2 ) {          }
179                  card->givenname = strdup( p );          switch (rectype) {
180                  if (!card->givenname)          case CARD_AID:
181                      return gpg_error (GPG_ERR_ENOMEM);              if (field == 2) {
182              }                  card->aid = strdup (p);
183              else if( field == 3 ) {                  if (!card->aid)
184                  card->surname = strdup( p );                      return gpg_error (GPG_ERR_ENOMEM);
185                  if (!card->surname)              }
186                      return gpg_error (GPG_ERR_ENOMEM);              else if (field == 3) {
187              }                  card->card_type = strdup (p);
188              break;                  if (!card->card_type)
189          case CARD_Lang:                      return gpg_error (GPG_ERR_ENOMEM);
190              if( field == 2 ) {              }
191                  card->lang = strdup( p );              break;
192                  if (!card->lang)  
193                      return gpg_error (GPG_ERR_ENOMEM);          case CARD_Version:
194              }              if (field == 2) {
195              break;                  card->version = strdup (p);
196          case CARD_Sex:                  if (!card->version)
197              if( field == 2 )                      return gpg_error (GPG_ERR_ENOMEM);
198                  card->sex = *p;              }
199              break;              break;
200          case CARD_Url:  
201              if( field == 2 ) {          case CARD_Vendor:
202                  if (card->url)              if (field == 3) {
203                      free (card->url);                  card->vendor = strdup (p);
204                  /*                  if (!card->vendor)
205                  card->url = calloc( 1, strlen( p ) + 1 );                      return gpg_error (GPG_ERR_ENOMEM);
206                  if( !card->url ) {              }
207                      return; // XXX              break;
208                  }  
209                  _gpgme_decode_c_string (p, &card->url, strlen (p) + 1);          case CARD_Serial:
210                  */              if (field == 2) {
211                  card->url = strdup (p); /* XXX */                  card->serial = strdup (p);
212                  if (!card->url)                  if (!card->serial)
213                      return gpg_error (GPG_ERR_ENOMEM);                      return gpg_error (GPG_ERR_ENOMEM);
214              }              }
215              break;              break;
216          case CARD_Login:          case CARD_Name:
217              if( field == 2 ) {              if (field == 2) {
218                  card->login = strdup (p);                  card->givenname = strdup (p);
219                  if (!card->login)                  if (!card->givenname)
220                      return gpg_error (GPG_ERR_ENOMEM);                      return gpg_error (GPG_ERR_ENOMEM);
221              }              }
222              break;              else if (field == 3) {
223          case CARD_MaxPinLen:                  card->surname = strdup (p);
224              break;                  if (!card->surname)
225          case CARD_SigCount:                      return gpg_error (GPG_ERR_ENOMEM);
226              if( field == 2 )              }
227                  card->sig_count = atol( p );              break;
228              break;          case CARD_Lang:
229          case CARD_Fpr:              if( field == 2 ) {
230              if( field == 2 || field == 3 || field == 4 ) {                  card->lang = strdup (p);
231                  card->fpr[(*cnt)++] = strdup( p );                  if (!card->lang)
232              }                      return gpg_error (GPG_ERR_ENOMEM);
233              break;              }
234          }              break;
235      }          case CARD_Sex:
236      return 0;              if( field == 2 )
237  }                  card->sex = *p;
238                break;
239    
240  /* Dummy handler to get the colon data and then quit. */          case CARD_Url:
241  static gpgme_error_t              if( field == 2 ) {
242  list_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)                  if (card->url)
243  {                      free (card->url);
244      const char *s = "quit\n";                  card->url = (char*)calloc (1, strlen (p) + 1);
245      write (fd, s, strlen (s));                  if( !card->url ) {
246      return 0;                      return gpg_error (GPG_ERR_ENOMEM);
247  }                  }
248                    gpg_decode_c_string (p, &card->url, strlen (p) + 1);
249                    if (!card->url)
250  /* Construct an empty object. */                      return gpg_error (GPG_ERR_ENOMEM);
251  GpgCardEdit::GpgCardEdit (void)              }
252  {              break;
253      pin = NULL;  
254      pin_new = NULL;          case CARD_Login:
255      admin_pin = NULL;              if (field == 2) {
256                    card->login = strdup (p);
257      type = 0;                  if (!card->login)
258      cnt = 0;                      return gpg_error (GPG_ERR_ENOMEM);
259      cancel = 0;              }
260                break;
261      gpgme_new (&ctx);  
262  }          case CARD_MaxPinLen:
263                break;
264  /* Release the object. */  
265  GpgCardEdit::~GpgCardEdit (void)          case CARD_SigCount:
266  {              if (field == 2)
267      gpgme_release (ctx);                      card->sig_count = atol (p);
268      if (this->keygen.name)              break;
269          free (this->keygen.name);  
270      if (this->keygen.comment)          case CARD_CAFpr:
271          free (this->keygen.comment);              if (!p)
272      if (this->keygen.email)                  break;
273          free (this->keygen.email);              if (field > 4 || field == 1)
274      if (this->keygen.expdate)                  break;
275          free (this->keygen.expdate);              card->ca_fpr[field-2] = strdup (p);
276  }              if (!card->ca_fpr[field-2])
277                    return gpg_error (GPG_ERR_ENOMEM);
278                break;
279  /* Set the user PIN for the object to @pin. */  
280  void          case CARD_Fpr:
281  GpgCardEdit::setPIN (const char *pin)              if (field > 4 || field == 1) /* max 3 fprs */
282  {                  break;
283      this->pin = pin;              card->fpr[field-2] = strdup (p);
284  }              if (!card->fpr[field-2])
285                    return gpg_error (GPG_ERR_ENOMEM);
286  /* Set the admin PIN for the object to @admin_pin. */              break;
287  void  
288  GpgCardEdit::setAdminPIN (const char *admin_pin)          case CARD_FprTime:
289  {              if (field > 4 || field == 1)
290      this->admin_pin = admin_pin;                  break;
291  }              card->fpr_created[field-2] = strtoul (p, NULL, 10);
292                card->fpr_created_str[field-2] = get_str_timestamp (strtoul (p, NULL, 10));
293                if (!card->fpr_created_str[field-2])
294  /* Set the new user PIN for the object to @new_pin. */                  return gpg_error (GPG_ERR_ENOMEM);
295  void              break;
296  GpgCardEdit::setNewPIN (const char *new_pin)  
297  {          }
298      this->pin_new = new_pin;      }
299  }      return 0;
300    }
301    
302  /* Set the passphrase needed when generating a key to @pass. */  
303  void  /* Dummy handler to get the colon data and then quit. */
304  GpgCardEdit::setKeygenPassphrase (const char *pass)  static gpgme_error_t
305  {  list_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)
306      this->keygen.pass = pass;  {
307  }      static int wait_card=0;
308        GpgCardEdit *ce = (GpgCardEdit *)opaque;
309        const char *s="";    
310  /* Set the callback to @cb and the hook value to @cb_value. */      DWORD n;
311  void          
312  GpgCardEdit::setCallback (const char* (*cb)(int code, void *opaque),  
313                            void *cb_value)      if (code == GPGME_STATUS_CARDCTRL) {
314  {          if (!strcmp (key, "5"))
315      this->cb_value = cb_value;              ce->setResult (GPG_CARDRES_NOCARD);
316      this->card_cb = cb;          else if (!strcmp (key, "1"))
317  }              wait_card = 1;
318        }
319        if (wait_card && !strcmp (key, "cardctrl.insert_card.okay")) {
320  void          n = MessageBox (NULL, _("Please insert the card and click OK or Cancel to abort."),
321  GpgCardEdit::setType (int type)                          _("GPG Card Status"), MB_ICONQUESTION|MB_OKCANCEL);
322  {          if (n == IDCANCEL) {
323      this->type = type;              ce->setResult (GPG_CARDRES_CANCEL);
324  }              WriteFile ((HANDLE)fd, "c\n", 2, &n, NULL);
325                wait_card = 0;
326  /* Read the information from the inserted card and return          }
327     it in form of a card context @r_card.      }
328     Return value: 0 on success. */      if (!strcmp (key, "cardedit.prompt")) {
329  gpgme_error_t          s = "quit\n";
330  GpgCardEdit::getCardStatus (gpg_card_t *r_card)          if (!WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL))
331  {              log_debug ("list_handler: WriteFile() failed ec=%d\r\n",
332      gpgme_data_t tmp = NULL;                         (int)GetLastError ());
333      gpgme_error_t err;          wait_card = 0;
334      char buf[200];      }
335      int cnt = 0;      return 0;
336    }
337      if (!r_card)  
338          return gpg_error (GPG_ERR_INV_ARG);  
339    /* Construct an empty object. */
340      err = gpgme_data_new (&tmp);  GpgCardEdit::GpgCardEdit (void)
341      if (err)  {
342          return err;      pin = NULL;
343            pin_new = NULL;
344      err = gpgme_op_card_edit  (ctx, NULL, list_handler, NULL, tmp);      admin_pin = NULL;
345      if (err) {  
346          gpgme_data_release (tmp);      keygen.comment = NULL;
347          return err;      keygen.email = NULL;
348      }      keygen.name = NULL;
349        keygen.expdate = NULL;
350      *r_card=NULL;      keygen.key_fpr = NULL;
351      gpgme_data_rewind (tmp);  
352      while (gpg_data_readline (tmp, buf, sizeof buf-2) > 0)      type = 0;
353          statuscard_colon_handler (r_card, buf, &cnt);      cnt = 0;
354      gpgme_data_release (tmp);      cancel = 0;
355        result = 0;
356      return err;  
357  }      gpgme_new (&ctx); /* XXX: check return code */
358    }
359    
360  /* Generate a key on a smart card with the following params:  /* Release the object. */
361     @flags: user specific params.  GpgCardEdit::~GpgCardEdit (void)
362     @name: name of the key holder.  {    
363     @email: email of the key holder.      if (keygen.name)
364     @comment: optional comment.          free (keygen.name);
365     @valid: how long is the key valid in days.      if (keygen.comment)
366     Return value: 0 on success. */          free (keygen.comment);
367  gpgme_error_t      if (keygen.email)
368  GpgCardEdit::genKey (int flags, const char *name,          free (keygen.email);
369                       const char *email, const char *comment,      if (keygen.expdate)
370                       long valid)          free (keygen.expdate);
371  {      if (keygen.key_fpr)
372      gpgme_error_t err;          free (keygen.key_fpr);
373        gpgme_release (ctx);
374      if (!name || !email)  }
375          return gpg_error (GPG_ERR_INV_ARG);  
376      if (!this->keygen.pass)  
377          return gpg_error (GPG_ERR_INV_OBJ);  /* Set the user PIN for the object to @pin. */
378    void
379      type = GPG_EDITCARD_GENKEY;  GpgCardEdit::setPIN (const char *pin)
380      this->keygen.flags = flags;  {
381        this->pin = pin;
382      if (this->keygen.name)  }
383          free (this->keygen.name);  
384      this->keygen.name = strdup (name);  /* Set the admin PIN for the object to @admin_pin. */
385      if (this->keygen.email)  void
386          free (this->keygen.email);  GpgCardEdit::setAdminPIN (const char *admin_pin)
387      this->keygen.email = strdup (email);  {
388      if (this->keygen.comment)      this->admin_pin = admin_pin;
389          free (this->keygen.comment);  }
390      this->keygen.comment = comment? strdup (comment) : strdup ("");  
391      if (this->keygen.expdate)  
392          free (this->keygen.expdate);      /* Set the new user PIN for the object to @new_pin. */
393      this->keygen.expdate = (char*)calloc (1, 16);  void
394      if (this->keygen.expdate)  GpgCardEdit::setNewPIN (const char *new_pin)
395          sprintf (this->keygen.expdate, "%d", valid);  {
396        this->pin_new = new_pin;
397      if (!this->keygen.name || !this->keygen.email ||  }
398          !this->keygen.comment || !this->keygen.expdate)  
399          return gpg_error (GPG_ERR_ENOMEM);  
400    /* Set the passphrase needed when generating a key to @pass. */
401      err = gpg_card_edit (ctx, this);  void
402      return err;  GpgCardEdit::setKeygenPassphrase (const char *pass)
403  }  {
404        this->keygen.pass = pass;
405    }
406  /* Change the pin from @pin to @pin_new.  
407     Return value: 0 on success. */  
408  gpgme_error_t  /* Set the callback to @cb and the hook value to @cb_value. */
409  GpgCardEdit::changePIN (void)  void
410  {  GpgCardEdit::setCallback (const char* (*cb)(int code, void *opaque),
411      gpgme_error_t err;                            void *cb_value)
412    {
413      if (!this->pin || !this->pin_new)      this->cb_value = cb_value;
414          return gpg_error (GPG_ERR_INV_ARG);      this->card_cb = cb;
415    }
416      if (!type) {  
417          if (this->pin && this->pin_new)  
418              type = GPG_EDITCARD_CHUPIN;  /* Read the information from the inserted card and return
419          else if (this->pin && this->admin_pin)     it in form of a card context @r_card.
420              type = GPG_EDITCARD_CHAPIN;     Return value: 0 on success. */
421          else  gpgme_error_t
422              type = GPG_EDITCARD_UNBPIN;  GpgCardEdit::getCardStatus (gpg_card_t *r_card)
423      }  {
424        gpgme_data_t out = NULL;
425      err = gpg_card_edit (ctx, this);      gpgme_error_t err;
426      return err;      gpg_card_t card=NULL;
427  }      char buf[200];
428    
429        if (!r_card)
430  gpgme_error_t          return gpg_error (GPG_ERR_INV_ARG);
431  GpgCardEdit::updateName (const char *given, const char *sur)  
432  {      err = gpg_card_new (&card);
433      gpgme_error_t err;      if (err)
434            return err;
435      if (!this->pin)  
436          return gpg_error (GPG_ERR_INV_OBJ);      err = gpgme_data_new (&out);
437        if (err) {
438      this->edit.surname = sur;          gpg_card_release (card);
439      this->edit.givenname = given;          return err;
440        }
441      err = gpg_card_edit (ctx, this);      
442      return err;      err = gpgme_op_card_edit  (ctx, NULL, list_handler, this, out);
443  }      gpgme_data_rewind (out);
444            if (err) {
445  gpgme_error_t          gpgme_data_release (out);
446  GpgCardEdit::updateURL (const char *url)          gpg_card_release (card);
447  {          return err;
448      gpgme_error_t err;      }
449        if (getResult () & GPG_CARDRES_NOCARD ||
450      if (!this->pin)          getResult () & GPG_CARDRES_CANCEL) {
451          return gpg_error (GPG_ERR_INV_OBJ);          gpg_card_release (card);
452            gpgme_data_release (out);
453      this->edit.keyurl = url;          return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
454        }
455      err = gpg_card_edit (ctx, this);  
456      return err;      *r_card = card;
457  }      while (gpg_data_readline (out, buf, sizeof (buf)-2) > 0) {
458            err = statuscard_colon_handler (card, buf);
459            if (err)
460  gpgme_error_t              break;
461  GpgCardEdit::updateLogin (const char *login)      }
462  {      gpgme_data_release (out);
463      gpgme_error_t err;  
464        return err;
465      if (!this->pin)  }
466          return gpg_error (GPG_ERR_INV_OBJ);  
467    
468      this->edit.login = login;  /* Generate a key on a smart card with the following params:
469       @flags: user specific params.
470      err = gpg_card_edit (ctx, this);     @name: name of the key holder.
471      return err;     @email: email of the key holder.
472  }     @comment: optional comment.
473       @valid: how long is the key valid in days.
474  gpgme_error_t     Return value: 0 on success. */
475  GpgCardEdit::updateSex (char sex)  gpgme_error_t
476  {  GpgCardEdit::genKey (int flags, const char *name,
477      gpgme_error_t err;                       const char *email, const char *comment, long valid,
478                         char **r_key_fpr)
479      if (!this->pin)  {
480          return gpg_error (GPG_ERR_INV_OBJ);      gpgme_error_t err;
481    
482      this->edit.sex = sex;      if (!name || !email)
483      err = gpg_card_edit (ctx, this);          return gpg_error (GPG_ERR_INV_ARG);
484      return err;      if (!this->keygen.pass)
485  }          return gpg_error (GPG_ERR_INV_OBJ);
486    
487  gpgme_error_t      type = GPG_EDITCARD_GENKEY;
488  GpgCardEdit::updateLanguage (const char *lang)      this->keygen.flags = flags;
489  {  
490      gpgme_error_t err;      if (this->keygen.name)
491            free (this->keygen.name);
492      if (!this->pin)      this->keygen.name = strdup (name);
493          return gpg_error (GPG_ERR_INV_OBJ);      if (this->keygen.email)
494            free (this->keygen.email);
495      this->edit.lang = lang;      this->keygen.email = strdup (email);
496      err = gpg_card_edit (ctx, this);      if (this->keygen.comment)
497      return err;          free (this->keygen.comment);
498  }      this->keygen.comment = comment? strdup (comment) : strdup ("");
499        if (this->keygen.expdate)
500            free (this->keygen.expdate);
501  /* Fetch the key specified by the url stored on the card.      this->keygen.expdate = (char*)calloc (1, 16);
502     Return value: 0 on success. */      if (this->keygen.expdate)
503  gpgme_error_t          sprintf (this->keygen.expdate, "%d", valid);
504  GpgCardEdit::fetchKey (void)  
505  {      if (!this->keygen.name || !this->keygen.email)
506      gpgme_error_t err = 0;          return gpg_error (GPG_ERR_ENOMEM);
507    
508      if (!this->pin)      err = gpg_card_edit (ctx, this);
509          return gpg_error (GPG_ERR_INV_OBJ);      if (!err)
510            err = getResult () & GPG_CARDRES_CANCEL? gpg_error (GPG_ERR_CANCELED) : 0;
511      return 0;      if (!err && r_key_fpr)
512  }          *r_key_fpr = strdup (keygen.key_fpr? keygen.key_fpr : "");
513        return err;
514    }
515  gpgme_error_t  
516  GpgCardEdit:: doCmd (int cmd, const char *arg1, const char *arg2)  
517  {  /* Change the pin from @pin to @pin_new.
518      switch (cmd) {     Return value: 0 on success. */
519      case GPG_EDITCARD_NAME:  gpgme_error_t
520          return updateName (arg1, arg2); /* given, surname */  GpgCardEdit::changePIN (int type)
521    {
522      case GPG_EDITCARD_LANG:      gpgme_error_t err;
523          return updateLanguage (arg1); /* lang */  
524        if (!this->pin_new)
525      case GPG_EDITCARD_SEX:          return gpg_error (GPG_ERR_INV_ARG);
526          return updateSex (*arg1); /* sex */  
527        if (!type) {
528      case GPG_EDITCARD_KEYURL:          if (this->pin && this->pin_new)
529          return updateURL (arg1); /* url */              this->type = GPG_EDITCARD_CHUPIN;
530            else if (this->pin && this->admin_pin)
531      case GPG_EDITCARD_LOGIN:              this->type = GPG_EDITCARD_CHAPIN;
532          return updateLogin (arg1); /* login */          else
533      }              this->type = GPG_EDITCARD_UNBPIN;
534        }
535      return 0;      else
536  }          this->type = type;
537        /* check if the user provided the needed PIN. */
538        if ((this->type == GPG_EDITCARD_CHUPIN && !this->pin) ||
539            (this->type == GPG_EDITCARD_CHAPIN && !this->admin_pin))
540            return gpg_error (GPG_ERR_INV_ARG);
541    
542        err = gpg_card_edit (ctx, this);
543        return err;
544    }
545    
546    
547    gpgme_error_t
548    GpgCardEdit::updateName (const char *given, const char *sur)
549    {
550        gpgme_error_t err;
551    
552        if (!this->admin_pin)
553            return gpg_error (GPG_ERR_INV_OBJ);
554    
555        this->type = GPG_EDITCARD_NAME;
556        this->edit.surname = sur;
557        this->edit.givenname = given;
558    
559        err = gpg_card_edit (ctx, this);
560        return err;
561    }
562        
563    gpgme_error_t
564    GpgCardEdit::updateURL (const char *url)
565    {
566        gpgme_error_t err;
567    
568        if (!this->admin_pin)
569            return gpg_error (GPG_ERR_INV_OBJ);
570    
571        type = GPG_EDITCARD_KEYURL;
572        this->edit.keyurl = url;
573    
574        err = gpg_card_edit (ctx, this);
575        return err;
576    }
577    
578    
579    gpgme_error_t
580    GpgCardEdit::updateLogin (const char *login)
581    {
582        gpgme_error_t err;
583    
584        if (!this->admin_pin)
585            return gpg_error (GPG_ERR_INV_OBJ);
586    
587        this->type = GPG_EDITCARD_LOGIN;
588        this->edit.login = login;
589    
590        err = gpg_card_edit (ctx, this);
591        return err;
592    }
593    
594    gpgme_error_t
595    GpgCardEdit::updateSex (char sex)
596    {
597        gpgme_error_t err;
598    
599        if (!this->admin_pin)
600            return gpg_error (GPG_ERR_INV_OBJ);
601    
602        type = GPG_EDITCARD_SEX;
603        this->edit.sex = sex;
604    
605        err = gpg_card_edit (ctx, this);
606        return err;
607    }
608    
609    gpgme_error_t
610    GpgCardEdit::updateLanguage (const char *lang)
611    {
612        gpgme_error_t err;
613    
614        if (!this->admin_pin)
615            return gpg_error (GPG_ERR_INV_OBJ);
616    
617        type = GPG_EDITCARD_LANG;
618        this->edit.lang = lang;
619    
620        err = gpg_card_edit (ctx, this);
621        return err;
622    }
623    
624    
625    /* Fetch the key specified by the url stored on the card.
626       Return value: 0 on success. */
627    gpgme_error_t
628    GpgCardEdit::fetchKey (void)
629    {
630        gpgme_error_t err = 0;
631    
632        if (!this->pin)
633            return gpg_error (GPG_ERR_INV_OBJ);
634    
635        return 0;
636    }
637    
638    
639    /* Dispatcher for the various commands. @cmd is the card command ID
640       and @arg1 and @arg2 the actual values for the command.
641       Return value: 0 on success. */
642    gpgme_error_t
643    GpgCardEdit:: doCmd (int cmd, const char *arg1, const char *arg2)
644    {
645        switch (cmd) {
646        case GPG_EDITCARD_NAME:
647            return updateName (arg1, arg2); /* given, surname */
648    
649        case GPG_EDITCARD_LANG:
650            return updateLanguage (arg1); /* lang */
651    
652        case GPG_EDITCARD_SEX:
653            return updateSex (*arg1); /* sex */
654    
655        case GPG_EDITCARD_KEYURL:
656            return updateURL (arg1); /* url */
657    
658        case GPG_EDITCARD_LOGIN:
659            return updateLogin (arg1); /* login */
660    
661        default:
662            return gpg_error (GPG_ERR_INV_VALUE);
663        }
664    
665        return 0;
666    }
667    
668    
669    /* Set the result for the executed operation.
670       The values will be ORed. */
671    void
672    GpgCardEdit::setResult (int res)
673    {
674        result |= res;
675    }
676    
677    
678    /* Return the result of the executed operation. */
679    int
680    GpgCardEdit::getResult (void)
681    {
682        return result;
683    }
684    
685    
686    /* Reset the object state. */
687    void
688    GpgCardEdit::reset (void)
689    {
690        cnt = 0;
691    }
692    
693    
694    /* Return card command type */
695    int
696    GpgCardEdit::getType (void)
697    {
698        return type;
699    }

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26