~ubuntu-branches/ubuntu/jaunty/gnupg2/jaunty-updates

« back to all changes in this revision

Viewing changes to scd/app.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Urlichs
  • Date: 2005-12-08 22:13:21 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20051208221321-4rvs2vu835iam5wv
Tags: 1.9.19-2
* Convert debian/changelog to UTF-8.
* Put gnupg-agent and gpgsm lintian overrides in the respectively
  right package.  Closes: #335066
* Added debhelper tokens to maintainer scripts.
* xsession fixes:
  o Added host name to gpg-agent PID file name.  Closes: #312717
  o Fixed xsession script to be able to run under zsh.  Closes: #308516
  o Don't run gpg-agent if one is already running.  Closes: #336480
* debian/control:
  o Fixed package description of gpgsm package.  Closes: #299842
  o Added mention of gpg-agent to description of gnupg-agent package.
    Closes: #304355
* Thanks to Peter Eisentraut <petere@debian.org> for all of the above.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* app.c - Application selection.
2
 
 *      Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
2
 *      Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of GnuPG.
5
5
 *
23
23
#include <stdio.h>
24
24
#include <stdlib.h>
25
25
#include <string.h>
26
 
 
 
26
# include <pth.h>
27
27
 
28
28
#include "scdaemon.h"
29
29
#include "app-common.h"
31
31
#include "iso7816.h"
32
32
#include "tlv.h"
33
33
 
34
 
 
 
34
/* This table is used to keep track of locks on a per reader base.
 
35
   The index into the table is the slot number of the reader.  The
 
36
   mutex will be initialized on demand (one of the advantages of a
 
37
   userland threading system). */
 
38
static struct
 
39
{
 
40
  int initialized;
 
41
  pth_mutex_t lock;
 
42
  app_t app;        /* Application context in use or NULL. */
 
43
} lock_table[10];
 
44
 
 
45
 
 
46
/* Lock the reader SLOT.  This function shall be used right before
 
47
   calling any of the actual application functions to serialize access
 
48
   to the reader.  We do this always even if the reader is not
 
49
   actually used.  This allows an actual connection to assume that it
 
50
   never shares a reader (while performing one command).  Returns 0 on
 
51
   success; only then the unlock_reader function must be called after
 
52
   returning from the handler. */
 
53
static gpg_error_t 
 
54
lock_reader (int slot)
 
55
{
 
56
  gpg_error_t err;
 
57
 
 
58
  if (slot < 0 || slot >= DIM (lock_table))
 
59
    return gpg_error (slot<0? GPG_ERR_INV_VALUE : GPG_ERR_RESOURCE_LIMIT);
 
60
 
 
61
  if (!lock_table[slot].initialized)
 
62
    {
 
63
      if (!pth_mutex_init (&lock_table[slot].lock))
 
64
        {
 
65
          err = gpg_error_from_errno (errno);
 
66
          log_error ("error initializing mutex: %s\n", strerror (errno));
 
67
          return err;
 
68
        }
 
69
      lock_table[slot].initialized = 1;
 
70
      lock_table[slot].app = NULL;
 
71
    }
 
72
  
 
73
  if (!pth_mutex_acquire (&lock_table[slot].lock, 0, NULL))
 
74
    {
 
75
      err = gpg_error_from_errno (errno);
 
76
      log_error ("failed to acquire APP lock for slot %d: %s\n",
 
77
                 slot, strerror (errno));
 
78
      return err;
 
79
    }
 
80
 
 
81
  return 0;
 
82
}
 
83
 
 
84
/* Release a lock on the reader.  See lock_reader(). */
 
85
static void
 
86
unlock_reader (int slot)
 
87
{
 
88
  if (slot < 0 || slot >= DIM (lock_table)
 
89
      || !lock_table[slot].initialized)
 
90
    log_bug ("unlock_reader called for invalid slot %d\n", slot);
 
91
 
 
92
  if (!pth_mutex_release (&lock_table[slot].lock))
 
93
    log_error ("failed to release APP lock for slot %d: %s\n",
 
94
               slot, strerror (errno));
 
95
 
 
96
}
 
97
 
 
98
 
 
99
static void
 
100
dump_mutex_state (pth_mutex_t *m)
 
101
{
 
102
  if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
 
103
    log_printf ("not_initialized");
 
104
  else if (!(m->mx_state & PTH_MUTEX_LOCKED))
 
105
    log_printf ("not_locked");
 
106
  else
 
107
    log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
 
108
}
 
109
 
 
110
 
 
111
/* This function may be called to print information pertaining to the
 
112
   current state of this module to the log. */
 
113
void
 
114
app_dump_state (void)
 
115
{
 
116
  int slot;
 
117
 
 
118
  for (slot=0; slot < DIM (lock_table); slot++)
 
119
    if (lock_table[slot].initialized)
 
120
      {
 
121
        log_info ("app_dump_state: slot=%d lock=", slot);
 
122
        dump_mutex_state (&lock_table[slot].lock);
 
123
        if (lock_table[slot].app)
 
124
          log_printf (" app=%p type=`%s'",
 
125
                      lock_table[slot].app, lock_table[slot].app->apptype);
 
126
        log_printf ("\n");
 
127
      }
 
128
}
 
129
 
 
130
 
35
131
/* Check wether the application NAME is allowed.  This does not mean
36
132
   we have support for it though.  */
37
133
static int
49
145
/* If called with NAME as NULL, select the best fitting application
50
146
   and return a context; otherwise select the application with NAME
51
147
   and return a context.  SLOT identifies the reader device. Returns
52
 
   NULL if no application was found or no card is present. */
53
 
APP
54
 
select_application (ctrl_t ctrl, int slot, const char *name)
 
148
   an error code and stores NULL at R_APP if no application was found
 
149
   or no card is present. */
 
150
gpg_error_t
 
151
select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
55
152
{
56
 
  int rc;
57
 
  APP app;
 
153
  gpg_error_t err;
 
154
  app_t app = NULL;
58
155
  unsigned char *result = NULL;
59
156
  size_t resultlen;
60
157
 
 
158
  *r_app = NULL;
 
159
 
 
160
  err = lock_reader (slot);
 
161
  if (err)
 
162
    return err;
 
163
 
 
164
  /* First check whether we already have an application to share. */
 
165
  app = lock_table[slot].initialized ? lock_table[slot].app : NULL;
 
166
  if (app && name)
 
167
    if (!app->apptype || ascii_strcasecmp (app->apptype, name))
 
168
      {
 
169
        unlock_reader (slot);
 
170
        if (app->apptype)
 
171
          log_info ("application `%s' in use by reader %d - can't switch\n",
 
172
                    app->apptype, slot);
 
173
        return gpg_error (GPG_ERR_CONFLICT);
 
174
      }
 
175
 
 
176
  if (app)
 
177
    {
 
178
      if (app->slot != slot)
 
179
        log_bug ("slot mismatch %d/%d\n", app->slot, slot);
 
180
      app->ref_count++;
 
181
      *r_app = app;
 
182
      unlock_reader (slot);
 
183
      return 0; /* Okay: We share that one. */
 
184
    }
 
185
 
61
186
  app = xtrycalloc (1, sizeof *app);
62
187
  if (!app)
63
188
    {
64
 
      rc = gpg_error (gpg_err_code_from_errno (errno));
65
 
      log_info ("error allocating context: %s\n", gpg_strerror (rc));
66
 
      return NULL;
 
189
      err = gpg_error_from_errno (errno);
 
190
      log_info ("error allocating context: %s\n", gpg_strerror (err));
 
191
      unlock_reader (slot);
 
192
      return err;
67
193
    }
68
194
  app->slot = slot;
69
195
 
 
196
 
70
197
  /* Fixme: We should now first check whether a card is at all
71
198
     present. */
72
199
 
73
200
  /* Try to read the GDO file first to get a default serial number. */
74
 
  rc = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
75
 
  if (!rc)
76
 
    rc = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
77
 
  if (!rc)
78
 
    rc = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
79
 
  if (!rc)
 
201
  err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
 
202
  if (!err)
 
203
    err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
 
204
  if (!err)
 
205
     err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
 
206
  if (!err)
80
207
    {
81
208
      size_t n;
82
209
      const unsigned char *p;
83
210
 
84
 
      p = find_tlv (result, resultlen, 0x5A, &n);
 
211
      p = find_tlv_unchecked (result, resultlen, 0x5A, &n);
85
212
      if (p)
86
213
        resultlen -= (p-result);
87
214
      if (p && n > resultlen && n == 0x0d && resultlen+1 == n)
91
218
             have some test cards with such an invalid encoding and
92
219
             therefore I use this ugly workaround to return something
93
220
             I can further experiment with. */
94
 
          log_debug ("enabling BMI testcard workaround\n");
 
221
          log_info ("enabling BMI testcard workaround\n");
95
222
          n--;
96
223
        }
97
224
 
102
229
          memmove (result, p, n);
103
230
          app->serialno = result;
104
231
          app->serialnolen = n;
105
 
          rc = app_munge_serialno (app);
106
 
          if (rc)
 
232
          err = app_munge_serialno (app);
 
233
          if (err)
107
234
            goto leave;
108
235
        }
109
236
      else
111
238
      result = NULL;
112
239
    }
113
240
 
 
241
  /* For certain error codes, there is no need to try more.  */
 
242
  if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
 
243
    goto leave;
114
244
  
115
 
  rc = gpg_error (GPG_ERR_NOT_FOUND);
116
 
 
117
 
  if (rc && is_app_allowed ("openpgp") && (!name || !strcmp (name, "openpgp")))
118
 
    rc = app_select_openpgp (app);
119
 
  if (rc && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
120
 
    rc = app_select_nks (app);
121
 
/*   if (rc && is_app_allowed ("p12") && (!name || !strcmp (name, "p12"))) */
122
 
/*     rc = app_select_p12 (app); */
123
 
  if (rc && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
124
 
    rc = app_select_dinsig (app);
125
 
  if (rc && name)
126
 
    rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
 
245
 
 
246
  /* Figure out the application to use.  */
 
247
  err = gpg_error (GPG_ERR_NOT_FOUND);
 
248
 
 
249
  if (err && is_app_allowed ("openpgp")
 
250
          && (!name || !strcmp (name, "openpgp")))
 
251
    err = app_select_openpgp (app);
 
252
  if (err && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
 
253
    err = app_select_nks (app);
 
254
  if (err && is_app_allowed ("p15") && (!name || !strcmp (name, "p15")))
 
255
    err = app_select_p15 (app);
 
256
  if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
 
257
    err = app_select_dinsig (app);
 
258
  if (err && name)
 
259
    err = gpg_error (GPG_ERR_NOT_SUPPORTED);
127
260
 
128
261
 leave:
129
 
  if (rc)
 
262
  if (err)
130
263
    {
131
264
      if (name)
132
265
        log_info ("can't select application `%s': %s\n",
133
 
                  name, gpg_strerror (rc));
 
266
                  name, gpg_strerror (err));
134
267
      else
135
268
        log_info ("no supported card application found: %s\n",
136
 
                  gpg_strerror (rc));
 
269
                  gpg_strerror (err));
137
270
      xfree (app);
138
 
      return NULL;
 
271
      unlock_reader (slot);
 
272
      return err;
139
273
    }
140
274
 
141
275
  app->initialized = 1;
142
 
  return app;
 
276
  app->ref_count = 1;
 
277
  lock_table[slot].app = app;
 
278
  *r_app = app;
 
279
  unlock_reader (slot);
 
280
  return 0;
143
281
}
144
282
 
145
283
 
 
284
/* Free the resources associated with the application APP.  APP is
 
285
   allowed to be NULL in which case this is a no-op.  Note that we are
 
286
   using reference counting to track the users of the application. */
146
287
void
147
288
release_application (app_t app)
148
289
{
 
290
  int slot;
 
291
 
149
292
  if (!app)
150
293
    return;
151
294
 
 
295
  if (app->ref_count < 1)
 
296
    log_bug ("trying to release an already released context\n");
 
297
  if (--app->ref_count)
 
298
    return;
 
299
 
 
300
  /* Clear the reference to the application from the lock table. */
 
301
  for (slot = 0;  slot < DIM (lock_table); slot++)
 
302
    if (lock_table[slot].initialized && lock_table[slot].app == app)
 
303
      lock_table[slot].app = NULL;
 
304
 
 
305
  /* Deallocate. */
152
306
  if (app->fnc.deinit)
153
307
    {
154
308
      app->fnc.deinit (app);
169
323
   
170
324
     FF 00 00 = For serial numbers starting with an FF
171
325
     FF 01 00 = Some german p15 cards return an empty serial number so the
172
 
                serial number from the EF(TokeInfo is used instead.
 
326
                serial number from the EF(TokenInfo) is used instead.
173
327
     
174
328
     All other serial number not starting with FF are used as they are.
175
329
*/
176
 
int
 
330
gpg_error_t
177
331
app_munge_serialno (app_t app)
178
332
{
179
333
  if (app->serialnolen && app->serialno[0] == 0xff)
200
354
   no update time is available the returned value is 0.  Caller must
201
355
   free SERIAL unless the function returns an error.  If STAMP is not
202
356
   of interest, NULL may be passed. */
203
 
int 
 
357
gpg_error_t 
204
358
app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
205
359
{
206
 
  unsigned char *buf, *p;
 
360
  char *buf, *p;
207
361
  int i;
208
362
 
209
363
  if (!app || !serial)
226
380
 
227
381
/* Write out the application specifig status lines for the LEARN
228
382
   command. */
229
 
int
230
 
app_write_learn_status (APP app, CTRL ctrl)
 
383
gpg_error_t
 
384
app_write_learn_status (app_t app, CTRL ctrl)
231
385
{
 
386
  gpg_error_t err;
 
387
 
232
388
  if (!app)
233
389
    return gpg_error (GPG_ERR_INV_VALUE);
234
390
  if (!app->initialized)
239
395
  if (app->apptype)
240
396
    send_status_info (ctrl, "APPTYPE",
241
397
                      app->apptype, strlen (app->apptype), NULL, 0);
242
 
 
243
 
  return app->fnc.learn_status (app, ctrl);
 
398
  err = lock_reader (app->slot);
 
399
  if (err)
 
400
    return err;
 
401
  err = app->fnc.learn_status (app, ctrl);
 
402
  unlock_reader (app->slot);
 
403
  return err;
244
404
}
245
405
 
246
406
 
248
408
   the CERTINFO status lines) and return it in the freshly allocated
249
409
   buffer put into CERT and the length of the certificate put into
250
410
   CERTLEN. */
251
 
int
 
411
gpg_error_t
252
412
app_readcert (app_t app, const char *certid,
253
413
              unsigned char **cert, size_t *certlen)
254
414
{
 
415
  gpg_error_t err;
 
416
 
255
417
  if (!app)
256
418
    return gpg_error (GPG_ERR_INV_VALUE);
257
419
  if (!app->initialized)
258
420
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
259
421
  if (!app->fnc.readcert)
260
422
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
261
 
 
262
 
  return app->fnc.readcert (app, certid, cert, certlen);
 
423
  err = lock_reader (app->slot);
 
424
  if (err)
 
425
    return err;
 
426
  err = app->fnc.readcert (app, certid, cert, certlen);
 
427
  unlock_reader (app->slot);
 
428
  return err;
 
429
}
 
430
 
 
431
 
 
432
/* Read the key with ID KEYID.  On success a canonical encoded
 
433
   S-expression with the public key will get stored at PK and its
 
434
   length (for assertions) at PKLEN; the caller must release that
 
435
   buffer. On error NULL will be stored at PK and PKLEN and an error
 
436
   code returned.
 
437
 
 
438
   This function might not be supported by all applications.  */
 
439
gpg_error_t
 
440
app_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
 
441
{
 
442
  gpg_error_t err;
 
443
 
 
444
  if (pk)
 
445
    *pk = NULL;
 
446
  if (pklen)
 
447
    *pklen = 0;
 
448
 
 
449
  if (!app || !keyid || !pk || !pklen)
 
450
    return gpg_error (GPG_ERR_INV_VALUE);
 
451
  if (!app->initialized)
 
452
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
 
453
  if (!app->fnc.readkey)
 
454
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
 
455
  err = lock_reader (app->slot);
 
456
  if (err)
 
457
    return err;
 
458
  err= app->fnc.readkey (app, keyid, pk, pklen);
 
459
  unlock_reader (app->slot);
 
460
  return err;
263
461
}
264
462
 
265
463
 
266
464
/* Perform a GETATTR operation.  */
267
 
int 
268
 
app_getattr (APP app, CTRL ctrl, const char *name)
 
465
gpg_error_t 
 
466
app_getattr (app_t app, CTRL ctrl, const char *name)
269
467
{
 
468
  gpg_error_t err;
 
469
 
270
470
  if (!app || !name || !*name)
271
471
    return gpg_error (GPG_ERR_INV_VALUE);
272
472
  if (!app->initialized)
273
473
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
 
474
 
 
475
  if (app->apptype && name && !strcmp (name, "APPTYPE"))
 
476
    {
 
477
      send_status_info (ctrl, "APPTYPE",
 
478
                        app->apptype, strlen (app->apptype), NULL, 0);
 
479
      return 0;
 
480
    }
 
481
  if (name && !strcmp (name, "SERIALNO"))
 
482
    {
 
483
      char *serial;
 
484
      time_t stamp;
 
485
      int rc;
 
486
      
 
487
      rc = app_get_serial_and_stamp (app, &serial, &stamp);
 
488
      if (rc)
 
489
        return rc;
 
490
      send_status_info (ctrl, "SERIALNO", serial, strlen (serial), NULL, 0);
 
491
      xfree (serial);
 
492
      return 0;
 
493
    }
 
494
 
274
495
  if (!app->fnc.getattr)
275
496
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
276
 
  return app->fnc.getattr (app, ctrl, name);
 
497
  err = lock_reader (app->slot);
 
498
  if (err)
 
499
    return err;
 
500
  err =  app->fnc.getattr (app, ctrl, name);
 
501
  unlock_reader (app->slot);
 
502
  return err;
277
503
}
278
504
 
279
505
/* Perform a SETATTR operation.  */
280
 
int 
281
 
app_setattr (APP app, const char *name,
282
 
             int (*pincb)(void*, const char *, char **),
 
506
gpg_error_t 
 
507
app_setattr (app_t app, const char *name,
 
508
             gpg_error_t (*pincb)(void*, const char *, char **),
283
509
             void *pincb_arg,
284
510
             const unsigned char *value, size_t valuelen)
285
511
{
 
512
  gpg_error_t err;
 
513
 
286
514
  if (!app || !name || !*name || !value)
287
515
    return gpg_error (GPG_ERR_INV_VALUE);
288
516
  if (!app->initialized)
289
517
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
290
518
  if (!app->fnc.setattr)
291
519
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
292
 
  return app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
 
520
  err = lock_reader (app->slot);
 
521
  if (err)
 
522
    return err;
 
523
  err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
 
524
  unlock_reader (app->slot);
 
525
  return err;
293
526
}
294
527
 
295
528
/* Create the signature and return the allocated result in OUTDATA.
296
529
   If a PIN is required the PINCB will be used to ask for the PIN; it
297
530
   should return the PIN in an allocated buffer and put it into PIN.  */
298
 
int 
299
 
app_sign (APP app, const char *keyidstr, int hashalgo,
300
 
          int (pincb)(void*, const char *, char **),
 
531
gpg_error_t 
 
532
app_sign (app_t app, const char *keyidstr, int hashalgo,
 
533
          gpg_error_t (*pincb)(void*, const char *, char **),
301
534
          void *pincb_arg,
302
535
          const void *indata, size_t indatalen,
303
536
          unsigned char **outdata, size_t *outdatalen )
304
537
{
305
 
  int rc;
 
538
  gpg_error_t err;
306
539
 
307
540
  if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
308
541
    return gpg_error (GPG_ERR_INV_VALUE);
310
543
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
311
544
  if (!app->fnc.sign)
312
545
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
313
 
  rc = app->fnc.sign (app, keyidstr, hashalgo,
314
 
                      pincb, pincb_arg,
315
 
                      indata, indatalen,
316
 
                      outdata, outdatalen);
 
546
  err = lock_reader (app->slot);
 
547
  if (err)
 
548
    return err;
 
549
  err = app->fnc.sign (app, keyidstr, hashalgo,
 
550
                       pincb, pincb_arg,
 
551
                       indata, indatalen,
 
552
                       outdata, outdatalen);
 
553
  unlock_reader (app->slot);
317
554
  if (opt.verbose)
318
 
    log_info ("operation sign result: %s\n", gpg_strerror (rc));
319
 
  return rc;
 
555
    log_info ("operation sign result: %s\n", gpg_strerror (err));
 
556
  return err;
320
557
}
321
558
 
322
559
/* Create the signature using the INTERNAL AUTHENTICATE command and
323
560
   return the allocated result in OUTDATA.  If a PIN is required the
324
561
   PINCB will be used to ask for the PIN; it should return the PIN in
325
562
   an allocated buffer and put it into PIN.  */
326
 
int 
327
 
app_auth (APP app, const char *keyidstr,
328
 
          int (pincb)(void*, const char *, char **),
 
563
gpg_error_t 
 
564
app_auth (app_t app, const char *keyidstr,
 
565
          gpg_error_t (*pincb)(void*, const char *, char **),
329
566
          void *pincb_arg,
330
567
          const void *indata, size_t indatalen,
331
568
          unsigned char **outdata, size_t *outdatalen )
332
569
{
333
 
  int rc;
 
570
  gpg_error_t err;
334
571
 
335
572
  if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
336
573
    return gpg_error (GPG_ERR_INV_VALUE);
338
575
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
339
576
  if (!app->fnc.auth)
340
577
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
341
 
  rc = app->fnc.auth (app, keyidstr,
342
 
                      pincb, pincb_arg,
343
 
                      indata, indatalen,
344
 
                      outdata, outdatalen);
 
578
  err = lock_reader (app->slot);
 
579
  if (err)
 
580
    return err;
 
581
  err = app->fnc.auth (app, keyidstr,
 
582
                       pincb, pincb_arg,
 
583
                       indata, indatalen,
 
584
                       outdata, outdatalen);
 
585
  unlock_reader (app->slot);
345
586
  if (opt.verbose)
346
 
    log_info ("operation auth result: %s\n", gpg_strerror (rc));
347
 
  return rc;
 
587
    log_info ("operation auth result: %s\n", gpg_strerror (err));
 
588
  return err;
348
589
}
349
590
 
350
591
 
351
592
/* Decrypt the data in INDATA and return the allocated result in OUTDATA.
352
593
   If a PIN is required the PINCB will be used to ask for the PIN; it
353
594
   should return the PIN in an allocated buffer and put it into PIN.  */
354
 
int 
355
 
app_decipher (APP app, const char *keyidstr,
356
 
              int (pincb)(void*, const char *, char **),
 
595
gpg_error_t 
 
596
app_decipher (app_t app, const char *keyidstr,
 
597
              gpg_error_t (*pincb)(void*, const char *, char **),
357
598
              void *pincb_arg,
358
599
              const void *indata, size_t indatalen,
359
600
              unsigned char **outdata, size_t *outdatalen )
360
601
{
361
 
  int rc;
 
602
  gpg_error_t err;
362
603
 
363
604
  if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
364
605
    return gpg_error (GPG_ERR_INV_VALUE);
366
607
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
367
608
  if (!app->fnc.decipher)
368
609
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
369
 
  rc = app->fnc.decipher (app, keyidstr,
370
 
                          pincb, pincb_arg,
371
 
                          indata, indatalen,
372
 
                          outdata, outdatalen);
373
 
  if (opt.verbose)
374
 
    log_info ("operation decipher result: %s\n", gpg_strerror (rc));
375
 
  return rc;
 
610
  err = lock_reader (app->slot);
 
611
  if (err)
 
612
    return err;
 
613
  err = app->fnc.decipher (app, keyidstr,
 
614
                           pincb, pincb_arg,
 
615
                           indata, indatalen,
 
616
                           outdata, outdatalen);
 
617
  unlock_reader (app->slot);
 
618
  if (opt.verbose)
 
619
    log_info ("operation decipher result: %s\n", gpg_strerror (err));
 
620
  return err;
 
621
}
 
622
 
 
623
 
 
624
/* Perform the WRITEKEY operation.  */
 
625
gpg_error_t
 
626
app_writekey (app_t app, ctrl_t ctrl,
 
627
              const char *keyidstr, unsigned int flags,
 
628
              gpg_error_t (*pincb)(void*, const char *, char **),
 
629
              void *pincb_arg,
 
630
              const unsigned char *keydata, size_t keydatalen)
 
631
{
 
632
  gpg_error_t err;
 
633
 
 
634
  if (!app || !keyidstr || !*keyidstr || !pincb)
 
635
    return gpg_error (GPG_ERR_INV_VALUE);
 
636
  if (!app->initialized)
 
637
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
 
638
  if (!app->fnc.writekey)
 
639
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
 
640
  err = lock_reader (app->slot);
 
641
  if (err)
 
642
    return err;
 
643
  err = app->fnc.writekey (app, ctrl, keyidstr, flags,
 
644
                           pincb, pincb_arg, keydata, keydatalen);
 
645
  unlock_reader (app->slot);
 
646
  if (opt.verbose)
 
647
    log_info ("operation writekey result: %s\n", gpg_strerror (err));
 
648
  return err;
 
649
 
376
650
}
377
651
 
378
652
 
379
653
/* Perform a SETATTR operation.  */
380
 
int 
381
 
app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
382
 
            int (*pincb)(void*, const char *, char **),
 
654
gpg_error_t 
 
655
app_genkey (app_t app, CTRL ctrl, const char *keynostr, unsigned int flags,
 
656
            gpg_error_t (*pincb)(void*, const char *, char **),
383
657
            void *pincb_arg)
384
658
{
385
 
  int rc;
 
659
  gpg_error_t err;
386
660
 
387
661
  if (!app || !keynostr || !*keynostr || !pincb)
388
662
    return gpg_error (GPG_ERR_INV_VALUE);
390
664
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
391
665
  if (!app->fnc.genkey)
392
666
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
393
 
  rc = app->fnc.genkey (app, ctrl, keynostr, flags, pincb, pincb_arg);
 
667
  err = lock_reader (app->slot);
 
668
  if (err)
 
669
    return err;
 
670
  err = app->fnc.genkey (app, ctrl, keynostr, flags, pincb, pincb_arg);
 
671
  unlock_reader (app->slot);
394
672
  if (opt.verbose)
395
 
    log_info ("operation genkey result: %s\n", gpg_strerror (rc));
396
 
  return rc;
 
673
    log_info ("operation genkey result: %s\n", gpg_strerror (err));
 
674
  return err;
397
675
}
398
676
 
399
677
 
400
678
/* Perform a GET CHALLENGE operation.  This fucntion is special as it
401
679
   directly accesses the card without any application specific
402
680
   wrapper. */
403
 
int
404
 
app_get_challenge (APP app, size_t nbytes, unsigned char *buffer)
 
681
gpg_error_t
 
682
app_get_challenge (app_t app, size_t nbytes, unsigned char *buffer)
405
683
{
 
684
  gpg_error_t err;
 
685
 
406
686
  if (!app || !nbytes || !buffer)
407
687
    return gpg_error (GPG_ERR_INV_VALUE);
408
688
  if (!app->initialized)
409
689
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
410
 
  return iso7816_get_challenge (app->slot, nbytes, buffer);
 
690
  err = lock_reader (app->slot);
 
691
  if (err)
 
692
    return err;
 
693
  err = iso7816_get_challenge (app->slot, nbytes, buffer);
 
694
  unlock_reader (app->slot);
 
695
  return err;
411
696
}
412
697
 
413
698
 
414
699
 
415
700
/* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation.  */
416
 
int 
417
 
app_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
418
 
                int (*pincb)(void*, const char *, char **),
 
701
gpg_error_t 
 
702
app_change_pin (app_t app, CTRL ctrl, const char *chvnostr, int reset_mode,
 
703
                gpg_error_t (*pincb)(void*, const char *, char **),
419
704
                void *pincb_arg)
420
705
{
421
 
  int rc;
 
706
  gpg_error_t err;
422
707
 
423
708
  if (!app || !chvnostr || !*chvnostr || !pincb)
424
709
    return gpg_error (GPG_ERR_INV_VALUE);
426
711
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
427
712
  if (!app->fnc.change_pin)
428
713
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
429
 
  rc = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode, pincb, pincb_arg);
 
714
  err = lock_reader (app->slot);
 
715
  if (err)
 
716
    return err;
 
717
  err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode,
 
718
                             pincb, pincb_arg);
 
719
  unlock_reader (app->slot);
430
720
  if (opt.verbose)
431
 
    log_info ("operation change_pin result: %s\n", gpg_strerror (rc));
432
 
  return rc;
 
721
    log_info ("operation change_pin result: %s\n", gpg_strerror (err));
 
722
  return err;
433
723
}
434
724
 
435
725
 
436
726
/* Perform a VERIFY operation without doing anything lese.  This may
437
 
   be used to initialze a the PION cache for long lasting other
 
727
   be used to initialze a the PIN cache for long lasting other
438
728
   operations.  Its use is highly application dependent. */
439
 
int 
440
 
app_check_pin (APP app, const char *keyidstr,
441
 
               int (*pincb)(void*, const char *, char **),
 
729
gpg_error_t 
 
730
app_check_pin (app_t app, const char *keyidstr,
 
731
               gpg_error_t (*pincb)(void*, const char *, char **),
442
732
               void *pincb_arg)
443
733
{
444
 
  int rc;
 
734
  gpg_error_t err;
445
735
 
446
736
  if (!app || !keyidstr || !*keyidstr || !pincb)
447
737
    return gpg_error (GPG_ERR_INV_VALUE);
449
739
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
450
740
  if (!app->fnc.check_pin)
451
741
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
452
 
  rc = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);
 
742
  err = lock_reader (app->slot);
 
743
  if (err)
 
744
    return err;
 
745
  err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);
 
746
  unlock_reader (app->slot);
453
747
  if (opt.verbose)
454
 
    log_info ("operation check_pin result: %s\n", gpg_strerror (rc));
455
 
  return rc;
 
748
    log_info ("operation check_pin result: %s\n", gpg_strerror (err));
 
749
  return err;
456
750
}
457
751