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