~ubuntu-branches/ubuntu/hardy/gnupg/hardy-updates

« back to all changes in this revision

Viewing changes to g10/cardglue.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2005-12-16 16:57:39 UTC
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051216165739-v0m2d1you6hd8jho
Tags: upstream-1.4.2
ImportĀ upstreamĀ versionĀ 1.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 *
16
16
 * You should have received a copy of the GNU General Public License
17
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
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 
19
 * USA.
19
20
 */
20
21
 
21
22
#include <config.h>
43
44
#include "apdu.h"
44
45
#include "app-common.h"
45
46
 
46
 
struct ctrl_ctx_s {
47
 
  int (*status_cb)(void *opaque, const char *line);
 
47
 
 
48
 
 
49
struct ctrl_ctx_s 
 
50
{
 
51
  assuan_error_t (*status_cb)(void *opaque, const char *line);
48
52
  void *status_cb_arg;
49
53
};
50
54
 
51
55
 
 
56
struct pincb_parm_s
 
57
{
 
58
  const char *sn;
 
59
};
 
60
 
 
61
 
 
62
struct writekey_parm_s
 
63
{
 
64
  assuan_context_t ctx;
 
65
  const unsigned char *keydata;
 
66
  size_t keydatalen;
 
67
};
 
68
 
 
69
 
 
70
 
52
71
static char *default_reader_port;
53
 
static APP current_app;
54
 
 
55
 
 
56
 
 
 
72
static app_t current_app;
 
73
 
 
74
 
 
75
/* Local prototypes. */
 
76
static assuan_error_t learn_status_cb (void *opaque, const char *line);
 
77
 
 
78
 
 
79
/* To avoid cluttering the code with bunches of ifdefs we use a few
 
80
   dummy functions instead and defines. */
 
81
#ifndef ENABLE_AGENT_SUPPORT
 
82
 
 
83
#define ASSUAN_LINELENGTH 100
 
84
 
 
85
static assuan_context_t 
 
86
agent_open (int try, const char *orig_codeset)
 
87
{
 
88
  return NULL;
 
89
}
 
90
 
 
91
void 
 
92
agent_close (assuan_context_t ctx)
 
93
{
 
94
}
 
95
 
 
96
const char *
 
97
assuan_strerror (assuan_error_t err)
 
98
{
 
99
  return "no Assuan support";
 
100
}
 
101
 
 
102
assuan_error_t 
 
103
assuan_transact (assuan_context_t ctx,
 
104
                 const char *command,
 
105
                 assuan_error_t (*data_cb)(void *, const void *, size_t),
 
106
                 void *data_cb_arg,
 
107
                 assuan_error_t (*inquire_cb)(void*, const char *),
 
108
                 void *inquire_cb_arg,
 
109
                 assuan_error_t (*status_cb)(void*, const char *),
 
110
                 void *status_cb_arg)
 
111
{
 
112
  return 100; /* ASSUAN_NOT_IMPLEMENTED */
 
113
}
 
114
assuan_error_t 
 
115
assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
 
116
{
 
117
  return 100; /* ASSUAN_NOT_IMPLEMENTED */
 
118
}  
 
119
#endif /*!ENABLE_AGENT_SUPPORT*/
 
120
 
 
121
 
57
122
/* Create a serialno/fpr string from the serial number and the secret
58
123
   key.  caller must free the returned string.  There is no error
59
124
   return. [Taken from 1.9's keyid.c]*/
82
147
   buffers. The variable elements are pairs of (char *, size_t),
83
148
   terminated with a (NULL, 0). */
84
149
void
85
 
send_status_info (CTRL ctrl, const char *keyword, ...)
 
150
send_status_info (ctrl_t ctrl, const char *keyword, ...)
86
151
{
87
152
  va_list arg_ptr;
88
153
  const unsigned char *value;
122
187
        }
123
188
    }
124
189
  *p = 0;
125
 
  ctrl->status_cb (ctrl->status_cb_arg, buf);
 
190
  if (ctrl && ctrl->status_cb)
 
191
    ctrl->status_cb (ctrl->status_cb_arg, buf);
126
192
 
127
193
  va_end (arg_ptr);
128
194
}
129
195
 
130
196
 
131
 
void gcry_md_hash_buffer (int algo, void *digest,
132
 
                          const void *buffer, size_t length)
 
197
/* Replacement function of the Libgcrypt onewhich is used in gnupg
 
198
   1.9.  Thus function computes the digest of ALGO from the data in
 
199
   BUFFER of LENGTH.  ALGO must be supported. */
 
200
void 
 
201
gcry_md_hash_buffer (int algo, void *digest,
 
202
                     const void *buffer, size_t length)
133
203
{
134
204
  MD_HANDLE h = md_open (algo, 0);
135
205
  if (!h)
197
267
   no update time is available the returned value is 0.  Caller must
198
268
   free SERIAL unless the function returns an error. */
199
269
int 
200
 
app_get_serial_and_stamp (APP app, char **serial, time_t *stamp)
 
270
app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
201
271
{
202
272
  unsigned char *buf, *p;
203
273
  int i;
220
290
 
221
291
 
222
292
 
223
 
 
224
 
 
225
 
 
226
293
/* Release the card info structure. */
227
294
void 
228
295
agent_release_card_info (struct agent_card_info_s *info)
247
314
}
248
315
 
249
316
 
 
317
/* Print an error message for a failed assuan_transact and return a
 
318
   gpg error code. No error is printed if RC is 0. */
 
319
static gpg_error_t
 
320
test_transact (int rc, const char *command)
 
321
{
 
322
  if (!rc)
 
323
    return 0;
 
324
  log_error ("sending command `%s' to agent failed: %s\n",
 
325
             command, assuan_strerror (rc));
 
326
  return gpg_error (GPG_ERR_CARD);
 
327
}
 
328
 
 
329
 
 
330
/* Try to open a card using an already running agent.  Prepare a
 
331
   proper application context and return it. */
 
332
static app_t
 
333
open_card_via_agent (int *scd_available)
 
334
{
 
335
  assuan_context_t ctx;
 
336
  app_t app;
 
337
  struct agent_card_info_s info;
 
338
  int rc;
 
339
 
 
340
  *scd_available = 0;
 
341
  ctx = agent_open (1, NULL);
 
342
  if (!ctx)
 
343
    return NULL;
 
344
 
 
345
  /* Request the serialbnumber of the card.  If we get
 
346
     NOT_SUPPORTED or NO_SCDAEMON back, the gpg-agent either has
 
347
     disabled scdaemon or it can't be used.  We close the connection
 
348
     in this case and use our own code.  This may happen if just the
 
349
     gpg-agent has been installed for the sake of passphrase
 
350
     caching. */
 
351
  memset (&info, 0, sizeof info);
 
352
  rc = assuan_transact (ctx, "SCD SERIALNO openpgp",
 
353
                        NULL, NULL, NULL, NULL,
 
354
                        learn_status_cb, &info);
 
355
  if (rc)
 
356
    {
 
357
      if ((rc & 0xffff) == 60 || (rc & 0xffff) == 119)
 
358
        ;  /* No scdaemon available to gpg-agent. */
 
359
      else
 
360
        {
 
361
          write_status_text (STATUS_CARDCTRL, "4");
 
362
          log_info ("selecting openpgp failed: %s\n", assuan_strerror (rc));
 
363
          *scd_available = 1;
 
364
        }
 
365
      agent_release_card_info (&info);
 
366
      agent_close (ctx);
 
367
      return NULL;
 
368
    }
 
369
  
 
370
  app = xcalloc (1, sizeof *app);
 
371
  app->assuan_ctx = ctx;
 
372
 
 
373
  return app;
 
374
}
 
375
 
 
376
 
 
377
 
250
378
/* Open the current card and select the openpgp application.  Return
251
379
   an APP context handle to be used for further procesing or NULL on
252
380
   error or if no OpenPGP application exists.*/
253
 
static APP
 
381
static app_t
254
382
open_card (void)
255
383
{
256
384
  int slot = -1;
257
385
  int rc;
258
 
  APP app;
 
386
  app_t app;
259
387
  int did_shutdown = 0;
260
 
 
 
388
  int retry_count = 0;
 
389
 
 
390
  /* First check whether we can contact a gpg-agent and divert all
 
391
     operation to it. This is required because gpg as well as the
 
392
     agent require exclusive access to the reader. */
 
393
  if (opt.use_agent)
 
394
    {
 
395
      int scd_available;
 
396
 
 
397
      app = open_card_via_agent (&scd_available);
 
398
      if (app)
 
399
        goto ready; /* Yes, there is a agent with a usable card, go that way. */
 
400
      if (scd_available)
 
401
        return NULL; /* agent avilabale but card problem. */
 
402
    }
 
403
 
 
404
 
 
405
  /* No agent or usable agent, thus we do it on our own. */
261
406
  card_close ();
262
 
 
263
407
  
264
408
 retry:
265
409
  if (did_shutdown)
269
413
      slot = apdu_open_reader (default_reader_port);
270
414
      if (slot == -1)
271
415
        {
 
416
          write_status_text (STATUS_CARDCTRL, "5");
272
417
          log_error ("card reader not available\n");
273
418
          return NULL;
274
419
        }
277
422
  app = xcalloc (1, sizeof *app);
278
423
  app->slot = slot;
279
424
  rc = app_select_openpgp (app);
280
 
  if (rc && !opt.batch)
 
425
  if (opt.limit_card_insert_tries 
 
426
      && ++retry_count >= opt.limit_card_insert_tries)
 
427
    ;
 
428
  else if (rc && !opt.batch)
281
429
    {
282
430
      write_status_text (STATUS_CARDCTRL, "1");
283
431
      
302
450
      return NULL;
303
451
    }
304
452
 
 
453
 ready:
305
454
  app->initialized = 1;
306
455
  current_app = app;
307
456
  if (is_status_enabled () )
320
469
  return app;
321
470
}
322
471
 
 
472
 
323
473
void
324
474
card_close (void)
325
475
{
326
476
  if (current_app)
327
477
    {
328
 
      APP app = current_app;
 
478
      app_t app = current_app;
329
479
      current_app = NULL;
330
480
 
331
 
      apdu_close_reader (app->slot);
 
481
      if (app->assuan_ctx)
 
482
        agent_close (app->assuan_ctx);
 
483
      else
 
484
        apdu_close_reader (app->slot);
332
485
      xfree (app);
333
486
    }
334
487
}
335
488
 
336
489
 
 
490
/* Format a cache ID from the serialnumber in SN and return it as an
 
491
   allocated string.  In case of an error NULL is returned. */
 
492
static char *
 
493
format_cacheid (const char *sn)
 
494
{
 
495
  const char *s;
 
496
  size_t snlen;
 
497
  char *cacheid = NULL;
 
498
 
 
499
  /* The serialnumber we use for a card is "CARDSN:serialno".  Where
 
500
     serialno is the BCD string (i.e. hex string) with the full
 
501
     number.  The serial number expect here constsis of hexdigits
 
502
     followed by other characters, we cut off these other
 
503
     characters. */
 
504
  if (sn)
 
505
    {
 
506
      for (s=sn,snlen=0; hexdigitp (s); s++, snlen++)
 
507
        ;
 
508
      if (snlen == 32)
 
509
        {
 
510
          /* Yes, this looks indeed like an OpenPGP card S/N. */
 
511
          cacheid = xtrymalloc (7+snlen+1);
 
512
          if (cacheid)
 
513
            {
 
514
              memcpy (cacheid, "CARDSN:", 7);
 
515
              memcpy (cacheid+7, sn, snlen);
 
516
              cacheid[7+snlen] = 0;
 
517
            }
 
518
        }
 
519
    }
 
520
  return cacheid;
 
521
}
 
522
 
337
523
/* Check that the serial number of the current card (as described by
338
524
   APP) matches SERIALNO.  If there is no match and we are not in
339
525
   batch mode, present a prompt to insert the desired card.  The
342
528
   card context will be closed in all cases except for 0 as return
343
529
   value and if it was possible to merely shutdown the reader. */
344
530
static int
345
 
check_card_serialno (APP app, const char *serialno)
 
531
check_card_serialno (app_t app, const char *serialno)
346
532
{
347
533
  const char *s;
348
534
  int ask = 0;
394
580
}
395
581
 
396
582
 
397
 
 
398
 
/* Return a new malloced string by unescaping the string S.  Escaping
399
 
   is percent escaping and '+'/space mapping.  A binary nul will
400
 
   silently be replaced by a 0xFF.  Function returns NULL to indicate
401
 
   an out of memory status. */
402
 
static char *
403
 
unescape_status_string (const unsigned char *s)
404
 
{
405
 
  char *buffer, *d;
406
 
 
407
 
  buffer = d = xmalloc (strlen (s)+1);
408
 
  while (*s)
409
 
    {
410
 
      if (*s == '%' && s[1] && s[2])
411
 
        { 
412
 
          s++;
413
 
          *d = xtoi_2 (s);
414
 
          if (!*d)
415
 
            *d = '\xff';
416
 
          d++;
417
 
          s += 2;
418
 
        }
419
 
      else if (*s == '+')
420
 
        {
421
 
          *d++ = ' ';
422
 
          s++;
423
 
        }
424
 
      else
425
 
        *d++ = *s++;
426
 
    }
427
 
  *d = 0; 
428
 
  return buffer;
429
 
}
430
 
 
431
583
/* Take a 20 byte hexencoded string and put it into the the provided
432
584
   20 byte buffer FPR in binary format. */
433
585
static int
465
617
 
466
618
 
467
619
 
468
 
static int
 
620
static assuan_error_t
469
621
learn_status_cb (void *opaque, const char *line)
470
622
{
471
623
  struct agent_card_info_s *parm = opaque;
487
639
  else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
488
640
    {
489
641
      xfree (parm->disp_name);
490
 
      parm->disp_name = unescape_status_string (line);
 
642
      parm->disp_name = unescape_percent_string (line);
491
643
    }
492
644
  else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
493
645
    {
494
646
      xfree (parm->disp_lang);
495
 
      parm->disp_lang = unescape_status_string (line);
 
647
      parm->disp_lang = unescape_percent_string (line);
496
648
    }
497
649
  else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
498
650
    {
501
653
  else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
502
654
    {
503
655
      xfree (parm->pubkey_url);
504
 
      parm->pubkey_url = unescape_status_string (line);
 
656
      parm->pubkey_url = unescape_percent_string (line);
505
657
    }
506
658
  else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
507
659
    {
508
660
      xfree (parm->login_data);
509
 
      parm->login_data = unescape_status_string (line);
 
661
      parm->login_data = unescape_percent_string (line);
510
662
    }
511
663
  else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
512
664
    {
516
668
    {
517
669
      char *p, *buf;
518
670
 
519
 
      buf = p = unescape_status_string (line);
 
671
      buf = p = unescape_percent_string (line);
520
672
      if (buf)
521
673
        {
522
674
          while (spacep (p))
593
745
      int no = keyword[11] - '1';
594
746
      assert (no >= 0 && no <= 3);
595
747
      xfree (parm->private_do[no]);
596
 
      parm->private_do[no] = unescape_status_string (line);
 
748
      parm->private_do[no] = unescape_percent_string (line);
597
749
    }
598
750
 
599
751
  return 0;
604
756
int 
605
757
agent_learn (struct agent_card_info_s *info)
606
758
{
607
 
  APP app;
 
759
  app_t app;
608
760
  int rc;
609
761
  struct ctrl_ctx_s ctrl;
610
762
  time_t stamp;
615
767
    return gpg_error (GPG_ERR_CARD);
616
768
 
617
769
  memset (info, 0, sizeof *info);
618
 
  memset (&ctrl, 0, sizeof ctrl);
619
 
  ctrl.status_cb = learn_status_cb;
620
 
  ctrl.status_cb_arg = info;
621
 
 
622
 
  rc = app_get_serial_and_stamp (app, &serial, &stamp);
623
 
  if (!rc)
624
 
    {
625
 
      send_status_info (&ctrl, "SERIALNO", serial, strlen(serial), NULL, 0);
626
 
      xfree (serial);
627
 
      rc = app->fnc.learn_status (app, &ctrl);
 
770
 
 
771
  if (app->assuan_ctx)
 
772
    {
 
773
      rc = assuan_transact (app->assuan_ctx, "SCD LEARN --force",
 
774
                            NULL, NULL, NULL, NULL,
 
775
                            learn_status_cb, info);
 
776
      rc = test_transact (rc, "SCD LEARN");
 
777
    }
 
778
  else
 
779
    {
 
780
      memset (&ctrl, 0, sizeof ctrl);
 
781
      ctrl.status_cb = learn_status_cb;
 
782
      ctrl.status_cb_arg = info;
 
783
 
 
784
      rc = app_get_serial_and_stamp (app, &serial, &stamp);
 
785
      if (!rc)
 
786
        {
 
787
          send_status_info (&ctrl, "SERIALNO",
 
788
                            serial, strlen(serial), NULL, 0);
 
789
          xfree (serial);
 
790
          rc = app->fnc.learn_status (app, &ctrl);
 
791
        }
628
792
    }
629
793
 
630
794
  return rc;
631
795
}
632
796
 
633
 
/* Get an attribite from the card. Make sure info is initialized. */
 
797
 
 
798
/* Get an attribute from the card. Make sure info is initialized. */
634
799
int 
635
800
agent_scd_getattr (const char *name, struct agent_card_info_s *info)
636
801
{
637
 
  APP app;
 
802
  int rc;
 
803
  app_t app;
638
804
  struct ctrl_ctx_s ctrl;
639
805
 
640
806
  app = current_app? current_app : open_card ();
641
807
  if (!app)
642
808
    return gpg_error (GPG_ERR_CARD);
643
809
 
644
 
  ctrl.status_cb = learn_status_cb;
645
 
  ctrl.status_cb_arg = info;
646
 
  return app->fnc.getattr (app, &ctrl, name);
 
810
  if (app->assuan_ctx)
 
811
    {
 
812
      char line[ASSUAN_LINELENGTH];
 
813
 
 
814
      /* We assume that NAME does not need escaping. */
 
815
      if (12 + strlen (name) > DIM(line)-1)
 
816
        return gpg_error (GPG_ERR_CARD);
 
817
      stpcpy (stpcpy (line, "SCD GETATTR "), name); 
 
818
 
 
819
      rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
820
                                           NULL, NULL, NULL, NULL,
 
821
                                           learn_status_cb, info),
 
822
                          "SCD GETATTR");
 
823
    }
 
824
  else
 
825
    {
 
826
      ctrl.status_cb = learn_status_cb;
 
827
      ctrl.status_cb_arg = info;
 
828
      rc = app->fnc.getattr (app, &ctrl, name);
 
829
    }
 
830
 
 
831
  return rc;
647
832
}
648
833
 
649
834
 
651
836
static int 
652
837
pin_cb (void *opaque, const char *info, char **retstr)
653
838
{
 
839
  struct pincb_parm_s *parm = opaque;
654
840
  char *value;
655
841
  int canceled;
656
842
  int isadmin = 0;
657
843
  int newpin = 0;
658
844
  const char *again_text = NULL;
659
845
  const char *ends, *s;
 
846
  char *cacheid = NULL;
660
847
 
661
848
  *retstr = NULL;
662
849
  /*   log_debug ("asking for PIN '%s'\n", info); */
674
861
        }
675
862
      info = ends+1;
676
863
    }
 
864
  else if (info && *info == '|')
 
865
    log_debug ("pin_cb called without proper PIN info hack\n");
 
866
 
 
867
  /* If we are not requesting a new PIN and we are not requesting an
 
868
     AdminPIN, compute a string to be used as the cacheID for
 
869
     gpg-agent. */
 
870
  if (!newpin && !isadmin && parm)
 
871
    {
 
872
      cacheid = format_cacheid (parm->sn);
 
873
    }
 
874
  else if (newpin && parm)
 
875
    {
 
876
      /* Make really sure that it is not cached anymore. */
 
877
      agent_clear_pin_cache (parm->sn);
 
878
    }
 
879
 
677
880
 
678
881
 again:
679
882
  if (is_status_enabled())
689
892
                          newpin?  _("Enter New PIN: ") :
690
893
                          isadmin? _("Enter Admin PIN: ")
691
894
                                 : _("Enter PIN: "),
 
895
                          cacheid,
692
896
                          &canceled);
 
897
  xfree (cacheid);
 
898
  cacheid = NULL;
693
899
  again_text = NULL;
694
900
  if (!value && canceled)
695
901
    return -1;
700
906
    {
701
907
      char *value2;
702
908
 
703
 
      value2 = ask_passphrase (info, NULL,
 
909
      value2 = ask_passphrase (info, NULL, NULL,
704
910
                               "passphrase.pin.repeat", 
705
911
                               _("Repeat this PIN: "),
706
912
                              &canceled);
736
942
agent_scd_setattr (const char *name,
737
943
                   const unsigned char *value, size_t valuelen)
738
944
{
739
 
  APP app;
740
 
  int rc;
741
 
 
742
 
  app = current_app? current_app : open_card ();
743
 
  if (!app)
744
 
    return gpg_error (GPG_ERR_CARD);
745
 
 
746
 
  rc = app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen);
747
 
 
748
 
  if (rc)
749
 
    write_status (STATUS_SC_OP_FAILURE);
750
 
  return rc;
751
 
}
752
 
 
753
 
 
754
 
static int
 
945
  app_t app;
 
946
  int rc;
 
947
 
 
948
  app = current_app? current_app : open_card ();
 
949
  if (!app)
 
950
    return gpg_error (GPG_ERR_CARD);
 
951
 
 
952
  if (app->assuan_ctx)
 
953
    {
 
954
      char line[ASSUAN_LINELENGTH];
 
955
      char *p;
 
956
 
 
957
      /* We assume that NAME does not need escaping. */
 
958
      if (12 + strlen (name) > DIM(line)-1)
 
959
        return gpg_error (GPG_ERR_CARD);
 
960
      p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
 
961
      *p++ = ' ';
 
962
      for (; valuelen; value++, valuelen--)
 
963
        {
 
964
          if (p >= line + DIM(line)-5 )
 
965
            return gpg_error (GPG_ERR_CARD);
 
966
          if (*value < ' ' || *value == '+' || *value == '%')
 
967
            {
 
968
              sprintf (p, "%%%02X", *value);
 
969
              p += 3;
 
970
            }
 
971
          else if (*value == ' ')
 
972
            *p++ = '+';
 
973
          else
 
974
            *p++ = *value;
 
975
        }
 
976
      *p = 0;
 
977
 
 
978
      rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
979
                                           NULL, NULL, NULL, NULL, NULL, NULL),
 
980
                          "SCD SETATTR");
 
981
    }
 
982
  else
 
983
    {
 
984
      rc = app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen);
 
985
    }
 
986
 
 
987
  if (rc)
 
988
    write_status (STATUS_SC_OP_FAILURE);
 
989
  return rc;
 
990
}
 
991
 
 
992
 
 
993
/* Handle a KEYDATA inquiry.  Note, we only send the data,
 
994
   assuan_transact takes care of flushing and writing the end */
 
995
static assuan_error_t
 
996
inq_writekey_parms (void *opaque, const char *keyword)
 
997
{
 
998
  struct writekey_parm_s *parm = opaque; 
 
999
 
 
1000
  return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
 
1001
}
 
1002
 
 
1003
 
 
1004
/* Send a WRITEKEY command to the SCdaemon. */
 
1005
int 
 
1006
agent_scd_writekey (int keyno, const unsigned char *keydata, size_t keydatalen)
 
1007
{
 
1008
  app_t app;
 
1009
  int rc;
 
1010
  char line[ASSUAN_LINELENGTH];
 
1011
  app = current_app? current_app : open_card ();
 
1012
  if (!app)
 
1013
    return gpg_error (GPG_ERR_CARD);
 
1014
 
 
1015
  if (app->assuan_ctx)
 
1016
    {
 
1017
      struct writekey_parm_s parms;
 
1018
 
 
1019
      snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
 
1020
      line[DIM(line)-1] = 0;
 
1021
      parms.ctx = app->assuan_ctx;
 
1022
      parms.keydata = keydata;
 
1023
      parms.keydatalen = keydatalen;
 
1024
      rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
1025
                                           NULL, NULL,
 
1026
                                           inq_writekey_parms, &parms,
 
1027
                                           NULL, NULL),
 
1028
                          "SCD WRITEKEY");
 
1029
    }
 
1030
  else
 
1031
    {
 
1032
      snprintf (line, DIM(line)-1, "OPENPGP.%d", keyno);
 
1033
      line[DIM(line)-1] = 0;
 
1034
      rc = app->fnc.writekey (app, NULL, line, 0x0001,
 
1035
                              pin_cb, NULL,
 
1036
                              keydata, keydatalen);
 
1037
    }
 
1038
 
 
1039
  if (rc)
 
1040
    write_status (STATUS_SC_OP_FAILURE);
 
1041
  return rc;
 
1042
}
 
1043
 
 
1044
 
 
1045
 
 
1046
static assuan_error_t
755
1047
genkey_status_cb (void *opaque, const char *line)
756
1048
{
757
1049
  struct agent_card_genkey_s *parm = opaque;
807
1099
int 
808
1100
agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force)
809
1101
{
810
 
  APP app;
811
 
  char keynostr[20];
 
1102
  app_t app;
 
1103
  char line[ASSUAN_LINELENGTH];
812
1104
  struct ctrl_ctx_s ctrl;
813
1105
  int rc;
814
1106
 
817
1109
    return gpg_error (GPG_ERR_CARD);
818
1110
 
819
1111
  memset (info, 0, sizeof *info);
820
 
  sprintf (keynostr, "%d", keyno);
821
 
  ctrl.status_cb = genkey_status_cb;
822
 
  ctrl.status_cb_arg = info;
823
 
 
824
 
  rc = app->fnc.genkey (app, &ctrl, keynostr,
825
 
                        force? 1:0,
826
 
                        pin_cb, NULL);
 
1112
 
 
1113
  if (app->assuan_ctx)
 
1114
    {
 
1115
      snprintf (line, DIM(line)-1, "SCD GENKEY %s%d",
 
1116
                force? "--force ":"", keyno);
 
1117
      line[DIM(line)-1] = 0;
 
1118
      rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
1119
                                           NULL, NULL, NULL, NULL,
 
1120
                                           genkey_status_cb, info),
 
1121
                          "SCD GENKEY");
 
1122
    }
 
1123
  else
 
1124
    {
 
1125
      snprintf (line, DIM(line)-1, "%d", keyno);
 
1126
      ctrl.status_cb = genkey_status_cb;
 
1127
      ctrl.status_cb_arg = info;
 
1128
      rc = app->fnc.genkey (app, &ctrl, line,
 
1129
                            force? 1:0,
 
1130
                            pin_cb, NULL);
 
1131
    }
 
1132
 
827
1133
  if (rc)
828
1134
    write_status (STATUS_SC_OP_FAILURE);
829
1135
  return rc;
830
1136
}
831
1137
 
 
1138
 
 
1139
static assuan_error_t
 
1140
membuf_data_cb (void *opaque, const void *buffer, size_t length)
 
1141
{
 
1142
  membuf_t *data = opaque;
 
1143
 
 
1144
  if (buffer)
 
1145
    put_membuf (data, buffer, length);
 
1146
  return 0;
 
1147
}
 
1148
  
 
1149
 
832
1150
/* Send a PKSIGN command to the SCdaemon. */
833
1151
int 
834
1152
agent_scd_pksign (const char *serialno, int hashalgo,
835
1153
                  const unsigned char *indata, size_t indatalen,
836
1154
                  unsigned char **r_buf, size_t *r_buflen)
837
1155
{
838
 
  APP app;
 
1156
  struct pincb_parm_s parm;
 
1157
  app_t app;
839
1158
  int rc;
840
1159
 
841
1160
  *r_buf = NULL;
842
1161
  *r_buflen = 0;
 
1162
  memset (&parm, 0, sizeof parm);
 
1163
  parm.sn = serialno;
843
1164
 retry:
844
1165
  app = current_app? current_app : open_card ();
845
1166
  if (!app)
846
1167
    return gpg_error (GPG_ERR_CARD);
847
1168
 
848
 
  /* Check that the card's serialnumber is as required.*/
849
 
  rc = check_card_serialno (app, serialno);
850
 
  if (rc == -1)
851
 
    goto retry;
852
 
 
853
 
  if (!rc)
854
 
    rc = app->fnc.sign (app, serialno, hashalgo,
855
 
                        pin_cb, NULL,
856
 
                        indata, indatalen,
857
 
                        r_buf, r_buflen);
 
1169
  if (app->assuan_ctx)
 
1170
    {
 
1171
      char *p, line[ASSUAN_LINELENGTH];
 
1172
      membuf_t data;
 
1173
      size_t len;
 
1174
      int i;
 
1175
 
 
1176
      if (indatalen*2 + 50 > DIM(line))
 
1177
        return gpg_error (GPG_ERR_GENERAL);
 
1178
 
 
1179
      p = stpcpy (line, "SCD SETDATA ");
 
1180
      for (i=0; i < indatalen ; i++, p += 2 )
 
1181
        sprintf (p, "%02X", indata[i]);
 
1182
      rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
1183
                                           NULL, NULL, NULL, NULL, NULL, NULL),
 
1184
                          "SCD SETDATA");
 
1185
      if (!rc)
 
1186
        {
 
1187
          init_membuf (&data, 1024);
 
1188
          snprintf (line, DIM(line)-1, "SCD PKSIGN %s", serialno);
 
1189
          line[DIM(line)-1] = 0;
 
1190
          rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
1191
                                               membuf_data_cb, &data,
 
1192
                                               NULL, NULL, NULL, NULL),
 
1193
                              "SCD PKSIGN");
 
1194
          if (rc)
 
1195
            xfree (get_membuf (&data, &len));
 
1196
          else
 
1197
            *r_buf = get_membuf (&data, r_buflen);
 
1198
        }
 
1199
    }
 
1200
  else
 
1201
    {
 
1202
      /* Check that the card's serialnumber is as required.*/
 
1203
      rc = check_card_serialno (app, serialno);
 
1204
      if (rc == -1)
 
1205
        goto retry;
 
1206
 
 
1207
      if (!rc)
 
1208
        rc = app->fnc.sign (app, serialno, hashalgo,
 
1209
                            pin_cb, &parm,
 
1210
                            indata, indatalen,
 
1211
                            r_buf, r_buflen);
 
1212
    }
 
1213
 
858
1214
  if (rc)
859
 
    write_status (STATUS_SC_OP_FAILURE);
 
1215
    {
 
1216
      write_status (STATUS_SC_OP_FAILURE);
 
1217
      if (!app->assuan_ctx)
 
1218
        agent_clear_pin_cache (serialno);
 
1219
    }
860
1220
  return rc;
861
1221
}
862
1222
 
867
1227
                     const unsigned char *indata, size_t indatalen,
868
1228
                     unsigned char **r_buf, size_t *r_buflen)
869
1229
{
870
 
  APP app;
 
1230
  struct pincb_parm_s parm;
 
1231
  app_t app;
871
1232
  int rc;
872
1233
 
873
1234
  *r_buf = NULL;
874
1235
  *r_buflen = 0;
 
1236
  memset (&parm, 0, sizeof parm);
 
1237
  parm.sn = serialno;
875
1238
 retry:
876
1239
  app = current_app? current_app : open_card ();
877
1240
  if (!app)
878
1241
    return gpg_error (GPG_ERR_CARD);
879
1242
 
880
 
  /* Check that the card's serialnumber is as required.*/
881
 
  rc = check_card_serialno (app, serialno);
882
 
  if (rc == -1)
883
 
    goto retry;
884
 
 
885
 
  if (!rc)
886
 
    rc = app->fnc.decipher (app, serialno, 
887
 
                            pin_cb, NULL,
888
 
                            indata, indatalen,
889
 
                            r_buf, r_buflen);
 
1243
  if (app->assuan_ctx)
 
1244
    {
 
1245
      char *p, line[ASSUAN_LINELENGTH];
 
1246
      membuf_t data;
 
1247
      size_t len;
 
1248
      int i;
 
1249
 
 
1250
      if (indatalen*2 + 50 > DIM(line))
 
1251
        return gpg_error (GPG_ERR_GENERAL);
 
1252
 
 
1253
      p = stpcpy (line, "SCD SETDATA ");
 
1254
      for (i=0; i < indatalen ; i++, p += 2 )
 
1255
        sprintf (p, "%02X", indata[i]);
 
1256
      rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
1257
                                           NULL, NULL, NULL, NULL, NULL, NULL),
 
1258
                          "SCD SETDATA");
 
1259
      if (!rc)
 
1260
        {
 
1261
          init_membuf (&data, 1024);
 
1262
          snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
 
1263
          line[DIM(line)-1] = 0;
 
1264
          rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
1265
                                               membuf_data_cb, &data,
 
1266
                                               NULL, NULL, NULL, NULL),
 
1267
                              "SCD PKDECRYPT");
 
1268
          if (rc)
 
1269
            xfree (get_membuf (&data, &len));
 
1270
          else
 
1271
            *r_buf = get_membuf (&data, r_buflen);
 
1272
        }
 
1273
    }
 
1274
  else
 
1275
    {
 
1276
      /* Check that the card's serialnumber is as required.*/
 
1277
      rc = check_card_serialno (app, serialno);
 
1278
      if (rc == -1)
 
1279
        goto retry;
 
1280
      
 
1281
      if (!rc)
 
1282
        rc = app->fnc.decipher (app, serialno, 
 
1283
                                pin_cb, &parm,
 
1284
                                indata, indatalen,
 
1285
                                r_buf, r_buflen);
 
1286
    }
 
1287
 
890
1288
  if (rc)
891
 
    write_status (STATUS_SC_OP_FAILURE);
 
1289
    {
 
1290
      write_status (STATUS_SC_OP_FAILURE);
 
1291
      if (!app->assuan_ctx)
 
1292
        agent_clear_pin_cache (serialno);
 
1293
    }
892
1294
  return rc;
893
1295
}
894
1296
 
896
1298
int 
897
1299
agent_scd_change_pin (int chvno)
898
1300
{
899
 
  APP app;
900
 
  char chvnostr[20];
 
1301
  app_t app;
901
1302
  int reset = 0;
902
1303
  int rc;
903
1304
 
908
1309
  if (!app)
909
1310
    return gpg_error (GPG_ERR_CARD);
910
1311
 
911
 
  sprintf (chvnostr, "%d", chvno);
912
 
  rc = app->fnc.change_pin (app, NULL, chvnostr, reset,
913
 
                            pin_cb, NULL);
 
1312
  if (app->assuan_ctx)
 
1313
    {
 
1314
      char line[ASSUAN_LINELENGTH];
 
1315
 
 
1316
      snprintf (line, DIM(line)-1, "SCD PASSWD%s %d",
 
1317
                reset? " --reset":"", chvno);
 
1318
      line[DIM(line)-1] = 0;
 
1319
      rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
1320
                                           NULL, NULL, NULL, NULL, NULL, NULL),
 
1321
                          "SCD PASSWD");
 
1322
    }
 
1323
  else
 
1324
    {
 
1325
      char chvnostr[50];
 
1326
 
 
1327
      sprintf (chvnostr, "%d", chvno);
 
1328
      rc = app->fnc.change_pin (app, NULL, chvnostr, reset,
 
1329
                                pin_cb, NULL);
 
1330
    }
 
1331
 
914
1332
  if (rc)
915
1333
    write_status (STATUS_SC_OP_FAILURE);
916
1334
  return rc;
922
1340
int
923
1341
agent_scd_checkpin (const char *serialnobuf)
924
1342
{
925
 
  APP app;
 
1343
  app_t app;
926
1344
  int rc;
927
1345
 
928
1346
  app = current_app? current_app : open_card ();
929
1347
  if (!app)
930
1348
    return gpg_error (GPG_ERR_CARD);
931
1349
 
932
 
  rc = app->fnc.check_pin (app, serialnobuf, pin_cb, NULL);
 
1350
  if (app->assuan_ctx)
 
1351
    {
 
1352
      char line[ASSUAN_LINELENGTH];
 
1353
 
 
1354
      if (15 + strlen (serialnobuf) > DIM(line)-1)
 
1355
        return gpg_error (GPG_ERR_CARD);
 
1356
      stpcpy (stpcpy (line, "SCD CHECKPIN "), serialnobuf); 
 
1357
      rc = test_transact (assuan_transact (app->assuan_ctx, line,
 
1358
                                           NULL, NULL, NULL, NULL, NULL, NULL),
 
1359
                          "SCD CHECKPIN");
 
1360
    }
 
1361
  else
 
1362
    {
 
1363
      rc = app->fnc.check_pin (app, serialnobuf, pin_cb, NULL);
 
1364
    }
 
1365
 
933
1366
  if (rc)
934
1367
    write_status (STATUS_SC_OP_FAILURE);
935
1368
  return rc;
936
1369
}
937
1370
 
938
1371
 
939
 
/* Wrapper to call the store key helper function of app-openpgp.c.  */
940
 
int 
941
 
agent_openpgp_storekey (int keyno,
942
 
                        unsigned char *template, size_t template_len,
943
 
                        time_t created_at,
944
 
                        const unsigned char *m, size_t mlen,
945
 
                        const unsigned char *e, size_t elen)
 
1372
 
 
1373
void
 
1374
agent_clear_pin_cache (const char *sn)
946
1375
{
947
 
  APP app;
948
 
  int rc;
949
 
 
950
 
  app = current_app? current_app : open_card ();
951
 
  if (!app)
952
 
    return gpg_error (GPG_ERR_CARD);
953
 
 
954
 
  rc = app_openpgp_storekey (app, keyno, template, template_len,
955
 
                             created_at, m, mlen, e, elen,
956
 
                             pin_cb, NULL);
957
 
  if (rc)
958
 
    write_status (STATUS_SC_OP_FAILURE);
959
 
  return rc;
 
1376
  char *cacheid = format_cacheid (sn);
 
1377
  if (cacheid)
 
1378
    {
 
1379
      passphrase_clear_cache (NULL, cacheid, 0);
 
1380
      xfree (cacheid);
 
1381
    }
960
1382
}