Bump to 2.4.3
[platform/upstream/gpg2.git] / scd / command.c
1 /* command.c - SCdaemon command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3  *               2007, 2008, 2009, 2011  Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #ifdef USE_NPTH
30 # include <npth.h>
31 #endif
32
33 #include "scdaemon.h"
34 #include <assuan.h>
35 #include <ksba.h>
36 #include "iso7816.h"
37 #include "apdu.h" /* Required for apdu_*_reader (). */
38 #include "atr.h"
39 #ifdef HAVE_LIBUSB
40 #include "ccid-driver.h"
41 #endif
42 #include "../common/asshelp.h"
43 #include "../common/server-help.h"
44 #include "../common/ssh-utils.h"
45
46 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN.  That
47  * length needs to small compared to the maximum Assuan line length.  */
48 #define MAXLEN_PIN 100
49
50 /* Maximum allowed size of key data as used in inquiries. */
51 #define MAXLEN_KEYDATA 4096
52
53 /* Maximum allowed total data size for SETDATA.  */
54 #define MAXLEN_SETDATA 4096
55
56 /* Maximum allowed size of certificate data as used in inquiries. */
57 #define MAXLEN_CERTDATA 16384
58
59 /* Maximum allowed size for "SETATTR --inquire". */
60 #define MAXLEN_SETATTRDATA 16384
61
62
63 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
64
65 #define IS_LOCKED(c) (locked_session && locked_session != (c)->server_local)
66
67
68 /* Data used to associate an Assuan context with local server data.
69    This object describes the local properties of one session.  */
70 struct server_local_s
71 {
72   /* We keep a list of all active sessions with the anchor at
73      SESSION_LIST (see below).  This field is used for linking. */
74   struct server_local_s *next_session;
75
76   /* This object is usually assigned to a CTRL object (which is
77      globally visible).  While enumerating all sessions we sometimes
78      need to access data of the CTRL object; thus we keep a
79      backpointer here. */
80   ctrl_t ctrl_backlink;
81
82   /* The Assuan context used by this session/server. */
83   assuan_context_t assuan_ctx;
84
85 #ifdef HAVE_W32_SYSTEM
86   void *event_signal;           /* Or NULL if not used. */
87 #else
88   int event_signal;             /* Or 0 if not used. */
89 #endif
90
91   /* True if the card has been removed and a reset is required to
92      continue operation. */
93   unsigned int card_removed:1;
94
95   /* If set to true we will be terminate ourself at the end of the
96      this session.  */
97   unsigned int stopme:1;
98
99   /* If set to true, status change will be reported. */
100   unsigned int watching_status:1;
101 };
102
103
104 /* To keep track of all running sessions, we link all active server
105    contexts and the anchor in this variable.  */
106 static struct server_local_s *session_list;
107
108 /* If a session has been locked we store a link to its server object
109    in this variable. */
110 static struct server_local_s *locked_session;
111
112
113 \f
114 /*  Local prototypes.  */
115 static int command_has_option (const char *cmd, const char *cmdopt);
116
117
118 \f
119 /* Convert the STRING into a newly allocated buffer while translating
120    the hex numbers.  Stops at the first invalid character.  Blanks and
121    colons are allowed to separate the hex digits.  Returns NULL on
122    error or a newly malloced buffer and its length in LENGTH.  */
123 static unsigned char *
124 hex_to_buffer (const char *string, size_t *r_length)
125 {
126   unsigned char *buffer;
127   const char *s;
128   size_t n;
129
130   buffer = xtrymalloc (strlen (string)+1);
131   if (!buffer)
132     return NULL;
133   for (s=string, n=0; *s; s++)
134     {
135       if (spacep (s) || *s == ':')
136         continue;
137       if (hexdigitp (s) && hexdigitp (s+1))
138         {
139           buffer[n++] = xtoi_2 (s);
140           s++;
141         }
142       else
143         break;
144     }
145   *r_length = n;
146   return buffer;
147 }
148
149
150
151 /* Reset the card and free the application context.  With SEND_RESET
152    set to true actually send a RESET to the reader; this is the normal
153    way of calling the function.  If KEEP_LOCK is set and the session
154    is locked that lock wil not be released.  */
155 static void
156 do_reset (ctrl_t ctrl, int send_reset, int keep_lock)
157 {
158   card_t card = card_get (ctrl, NULL);
159
160   if (card)
161     {
162       if (!IS_LOCKED (ctrl) && send_reset)
163         card_reset (card);
164       else
165         {
166           ctrl->card_ctx = NULL;
167           ctrl->current_apptype = APPTYPE_NONE;
168           card_unref_locked (card);
169         }
170       card_put (card);
171     }
172
173   /* If we hold a lock, unlock now. */
174   if (!keep_lock && locked_session && ctrl->server_local == locked_session)
175     {
176       locked_session = NULL;
177       log_info ("implicitly unlocking due to RESET\n");
178     }
179 }
180
181
182 \f
183 static gpg_error_t
184 reset_notify (assuan_context_t ctx, char *line)
185 {
186   ctrl_t ctrl = assuan_get_pointer (ctx);
187
188   do_reset (ctrl, 1, has_option (line, "--keep-lock"));
189   return 0;
190 }
191
192
193 static gpg_error_t
194 option_handler (assuan_context_t ctx, const char *key, const char *value)
195 {
196   ctrl_t ctrl = assuan_get_pointer (ctx);
197
198   if (!strcmp (key, "event-signal"))
199     {
200       /* A value of 0 is allowed to reset the event signal. */
201 #ifdef HAVE_W32_SYSTEM
202       if (!*value)
203         return gpg_error (GPG_ERR_ASS_PARAMETER);
204 #ifdef _WIN64
205       ctrl->server_local->event_signal = (void *)strtoull (value, NULL, 16);
206 #else
207       ctrl->server_local->event_signal = (void *)strtoul (value, NULL, 16);
208 #endif
209 #else
210       int i = *value? atoi (value) : -1;
211       if (i < 0)
212         return gpg_error (GPG_ERR_ASS_PARAMETER);
213       ctrl->server_local->event_signal = i;
214 #endif
215     }
216
217  return 0;
218 }
219
220
221 /* If the card has not yet been opened, do it.  */
222 static gpg_error_t
223 open_card (ctrl_t ctrl)
224 {
225   /* If we ever got a card not present error code, return that.  Only
226      the SERIALNO command and a reset are able to clear from that
227      state. */
228   if (ctrl->server_local->card_removed)
229     return gpg_error (GPG_ERR_CARD_REMOVED);
230
231   if ( IS_LOCKED (ctrl) )
232     return gpg_error (GPG_ERR_LOCKED);
233
234   if (ctrl->card_ctx)
235     return 0;
236
237   return select_application (ctrl, NULL, 0, NULL, 0);
238 }
239
240 /* Explicitly open a card for a specific use of APPTYPE or SERIALNO.
241  * If OPT_ALL is set also add all possible additional apps. */
242 static gpg_error_t
243 open_card_with_request (card_t *card_p, ctrl_t ctrl,
244                         const char *apptypestr, const char *serialno,
245                         int opt_all)
246 {
247   gpg_error_t err;
248   unsigned char *serialno_bin = NULL;
249   size_t serialno_bin_len = 0;
250   card_t card = card_get (ctrl, NULL);
251
252   if (serialno)
253     serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
254
255   /* If we are already initialized for one specific application we
256      need to check that the client didn't requested a specific
257      application different from the one in use before we continue. */
258   if (apptypestr && card)
259     {
260       err = check_application_conflict (card, apptypestr,
261                                         serialno_bin, serialno_bin_len);
262       if (gpg_err_code (err) == GPG_ERR_FALSE)
263         {
264           /* Different application but switching is supported.  */
265           err = select_additional_application (card, ctrl, apptypestr);
266         }
267       if (err)
268         card_put (card);
269       goto leave;
270     }
271
272   /* Re-scan USB devices.  Release CARD, before the scan.  */
273   if (card)
274     {
275       ctrl->card_ctx = NULL;
276       ctrl->current_apptype = APPTYPE_NONE;
277       card_unref_locked (card);
278       card_put (card);
279     }
280
281   err = select_application (ctrl, apptypestr, 1,
282                             serialno_bin, serialno_bin_len);
283   card = card_get (ctrl, NULL);
284   if (!err && opt_all)
285     {
286       if (card)
287         {
288           err = select_additional_application (card, ctrl, NULL);
289           if (err)
290             card_put (card);
291         }
292     }
293
294  leave:
295   if (!err)
296     *card_p = card;
297   xfree (serialno_bin);
298   return err;
299 }
300
301
302 static const char hlp_serialno[] =
303   "SERIALNO [--demand=<serialno>] [--all] [<apptype>]\n"
304   "\n"
305   "Return the serial number of the card using a status response.  This\n"
306   "function should be used to check for the presence of a card.\n"
307   "\n"
308   "If --demand is given, an application on the card with SERIALNO is\n"
309   "selected and an error is returned if no such card available.\n"
310   "\n"
311   "If --all is given, all possible other applications of the card are\n"
312   "also selected to prepare for things like \"LEARN --force --multi\".\n"
313   "\n"
314   "If APPTYPE is given, an application of that type is selected and an\n"
315   "error is returned if the application is not supported or available.\n"
316   "The default is to auto-select the application using a hardwired\n"
317   "preference system.\n"
318   "\n"
319   "This function is special in that it can be used to reset the card.\n"
320   "Most other functions will return an error when a card change has\n"
321   "been detected and the use of this function is therefore required.\n"
322   "\n"
323   "Background: We want to keep the client clear of handling card\n"
324   "changes between operations; i.e. the client can assume that all\n"
325   "operations are done on the same card unless he calls this function.";
326 static gpg_error_t
327 cmd_serialno (assuan_context_t ctx, char *line)
328 {
329   ctrl_t ctrl = assuan_get_pointer (ctx);
330   struct server_local_s *sl;
331   gpg_error_t err = 0;
332   char *serial;
333   const char *demand;
334   int opt_all = has_option (line, "--all");
335   card_t card = NULL;
336   int thisslot;
337
338   if ( IS_LOCKED (ctrl) )
339     return gpg_error (GPG_ERR_LOCKED);
340
341   if ((demand = has_option_name (line, "--demand")))
342     {
343       if (*demand != '=')
344         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
345       line = (char *)++demand;
346       while (*line && !spacep (line))
347         line++;
348       if (*line)
349         *line++ = 0;
350     }
351   else
352     demand = NULL;
353
354   line = skip_options (line);
355
356   /* Clear the remove flag so that the open_card is able to reread it.  */
357   ctrl->server_local->card_removed = 0;
358   err = open_card_with_request (&card, ctrl, *line? line:NULL, demand, opt_all);
359   /* Now clear or set the card_removed flag for all sessions using the
360    * current slot.  In the error case make sure that the flag is set
361    * for the current session. */
362   thisslot = card? card->slot : -1;
363   for (sl=session_list; sl; sl = sl->next_session)
364     {
365       ctrl_t c = sl->ctrl_backlink;
366       if (c && c->card_ctx && c->card_ctx->slot == thisslot)
367         c->server_local->card_removed = err? 1 : 0;
368     }
369   if (err)
370     {
371       ctrl->server_local->card_removed = 1;
372       return err;
373     }
374
375   serial = card_get_serialno (card);
376   card_put (card);
377   if (!serial)
378     return gpg_error (GPG_ERR_INV_VALUE);
379
380   err = assuan_write_status (ctx, "SERIALNO", serial);
381   xfree (serial);
382   return err;
383 }
384
385
386 \f
387 static const char hlp_switchcard[] =
388   "SWITCHCARD [<serialno>]\n"
389   "\n"
390   "Make the card with SERIALNO the current card.\n"
391   "The command \"getinfo card_list\" can be used to list\n"
392   "the serial numbers of inserted and known cards.  Note\n"
393   "that the command \"SERIALNO\" can be used to refresh\n"
394   "the list of known cards.  A simple SERIALNO status\n"
395   "is printed on success.";
396 static gpg_error_t
397 cmd_switchcard (assuan_context_t ctx, char *line)
398 {
399   ctrl_t ctrl = assuan_get_pointer (ctx);
400   gpg_error_t err = 0;
401   unsigned char *sn_bin = NULL;
402   size_t sn_bin_len = 0;
403
404   if ((err = open_card (ctrl)))
405     return err;
406
407   line = skip_options (line);
408
409   if (*line)
410     {
411       sn_bin = hex_to_buffer (line, &sn_bin_len);
412       if (!sn_bin)
413         {
414           err = gpg_error_from_syserror ();
415           goto leave;
416         }
417     }
418
419   /* Note that an SN_BIN of NULL will only print the status.  */
420   err = app_switch_current_card (ctrl, sn_bin, sn_bin_len);
421
422  leave:
423   xfree (sn_bin);
424   return err;
425 }
426
427
428 static const char hlp_switchapp[] =
429   "SWITCHAPP [<appname>]\n"
430   "\n"
431   "Make APPNAME the active application for the current card.\n"
432   "Only some cards support switching between application; the\n"
433   "command \"getinfo active_app\" can be used to get a list of\n"
434   "applications which can be switched to.  A SERIALNO status\n"
435   "including the active appname is printed on success.";
436 static gpg_error_t
437 cmd_switchapp (assuan_context_t ctx, char *line)
438 {
439   ctrl_t ctrl = assuan_get_pointer (ctx);
440   gpg_error_t err = 0;
441   card_t card;
442
443   if ((err = open_card (ctrl)))
444     return err;
445
446   line = skip_options (line);
447   card = card_get (ctrl, NULL);
448   if (card)
449     {
450       err = app_switch_active_app (card, ctrl, line);
451       card_put (card);
452     }
453   else
454     err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
455
456   return err;
457 }
458
459
460 static const char hlp_learn[] =
461   "LEARN [--force] [--keypairinfo] [--reread] [--multi]\n"
462   "\n"
463   "Learn all useful information of the currently inserted card.  When\n"
464   "used without the force options, the command might do an INQUIRE\n"
465   "like this:\n"
466   "\n"
467   "   INQUIRE KNOWNCARDP <hexstring_with_serialNumber>\n"
468   "\n"
469   "The client should just send an \"END\" if the processing should go on\n"
470   "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
471   "error message.\n"
472   "\n"
473   "With the option --keypairinfo only KEYPAIRINFO status lines are\n"
474   "returned.  With the option --reread information from the card are\n"
475   "read again without the need for a reset (sone some cards).\n"
476   "\n"
477   "The response of this command is a list of status lines formatted as\n"
478   "this:\n"
479   "\n"
480   "  S APPTYPE <apptype>\n"
481   "\n"
482   "This returns the type of the application, currently the strings:\n"
483   "\n"
484   "    P15     = PKCS-15 structure used\n"
485   "    DINSIG  = DIN SIG\n"
486   "    OPENPGP = OpenPGP card\n"
487   "    PIV     = PIV card\n"
488   "    NKS     = NetKey card\n"
489   "\n"
490   "are implemented.  These strings are aliases for the AID.  With option\n"
491   "--multi information for all switchable apps are returned.\n"
492   "\n"
493   "  S KEYPAIRINFO <hexgrip> <keyref> [<usage>] [<keytime>] [<algo>]\n"
494   "\n"
495   "If there is no certificate yet stored on the card a single 'X' is\n"
496   "returned as the keygrip.  For more info see doc/DETAILS.  In addition\n"
497   "to the keypair info, information about all certificates stored on the\n"
498   "card is also returned:\n"
499   "\n"
500   "  S CERTINFO <certtype> <keyref> [<label>]\n"
501   "\n"
502   "Where CERTTYPE is a number indicating the type of certificate:\n"
503   "   0   := Unknown\n"
504   "   100 := Regular X.509 cert\n"
505   "   101 := Trusted X.509 cert\n"
506   "   102 := Useful X.509 cert\n"
507   "   110 := Root CA cert in a special format (e.g. DINSIG)\n"
508   "   111 := Root CA cert as standard X509 cert.\n"
509   "\n"
510   "For certain cards, more information will be returned:\n"
511   "\n"
512   "  S KEY-FPR <keyref> <hexstring>\n"
513   "\n"
514   "For some cards this returns the stored fingerprints of the\n"
515   "keys. This can be used check whether a key is available on the\n"
516   "card.  KEYREF may be 1, 2 or 3 for OpenPGP or a standard keyref.\n"
517   "\n"
518   "  S CA-FPR <no> <hexstring>\n"
519   "\n"
520   "Similar to above, these are the fingerprints of keys assumed to be\n"
521   "ultimately trusted.\n"
522   "\n"
523   "  S DISP-NAME <name_of_card_holder>\n"
524   "\n"
525   "The name of the card holder as stored on the card; percent\n"
526   "escaping takes place, spaces are encoded as '+'\n"
527   "\n"
528   "  S PUBKEY-URL <url>\n"
529   "\n"
530   "The URL to be used for locating the entire public key.\n"
531   "  \n"
532   "Note, that this function may even be used on a locked card.";
533 static gpg_error_t
534 cmd_learn (assuan_context_t ctx, char *line)
535 {
536   ctrl_t ctrl = assuan_get_pointer (ctx);
537   int rc = 0;
538   int only_keypairinfo = has_option (line, "--keypairinfo");
539   int opt_multi = has_option (line, "--multi");
540   int opt_reread = has_option (line, "--reread");
541   int opt_force = has_option (line, "--force");
542   unsigned int flags;
543   card_t card;
544   const char *keygrip = NULL;
545
546   if ((rc = open_card (ctrl)))
547     return rc;
548
549   line = skip_options (line);
550   if (strlen (line) == 40)
551     keygrip = line;
552
553   card = card_get (ctrl, keygrip);
554   if (!card)
555     return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
556
557   /* Unless the force option is used we try a shortcut by identifying
558      the card using a serial number and inquiring the client with
559      that. The client may choose to cancel the operation if he already
560      knows about this card */
561   if (!only_keypairinfo)
562     {
563       const char *reader;
564       char *serial;
565
566       reader = apdu_get_reader_name (card->slot);
567       if (!reader)
568         {
569           card_put (card);
570           return out_of_core ();
571         }
572       send_status_direct (ctrl, "READER", reader);
573       /* No need to free the string of READER.  */
574
575       serial = card_get_serialno (card);
576       if (!serial)
577         {
578           card_put (card);
579           return gpg_error (GPG_ERR_INV_VALUE);
580         }
581
582       rc = assuan_write_status (ctx, "SERIALNO", serial);
583       if (rc < 0)
584         {
585           xfree (serial);
586           card_put (card);
587           return out_of_core ();
588         }
589
590       if (!opt_force)
591         {
592           char *command;
593
594           rc = gpgrt_asprintf (&command, "KNOWNCARDP %s", serial);
595           if (rc < 0)
596             {
597               xfree (serial);
598               card_put (card);
599               return out_of_core ();
600             }
601           rc = assuan_inquire (ctx, command, NULL, NULL, 0);
602           xfree (command);
603           if (rc)
604             {
605               if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
606                 log_error ("inquire KNOWNCARDP failed: %s\n",
607                            gpg_strerror (rc));
608               xfree (serial);
609               card_put (card);
610               return rc;
611             }
612           /* Not canceled, so we have to proceed.  */
613         }
614       xfree (serial);
615     }
616
617   /* Let the application print out its collection of useful status
618      information. */
619   flags = 0;
620   if (only_keypairinfo)
621     flags |= APP_LEARN_FLAG_KEYPAIRINFO;
622   if (opt_multi)
623     flags |= APP_LEARN_FLAG_MULTI;
624   if (opt_reread)
625     flags |= APP_LEARN_FLAG_REREAD;
626
627   if (!rc)
628     rc = app_write_learn_status (card, ctrl, flags);
629
630   card_put (card);
631   return rc;
632 }
633
634
635 \f
636 static const char hlp_readcert[] =
637   "READCERT <hexified_certid>|<keyid>|<oid>\n"
638   "\n"
639   "Note, that this function may even be used on a locked card.";
640 static gpg_error_t
641 cmd_readcert (assuan_context_t ctx, char *line)
642 {
643   ctrl_t ctrl = assuan_get_pointer (ctx);
644   int rc;
645   unsigned char *cert;
646   size_t ncert;
647   card_t card;
648   const char *keygrip = NULL;
649
650   if ((rc = open_card (ctrl)))
651     return rc;
652
653   line = xtrystrdup (line); /* Need a copy of the line. */
654   if (!line)
655     return gpg_error_from_syserror ();
656
657   if (strlen (line) == 40)
658     keygrip = line;
659
660   card = card_get (ctrl, keygrip);
661   if (!card)
662     {
663       xfree (line);
664       return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
665     }
666
667   rc = app_readcert (card, ctrl, line, &cert, &ncert);
668   if (rc)
669     log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
670   card_put (card);
671   xfree (line);
672   line = NULL;
673   if (!rc)
674     {
675       rc = assuan_send_data (ctx, cert, ncert);
676       xfree (cert);
677       if (rc)
678         return rc;
679     }
680
681   return rc;
682 }
683
684
685 static gpg_error_t
686 do_readkey (card_t card, ctrl_t ctrl, const char *line,
687             int opt_info, unsigned char **pk_p, size_t *pklen_p)
688 {
689   int rc;
690   int direct_readkey = 0;
691
692   /* If the application supports the READKEY function we use that.
693      Otherwise we use the old way by extracting it from the
694      certificate.  */
695   rc = app_readkey (card, ctrl, line,
696                     opt_info? APP_READKEY_FLAG_INFO : 0,
697                     pk_p, pklen_p);
698   if (!rc)
699     direct_readkey = 1; /* Got the key.  */
700   else if (gpg_err_code (rc) == GPG_ERR_UNSUPPORTED_OPERATION
701            || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
702     {
703       /* Fall back to certificate reading.  */
704       unsigned char *cert = NULL;
705       size_t ncert;
706
707       rc = app_readcert (card, ctrl, line, &cert, &ncert);
708       if (rc)
709         log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
710       else
711         {
712           rc = app_help_pubkey_from_cert (cert, ncert, pk_p, pklen_p);
713           xfree (cert);
714           if (rc)
715             log_error ("failed to parse the certificate: %s\n",
716                        gpg_strerror (rc));
717         }
718     }
719   else
720     log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
721
722   if (!rc && opt_info && !direct_readkey)
723     {
724       char keygripstr[KEYGRIP_LEN*2+1];
725       char *algostr;
726
727       rc = app_help_get_keygrip_string_pk (*pk_p, *pklen_p,
728                                            keygripstr, NULL, NULL,
729                                            &algostr);
730       if (rc)
731         {
732           log_error ("app_help_get_keygrip_string failed: %s\n",
733                      gpg_strerror (rc));
734           return rc;
735         }
736
737       /* FIXME: Using LINE is not correct because it might be an
738        * OID and has not been canonicalized (i.e. uppercased).  */
739       send_status_info (ctrl, "KEYPAIRINFO",
740                         keygripstr, strlen (keygripstr),
741                         line, strlen (line),
742                         "-", (size_t)1,
743                         "-", (size_t)1,
744                         algostr, strlen (algostr),
745                         NULL, (size_t)0);
746       xfree (algostr);
747     }
748
749   return rc;
750 }
751
752 static const char hlp_readkey[] =
753   "READKEY [--format=advanced|ssh] [--info[-only]] <keyid>|<oid>|<keygrip>\n"
754   "\n"
755   "Return the public key for the given cert or key ID as a standard\n"
756   "S-expression.  With --format option, it may be returned in advanced\n"
757   "S-expression format, or SSH format.  With --info a KEYPAIRINFO\n"
758   "status line is also emitted; with --info-only the regular output is\n"
759   "suppressed.";
760 static gpg_error_t
761 cmd_readkey (assuan_context_t ctx, char *line)
762 {
763   ctrl_t ctrl = assuan_get_pointer (ctx);
764   gpg_error_t err;
765   int advanced = 0;
766   int ssh = 0;
767   int opt_info = 0;
768   int opt_nokey = 0;
769   unsigned char *pk = NULL;
770   size_t pklen;
771   card_t card;
772   const char *keygrip = NULL;
773
774   if ((err = open_card (ctrl)))
775     return err;
776
777   if (has_option (line, "--advanced"))
778     advanced = 1;
779   if (has_option (line, "--format=advanced"))
780     advanced = 1;
781   if (has_option (line, "--format=ssh"))
782     ssh = 1;
783   if (has_option (line, "--info"))
784     opt_info = 1;
785   if (has_option (line, "--info-only"))
786     opt_info = opt_nokey = 1;
787
788   line = skip_options (line);
789
790   line = xtrystrdup (line); /* Need a copy of the line. */
791   if (!line)
792     return gpg_error_from_syserror ();
793
794   if (strlen (line) == 40)
795     keygrip = line;
796
797   card = card_get (ctrl, keygrip);
798   if (card)
799     {
800       err = do_readkey (card, ctrl, line, opt_info, &pk, &pklen);
801       card_put (card);
802     }
803   else
804     err = gpg_error (GPG_ERR_NO_SECKEY);
805
806   if (err)
807     goto leave;
808
809   if (opt_nokey)
810     ;
811   else if (ssh)
812     {
813       estream_t stream = NULL;
814       gcry_sexp_t s_key;
815       void *buf = NULL;
816       size_t buflen;
817
818       stream = es_fopenmem (0, "r+b");
819       if (!stream)
820         {
821           err = gpg_error_from_syserror ();
822           goto leave;
823         }
824
825       err = gcry_sexp_new (&s_key, pk, pklen, 0);
826       if (err)
827         {
828           es_fclose (stream);
829           goto leave;
830         }
831
832       err = ssh_public_key_in_base64 (s_key, stream, "(none)");
833       if (err)
834         {
835           gcry_sexp_release (s_key);
836           es_fclose (stream);
837           goto leave;
838         }
839
840       err = es_fclose_snatch (stream, &buf, &buflen);
841       gcry_sexp_release (s_key);
842       if (!err)
843         err = assuan_send_data (ctx, buf, buflen);
844     }
845   else if (advanced)
846     {
847       gcry_sexp_t s_key;
848       unsigned char *pkadv;
849       size_t pkadvlen;
850
851       err = gcry_sexp_new (&s_key, pk, pklen, 0);
852       if (err)
853         goto leave;
854
855       pkadvlen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_ADVANCED, NULL, 0);
856       pkadv = xtrymalloc (pkadvlen);
857       if (!pkadv)
858         {
859           err = gpg_error_from_syserror ();
860           gcry_sexp_release (s_key);
861           goto leave;
862         }
863       log_assert (pkadvlen);
864
865       gcry_sexp_sprint (s_key, GCRYSEXP_FMT_ADVANCED, pkadv, pkadvlen);
866       gcry_sexp_release (s_key);
867       /* (One less to adjust for the trailing '\0') */
868       err = assuan_send_data (ctx, pkadv, pkadvlen-1);
869       xfree (pkadv);
870     }
871   else
872     err = assuan_send_data (ctx, pk, pklen);
873
874  leave:
875   xfree (pk);
876   xfree (line);
877   return err;
878 }
879
880
881 \f
882 static const char hlp_setdata[] =
883   "SETDATA [--append] <hexstring>\n"
884   "\n"
885   "The client should use this command to tell us the data he want to sign.\n"
886   "With the option --append, the data is appended to the data set by a\n"
887   "previous SETDATA command.";
888 static gpg_error_t
889 cmd_setdata (assuan_context_t ctx, char *line)
890 {
891   ctrl_t ctrl = assuan_get_pointer (ctx);
892   int append;
893   int n, i, off;
894   char *p;
895   unsigned char *buf;
896
897   append = (ctrl->in_data.value && has_option (line, "--append"));
898
899   line = skip_options (line);
900
901   if (locked_session && locked_session != ctrl->server_local)
902     return gpg_error (GPG_ERR_LOCKED);
903
904   /* Parse the hexstring. */
905   for (p=line,n=0; hexdigitp (p); p++, n++)
906     ;
907   if (*p)
908     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
909   if (!n)
910     return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
911   if ((n&1))
912     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
913   n /= 2;
914   if (append)
915     {
916       if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
917         return set_error (GPG_ERR_TOO_LARGE,
918                           "limit on total size of data reached");
919       buf = xtrymalloc (ctrl->in_data.valuelen + n);
920     }
921   else
922     buf = xtrymalloc (n);
923   if (!buf)
924     return out_of_core ();
925
926   if (append)
927     {
928       memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
929       off = ctrl->in_data.valuelen;
930     }
931   else
932     off = 0;
933   for (p=line, i=0; i < n; p += 2, i++)
934     buf[off+i] = xtoi_2 (p);
935
936   xfree (ctrl->in_data.value);
937   ctrl->in_data.value = buf;
938   ctrl->in_data.valuelen = off+n;
939   return 0;
940 }
941
942
943
944 static gpg_error_t
945 pin_cb (void *opaque, const char *info, char **retstr)
946 {
947   assuan_context_t ctx = opaque;
948   char *command;
949   int rc;
950   unsigned char *value;
951   size_t valuelen;
952
953   if (!retstr)
954     {
955       /* We prompt for pinpad entry.  To make sure that the popup has
956          been show we use an inquire and not just a status message.
957          We ignore any value returned.  */
958       if (info)
959         {
960           log_debug ("prompting for pinpad entry '%s'\n", info);
961           rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
962           if (rc < 0)
963             return gpg_error (gpg_err_code_from_errno (errno));
964           rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
965           xfree (command);
966         }
967       else
968         {
969           log_debug ("dismiss pinpad entry prompt\n");
970           rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT",
971                                &value, &valuelen, MAXLEN_PIN);
972         }
973       if (!rc)
974         xfree (value);
975       return rc;
976     }
977
978   *retstr = NULL;
979   log_debug ("asking for PIN '%s'\n", info);
980
981   rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
982   if (rc < 0)
983     return gpg_error (gpg_err_code_from_errno (errno));
984
985   /* Fixme: Write an inquire function which returns the result in
986      secure memory and check all further handling of the PIN. */
987   assuan_begin_confidential (ctx);
988   rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
989   assuan_end_confidential (ctx);
990   xfree (command);
991   if (rc)
992     return rc;
993
994   if (!valuelen || value[valuelen-1])
995     {
996       /* We require that the returned value is an UTF-8 string */
997       xfree (value);
998       return gpg_error (GPG_ERR_INV_RESPONSE);
999     }
1000   *retstr = (char*)value;
1001   return 0;
1002 }
1003
1004
1005 static const char hlp_pksign[] =
1006   "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5|none]] <hexified_id>\n"
1007   "\n"
1008   "The --hash option is optional; the default is SHA1.";
1009 static gpg_error_t
1010 cmd_pksign (assuan_context_t ctx, char *line)
1011 {
1012   ctrl_t ctrl = assuan_get_pointer (ctx);
1013   int rc;
1014   unsigned char *outdata;
1015   size_t outdatalen;
1016   char *keyidstr;
1017   int hash_algo;
1018   card_t card;
1019   const char *keygrip = NULL;
1020
1021   if (has_option (line, "--hash=rmd160"))
1022     hash_algo = GCRY_MD_RMD160;
1023   else if (has_option (line, "--hash=sha1"))
1024     hash_algo = GCRY_MD_SHA1;
1025   else if (has_option (line, "--hash=sha224"))
1026     hash_algo = GCRY_MD_SHA224;
1027   else if (has_option (line, "--hash=sha256"))
1028     hash_algo = GCRY_MD_SHA256;
1029   else if (has_option (line, "--hash=sha384"))
1030     hash_algo = GCRY_MD_SHA384;
1031   else if (has_option (line, "--hash=sha512"))
1032     hash_algo = GCRY_MD_SHA512;
1033   else if (has_option (line, "--hash=md5"))
1034     hash_algo = GCRY_MD_MD5;
1035   else if (has_option (line, "--hash=none"))  /* For raw RSA.  */
1036     hash_algo = 0;
1037   else if (!strstr (line, "--"))
1038     hash_algo = GCRY_MD_SHA1;
1039   else
1040     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
1041
1042   line = skip_options (line);
1043
1044   if ((rc = open_card (ctrl)))
1045     return rc;
1046
1047   /* We have to use a copy of the key ID because the function may use
1048      the pin_cb which in turn uses the assuan line buffer and thus
1049      overwriting the original line with the keyid */
1050   keyidstr = xtrystrdup (line);
1051   if (!keyidstr)
1052     return out_of_core ();
1053
1054   /* When it's a keygrip, we directly use the card, with no change of
1055      ctrl->card_ctx. */
1056   if (strlen (keyidstr) == 40)
1057     keygrip = keyidstr;
1058
1059   card = card_get (ctrl, keygrip);
1060   if (card)
1061     {
1062       rc = app_sign (card, ctrl,
1063                      keyidstr, hash_algo,
1064                      pin_cb, ctx,
1065                      ctrl->in_data.value, ctrl->in_data.valuelen,
1066                      &outdata, &outdatalen);
1067       card_put (card);
1068     }
1069   else
1070     rc = gpg_error (GPG_ERR_NO_SECKEY);
1071
1072   xfree (keyidstr);
1073   if (rc)
1074     {
1075       log_error ("app_sign failed: %s\n", gpg_strerror (rc));
1076     }
1077   else
1078     {
1079       rc = assuan_send_data (ctx, outdata, outdatalen);
1080       xfree (outdata);
1081       if (rc)
1082         return rc; /* that is already an assuan error code */
1083     }
1084
1085   return rc;
1086 }
1087
1088
1089 static const char hlp_pkauth[] =
1090   "PKAUTH [--challenge-response] <hexified_id>";
1091 static gpg_error_t
1092 cmd_pkauth (assuan_context_t ctx, char *line)
1093 {
1094   ctrl_t ctrl = assuan_get_pointer (ctx);
1095   int rc;
1096   unsigned char *outdata;
1097   size_t outdatalen;
1098   char *keyidstr;
1099   card_t card;
1100   const char *keygrip = NULL;
1101   int challenge_response = 0;
1102
1103   if ((rc = open_card (ctrl)))
1104     return rc;
1105
1106   if (has_option (line, "--challenge-response"))
1107     challenge_response = 1;
1108
1109   line = skip_options (line);
1110
1111   /* We have to use a copy of the key ID because the function may use
1112      the pin_cb which in turn uses the assuan line buffer and thus
1113      overwriting the original line with the keyid */
1114   keyidstr = xtrystrdup (line);
1115   if (!keyidstr)
1116     return out_of_core ();
1117
1118   /* When it's a keygrip, we directly use CARD, with no change of
1119      ctrl->card_ctx. */
1120   if (strlen (keyidstr) == 40)
1121     keygrip = keyidstr;
1122
1123   if (challenge_response)
1124     {
1125       xfree (ctrl->in_data.value);
1126       ctrl->in_data.value = NULL;
1127       ctrl->in_data.valuelen = 0;
1128     }
1129
1130   card = card_get (ctrl, keygrip);
1131   if (card)
1132     {
1133       rc = app_auth (card, ctrl, keyidstr, pin_cb, ctx,
1134                      ctrl->in_data.value, ctrl->in_data.valuelen,
1135                      &outdata, &outdatalen);
1136       card_put (card);
1137     }
1138   else
1139     rc = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1140
1141   xfree (keyidstr);
1142   if (rc)
1143     {
1144       log_error ("app_auth failed: %s\n", gpg_strerror (rc));
1145     }
1146   else
1147     {
1148       if (!challenge_response)
1149         rc = assuan_send_data (ctx, outdata, outdatalen);
1150       xfree (outdata);
1151     }
1152
1153   return rc;
1154 }
1155
1156
1157 static const char hlp_pkdecrypt[] =
1158   "PKDECRYPT <hexified_id>";
1159 static gpg_error_t
1160 cmd_pkdecrypt (assuan_context_t ctx, char *line)
1161 {
1162   ctrl_t ctrl = assuan_get_pointer (ctx);
1163   int rc;
1164   unsigned char *outdata;
1165   size_t outdatalen;
1166   char *keyidstr;
1167   unsigned int infoflags;
1168   card_t card;
1169   const char *keygrip = NULL;
1170
1171   if ((rc = open_card (ctrl)))
1172     return rc;
1173
1174   keyidstr = xtrystrdup (line);
1175   if (!keyidstr)
1176     return out_of_core ();
1177
1178   /* When it's a keygrip, we directly use CARD, with no change of
1179      ctrl->card_ctx. */
1180   if (strlen (keyidstr) == 40)
1181     keygrip = keyidstr;
1182
1183   card = card_get (ctrl, keygrip);
1184   if (card)
1185     {
1186       rc = app_decipher (card, ctrl, keyidstr, pin_cb, ctx,
1187                          ctrl->in_data.value, ctrl->in_data.valuelen,
1188                          &outdata, &outdatalen, &infoflags);
1189       card_put (card);
1190     }
1191   else
1192     rc = gpg_error (GPG_ERR_NO_SECKEY);
1193
1194   xfree (keyidstr);
1195   if (rc)
1196     {
1197       log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
1198     }
1199   else
1200     {
1201       /* If the card driver told us that there is no padding, send a
1202          status line.  If there is a padding it is assumed that the
1203          caller knows what padding is used.  It would have been better
1204          to always send that information but for backward
1205          compatibility we can't do that.  */
1206       if ((infoflags & APP_DECIPHER_INFO_NOPAD))
1207         send_status_direct (ctrl, "PADDING", "0");
1208       rc = assuan_send_data (ctx, outdata, outdatalen);
1209       xfree (outdata);
1210       if (rc)
1211         return rc; /* that is already an assuan error code */
1212     }
1213
1214   return rc;
1215 }
1216
1217
1218 static const char hlp_getattr[] =
1219   "GETATTR <name> [<keygrip>]\n"
1220   "\n"
1221   "This command is used to retrieve data from a smartcard.  The\n"
1222   "allowed names depend on the currently selected smartcard\n"
1223   "application.  NAME must be percent and '+' escaped.  The value is\n"
1224   "returned through status message, see the LEARN command for details.\n"
1225   "\n"
1226   "However, the current implementation assumes that Name is not escaped;\n"
1227   "this works as long as no one uses arbitrary escaping. \n"
1228   "\n"
1229   "Note, that this function may even be used on a locked card.\n"
1230   "When KEYGRIP is specified, it accesses directly with the KEYGRIP.";
1231 static gpg_error_t
1232 cmd_getattr (assuan_context_t ctx, char *line)
1233 {
1234   ctrl_t ctrl = assuan_get_pointer (ctx);
1235   int rc;
1236   const char *keyword;
1237   card_t card;
1238   const char *keygrip = NULL;
1239
1240   if ((rc = open_card (ctrl)))
1241     return rc;
1242
1243   keyword = line;
1244   while (*line && !spacep (line))
1245     line++;
1246   if (*line)
1247     *line++ = 0;
1248
1249   if (strlen (line) == 40)
1250     keygrip = line;
1251
1252   card = card_get (ctrl, keygrip);
1253   if (card)
1254     {
1255       /* FIXME: Applications should not return sensitive data if the card
1256          is locked.  */
1257       rc = app_getattr (card, ctrl, keyword);
1258       card_put (card);
1259     }
1260   else
1261     rc = gpg_error (GPG_ERR_NO_SECKEY);
1262
1263   return rc;
1264 }
1265
1266
1267 static const char hlp_setattr[] =
1268   "SETATTR [--inquire] <name> <value> \n"
1269   "\n"
1270   "This command is used to store data on a smartcard.  The allowed\n"
1271   "names and values are depend on the currently selected smartcard\n"
1272   "application.  NAME and VALUE must be percent and '+' escaped.\n"
1273   "\n"
1274   "However, the current implementation assumes that NAME is not\n"
1275   "escaped; this works as long as no one uses arbitrary escaping.\n"
1276   "\n"
1277   "If the option --inquire is used, VALUE shall not be given; instead\n"
1278   "an inquiry using the keyword \"VALUE\" is used to retrieve it.  The\n"
1279   "value is in this case considered to be confidential and not logged.\n"
1280   "\n"
1281   "A PIN will be requested for most NAMEs.  See the corresponding\n"
1282   "setattr function of the actually used application (app-*.c) for\n"
1283   "details.";
1284 static gpg_error_t
1285 cmd_setattr (assuan_context_t ctx, char *orig_line)
1286 {
1287   ctrl_t ctrl = assuan_get_pointer (ctx);
1288   gpg_error_t err;
1289   char *keyword;
1290   int keywordlen;
1291   size_t nbytes;
1292   char *line, *linebuf;
1293   int opt_inquire;
1294   card_t card;
1295
1296   opt_inquire = has_option (orig_line, "--inquire");
1297   orig_line = skip_options (orig_line);
1298
1299   if ((err = open_card (ctrl)))
1300     return err;
1301
1302   /* We need to use a copy of LINE, because PIN_CB uses the same
1303      context and thus reuses the Assuan provided LINE. */
1304   line = linebuf = xtrystrdup (orig_line);
1305   if (!line)
1306     return out_of_core ();
1307
1308   card = card_get (ctrl, NULL);
1309   if (!card)
1310     {
1311       xfree (linebuf);
1312       return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
1313     }
1314
1315   keyword = line;
1316   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1317     ;
1318   if (*line)
1319       *line++ = 0;
1320   while (spacep (line))
1321     line++;
1322   if (opt_inquire)
1323     {
1324       unsigned char *value;
1325
1326       assuan_begin_confidential (ctx);
1327       err = assuan_inquire (ctx, "VALUE", &value, &nbytes, MAXLEN_SETATTRDATA);
1328       assuan_end_confidential (ctx);
1329       if (!err)
1330         {
1331           err = app_setattr (card, ctrl, keyword, pin_cb, ctx,
1332                              value, nbytes);
1333           wipememory (value, nbytes);
1334           xfree (value);
1335         }
1336
1337    }
1338   else
1339     {
1340       nbytes = percent_plus_unescape_inplace (line, 0);
1341       err = app_setattr (card, ctrl, keyword, pin_cb, ctx,
1342                          (const unsigned char*)line, nbytes);
1343     }
1344
1345   card_put (card);
1346   xfree (linebuf);
1347   return err;
1348 }
1349
1350
1351 static const char hlp_writecert[] =
1352   "WRITECERT <hexified_certid>\n"
1353   "\n"
1354   "This command is used to store a certificate on a smartcard.  The\n"
1355   "allowed certids depend on the currently selected smartcard\n"
1356   "application. The actual certifciate is requested using the inquiry\n"
1357   "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
1358   "\n"
1359   "In almost all cases a PIN will be requested.  See the related\n"
1360   "writecert function of the actually used application (app-*.c) for\n"
1361   "details.";
1362 static gpg_error_t
1363 cmd_writecert (assuan_context_t ctx, char *line)
1364 {
1365   ctrl_t ctrl = assuan_get_pointer (ctx);
1366   int rc;
1367   char *certid;
1368   unsigned char *certdata;
1369   size_t certdatalen;
1370   card_t card;
1371
1372   line = skip_options (line);
1373
1374   if (!*line)
1375     return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1376   certid = line;
1377   while (*line && !spacep (line))
1378     line++;
1379   *line = 0;
1380
1381   if ((rc = open_card (ctrl)))
1382     return rc;
1383
1384   card = card_get (ctrl, NULL);
1385   if (!card)
1386     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1387
1388   certid = xtrystrdup (certid);
1389   if (!certid)
1390     {
1391       card_put (card);
1392       return out_of_core ();
1393     }
1394
1395   /* Now get the actual keydata. */
1396   rc = assuan_inquire (ctx, "CERTDATA",
1397                        &certdata, &certdatalen, MAXLEN_CERTDATA);
1398   if (rc)
1399     {
1400       card_put (card);
1401       xfree (certid);
1402       return rc;
1403     }
1404
1405   /* Write the certificate to the card. */
1406   rc = app_writecert (card, ctrl, certid,
1407                       pin_cb, ctx, certdata, certdatalen);
1408   card_put (card);
1409   xfree (certid);
1410   xfree (certdata);
1411
1412   return rc;
1413 }
1414
1415
1416 static const char hlp_writekey[] =
1417   "WRITEKEY [--force] <keyid> \n"
1418   "\n"
1419   "This command is used to store a secret key on a smartcard.  The\n"
1420   "allowed keyids depend on the currently selected smartcard\n"
1421   "application. The actual keydata is requested using the inquiry\n"
1422   "\"KEYDATA\" and need to be provided without any protection.  With\n"
1423   "--force set an existing key under this KEYID will get overwritten.\n"
1424   "The keydata is expected to be the usual canonical encoded\n"
1425   "S-expression.\n"
1426   "\n"
1427   "A PIN will be requested for most NAMEs.  See the corresponding\n"
1428   "writekey function of the actually used application (app-*.c) for\n"
1429   "details.";
1430 static gpg_error_t
1431 cmd_writekey (assuan_context_t ctx, char *line)
1432 {
1433   ctrl_t ctrl = assuan_get_pointer (ctx);
1434   int rc;
1435   char *keyid;
1436   int force = has_option (line, "--force");
1437   unsigned char *keydata;
1438   size_t keydatalen;
1439   card_t card;
1440
1441   line = skip_options (line);
1442
1443   if (!*line)
1444     return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1445   keyid = line;
1446   while (*line && !spacep (line))
1447     line++;
1448   *line = 0;
1449
1450   if ((rc = open_card (ctrl)))
1451     return rc;
1452
1453   card = card_get (ctrl, NULL);
1454   if (!card)
1455     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1456
1457   keyid = xtrystrdup (keyid);
1458   if (!keyid)
1459     {
1460       card_put (card);
1461       return out_of_core ();
1462     }
1463
1464   /* Now get the actual keydata. */
1465   assuan_begin_confidential (ctx);
1466   rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1467   assuan_end_confidential (ctx);
1468   if (rc)
1469     {
1470       xfree (keyid);
1471       return rc;
1472     }
1473
1474   /* Write the key to the card. */
1475   rc = app_writekey (card, ctrl, keyid, force? 1:0,
1476                      pin_cb, ctx, keydata, keydatalen);
1477   card_put (card);
1478   xfree (keyid);
1479   xfree (keydata);
1480
1481   return rc;
1482 }
1483
1484
1485 static const char hlp_genkey[] =
1486   "GENKEY [--force] [--timestamp=<isodate>] [--algo=ALGO] <keyref>\n"
1487   "\n"
1488   "Generate a key on-card identified by <keyref>, which is application\n"
1489   "specific.  Return values are also application specific.  For OpenPGP\n"
1490   "cards 3 status lines are returned:\n"
1491   "\n"
1492   "  S KEY-FPR  <hexstring>\n"
1493   "  S KEY-CREATED-AT <seconds_since_epoch>\n"
1494   "  S KEY-DATA [-|p|n] <hexdata>\n"
1495   "\n"
1496   "  'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
1497   "  indicate that HEXDATA is the first chunk of a parameter given\n"
1498   "  by the next KEY-DATA.  Only used by GnuPG version < 2.1.\n"
1499   "\n"
1500   "--force is required to overwrite an already existing key.  The\n"
1501   "KEY-CREATED-AT is required for further processing because it is\n"
1502   "part of the hashed key material for the fingerprint.\n"
1503   "\n"
1504   "If --timestamp is given an OpenPGP key will be created using this\n"
1505   "value.  The value needs to be in ISO Format; e.g.\n"
1506   "\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
1507   "\n"
1508   "The option --algo can be used to request creation using a specific\n"
1509   "algorithm.  The possible algorithms are card dependent.\n"
1510   "\n"
1511   "The public part of the key can also later be retrieved using the\n"
1512   "READKEY command.";
1513 static gpg_error_t
1514 cmd_genkey (assuan_context_t ctx, char *line)
1515 {
1516   ctrl_t ctrl = assuan_get_pointer (ctx);
1517   gpg_error_t err;
1518   char *keyref_buffer = NULL;
1519   char *keyref;
1520   int force;
1521   const char *s;
1522   char *opt_algo = NULL;
1523   time_t timestamp;
1524   card_t card;
1525
1526   force = has_option (line, "--force");
1527
1528   if ((s=has_option_name (line, "--timestamp")))
1529     {
1530       if (*s != '=')
1531         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1532       timestamp = isotime2epoch (s+1);
1533       if (timestamp < 1)
1534         return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1535     }
1536   else
1537     timestamp = 0;
1538
1539   err = get_option_value (line, "--algo", &opt_algo);
1540   if (err)
1541     goto leave;
1542
1543   line = skip_options (line);
1544   if (!*line)
1545     {
1546       err = set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1547       goto leave;
1548     }
1549   keyref = line;
1550   while (*line && !spacep (line))
1551     line++;
1552   *line = 0;
1553
1554   if ((err = open_card (ctrl)))
1555     goto leave;
1556
1557   card = card_get (ctrl, NULL);
1558   if (!card)
1559     {
1560       err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1561       goto leave;
1562     }
1563
1564   keyref = keyref_buffer = xtrystrdup (keyref);
1565   if (!keyref)
1566     {
1567       err = gpg_error_from_syserror ();
1568       card_put (card);
1569       goto leave;
1570     }
1571   err = app_genkey (card, ctrl, keyref, opt_algo,
1572                     force? APP_GENKEY_FLAG_FORCE : 0,
1573                     timestamp, pin_cb, ctx);
1574   card_put (card);
1575
1576  leave:
1577   xfree (keyref_buffer);
1578   xfree (opt_algo);
1579   return err;
1580 }
1581
1582
1583 static const char hlp_random[] =
1584   "RANDOM <nbytes>\n"
1585   "\n"
1586   "Get NBYTES of random from the card and send them back as data.\n"
1587   "This usually involves EEPROM write on the card and thus excessive\n"
1588   "use of this command may destroy the card.\n"
1589   "\n"
1590   "Note, that this function may be even be used on a locked card.";
1591 static gpg_error_t
1592 cmd_random (assuan_context_t ctx, char *line)
1593 {
1594   ctrl_t ctrl = assuan_get_pointer (ctx);
1595   int rc;
1596   size_t nbytes;
1597   unsigned char *buffer;
1598   card_t card;
1599
1600   if (!*line)
1601     return set_error (GPG_ERR_ASS_PARAMETER,
1602                       "number of requested bytes missing");
1603   nbytes = strtoul (line, NULL, 0);
1604
1605   if ((rc = open_card (ctrl)))
1606     return rc;
1607
1608   card = card_get (ctrl, NULL);
1609   if (!card)
1610     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1611
1612   buffer = xtrymalloc (nbytes);
1613   if (!buffer)
1614     {
1615       card_put (card);
1616       return out_of_core ();
1617     }
1618
1619   rc = app_get_challenge (card, ctrl, nbytes, buffer);
1620   card_put (card);
1621   if (!rc)
1622     {
1623       rc = assuan_send_data (ctx, buffer, nbytes);
1624       xfree (buffer);
1625       return rc; /* that is already an assuan error code */
1626     }
1627   xfree (buffer);
1628
1629   return rc;
1630 }
1631
1632
1633 \f
1634 static const char hlp_passwd[] =
1635   "PASSWD [--reset] [--nullpin] [--clear] <chvno> [<keygrip>]\n"
1636   "\n"
1637   "Change the PIN or, if --reset is given, reset the retry counter of\n"
1638   "the card holder verification vector CHVNO.  The option --nullpin is\n"
1639   "used for TCOS cards to set the initial PIN.  The option --clear clears\n"
1640   "the security status associated with the PIN so that the PIN needs to\n"
1641   "be presented again.  The format of CHVNO depends on the card application.\n"
1642   "\n"
1643   "The target card is the currently selected smartcard, when KEYPGIP is not\n"
1644   "specified.  When it is specified, it accesses directly with the KEYGRIP.";
1645 static gpg_error_t
1646 cmd_passwd (assuan_context_t ctx, char *line)
1647 {
1648   ctrl_t ctrl = assuan_get_pointer (ctx);
1649   int rc;
1650   char *chvnostr;
1651   unsigned int flags = 0;
1652   card_t card;
1653   const char *keygrip = NULL;
1654
1655   if (has_option (line, "--reset"))
1656     flags |= APP_CHANGE_FLAG_RESET;
1657   if (has_option (line, "--nullpin"))
1658     flags |= APP_CHANGE_FLAG_NULLPIN;
1659   if (has_option (line, "--clear"))
1660     flags |= APP_CHANGE_FLAG_CLEAR;
1661
1662   line = skip_options (line);
1663
1664   if (!*line)
1665     return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1666   chvnostr = line;
1667   while (*line && !spacep (line))
1668     line++;
1669   if (*line)
1670     *line++ = 0;
1671
1672   if (strlen (line) == 40)
1673     keygrip = line;
1674
1675   /* Do not allow other flags aside of --clear. */
1676   if ((flags & APP_CHANGE_FLAG_CLEAR) && (flags & ~APP_CHANGE_FLAG_CLEAR))
1677     return set_error (GPG_ERR_UNSUPPORTED_OPERATION,
1678                       "--clear used with other options");
1679
1680   if ((rc = open_card (ctrl)))
1681     return rc;
1682
1683   card = card_get (ctrl, keygrip);
1684   if (!card)
1685     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1686
1687   chvnostr = xtrystrdup (chvnostr);
1688   if (!chvnostr)
1689     {
1690       card_put (card);
1691       return out_of_core ();
1692     }
1693   rc = app_change_pin (card, ctrl, chvnostr, flags, pin_cb, ctx);
1694   card_put (card);
1695   if (rc)
1696     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1697   xfree (chvnostr);
1698
1699   return rc;
1700 }
1701
1702
1703 static const char hlp_checkpin[] =
1704   "CHECKPIN <idstr>\n"
1705   "\n"
1706   "Perform a VERIFY operation without doing anything else.  This may\n"
1707   "be used to initialize a the PIN cache earlier to long lasting\n"
1708   "operations.  Its use is highly application dependent.\n"
1709   "\n"
1710   "For OpenPGP:\n"
1711   "\n"
1712   "   Perform a simple verify operation for CHV1 and CHV2, so that\n"
1713   "   further operations won't ask for CHV2 and it is possible to do a\n"
1714   "   cheap check on the PIN: If there is something wrong with the PIN\n"
1715   "   entry system, only the regular CHV will get blocked and not the\n"
1716   "   dangerous CHV3.  IDSTR is the usual card's serial number in hex\n"
1717   "   notation; an optional fingerprint part will get ignored.  There\n"
1718   "   is however a special mode if the IDSTR is suffixed with the\n"
1719   "   literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1720   "   if and only if the retry counter is still at 3.\n"
1721   "\n"
1722   "For Netkey:\n"
1723   "\n"
1724   "   Any of the valid PIN Ids may be used.  These are the strings:\n"
1725   "\n"
1726   "     PW1.CH       - Global password 1\n"
1727   "     PW2.CH       - Global password 2\n"
1728   "     PW1.CH.SIG   - SigG password 1\n"
1729   "     PW2.CH.SIG   - SigG password 2\n"
1730   "\n"
1731   "   For a definitive list, see the implementation in app-nks.c.\n"
1732   "   Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1733   "   3.0 they are technically alternative PINs used to mutally\n"
1734   "   unblock each other.\n"
1735   "\n"
1736   "For PKCS#15:\n"
1737   "\n"
1738   "   The key's ID string or the PIN's label may be used.";
1739 static gpg_error_t
1740 cmd_checkpin (assuan_context_t ctx, char *line)
1741 {
1742   ctrl_t ctrl = assuan_get_pointer (ctx);
1743   gpg_error_t err;
1744   char *idstr;
1745   card_t card;
1746
1747   if ((err = open_card (ctrl)))
1748     return err;
1749
1750   card = card_get (ctrl, NULL);
1751   if (!card)
1752     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1753
1754   /* We have to use a copy of the key ID because the function may use
1755      the pin_cb which in turn uses the assuan line buffer and thus
1756      overwriting the original line with the keyid. */
1757   idstr = xtrystrdup (line);
1758   if (!idstr)
1759     {
1760       card_put (card);
1761       return out_of_core ();
1762     }
1763
1764   err = app_check_pin (card, ctrl, idstr, pin_cb, ctx);
1765   card_put (card);
1766   xfree (idstr);
1767   if (err)
1768     log_error ("app_check_pin failed: %s\n", gpg_strerror (err));
1769
1770   return err;
1771 }
1772
1773
1774 static const char hlp_lock[] =
1775   "LOCK [--wait]\n"
1776   "\n"
1777   "Grant exclusive card access to this session.  Note that there is\n"
1778   "no lock counter used and a second lock from the same session will\n"
1779   "be ignored.  A single unlock (or RESET) unlocks the session.\n"
1780   "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1781   "\n"
1782   "If the option --wait is given the command will wait until a\n"
1783   "lock has been released.";
1784 static gpg_error_t
1785 cmd_lock (assuan_context_t ctx, char *line)
1786 {
1787   ctrl_t ctrl = assuan_get_pointer (ctx);
1788   int rc = 0;
1789
1790  retry:
1791   if (locked_session)
1792     {
1793       if (locked_session != ctrl->server_local)
1794         rc = gpg_error (GPG_ERR_LOCKED);
1795     }
1796   else
1797     locked_session = ctrl->server_local;
1798
1799 #ifdef USE_NPTH
1800   if (rc && has_option (line, "--wait"))
1801     {
1802       rc = 0;
1803       gnupg_sleep (1); /* Better implement an event mechanism. However,
1804                           for card operations this should be
1805                           sufficient. */
1806       /* Send a progress so that we can detect a connection loss.  */
1807       rc = send_status_printf (ctrl, "PROGRESS", "scd_locked . 0 0");
1808       if (!rc)
1809         goto retry;
1810     }
1811 #endif /*USE_NPTH*/
1812
1813   if (rc)
1814     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1815   return rc;
1816 }
1817
1818
1819 static const char hlp_unlock[] =
1820   "UNLOCK\n"
1821   "\n"
1822   "Release exclusive card access.";
1823 static gpg_error_t
1824 cmd_unlock (assuan_context_t ctx, char *line)
1825 {
1826   ctrl_t ctrl = assuan_get_pointer (ctx);
1827   int rc = 0;
1828
1829   (void)line;
1830
1831   if (locked_session)
1832     {
1833       if (locked_session != ctrl->server_local)
1834         rc = gpg_error (GPG_ERR_LOCKED);
1835       else
1836         locked_session = NULL;
1837     }
1838   else
1839     rc = gpg_error (GPG_ERR_NOT_LOCKED);
1840
1841   if (rc)
1842     log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1843   return rc;
1844 }
1845
1846
1847 static const char hlp_getinfo[] =
1848   "GETINFO <what>\n"
1849   "\n"
1850   "Multi purpose command to return certain information.  \n"
1851   "Supported values of WHAT are:\n"
1852   "\n"
1853   "  version     - Return the version of the program.\n"
1854   "  pid         - Return the process id of the server.\n"
1855   "  socket_name - Return the name of the socket.\n"
1856   "  connections - Return number of active connections.\n"
1857   "  status      - Return the status of the current reader (in the future,\n"
1858   "                may also return the status of all readers).  The status\n"
1859   "                is a list of one-character flags.  The following flags\n"
1860   "                are currently defined:\n"
1861   "                  'u'  Usable card present.\n"
1862   "                  'r'  Card removed.  A reset is necessary.\n"
1863   "                These flags are exclusive.\n"
1864   "  reader_list - Return a list of detected card readers.  Does\n"
1865   "                currently only work with the internal CCID driver.\n"
1866   "  deny_admin  - Returns OK if admin commands are not allowed or\n"
1867   "                GPG_ERR_GENERAL if admin commands are allowed.\n"
1868   "  app_list    - Return a list of supported applications.  One\n"
1869   "                application per line, fields delimited by colons,\n"
1870   "                first field is the name.\n"
1871   "  card_list   - Return a list of serial numbers of all inserted cards.\n"
1872   "  active_apps - Return a list of active apps on the current card.\n"
1873   "  all_active_apps\n"
1874   "              - Return a list of active apps on all inserted cards.\n"
1875   "  cmd_has_option CMD OPT\n"
1876   "              - Returns OK if command CMD has option OPT.\n"
1877   "  apdu_strerror NUMBER\n"
1878   "              - Return a string for a status word.\n";
1879 static gpg_error_t
1880 cmd_getinfo (assuan_context_t ctx, char *line)
1881 {
1882   int rc = 0;
1883   const char *s;
1884
1885   if (!strcmp (line, "version"))
1886     {
1887       s = VERSION;
1888       rc = assuan_send_data (ctx, s, strlen (s));
1889     }
1890   else if (!strcmp (line, "pid"))
1891     {
1892       char numbuf[50];
1893
1894       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1895       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1896     }
1897   else if (!strncmp (line, "cmd_has_option", 14)
1898            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
1899     {
1900       char *cmd, *cmdopt;
1901       line += 14;
1902       while (*line == ' ' || *line == '\t')
1903         line++;
1904       if (!*line)
1905         rc = gpg_error (GPG_ERR_MISSING_VALUE);
1906       else
1907         {
1908           cmd = line;
1909           while (*line && (*line != ' ' && *line != '\t'))
1910             line++;
1911           if (!*line)
1912             rc = gpg_error (GPG_ERR_MISSING_VALUE);
1913           else
1914             {
1915               *line++ = 0;
1916               while (*line == ' ' || *line == '\t')
1917                 line++;
1918               if (!*line)
1919                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
1920               else
1921                 {
1922                   cmdopt = line;
1923                   if (!command_has_option (cmd, cmdopt))
1924                     rc = gpg_error (GPG_ERR_FALSE);
1925                 }
1926             }
1927         }
1928     }
1929   else if (!strcmp (line, "socket_name"))
1930     {
1931       s = scd_get_socket_name ();
1932       if (s)
1933         rc = assuan_send_data (ctx, s, strlen (s));
1934       else
1935         rc = gpg_error (GPG_ERR_NO_DATA);
1936     }
1937   else if (!strcmp (line, "connections"))
1938     {
1939       char numbuf[20];
1940
1941       snprintf (numbuf, sizeof numbuf, "%d", get_active_connection_count ());
1942       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1943     }
1944   else if (!strcmp (line, "status"))
1945     {
1946       ctrl_t ctrl = assuan_get_pointer (ctx);
1947       char flag;
1948
1949       if (open_card (ctrl))
1950         flag = 'r';
1951       else
1952         flag = 'u';
1953
1954       rc = assuan_send_data (ctx, &flag, 1);
1955     }
1956   else if (!strcmp (line, "reader_list"))
1957     {
1958 #ifdef HAVE_LIBUSB
1959       char *p = ccid_get_reader_list ();
1960 #else
1961       char *p = NULL;
1962 #endif
1963
1964       if (p)
1965         rc = assuan_send_data (ctx, p, strlen (p));
1966       else
1967         rc = gpg_error (GPG_ERR_NO_DATA);
1968       xfree (p);
1969     }
1970   else if (!strcmp (line, "deny_admin"))
1971     rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1972   else if (!strcmp (line, "app_list"))
1973     {
1974       char *p = get_supported_applications ();
1975       if (p)
1976         rc = assuan_send_data (ctx, p, strlen (p));
1977       else
1978         rc = 0;
1979       xfree (p);
1980     }
1981   else if (!strcmp (line, "card_list"))
1982     {
1983       ctrl_t ctrl = assuan_get_pointer (ctx);
1984
1985       rc = app_send_card_list (ctrl);
1986     }
1987   else if (!strcmp (line, "active_apps"))
1988     {
1989       ctrl_t ctrl = assuan_get_pointer (ctx);
1990       card_t card = card_get (ctrl, NULL);
1991
1992       if (!card)
1993         rc = 0; /* No current card - no active apps.  */
1994       else
1995         {
1996           rc = app_send_active_apps (card, ctrl);
1997           card_put (card);
1998         }
1999     }
2000   else if (!strcmp (line, "all_active_apps"))
2001     {
2002       ctrl_t ctrl = assuan_get_pointer (ctx);
2003       rc = app_send_active_apps (NULL, ctrl);
2004     }
2005   else if ((s=has_leading_keyword (line, "apdu_strerror")))
2006     {
2007       unsigned long ul = strtoul (s, NULL, 0);
2008       s = apdu_strerror (ul);
2009       rc = assuan_send_data (ctx, s, strlen (s));
2010     }
2011   else
2012     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2013   return rc;
2014 }
2015
2016
2017 static const char hlp_restart[] =
2018   "RESTART\n"
2019   "\n"
2020   "Restart the current connection; this is a kind of warm reset.  It\n"
2021   "deletes the context used by this connection but does not send a\n"
2022   "RESET to the card.  Thus the card itself won't get reset. \n"
2023   "\n"
2024   "This is used by gpg-agent to reuse a primary pipe connection and\n"
2025   "may be used by clients to backup from a conflict in the serial\n"
2026   "command; i.e. to select another application.";
2027 static gpg_error_t
2028 cmd_restart (assuan_context_t ctx, char *line)
2029 {
2030   ctrl_t ctrl = assuan_get_pointer (ctx);
2031   card_t card = card_get (ctrl, NULL);
2032
2033   (void)line;
2034
2035   if (card)
2036     {
2037       ctrl->card_ctx = NULL;
2038       ctrl->current_apptype = APPTYPE_NONE;
2039       card_unref_locked (card);
2040       card_put (card);
2041     }
2042   if (locked_session && ctrl->server_local == locked_session)
2043     {
2044       locked_session = NULL;
2045       log_info ("implicitly unlocking due to RESTART\n");
2046     }
2047   return 0;
2048 }
2049
2050
2051 static const char hlp_disconnect[] =
2052   "DISCONNECT\n"
2053   "\n"
2054   "Disconnect the card if the backend supports a disconnect operation.";
2055 static gpg_error_t
2056 cmd_disconnect (assuan_context_t ctx, char *line)
2057 {
2058   ctrl_t ctrl = assuan_get_pointer (ctx);
2059   card_t card;
2060
2061   (void)line;
2062
2063   card = card_get (ctrl, NULL);
2064   if (card)
2065     {
2066       apdu_disconnect (card->slot);
2067       card_put (card);
2068       return 0;
2069     }
2070   else
2071     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
2072 }
2073
2074
2075
2076 static const char hlp_apdu[] =
2077   "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
2078   "\n"
2079   "Send an APDU to the current reader.  This command bypasses the high\n"
2080   "level functions and sends the data directly to the card.  HEXSTRING\n"
2081   "is expected to be a proper APDU.  If HEXSTRING is not given no\n"
2082   "commands are set to the card but the command will implicitly check\n"
2083   "whether the card is ready for use. \n"
2084   "\n"
2085   "Using the option \"--atr\" returns the ATR of the card as a status\n"
2086   "message before any data like this:\n"
2087   "  S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
2088   "\n"
2089   "Using the option --more handles the card status word MORE_DATA\n"
2090   "(61xx) and concatenates all responses to one block.\n"
2091   "\n"
2092   "Using the option \"--exlen\" the returned APDU may use extended\n"
2093   "length up to N bytes.  If N is not given a default value is used\n"
2094   "(currently 4096).";
2095 static gpg_error_t
2096 cmd_apdu (assuan_context_t ctx, char *line)
2097 {
2098   ctrl_t ctrl = assuan_get_pointer (ctx);
2099   card_t card;
2100   int rc;
2101   unsigned char *apdu;
2102   size_t apdulen;
2103   int with_atr;
2104   int handle_more;
2105   const char *s;
2106   size_t exlen;
2107
2108   if (has_option (line, "--dump-atr"))
2109     with_atr = 3;
2110   else if (has_option (line, "--data-atr"))
2111     with_atr = 2;
2112   else
2113     with_atr = has_option (line, "--atr");
2114   handle_more = has_option (line, "--more");
2115
2116   if ((s=has_option_name (line, "--exlen")))
2117     {
2118       if (*s == '=')
2119         exlen = strtoul (s+1, NULL, 0);
2120       else
2121         exlen = 4096;
2122     }
2123   else
2124     exlen = 0;
2125
2126   line = skip_options (line);
2127
2128   if ((rc = open_card (ctrl)))
2129     return rc;
2130
2131   card = card_get (ctrl, NULL);
2132   if (!card)
2133     return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
2134
2135   if (with_atr)
2136     {
2137       unsigned char *atr;
2138       size_t atrlen;
2139       char hexbuf[400];
2140
2141       atr = apdu_get_atr (card->slot, &atrlen);
2142       if (!atr || atrlen > sizeof hexbuf - 2 )
2143         {
2144           rc = gpg_error (GPG_ERR_INV_CARD);
2145           goto leave;
2146         }
2147       if (with_atr == 3)
2148         {
2149           char *string, *p, *pend;
2150
2151           string = atr_dump (atr, atrlen);
2152           if (string)
2153             {
2154               for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
2155                 {
2156                   rc = assuan_send_data (ctx, p, pend - p + 1);
2157                   if (!rc)
2158                     rc = assuan_send_data (ctx, NULL, 0);
2159                 }
2160               if (!rc && *p)
2161                 rc = assuan_send_data (ctx, p, strlen (p));
2162               es_free (string);
2163               if (rc)
2164                 {
2165                   xfree (atr);
2166                   goto leave;
2167                 }
2168             }
2169         }
2170       else if (with_atr == 2)
2171         {
2172           rc = assuan_send_data (ctx, atr, atrlen);
2173           if (rc)
2174             {
2175               xfree (atr);
2176               goto leave;
2177             }
2178         }
2179       else
2180         {
2181           bin2hex (atr, atrlen, hexbuf);
2182           send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
2183         }
2184       xfree (atr);
2185     }
2186
2187   apdu = hex_to_buffer (line, &apdulen);
2188   if (!apdu)
2189     {
2190       rc = gpg_error_from_syserror ();
2191       goto leave;
2192     }
2193   if (apdulen)
2194     {
2195       unsigned char *result = NULL;
2196       size_t resultlen;
2197
2198       card->maybe_check_aid = 1;
2199       rc = apdu_send_direct (card->slot, exlen,
2200                              apdu, apdulen, handle_more,
2201                              NULL, &result, &resultlen);
2202       if (rc)
2203         {
2204           log_error ("apdu_send_direct failed: %s\n", apdu_strerror (rc));
2205           rc = iso7816_map_sw (rc);
2206         }
2207       else
2208         {
2209           rc = assuan_send_data (ctx, result, resultlen);
2210           xfree (result);
2211         }
2212     }
2213   xfree (apdu);
2214
2215  leave:
2216   card_put (card);
2217   return rc;
2218 }
2219
2220
2221 static const char hlp_killscd[] =
2222   "KILLSCD\n"
2223   "\n"
2224   "Commit suicide.";
2225 static gpg_error_t
2226 cmd_killscd (assuan_context_t ctx, char *line)
2227 {
2228   ctrl_t ctrl = assuan_get_pointer (ctx);
2229
2230   (void)line;
2231
2232   ctrl->server_local->stopme = 1;
2233   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2234   return 0;
2235 }
2236
2237
2238 static const char hlp_keyinfo[] =
2239   "KEYINFO [--list[=auth|encr|sign]] [--data] <keygrip>\n"
2240   "\n"
2241   "Return information about the key specified by the KEYGRIP.  If the\n"
2242   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
2243   "--list is given the keygrip is ignored and information about all\n"
2244   "available keys are returned.  Capability may limit the listing.\n"
2245   "Unless --data is given, the\n"
2246   "information is returned as a status line using the format:\n"
2247   "\n"
2248   "  KEYINFO <keygrip> T <serialno> <idstr> <usage>\n"
2249   "\n"
2250   "KEYGRIP is the keygrip.\n"
2251   "\n"
2252   "SERIALNO is an ASCII string with the serial number of the\n"
2253   "         smartcard.  If the serial number is not known a single\n"
2254   "         dash '-' is used instead.\n"
2255   "\n"
2256   "IDSTR is a string used to distinguish keys on a smartcard.  If it\n"
2257   "      is not known a dash is used instead.\n"
2258   "\n"
2259   "USAGE is a string of capabilities of the key, 's' for sign, \n"
2260   "'e' for encryption, 'a' for auth, and 'c' for cert.  If it is not\n"
2261   "known a dash is used instead.\n"
2262   "\n"
2263   "More information may be added in the future.";
2264 static gpg_error_t
2265 cmd_keyinfo (assuan_context_t ctx, char *line)
2266 {
2267   int cap;
2268   int opt_data;
2269   int action;
2270   char *keygrip_str;
2271   ctrl_t ctrl = assuan_get_pointer (ctx);
2272   card_t card;
2273
2274   opt_data = has_option (line, "--data");
2275
2276   cap = 0;
2277   keygrip_str = NULL;
2278   if (has_option (line, "--list"))
2279     cap = 0;
2280   else if (has_option (line, "--list=sign"))
2281     cap = GCRY_PK_USAGE_SIGN;
2282   else if (has_option (line, "--list=encr"))
2283     cap = GCRY_PK_USAGE_ENCR;
2284   else if (has_option (line, "--list=auth"))
2285     cap = GCRY_PK_USAGE_AUTH;
2286   else
2287     keygrip_str = skip_options (line);
2288
2289   if (opt_data)
2290     action = KEYGRIP_ACTION_SEND_DATA;
2291   else
2292     action = KEYGRIP_ACTION_WRITE_STATUS;
2293
2294   card = app_do_with_keygrip (ctrl, action, keygrip_str, cap);
2295
2296   if (keygrip_str && !card)
2297     return gpg_error (GPG_ERR_NOT_FOUND);
2298   return 0;
2299 }
2300
2301
2302 /* Send a keyinfo string as used by the KEYGRIP_ACTION_SEND_DATA.  If
2303  * DATA is true the string is emitted as a data line, else as a status
2304  * line.  */
2305 void
2306 send_keyinfo (ctrl_t ctrl, int data, const char *keygrip_str,
2307               const char *serialno, const char *idstr, const char *usage)
2308 {
2309   char *string;
2310   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2311
2312   string = xtryasprintf ("%s T %s %s %s%s", keygrip_str,
2313                          serialno? serialno : "-",
2314                          idstr? idstr : "-",
2315                          usage? usage : "-",
2316                          data? "\n" : "");
2317
2318   if (!string)
2319     return;
2320
2321   if (!data)
2322     assuan_write_status (ctx, "KEYINFO", string);
2323   else
2324     assuan_send_data (ctx, string, strlen (string));
2325
2326   xfree (string);
2327   return;
2328 }
2329
2330
2331 static const char hlp_devinfo[] =
2332   "DEVINFO [--watch]\n"
2333   "\n"
2334   "Return information about devices.  If the option --watch is given,\n"
2335   "it keeps reporting status change until it detects no device is\n"
2336   "available.\n"
2337   "The information is returned as a status line using the format:\n"
2338   "\n"
2339   "  DEVICE <card_type> <serialno> <app_type>\n"
2340   "\n"
2341   "CARD_TYPE is the type of the card.\n"
2342   "\n"
2343   "SERIALNO is an ASCII string with the serial number of the\n"
2344   "         smartcard.  If the serial number is not known a single\n"
2345   "         dash '-' is used instead.\n"
2346   "\n"
2347   "APP_TYPE is the type of the application.\n"
2348   "\n"
2349   "More information may be added in the future.";
2350 static gpg_error_t
2351 cmd_devinfo (assuan_context_t ctx, char *line)
2352 {
2353   ctrl_t ctrl = assuan_get_pointer (ctx);
2354   gpg_error_t err = 0;
2355   int watch = 0;
2356   card_t card;
2357
2358   if (has_option (line, "--watch"))
2359     {
2360       watch = 1;
2361       ctrl->server_local->watching_status = 1;
2362     }
2363
2364   /* Firstly, send information of available devices.  */
2365   err = app_send_devinfo (ctrl, 0);
2366
2367   /* If not watching, that's all.  */
2368   if (!watch)
2369     return err;
2370
2371   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
2372     return err;
2373
2374   /* Secondly, try to open device(s) available.  */
2375
2376   /* Clear the remove flag so that the open_card is able to reread it.  */
2377   if (ctrl->server_local->card_removed)
2378     ctrl->server_local->card_removed = 0;
2379
2380   if ((err = open_card (ctrl))
2381       && gpg_err_code (err) != GPG_ERR_ENODEV)
2382     return err;
2383
2384   err = 0;
2385
2386   card = card_get (ctrl, NULL);
2387   if (card)
2388     {
2389       /* If any, remove reference to the card in CTRL.  */
2390       ctrl->card_ctx = NULL;
2391       ctrl->current_apptype = APPTYPE_NONE;
2392       card_unref_locked (card);
2393       card_put (card);
2394     }
2395
2396   /* Then, keep watching the status change.  */
2397   err = app_send_devinfo (ctrl, 1);
2398
2399   ctrl->server_local->watching_status = 0;
2400   return err;
2401 }
2402 \f
2403 /* Return true if the command CMD implements the option OPT.  */
2404 static int
2405 command_has_option (const char *cmd, const char *cmdopt)
2406 {
2407   if (!strcmp (cmd, "SERIALNO"))
2408     {
2409       if (!strcmp (cmdopt, "all"))
2410         return 1;
2411     }
2412
2413   return 0;
2414 }
2415
2416
2417 /* Tell the assuan library about our commands */
2418 static int
2419 register_commands (assuan_context_t ctx)
2420 {
2421   static struct {
2422     const char *name;
2423     assuan_handler_t handler;
2424     const char * const help;
2425   } table[] = {
2426     { "SERIALNO",     cmd_serialno, hlp_serialno },
2427     { "SWITCHCARD",   cmd_switchcard,hlp_switchcard },
2428     { "SWITCHAPP",    cmd_switchapp,hlp_switchapp },
2429     { "LEARN",        cmd_learn,    hlp_learn },
2430     { "READCERT",     cmd_readcert, hlp_readcert },
2431     { "READKEY",      cmd_readkey,  hlp_readkey },
2432     { "SETDATA",      cmd_setdata,  hlp_setdata },
2433     { "PKSIGN",       cmd_pksign,   hlp_pksign },
2434     { "PKAUTH",       cmd_pkauth,   hlp_pkauth },
2435     { "PKDECRYPT",    cmd_pkdecrypt,hlp_pkdecrypt },
2436     { "INPUT",        NULL },
2437     { "OUTPUT",       NULL },
2438     { "GETATTR",      cmd_getattr,  hlp_getattr },
2439     { "SETATTR",      cmd_setattr,  hlp_setattr },
2440     { "WRITECERT",    cmd_writecert,hlp_writecert },
2441     { "WRITEKEY",     cmd_writekey, hlp_writekey },
2442     { "GENKEY",       cmd_genkey,   hlp_genkey },
2443     { "RANDOM",       cmd_random,   hlp_random },
2444     { "PASSWD",       cmd_passwd,   hlp_passwd },
2445     { "CHECKPIN",     cmd_checkpin, hlp_checkpin },
2446     { "LOCK",         cmd_lock,     hlp_lock },
2447     { "UNLOCK",       cmd_unlock,   hlp_unlock },
2448     { "GETINFO",      cmd_getinfo,  hlp_getinfo },
2449     { "RESTART",      cmd_restart,  hlp_restart },
2450     { "DISCONNECT",   cmd_disconnect,hlp_disconnect },
2451     { "APDU",         cmd_apdu,     hlp_apdu },
2452     { "KILLSCD",      cmd_killscd,  hlp_killscd },
2453     { "KEYINFO",      cmd_keyinfo,  hlp_keyinfo },
2454     { "DEVINFO",      cmd_devinfo,  hlp_devinfo },
2455     { NULL }
2456   };
2457   int i, rc;
2458
2459   for (i=0; table[i].name; i++)
2460     {
2461       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2462                                     table[i].help);
2463       if (rc)
2464         return rc;
2465     }
2466   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
2467
2468   assuan_register_reset_notify (ctx, reset_notify);
2469   assuan_register_option_handler (ctx, option_handler);
2470   return 0;
2471 }
2472
2473
2474 /* Startup the server.  If FD is given as -1 this is simple pipe
2475    server, otherwise it is a regular server.  Returns true if there
2476    are no more active asessions.  */
2477 int
2478 scd_command_handler (ctrl_t ctrl, gnupg_fd_t fd)
2479 {
2480   int rc;
2481   assuan_context_t ctx = NULL;
2482   int stopme;
2483
2484   rc = assuan_new (&ctx);
2485   if (rc)
2486     {
2487       log_error ("failed to allocate assuan context: %s\n",
2488                  gpg_strerror (rc));
2489       scd_exit (2);
2490     }
2491
2492   if (fd == GNUPG_INVALID_FD)
2493     {
2494       assuan_fd_t filedes[2];
2495
2496       filedes[0] = assuan_fdopen (0);
2497       filedes[1] = assuan_fdopen (1);
2498       rc = assuan_init_pipe_server (ctx, filedes);
2499     }
2500   else
2501     {
2502       rc = assuan_init_socket_server (ctx, fd,
2503                                       ASSUAN_SOCKET_SERVER_ACCEPTED);
2504     }
2505   if (rc)
2506     {
2507       log_error ("failed to initialize the server: %s\n",
2508                  gpg_strerror(rc));
2509       scd_exit (2);
2510     }
2511   rc = register_commands (ctx);
2512   if (rc)
2513     {
2514       log_error ("failed to register commands with Assuan: %s\n",
2515                  gpg_strerror(rc));
2516       scd_exit (2);
2517     }
2518   assuan_set_pointer (ctx, ctrl);
2519
2520   /* Allocate and initialize the server object.  Put it into the list
2521      of active sessions. */
2522   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2523   ctrl->server_local->next_session = session_list;
2524   session_list = ctrl->server_local;
2525   ctrl->server_local->ctrl_backlink = ctrl;
2526   ctrl->server_local->assuan_ctx = ctx;
2527
2528   /* Command processing loop. */
2529   for (;;)
2530     {
2531       rc = assuan_accept (ctx);
2532       if (rc == -1)
2533         {
2534           break;
2535         }
2536       else if (rc)
2537         {
2538           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2539           break;
2540         }
2541
2542       rc = assuan_process (ctx);
2543       if (rc)
2544         {
2545           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2546           continue;
2547         }
2548     }
2549
2550   /* Cleanup.  We don't send an explicit reset to the card.  */
2551   do_reset (ctrl, 0, 0);
2552
2553   /* Release the server object.  */
2554   if (session_list == ctrl->server_local)
2555     session_list = ctrl->server_local->next_session;
2556   else
2557     {
2558       struct server_local_s *sl;
2559
2560       for (sl=session_list; sl->next_session; sl = sl->next_session)
2561         if (sl->next_session == ctrl->server_local)
2562           break;
2563       if (!sl->next_session)
2564           BUG ();
2565       sl->next_session = ctrl->server_local->next_session;
2566     }
2567   stopme = ctrl->server_local->stopme;
2568   xfree (ctrl->server_local);
2569   ctrl->server_local = NULL;
2570
2571   /* Release the Assuan context.  */
2572   assuan_release (ctx);
2573
2574   if (stopme)
2575     scd_exit (0);
2576
2577   /* If there are no more sessions return true.  */
2578   return !session_list;
2579 }
2580
2581
2582 /* Send a line with status information via assuan and escape all given
2583    buffers. The variable elements are pairs of (char *, size_t),
2584    terminated with a (NULL, 0). */
2585 void
2586 send_status_info (ctrl_t ctrl, const char *keyword, ...)
2587 {
2588   va_list arg_ptr;
2589   const unsigned char *value;
2590   size_t valuelen;
2591   char buf[950], *p;
2592   size_t n;
2593   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2594
2595   va_start (arg_ptr, keyword);
2596
2597   p = buf;
2598   n = 0;
2599   while ( (value = va_arg (arg_ptr, const unsigned char *))
2600            && n < DIM (buf)-2 )
2601     {
2602       valuelen = va_arg (arg_ptr, size_t);
2603       if (!valuelen)
2604         continue; /* empty buffer */
2605       if (n)
2606         {
2607           *p++ = ' ';
2608           n++;
2609         }
2610       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2611         {
2612           if (*value == '+' || *value == '\"' || *value == '%'
2613               || *value < ' ')
2614             {
2615               sprintf (p, "%%%02X", *value);
2616               p += 3;
2617               n += 2;
2618             }
2619           else if (*value == ' ')
2620             *p++ = '+';
2621           else
2622             *p++ = *value;
2623         }
2624     }
2625   *p = 0;
2626   assuan_write_status (ctx, keyword, buf);
2627
2628   va_end (arg_ptr);
2629 }
2630
2631
2632 /* Send a ready formatted status line via assuan.  */
2633 gpg_error_t
2634 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2635 {
2636   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2637
2638   if (strchr (args, '\n'))
2639     {
2640       log_error ("error: LF detected in status line - not sending\n");
2641       return gpg_error (GPG_ERR_INTERNAL);
2642     }
2643   return assuan_write_status (ctx, keyword, args);
2644 }
2645
2646
2647 /* This status functions expects a printf style format string.  No
2648  * filtering of the data is done instead the printf formatted data is
2649  * send using assuan_send_status. */
2650 gpg_error_t
2651 send_status_printf (ctrl_t ctrl, const char *keyword, const char *format, ...)
2652 {
2653   gpg_error_t err;
2654   va_list arg_ptr;
2655   assuan_context_t ctx;
2656
2657   if (!ctrl || !ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
2658     return 0;
2659
2660   va_start (arg_ptr, format);
2661   err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
2662   va_end (arg_ptr);
2663   return err;
2664 }
2665
2666
2667 /* Set a gcrypt key for use with the pincache.  The key is a random
2668  * key unique for this process and is useless after this process has
2669  * terminated.  This way the cached PINs stored in the gpg-agent are
2670  * bound to this specific process.  The main purpose of this
2671  * encryption is to hide the PIN in logs of the IPC.  */
2672 static gpg_error_t
2673 set_key_for_pincache (gcry_cipher_hd_t hd)
2674 {
2675   static int initialized;
2676   static unsigned char keybuf[16];
2677
2678   if (!initialized)
2679     {
2680       gcry_randomize (keybuf, sizeof keybuf, GCRY_STRONG_RANDOM);
2681       initialized = 1;
2682     }
2683
2684   return gcry_cipher_setkey (hd, keybuf, sizeof keybuf);
2685 }
2686
2687
2688 /* Store the PIN in the PIN cache. The key to identify the PIN
2689  * consists of (SLOT,APPNAME,PINREF).  If PIN is NULL the PIN stored
2690  * under the given key is cleared.  If APPNAME and PINREF are NULL the
2691  * entire PIN cache for SLOT is cleared.  If SLOT is -1 the entire PIN
2692  * cache is cleared.  We do no use an scdaemon internal cache but let
2693  * gpg-agent cache it because it is better suited for this.  */
2694 void
2695 pincache_put (ctrl_t ctrl, int slot, const char *appname, const char *pinref,
2696               const char *pin, unsigned int pinlen)
2697 {
2698   gpg_error_t err = 0;
2699   assuan_context_t ctx;
2700   char line[950];
2701   gcry_cipher_hd_t cipherhd = NULL;
2702   char *pinbuf = NULL;
2703   unsigned char *wrappedkey = NULL;
2704   size_t pinbuflen, wrappedkeylen;
2705
2706   if (!ctrl)
2707     {
2708       /* No CTRL object provided.  We could pick an arbitrary
2709        * connection and send the status to that one.  However, such a
2710        * connection is inlikley to wait for a respinse from use and
2711        * thus it would at best be read as a response to the next
2712        * command send to us.  That is not good because it may clog up
2713        * our connection.  Thus we better don't do that.  A better will
2714        * be to queue this up and let the agent poll for general status
2715        * messages.  */
2716       /* struct server_local_s *sl; */
2717       /* for (sl=session_list; sl; sl = sl->next_session) */
2718       /*   if (sl->ctrl_backlink && sl->ctrl_backlink->server_local */
2719       /*       && sl->ctrl_backlink->server_local->assuan_ctx) */
2720       /*     { */
2721       /*       ctrl = sl->ctrl_backlink; */
2722       /*       break; */
2723       /*     } */
2724     }
2725
2726   if (!ctrl || !ctrl->server_local || !(ctx=ctrl->server_local->assuan_ctx))
2727     return;
2728   if (pin && !pinlen)
2729     return;  /* Ignore an empty PIN.  */
2730
2731   snprintf (line, sizeof line, "%d/%s/%s ",
2732             slot, appname? appname:"", pinref? pinref:"");
2733
2734   /* Without an APPNAME etc or without a PIN we clear the cache and
2735    * thus there is no need to send the pin - even if the caller
2736    * accidentally passed a pin.  */
2737   if (pin && slot != -1 && appname && pinref)
2738     {
2739       /* FIXME: Replace this by OCB mode and use the cache key as
2740        * additional data.  */
2741       /* Pad with zeroes (AESWRAP requires multiples of 64 bit but
2742        * at least 128 bit data).  */
2743       pinbuflen = pinlen + 8 - (pinlen % 8);
2744       if (pinbuflen < 16)
2745         pinbuflen = 16;
2746       pinbuf = xtrycalloc_secure (1, pinbuflen);
2747       if (!pinbuf)
2748         {
2749           err = gpg_error_from_syserror ();
2750           goto leave;
2751         }
2752       memcpy (pinbuf, pin, pinlen);
2753       pinlen = pinbuflen;
2754       pin = pinbuf;
2755
2756       err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2757                               GCRY_CIPHER_MODE_AESWRAP, 0);
2758       if (!err)
2759         err = set_key_for_pincache (cipherhd);
2760       if (err)
2761         goto leave;
2762
2763       wrappedkeylen = pinlen + 8;
2764       wrappedkey = xtrymalloc (wrappedkeylen);
2765       if (!wrappedkey)
2766         {
2767           err = gpg_error_from_syserror ();
2768           goto leave;
2769         }
2770
2771       err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen,
2772                                  pin, pinlen);
2773       if (err)
2774         goto leave;
2775       gcry_cipher_close (cipherhd);
2776       cipherhd = NULL;
2777       if (strlen (line) + 2*wrappedkeylen + 1 >= sizeof line)
2778         {
2779           log_error ("%s: PIN or pinref string too long - ignored", __func__);
2780           goto leave;
2781         }
2782       bin2hex (wrappedkey, wrappedkeylen, line + strlen (line));
2783     }
2784
2785   send_status_direct (ctrl, "PINCACHE_PUT", line);
2786
2787  leave:
2788   xfree (pinbuf);
2789   xfree (wrappedkey);
2790   gcry_cipher_close (cipherhd);
2791   if (err)
2792     log_error ("%s: error caching PIN: %s\n", __func__, gpg_strerror (err));
2793 }
2794
2795
2796 /* Ask the agent for a cached PIN for the tuple (SLOT,APPNAME,PINREF).
2797  * Returns on success and stores the PIN at R_PIN; the caller needs to
2798  * wipe(!)  and then free that value.  On error NULL is stored at
2799  * R_PIN and an error code returned.  Common error codes are:
2800  *  GPG_ERR_NOT_SUPPORTED - Client does not support the PIN cache
2801  *  GPG_ERR_NO_DATA       - No PIN cached for the given key tuple
2802  */
2803 gpg_error_t
2804 pincache_get (ctrl_t ctrl, int slot, const char *appname, const char *pinref,
2805               char **r_pin)
2806 {
2807   gpg_error_t err;
2808   assuan_context_t ctx;
2809   char command[512];
2810   unsigned char *value = NULL;
2811   size_t valuelen;
2812   unsigned char *wrappedkey = NULL;
2813   size_t wrappedkeylen;
2814   gcry_cipher_hd_t cipherhd = NULL;
2815
2816   if (slot == -1 || !appname || !pinref || !r_pin)
2817     {
2818       err = gpg_error (GPG_ERR_INV_ARG);
2819       goto leave;
2820     }
2821   if (!ctrl || !ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
2822     {
2823       err = gpg_error (GPG_ERR_USE_CONDITIONS);
2824       log_error ("%s: called w/o assuan context\n", __func__);
2825       goto leave;
2826     }
2827
2828   snprintf (command, sizeof command, "PINCACHE_GET %d/%s/%s",
2829             slot, appname? appname:"", pinref? pinref:"");
2830
2831   /* Limit the inquire to something reasonable.  The 32 extra bytes
2832    * are a guessed size for padding etc.  */
2833   err = assuan_inquire (ctx, command, &wrappedkey, &wrappedkeylen,
2834                         2*MAXLEN_PIN+32);
2835   if (gpg_err_code (err) == GPG_ERR_ASS_CANCELED)
2836     {
2837       err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2838       log_info ("caller does not feature a PIN cache");
2839       goto leave;
2840     }
2841   if (err)
2842     {
2843       log_error ("%s: sending PINCACHE_GET to caller failed: %s\n",
2844                  __func__, gpg_strerror (err));
2845       goto leave;
2846     }
2847   if (!wrappedkey || !wrappedkeylen)
2848     {
2849       err = gpg_error (GPG_ERR_NOT_FOUND);
2850       goto leave;
2851     }
2852
2853   /* Convert to hex to binary and store it in (wrappedkey, wrappedkeylen).  */
2854   if (!hex2str (wrappedkey, wrappedkey, wrappedkeylen, &wrappedkeylen))
2855     {
2856       err = gpg_error_from_syserror ();
2857       log_error ("%s: caller returned invalid hex string: %s\n",
2858                  __func__, gpg_strerror (err));
2859       goto leave;
2860     }
2861
2862   if (!wrappedkey || wrappedkeylen < 24)
2863     {
2864       err = gpg_error (GPG_ERR_INV_LENGTH); /* too short cryptogram */
2865       goto leave;
2866     }
2867
2868   valuelen = wrappedkeylen - 8;
2869   value = xtrymalloc_secure (valuelen);
2870   if (!value)
2871     {
2872       err = gpg_error_from_syserror ();
2873       goto leave;
2874     }
2875
2876   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2877                           GCRY_CIPHER_MODE_AESWRAP, 0);
2878   if (!err)
2879     err = set_key_for_pincache (cipherhd);
2880   if (err)
2881     goto leave;
2882
2883   err = gcry_cipher_decrypt (cipherhd, value, valuelen,
2884                              wrappedkey, wrappedkeylen);
2885   if (err)
2886     {
2887       log_error ("%s: cached value could not be decrypted: %s\n",
2888                  __func__, gpg_strerror (err));
2889       goto leave;
2890     }
2891
2892   *r_pin = value;
2893   value = NULL;
2894
2895  leave:
2896   gcry_cipher_close (cipherhd);
2897   xfree (wrappedkey);
2898   xfree (value);
2899   return err;
2900 }
2901
2902
2903 void
2904 popup_prompt (void *opaque, int on)
2905 {
2906   ctrl_t ctrl = opaque;
2907
2908   if (ctrl)
2909     {
2910       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2911
2912       if (ctx)
2913         {
2914           const char *cmd;
2915           gpg_error_t err;
2916           unsigned char *value;
2917           size_t valuelen;
2918
2919           if (on)
2920             cmd = "POPUPPINPADPROMPT --ack";
2921           else
2922             cmd = "DISMISSPINPADPROMPT";
2923           err = assuan_inquire (ctx, cmd, &value, &valuelen, 100);
2924           if (!err)
2925             xfree (value);
2926         }
2927     }
2928 }
2929
2930
2931 /*
2932  * Helper to send the clients a status change notification.
2933  *
2934  * When it's removal of card, this function also clean up all
2935  * references by ctrl->card_ctx of all sessions.
2936  *
2937  * Note that this function assumes that all accesses to cards and
2938  * applications are locked.  By the mrsw-lock, it is guaranteed that
2939  * no card/app is accessed, when this function is called..
2940  */
2941 void
2942 send_client_notifications (card_t card, int removal)
2943 {
2944   struct {
2945     pid_t pid;
2946 #ifdef HAVE_W32_SYSTEM
2947     HANDLE handle;
2948 #else
2949     int signo;
2950 #endif
2951   } killed[50];
2952   int killidx = 0;
2953   int kidx;
2954   struct server_local_s *sl;
2955
2956   for (sl=session_list; sl; sl = sl->next_session)
2957     {
2958       if (sl->watching_status)
2959         {
2960           if (removal)
2961             assuan_write_status (sl->assuan_ctx, "DEVINFO_STATUS", "removal");
2962           else
2963             assuan_write_status (sl->assuan_ctx, "DEVINFO_STATUS", "new");
2964         }
2965
2966       if (sl->ctrl_backlink && sl->ctrl_backlink->card_ctx == card)
2967         {
2968           pid_t pid;
2969 #ifdef HAVE_W32_SYSTEM
2970           HANDLE handle;
2971 #else
2972           int signo;
2973 #endif
2974
2975           if (removal)
2976             {
2977               sl->ctrl_backlink->card_ctx = NULL;
2978               sl->ctrl_backlink->current_apptype = APPTYPE_NONE;
2979               sl->card_removed = 1;
2980               card_unref_locked (card);
2981             }
2982
2983           if (!sl->event_signal || !sl->assuan_ctx)
2984             continue;
2985
2986           pid = assuan_get_pid (sl->assuan_ctx);
2987
2988 #ifdef HAVE_W32_SYSTEM
2989           handle = sl->event_signal;
2990           for (kidx=0; kidx < killidx; kidx++)
2991             if (killed[kidx].pid == pid
2992                 && killed[kidx].handle == handle)
2993               break;
2994           if (kidx < killidx)
2995             log_info ("event %p (%p) already triggered for client %d\n",
2996                       sl->event_signal, handle, (int)pid);
2997           else
2998             {
2999               log_info ("triggering event %p (%p) for client %d\n",
3000                         sl->event_signal, handle, (int)pid);
3001               if (!SetEvent (handle))
3002                 log_error ("SetEvent(%p) failed: %s\n",
3003                            sl->event_signal, w32_strerror (-1));
3004               if (killidx < DIM (killed))
3005                 {
3006                   killed[killidx].pid = pid;
3007                   killed[killidx].handle = handle;
3008                   killidx++;
3009                 }
3010             }
3011 #else /*!HAVE_W32_SYSTEM*/
3012           signo = sl->event_signal;
3013
3014           if (pid != (pid_t)(-1) && pid && signo > 0)
3015             {
3016               for (kidx=0; kidx < killidx; kidx++)
3017                 if (killed[kidx].pid == pid
3018                     && killed[kidx].signo == signo)
3019                   break;
3020               if (kidx < killidx)
3021                 log_info ("signal %d already sent to client %d\n",
3022                           signo, (int)pid);
3023               else
3024                 {
3025                   log_info ("sending signal %d to client %d\n",
3026                             signo, (int)pid);
3027                   kill (pid, signo);
3028                   if (killidx < DIM (killed))
3029                     {
3030                       killed[killidx].pid = pid;
3031                       killed[killidx].signo = signo;
3032                       killidx++;
3033                     }
3034                 }
3035             }
3036 #endif /*!HAVE_W32_SYSTEM*/
3037         }
3038     }
3039 }