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

« back to all changes in this revision

Viewing changes to g10/cardglue.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* cardglue.c - mainly dispatcher for card related functions.
 
2
 * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
3
 *
 
4
 * This file is part of GnuPG.
 
5
 *
 
6
 * GnuPG is free software; you can redistribute it and/or modify
 
7
 * 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
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * GnuPG is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
19
 */
 
20
 
 
21
#include <config.h>
 
22
#ifndef ENABLE_CARD_SUPPORT
 
23
#error  not configured for card support.
 
24
#endif
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
#include <errno.h>
 
29
#include <stdarg.h>
 
30
#include <assert.h>
 
31
 
 
32
#include "options.h"
 
33
#include "packet.h"
 
34
#include "errors.h"
 
35
#include "memory.h"
 
36
#include "util.h"
 
37
#include "main.h"
 
38
#include "status.h"
 
39
#include "ttyio.h"
 
40
#include "i18n.h"
 
41
 
 
42
#include "cardglue.h"
 
43
#include "apdu.h"
 
44
#include "app-common.h"
 
45
 
 
46
struct ctrl_ctx_s {
 
47
  int (*status_cb)(void *opaque, const char *line);
 
48
  void *status_cb_arg;
 
49
};
 
50
 
 
51
 
 
52
static char *default_reader_port;
 
53
static APP current_app;
 
54
 
 
55
 
 
56
 
 
57
/* Create a serialno/fpr string from the serial number and the secret
 
58
   key.  caller must free the returned string.  There is no error
 
59
   return. [Taken from 1.9's keyid.c]*/
 
60
char *
 
61
serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
 
62
                          PKT_secret_key *sk)
 
63
{
 
64
  unsigned char fpr[MAX_FINGERPRINT_LEN];
 
65
  size_t fprlen;
 
66
  char *buffer, *p;
 
67
  int i;
 
68
  
 
69
  fingerprint_from_sk (sk, fpr, &fprlen);
 
70
  buffer = p = xmalloc (snlen*2 + 1 + fprlen*2 + 1);
 
71
  for (i=0; i < snlen; i++, p+=2)
 
72
    sprintf (p, "%02X", sn[i]);
 
73
  *p++ = '/';
 
74
  for (i=0; i < fprlen; i++, p+=2)
 
75
    sprintf (p, "%02X", fpr[i]);
 
76
  *p = 0;
 
77
  return buffer;
 
78
}
 
79
 
 
80
 
 
81
/* Send a line with status information via assuan and escape all given
 
82
   buffers. The variable elements are pairs of (char *, size_t),
 
83
   terminated with a (NULL, 0). */
 
84
void
 
85
send_status_info (CTRL ctrl, const char *keyword, ...)
 
86
{
 
87
  va_list arg_ptr;
 
88
  const unsigned char *value;
 
89
  size_t valuelen;
 
90
  char buf[950], *p;
 
91
  size_t n;
 
92
  
 
93
  va_start (arg_ptr, keyword);
 
94
 
 
95
  p = buf; 
 
96
  n = 0;
 
97
  valuelen = strlen (keyword);
 
98
  for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, keyword++)
 
99
    *p++ = *keyword;
 
100
 
 
101
  while ( (value = va_arg (arg_ptr, const unsigned char *)) )
 
102
    {
 
103
      valuelen = va_arg (arg_ptr, size_t);
 
104
      if (!valuelen)
 
105
        continue; /* empty buffer */
 
106
      if (n)
 
107
        {
 
108
          *p++ = ' ';
 
109
          n++;
 
110
        }
 
111
      for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
 
112
        {
 
113
          if (*value < ' ' || *value == '+')
 
114
            {
 
115
              sprintf (p, "%%%02X", *value);
 
116
              p += 3;
 
117
            }
 
118
          else if (*value == ' ')
 
119
            *p++ = '+';
 
120
          else
 
121
            *p++ = *value;
 
122
        }
 
123
    }
 
124
  *p = 0;
 
125
  ctrl->status_cb (ctrl->status_cb_arg, buf);
 
126
 
 
127
  va_end (arg_ptr);
 
128
}
 
129
 
 
130
 
 
131
void gcry_md_hash_buffer (int algo, void *digest,
 
132
                          const void *buffer, size_t length)
 
133
{
 
134
  MD_HANDLE h = md_open (algo, 0);
 
135
  if (!h)
 
136
    BUG();
 
137
  md_write (h, (byte *) buffer, length);
 
138
  md_final (h);
 
139
  memcpy (digest, md_read (h, algo), md_digest_length (algo));
 
140
  md_close (h);
 
141
}
 
142
 
 
143
 
 
144
/* This is a limited version of the one in 1.9 but it should be
 
145
   sufficient here. */
 
146
void
 
147
log_printf (const char *fmt, ...)
 
148
{
 
149
  va_list arg_ptr;
 
150
 
 
151
  va_start (arg_ptr, fmt);
 
152
  vfprintf (log_stream (), fmt, arg_ptr);
 
153
  va_end (arg_ptr);
 
154
}
 
155
 
 
156
 
 
157
 
 
158
/* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
 
159
   dump, with TEXT just an empty string, print a trailing linefeed,
 
160
   otherwise print an entire debug line. */
 
161
void
 
162
log_printhex (const char *text, const void *buffer, size_t length)
 
163
{
 
164
  if (text && *text)
 
165
    log_debug ("%s ", text);
 
166
  if (length)
 
167
    {
 
168
      const unsigned char *p = buffer;
 
169
      log_printf ("%02X", *p);
 
170
      for (length--, p++; length--; p++)
 
171
        log_printf (" %02X", *p);
 
172
    }
 
173
  if (text)
 
174
    log_printf ("\n");
 
175
}
 
176
 
 
177
 
 
178
 
 
179
void
 
180
app_set_default_reader_port (const char *portstr)
 
181
{
 
182
  xfree (default_reader_port);
 
183
  default_reader_port = portstr? xstrdup (portstr): NULL;
 
184
}
 
185
 
 
186
 
 
187
void
 
188
card_set_reader_port (const char *portstr)
 
189
{
 
190
  app_set_default_reader_port (portstr);
 
191
}
 
192
 
 
193
 
 
194
/* Retrieve the serial number and the time of the last update of the
 
195
   card.  The serial number is returned as a malloced string (hex
 
196
   encoded) in SERIAL and the time of update is returned in STAMP.  If
 
197
   no update time is available the returned value is 0.  Caller must
 
198
   free SERIAL unless the function returns an error. */
 
199
int 
 
200
app_get_serial_and_stamp (APP app, char **serial, time_t *stamp)
 
201
{
 
202
  unsigned char *buf, *p;
 
203
  int i;
 
204
 
 
205
  if (!app || !serial || !stamp)
 
206
    return gpg_error (GPG_ERR_INV_VALUE);
 
207
 
 
208
  *serial = NULL;
 
209
  *stamp = 0; /* not available */
 
210
 
 
211
  buf = xtrymalloc (app->serialnolen * 2 + 1);
 
212
  if (!buf)
 
213
    return gpg_error_from_errno (errno);
 
214
  for (p=buf, i=0; i < app->serialnolen; p +=2, i++)
 
215
    sprintf (p, "%02X", app->serialno[i]);
 
216
  *p = 0;
 
217
  *serial = buf;
 
218
  return 0;
 
219
}
 
220
 
 
221
 
 
222
 
 
223
 
 
224
 
 
225
 
 
226
/* Release the card info structure. */
 
227
void 
 
228
agent_release_card_info (struct agent_card_info_s *info)
 
229
{
 
230
  int i;
 
231
 
 
232
  if (!info)
 
233
    return;
 
234
 
 
235
  xfree (info->serialno); info->serialno = NULL;
 
236
  xfree (info->disp_name); info->disp_name = NULL;
 
237
  xfree (info->disp_lang); info->disp_lang = NULL;
 
238
  xfree (info->pubkey_url); info->pubkey_url = NULL;
 
239
  xfree (info->login_data); info->login_data = NULL;
 
240
  info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
 
241
  info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
 
242
  for (i=0; i < 4; i++)
 
243
    {
 
244
      xfree (info->private_do[i]);
 
245
      info->private_do[i] = NULL;
 
246
    }
 
247
}
 
248
 
 
249
 
 
250
/* Open the current card and select the openpgp application.  Return
 
251
   an APP context handle to be used for further procesing or NULL on
 
252
   error or if no OpenPGP application exists.*/
 
253
static APP
 
254
open_card (void)
 
255
{
 
256
  int slot = -1;
 
257
  int rc;
 
258
  APP app;
 
259
  int did_shutdown = 0;
 
260
 
 
261
  card_close ();
 
262
 
 
263
  
 
264
 retry:
 
265
  if (did_shutdown)
 
266
    apdu_reset (slot);
 
267
  else
 
268
    {
 
269
      slot = apdu_open_reader (default_reader_port);
 
270
      if (slot == -1)
 
271
        {
 
272
          log_error ("card reader not available\n");
 
273
          return NULL;
 
274
        }
 
275
    }
 
276
 
 
277
  app = xcalloc (1, sizeof *app);
 
278
  app->slot = slot;
 
279
  rc = app_select_openpgp (app);
 
280
  if (rc && !opt.batch)
 
281
    {
 
282
      write_status_text (STATUS_CARDCTRL, "1");
 
283
      
 
284
      did_shutdown = !!apdu_shutdown_reader (slot);
 
285
 
 
286
      if ( cpr_get_answer_okay_cancel ("cardctrl.insert_card.okay",
 
287
           _("Please insert the card and hit return or enter 'c' to cancel: "),
 
288
                                       1) )
 
289
        {
 
290
          if (!did_shutdown)
 
291
            apdu_close_reader (slot);
 
292
          xfree (app);
 
293
          goto retry;
 
294
        }
 
295
    }
 
296
  if (rc)
 
297
    {
 
298
      log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
 
299
      apdu_close_reader (slot);
 
300
      xfree (app);
 
301
      return NULL;
 
302
    }
 
303
 
 
304
  app->initialized = 1;
 
305
  current_app = app;
 
306
  if (is_status_enabled () )
 
307
    {
 
308
      int i;
 
309
      char *p, *buf;
 
310
 
 
311
      buf = xmalloc (5 + app->serialnolen * 2 + 1);
 
312
      p = stpcpy (buf, "3 ");
 
313
      for (i=0; i < app->serialnolen; p +=2, i++)
 
314
        sprintf (p, "%02X", app->serialno[i]);
 
315
      write_status_text (STATUS_CARDCTRL, buf);
 
316
      xfree (buf);
 
317
    }
 
318
 
 
319
  return app;
 
320
}
 
321
 
 
322
void
 
323
card_close (void)
 
324
{
 
325
  if (current_app)
 
326
    {
 
327
      APP app = current_app;
 
328
      current_app = NULL;
 
329
 
 
330
      apdu_close_reader (app->slot);
 
331
      xfree (app);
 
332
    }
 
333
}
 
334
 
 
335
 
 
336
/* Check that the serial number of the current card (as described by
 
337
   APP) matches SERIALNO.  If there is no match and we are not in
 
338
   batch mode, present a prompt to insert the desired card.  The
 
339
   function return 0 is the present card is okay, -1 if the user
 
340
   selected to insert a new card or an error value.  Note that the
 
341
   card context will be closed in all cases except for 0 as return
 
342
   value and if it was possible to merely shutdown the reader. */
 
343
static int
 
344
check_card_serialno (APP app, const char *serialno)
 
345
{
 
346
  const char *s;
 
347
  int ask = 0;
 
348
  int n;
 
349
  
 
350
  for (s = serialno, n=0; *s != '/' && hexdigitp (s); s++, n++)
 
351
    ;
 
352
  if (n != 32)
 
353
    {
 
354
      log_error ("invalid serial number in keyring detected\n");
 
355
      return gpg_error (GPG_ERR_INV_ID);
 
356
    }
 
357
  if (app->serialnolen != 16)
 
358
    ask = 1;
 
359
  for (s = serialno, n=0; !ask && n < 16; s += 2, n++)
 
360
    if (app->serialno[n] != xtoi_2 (s))
 
361
      ask = 1;
 
362
  if (ask)
 
363
    {
 
364
      char buf[5+32+1];
 
365
      int did_shutdown = 0;
 
366
 
 
367
      if (current_app && !apdu_shutdown_reader (current_app->slot))
 
368
        did_shutdown = 1;
 
369
      else
 
370
        card_close ();
 
371
      tty_printf (_("Please remove the current card and "
 
372
                    "insert the one with serial number:\n"
 
373
                    "   %.*s\n"), 32, serialno);
 
374
 
 
375
      sprintf (buf, "1 %.32s", serialno);
 
376
      write_status_text (STATUS_CARDCTRL, buf);
 
377
 
 
378
      if ( cpr_get_answer_okay_cancel ("cardctrl.change_card.okay",
 
379
                          _("Hit return when ready "
 
380
                            "or enter 'c' to cancel: "),
 
381
                                       1) )
 
382
        {
 
383
          card_close ();
 
384
          return -1;
 
385
        }
 
386
      if (did_shutdown)
 
387
        apdu_reset (current_app->slot);
 
388
      else
 
389
        card_close ();
 
390
      return gpg_error (GPG_ERR_INV_ID);
 
391
    }
 
392
  return 0;
 
393
}
 
394
 
 
395
 
 
396
 
 
397
/* Return a new malloced string by unescaping the string S.  Escaping
 
398
   is percent escaping and '+'/space mapping.  A binary nul will
 
399
   silently be replaced by a 0xFF.  Function returns NULL to indicate
 
400
   an out of memory status. */
 
401
static char *
 
402
unescape_status_string (const unsigned char *s)
 
403
{
 
404
  char *buffer, *d;
 
405
 
 
406
  buffer = d = xmalloc (strlen (s)+1);
 
407
  while (*s)
 
408
    {
 
409
      if (*s == '%' && s[1] && s[2])
 
410
        { 
 
411
          s++;
 
412
          *d = xtoi_2 (s);
 
413
          if (!*d)
 
414
            *d = '\xff';
 
415
          d++;
 
416
          s += 2;
 
417
        }
 
418
      else if (*s == '+')
 
419
        {
 
420
          *d++ = ' ';
 
421
          s++;
 
422
        }
 
423
      else
 
424
        *d++ = *s++;
 
425
    }
 
426
  *d = 0; 
 
427
  return buffer;
 
428
}
 
429
 
 
430
/* Take a 20 byte hexencoded string and put it into the the provided
 
431
   20 byte buffer FPR in binary format. */
 
432
static int
 
433
unhexify_fpr (const char *hexstr, unsigned char *fpr)
 
434
{
 
435
  const char *s;
 
436
  int n;
 
437
 
 
438
  for (s=hexstr, n=0; hexdigitp (s); s++, n++)
 
439
    ;
 
440
  if (*s || (n != 40))
 
441
    return 0; /* no fingerprint (invalid or wrong length). */
 
442
  n /= 2;
 
443
  for (s=hexstr, n=0; *s; s += 2, n++)
 
444
    fpr[n] = xtoi_2 (s);
 
445
  return 1; /* okay */
 
446
}
 
447
 
 
448
/* Take the serial number from LINE and return it verbatim in a newly
 
449
   allocated string.  We make sure that only hex characters are
 
450
   returned. */
 
451
static char *
 
452
store_serialno (const char *line)
 
453
{
 
454
  const char *s;
 
455
  char *p;
 
456
 
 
457
  for (s=line; hexdigitp (s); s++)
 
458
    ;
 
459
  p = xmalloc (s + 1 - line);
 
460
  memcpy (p, line, s-line);
 
461
  p[s-line] = 0;
 
462
  return p;
 
463
}
 
464
 
 
465
 
 
466
 
 
467
static int
 
468
learn_status_cb (void *opaque, const char *line)
 
469
{
 
470
  struct agent_card_info_s *parm = opaque;
 
471
  const char *keyword = line;
 
472
  int keywordlen;
 
473
  int i;
 
474
 
 
475
/*   log_debug ("got status line `%s'\n", line); */
 
476
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
 
477
    ;
 
478
  while (spacep (line))
 
479
    line++;
 
480
 
 
481
  if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
 
482
    {
 
483
      xfree (parm->serialno);
 
484
      parm->serialno = store_serialno (line);
 
485
    }
 
486
  else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
 
487
    {
 
488
      xfree (parm->disp_name);
 
489
      parm->disp_name = unescape_status_string (line);
 
490
    }
 
491
  else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
 
492
    {
 
493
      xfree (parm->disp_lang);
 
494
      parm->disp_lang = unescape_status_string (line);
 
495
    }
 
496
  else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
 
497
    {
 
498
      parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
 
499
    }
 
500
  else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
 
501
    {
 
502
      xfree (parm->pubkey_url);
 
503
      parm->pubkey_url = unescape_status_string (line);
 
504
    }
 
505
  else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
 
506
    {
 
507
      xfree (parm->login_data);
 
508
      parm->login_data = unescape_status_string (line);
 
509
    }
 
510
  else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
 
511
    {
 
512
      parm->sig_counter = strtoul (line, NULL, 0);
 
513
    }
 
514
  else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
 
515
    {
 
516
      char *p, *buf;
 
517
 
 
518
      buf = p = unescape_status_string (line);
 
519
      if (buf)
 
520
        {
 
521
          while (spacep (p))
 
522
            p++;
 
523
          parm->chv1_cached = atoi (p);
 
524
          while (*p && !spacep (p))
 
525
            p++;
 
526
          while (spacep (p))
 
527
            p++;
 
528
          for (i=0; *p && i < 3; i++)
 
529
            {
 
530
              parm->chvmaxlen[i] = atoi (p);
 
531
              while (*p && !spacep (p))
 
532
                p++;
 
533
              while (spacep (p))
 
534
                p++;
 
535
            }
 
536
          for (i=0; *p && i < 3; i++)
 
537
            {
 
538
              parm->chvretry[i] = atoi (p);
 
539
              while (*p && !spacep (p))
 
540
                p++;
 
541
              while (spacep (p))
 
542
                p++;
 
543
            }
 
544
          xfree (buf);
 
545
        }
 
546
    }
 
547
  else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
 
548
    {
 
549
      int no = atoi (line);
 
550
      while (* line && !spacep (line))
 
551
        line++;
 
552
      while (spacep (line))
 
553
        line++;
 
554
      if (no == 1)
 
555
        parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
 
556
      else if (no == 2)
 
557
        parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
 
558
      else if (no == 3)
 
559
        parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
 
560
    }
 
561
  else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
 
562
    {
 
563
      int no = atoi (line);
 
564
      while (* line && !spacep (line))
 
565
        line++;
 
566
      while (spacep (line))
 
567
        line++;
 
568
      if (no == 1)
 
569
        parm->fpr1time = strtoul (line, NULL, 10);
 
570
      else if (no == 2)
 
571
        parm->fpr2time = strtoul (line, NULL, 10);
 
572
      else if (no == 3)
 
573
        parm->fpr3time = strtoul (line, NULL, 10);
 
574
    }
 
575
  else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
 
576
    {
 
577
      int no = atoi (line);
 
578
      while (*line && !spacep (line))
 
579
        line++;
 
580
      while (spacep (line))
 
581
        line++;
 
582
      if (no == 1)
 
583
        parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
 
584
      else if (no == 2)
 
585
        parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
 
586
      else if (no == 3)
 
587
        parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
 
588
    }
 
589
  else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
 
590
           && strchr ("1234", keyword[11]))
 
591
    {
 
592
      int no = keyword[11] - '1';
 
593
      assert (no >= 0 && no <= 3);
 
594
      xfree (parm->private_do[no]);
 
595
      parm->private_do[no] = unescape_status_string (line);
 
596
    }
 
597
 
 
598
  return 0;
 
599
}
 
600
 
 
601
 
 
602
/* Return card info. */
 
603
int 
 
604
agent_learn (struct agent_card_info_s *info)
 
605
{
 
606
  APP app;
 
607
  int rc;
 
608
  struct ctrl_ctx_s ctrl;
 
609
  time_t stamp;
 
610
  char *serial;
 
611
  
 
612
  app = current_app? current_app : open_card ();
 
613
  if (!app)
 
614
    return gpg_error (GPG_ERR_CARD);
 
615
 
 
616
  memset (info, 0, sizeof *info);
 
617
  memset (&ctrl, 0, sizeof ctrl);
 
618
  ctrl.status_cb = learn_status_cb;
 
619
  ctrl.status_cb_arg = info;
 
620
 
 
621
  rc = app_get_serial_and_stamp (app, &serial, &stamp);
 
622
  if (!rc)
 
623
    {
 
624
      send_status_info (&ctrl, "SERIALNO", serial, strlen(serial), NULL, 0);
 
625
      xfree (serial);
 
626
      rc = app->fnc.learn_status (app, &ctrl);
 
627
    }
 
628
 
 
629
  return rc;
 
630
}
 
631
 
 
632
/* Get an attribite from the card. Make sure info is initialized. */
 
633
int 
 
634
agent_scd_getattr (const char *name, struct agent_card_info_s *info)
 
635
{
 
636
  APP app;
 
637
  struct ctrl_ctx_s ctrl;
 
638
 
 
639
  app = current_app? current_app : open_card ();
 
640
  if (!app)
 
641
    return gpg_error (GPG_ERR_CARD);
 
642
 
 
643
  ctrl.status_cb = learn_status_cb;
 
644
  ctrl.status_cb_arg = info;
 
645
  return app->fnc.getattr (app, &ctrl, name);
 
646
}
 
647
 
 
648
 
 
649
 
 
650
static int 
 
651
pin_cb (void *opaque, const char *info, char **retstr)
 
652
{
 
653
  char *value;
 
654
  int canceled;
 
655
  int isadmin = 0;
 
656
  int newpin = 0;
 
657
  const char *again_text = NULL;
 
658
  const char *ends, *s;
 
659
 
 
660
  *retstr = NULL;
 
661
  log_debug ("asking for PIN '%s'\n", info);
 
662
 
 
663
  /* We use a special prefix to check whether the Admin PIN has been
 
664
     requested. */
 
665
  if (info && *info =='|' && (ends=strchr (info+1, '|')))
 
666
    {
 
667
      for (s=info+1; s < ends; s++)
 
668
        {
 
669
          if (*s == 'A')
 
670
            isadmin = 1;
 
671
          else if (*s == 'N')
 
672
            newpin = 1;
 
673
        }
 
674
      info = ends+1;
 
675
    }
 
676
 
 
677
 again:
 
678
  if (is_status_enabled())
 
679
    write_status_text (STATUS_NEED_PASSPHRASE_PIN,
 
680
                       isadmin? "OPENPGP 3" : "OPENPGP 1");
 
681
 
 
682
  value = ask_passphrase (info, again_text,
 
683
                          newpin && isadmin? "passphrase.adminpin.new.ask" :
 
684
                          newpin?  "passphrase.pin.new.ask" :
 
685
                          isadmin? "passphrase.adminpin.ask" :
 
686
                                   "passphrase.pin.ask", 
 
687
                          newpin && isadmin? _("Enter New Admin PIN: ") :
 
688
                          newpin?  _("Enter New PIN: ") :
 
689
                          isadmin? _("Enter Admin PIN: ")
 
690
                                 : _("Enter PIN: "),
 
691
                          &canceled);
 
692
  again_text = NULL;
 
693
  if (!value && canceled)
 
694
    return -1;
 
695
  else if (!value)
 
696
    return G10ERR_GENERAL;
 
697
 
 
698
  if (newpin)
 
699
    {
 
700
      char *value2;
 
701
 
 
702
      value2 = ask_passphrase (info, NULL,
 
703
                               "passphrase.pin.repeat", 
 
704
                               _("Repeat this PIN: "),
 
705
                              &canceled);
 
706
      if (!value && canceled)
 
707
        {
 
708
          xfree (value);
 
709
          return -1;
 
710
        }
 
711
      else if (!value)
 
712
        {
 
713
          xfree (value);
 
714
          return G10ERR_GENERAL;
 
715
        }
 
716
      if (strcmp (value, value2))
 
717
        {
 
718
          again_text = N_("PIN not correctly repeated; try again");
 
719
          xfree (value2);
 
720
          xfree (value);
 
721
          value = NULL;
 
722
          goto again;
 
723
        }
 
724
      xfree (value2);
 
725
    }
 
726
 
 
727
  *retstr = value;
 
728
  return 0;
 
729
}
 
730
 
 
731
 
 
732
 
 
733
/* Send a SETATTR command to the SCdaemon. */
 
734
int 
 
735
agent_scd_setattr (const char *name,
 
736
                   const unsigned char *value, size_t valuelen)
 
737
{
 
738
  APP app;
 
739
 
 
740
  app = current_app? current_app : open_card ();
 
741
  if (!app)
 
742
    return gpg_error (GPG_ERR_CARD);
 
743
 
 
744
  return app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen);
 
745
}
 
746
 
 
747
 
 
748
static int
 
749
genkey_status_cb (void *opaque, const char *line)
 
750
{
 
751
  struct agent_card_genkey_s *parm = opaque;
 
752
  const char *keyword = line;
 
753
  int keywordlen;
 
754
 
 
755
/*   log_debug ("got status line `%s'\n", line); */
 
756
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
 
757
    ;
 
758
  while (spacep (line))
 
759
    line++;
 
760
 
 
761
  if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
 
762
    {
 
763
      parm->fprvalid = unhexify_fpr (line, parm->fpr);
 
764
    }
 
765
  if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
 
766
    {
 
767
      MPI a;
 
768
      const char *name = line;
 
769
      char *buf;
 
770
 
 
771
      while (*line && !spacep (line))
 
772
        line++;
 
773
      while (spacep (line))
 
774
        line++;
 
775
 
 
776
      buf = xmalloc ( 2 + strlen (line) + 1);
 
777
      strcpy (stpcpy (buf, "0x"), line);
 
778
      a = mpi_alloc (300);
 
779
      if( mpi_fromstr (a, buf) )
 
780
        log_error ("error parsing received key data\n");
 
781
      else if (*name == 'n' && spacep (name+1))
 
782
        parm->n = a;
 
783
      else if (*name == 'e' && spacep (name+1))
 
784
        parm->e = a;
 
785
      else
 
786
        {
 
787
          log_info ("unknown parameter name in received key data\n");
 
788
          mpi_free (a);
 
789
        }
 
790
      xfree (buf);
 
791
    }
 
792
  else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
 
793
    {
 
794
      parm->created_at = (u32)strtoul (line, NULL, 10);
 
795
    }
 
796
 
 
797
  return 0;
 
798
}
 
799
 
 
800
/* Send a GENKEY command to the SCdaemon. */
 
801
int 
 
802
agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force)
 
803
{
 
804
  APP app;
 
805
  char keynostr[20];
 
806
  struct ctrl_ctx_s ctrl;
 
807
 
 
808
  app = current_app? current_app : open_card ();
 
809
  if (!app)
 
810
    return gpg_error (GPG_ERR_CARD);
 
811
 
 
812
  memset (info, 0, sizeof *info);
 
813
  sprintf (keynostr, "%d", keyno);
 
814
  ctrl.status_cb = genkey_status_cb;
 
815
  ctrl.status_cb_arg = info;
 
816
 
 
817
  return app->fnc.genkey (app, &ctrl, keynostr,
 
818
                           force? 1:0,
 
819
                           pin_cb, NULL);
 
820
}
 
821
 
 
822
/* Send a PKSIGN command to the SCdaemon. */
 
823
int 
 
824
agent_scd_pksign (const char *serialno, int hashalgo,
 
825
                  const unsigned char *indata, size_t indatalen,
 
826
                  unsigned char **r_buf, size_t *r_buflen)
 
827
{
 
828
  APP app;
 
829
  int rc;
 
830
 
 
831
  *r_buf = NULL;
 
832
  *r_buflen = 0;
 
833
 retry:
 
834
  app = current_app? current_app : open_card ();
 
835
  if (!app)
 
836
    return gpg_error (GPG_ERR_CARD);
 
837
 
 
838
  /* Check that the card's serialnumber is as required.*/
 
839
  rc = check_card_serialno (app, serialno);
 
840
  if (rc == -1)
 
841
    goto retry;
 
842
  if (rc)
 
843
    return rc;
 
844
 
 
845
  return app->fnc.sign (app, serialno, hashalgo,
 
846
                        pin_cb, NULL,
 
847
                        indata, indatalen,
 
848
                        r_buf, r_buflen);
 
849
}
 
850
 
 
851
 
 
852
/* Send a PKDECRYPT command to the SCdaemon. */
 
853
int 
 
854
agent_scd_pkdecrypt (const char *serialno,
 
855
                     const unsigned char *indata, size_t indatalen,
 
856
                     unsigned char **r_buf, size_t *r_buflen)
 
857
{
 
858
  APP app;
 
859
  int rc;
 
860
 
 
861
  *r_buf = NULL;
 
862
  *r_buflen = 0;
 
863
 retry:
 
864
  app = current_app? current_app : open_card ();
 
865
  if (!app)
 
866
    return gpg_error (GPG_ERR_CARD);
 
867
 
 
868
  /* Check that the card's serialnumber is as required.*/
 
869
  rc = check_card_serialno (app, serialno);
 
870
  if (rc == -1)
 
871
    goto retry;
 
872
  if (rc)
 
873
    return rc;
 
874
 
 
875
  return app->fnc.decipher (app, serialno, 
 
876
                            pin_cb, NULL,
 
877
                            indata, indatalen,
 
878
                            r_buf, r_buflen);
 
879
}
 
880
 
 
881
/* Change the PIN of an OpenPGP card or reset the retry counter. */
 
882
int 
 
883
agent_scd_change_pin (int chvno)
 
884
{
 
885
  APP app;
 
886
  char chvnostr[20];
 
887
  int reset = 0;
 
888
 
 
889
  reset = (chvno >= 100);
 
890
  chvno %= 100;
 
891
 
 
892
  app = current_app? current_app : open_card ();
 
893
  if (!app)
 
894
    return gpg_error (GPG_ERR_CARD);
 
895
 
 
896
  sprintf (chvnostr, "%d", chvno);
 
897
  return app->fnc.change_pin (app, NULL, chvnostr, reset,
 
898
                              pin_cb, NULL);
 
899
}
 
900
 
 
901
/* Perform a CHECKPIN operation.  SERIALNO should be the serial
 
902
   number of the card - optionally followed by the fingerprint;
 
903
   however the fingerprint is ignored here. */
 
904
int
 
905
agent_scd_checkpin (const char *serialnobuf)
 
906
{
 
907
  APP app;
 
908
 
 
909
  app = current_app? current_app : open_card ();
 
910
  if (!app)
 
911
    return gpg_error (GPG_ERR_CARD);
 
912
 
 
913
  return app->fnc.check_pin (app, serialnobuf, pin_cb, NULL);
 
914
}
 
915
 
 
916
 
 
917
/* Wrapper to call the store key helper function of app-openpgp.c.  */
 
918
int 
 
919
agent_openpgp_storekey (int keyno,
 
920
                        unsigned char *template, size_t template_len,
 
921
                        time_t created_at,
 
922
                        const unsigned char *m, size_t mlen,
 
923
                        const unsigned char *e, size_t elen)
 
924
{
 
925
  APP app;
 
926
 
 
927
  app = current_app? current_app : open_card ();
 
928
  if (!app)
 
929
    return gpg_error (GPG_ERR_CARD);
 
930
 
 
931
  return app_openpgp_storekey (app, keyno, template, template_len,
 
932
                               created_at, m, mlen, e, elen,
 
933
                               pin_cb, NULL);
 
934
}