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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26