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

Legend:
Removed from v.26  
changed lines
  Added in v.306

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26