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

Legend:
Removed from v.28  
changed lines
  Added in v.260

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26