Imported Upstream version 2.1.20
[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 "app-common.h"
37 #include "iso7816.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
39 #include "atr.h"
40 #ifdef HAVE_LIBUSB
41 #include "ccid-driver.h"
42 #endif
43 #include "../common/asshelp.h"
44 #include "../common/server-help.h"
45
46 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
47 #define MAXLEN_PIN 100
48
49 /* Maximum allowed size of key data as used in inquiries. */
50 #define MAXLEN_KEYDATA 4096
51
52 /* Maximum allowed total data size for SETDATA.  */
53 #define MAXLEN_SETDATA 4096
54
55 /* Maximum allowed size of certificate data as used in inquiries. */
56 #define MAXLEN_CERTDATA 16384
57
58
59 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
60
61 #define IS_LOCKED(c) (locked_session && locked_session != (c)->server_local)
62
63
64 /* Data used to associate an Assuan context with local server data.
65    This object describes the local properties of one session.  */
66 struct server_local_s
67 {
68   /* We keep a list of all active sessions with the anchor at
69      SESSION_LIST (see below).  This field is used for linking. */
70   struct server_local_s *next_session;
71
72   /* This object is usually assigned to a CTRL object (which is
73      globally visible).  While enumerating all sessions we sometimes
74      need to access data of the CTRL object; thus we keep a
75      backpointer here. */
76   ctrl_t ctrl_backlink;
77
78   /* The Assuan context used by this session/server. */
79   assuan_context_t assuan_ctx;
80
81 #ifdef HAVE_W32_SYSTEM
82   unsigned long event_signal;   /* Or 0 if not used. */
83 #else
84   int event_signal;             /* Or 0 if not used. */
85 #endif
86
87   /* True if the card has been removed and a reset is required to
88      continue operation. */
89   int card_removed;
90
91   /* If set to true we will be terminate ourself at the end of the
92      this session.  */
93   int stopme;
94
95 };
96
97
98 /* To keep track of all running sessions, we link all active server
99    contexts and the anchor in this variable.  */
100 static struct server_local_s *session_list;
101
102 /* If a session has been locked we store a link to its server object
103    in this variable. */
104 static struct server_local_s *locked_session;
105
106 \f
107 /* Convert the STRING into a newly allocated buffer while translating
108    the hex numbers.  Stops at the first invalid character.  Blanks and
109    colons are allowed to separate the hex digits.  Returns NULL on
110    error or a newly malloced buffer and its length in LENGTH.  */
111 static unsigned char *
112 hex_to_buffer (const char *string, size_t *r_length)
113 {
114   unsigned char *buffer;
115   const char *s;
116   size_t n;
117
118   buffer = xtrymalloc (strlen (string)+1);
119   if (!buffer)
120     return NULL;
121   for (s=string, n=0; *s; s++)
122     {
123       if (spacep (s) || *s == ':')
124         continue;
125       if (hexdigitp (s) && hexdigitp (s+1))
126         {
127           buffer[n++] = xtoi_2 (s);
128           s++;
129         }
130       else
131         break;
132     }
133   *r_length = n;
134   return buffer;
135 }
136
137
138
139 /* Reset the card and free the application context.  With SEND_RESET
140    set to true actually send a RESET to the reader; this is the normal
141    way of calling the function.  */
142 static void
143 do_reset (ctrl_t ctrl, int send_reset)
144 {
145   app_t app = ctrl->app_ctx;
146
147   if (app)
148     app_reset (app, ctrl, IS_LOCKED (ctrl)? 0: send_reset);
149
150   /* If we hold a lock, unlock now. */
151   if (locked_session && ctrl->server_local == locked_session)
152     {
153       locked_session = NULL;
154       log_info ("implicitly unlocking due to RESET\n");
155     }
156 }
157 \f
158 static gpg_error_t
159 reset_notify (assuan_context_t ctx, char *line)
160 {
161   ctrl_t ctrl = assuan_get_pointer (ctx);
162
163   (void) line;
164
165   do_reset (ctrl, 1);
166   return 0;
167 }
168
169
170 static gpg_error_t
171 option_handler (assuan_context_t ctx, const char *key, const char *value)
172 {
173   ctrl_t ctrl = assuan_get_pointer (ctx);
174
175   if (!strcmp (key, "event-signal"))
176     {
177       /* A value of 0 is allowed to reset the event signal. */
178 #ifdef HAVE_W32_SYSTEM
179       if (!*value)
180         return gpg_error (GPG_ERR_ASS_PARAMETER);
181       ctrl->server_local->event_signal = strtoul (value, NULL, 16);
182 #else
183       int i = *value? atoi (value) : -1;
184       if (i < 0)
185         return gpg_error (GPG_ERR_ASS_PARAMETER);
186       ctrl->server_local->event_signal = i;
187 #endif
188     }
189
190  return 0;
191 }
192
193
194 /* If the card has not yet been opened, do it.  */
195 static gpg_error_t
196 open_card (ctrl_t ctrl)
197 {
198   /* If we ever got a card not present error code, return that.  Only
199      the SERIALNO command and a reset are able to clear from that
200      state. */
201   if (ctrl->server_local->card_removed)
202     return gpg_error (GPG_ERR_CARD_REMOVED);
203
204   if ( IS_LOCKED (ctrl) )
205     return gpg_error (GPG_ERR_LOCKED);
206
207   if (ctrl->app_ctx)
208     return 0;
209
210   return select_application (ctrl, NULL, &ctrl->app_ctx, 0, NULL, 0);
211 }
212
213 /* Explicitly open a card for a specific use of APPTYPE or SERIALNO.  */
214 static gpg_error_t
215 open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
216 {
217   gpg_error_t err;
218   unsigned char *serialno_bin = NULL;
219   size_t serialno_bin_len = 0;
220   app_t app = ctrl->app_ctx;
221
222   /* If we are already initialized for one specific application we
223      need to check that the client didn't requested a specific
224      application different from the one in use before we continue. */
225   if (apptype && ctrl->app_ctx)
226     return check_application_conflict (apptype, ctrl->app_ctx);
227
228   /* Re-scan USB devices.  Release APP, before the scan.  */
229   ctrl->app_ctx = NULL;
230   release_application (app, 0);
231
232   if (serialno)
233     serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
234
235   err = select_application (ctrl, apptype, &ctrl->app_ctx, 1,
236                             serialno_bin, serialno_bin_len);
237   xfree (serialno_bin);
238
239   return err;
240 }
241
242
243 static const char hlp_serialno[] =
244   "SERIALNO [--demand=<serialno>] [<apptype>]\n"
245   "\n"
246   "Return the serial number of the card using a status response.  This\n"
247   "function should be used to check for the presence of a card.\n"
248   "\n"
249   "If --demand is given, an application on the card with SERIALNO is\n"
250   "selected and an error is returned if no such card available.\n"
251   "\n"
252   "If APPTYPE is given, an application of that type is selected and an\n"
253   "error is returned if the application is not supported or available.\n"
254   "The default is to auto-select the application using a hardwired\n"
255   "preference system.  Note, that a future extension to this function\n"
256   "may enable specifying a list and order of applications to try.\n"
257   "\n"
258   "This function is special in that it can be used to reset the card.\n"
259   "Most other functions will return an error when a card change has\n"
260   "been detected and the use of this function is therefore required.\n"
261   "\n"
262   "Background: We want to keep the client clear of handling card\n"
263   "changes between operations; i.e. the client can assume that all\n"
264   "operations are done on the same card unless he calls this function.";
265 static gpg_error_t
266 cmd_serialno (assuan_context_t ctx, char *line)
267 {
268   ctrl_t ctrl = assuan_get_pointer (ctx);
269   struct server_local_s *sl;
270   int rc = 0;
271   char *serial;
272   const char *demand;
273
274   if ( IS_LOCKED (ctrl) )
275     return gpg_error (GPG_ERR_LOCKED);
276
277   if ((demand = has_option_name (line, "--demand")))
278     {
279       if (*demand != '=')
280         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
281       line = (char *)++demand;
282       for (; *line && !spacep (line); line++)
283         ;
284       if (*line)
285         *line++ = 0;
286     }
287   else
288     demand = NULL;
289
290   /* Clear the remove flag so that the open_card is able to reread it.  */
291   if (ctrl->server_local->card_removed)
292     ctrl->server_local->card_removed = 0;
293
294   if ((rc = open_card_with_request (ctrl, *line? line:NULL, demand)))
295     {
296       ctrl->server_local->card_removed = 1;
297       return rc;
298     }
299
300   /* Success, clear the card_removed flag for all sessions.  */
301   for (sl=session_list; sl; sl = sl->next_session)
302     {
303       ctrl_t c = sl->ctrl_backlink;
304
305       if (c != ctrl)
306         c->server_local->card_removed = 0;
307     }
308
309   serial = app_get_serialno (ctrl->app_ctx);
310   if (!serial)
311     return gpg_error (GPG_ERR_INV_VALUE);
312
313   rc = assuan_write_status (ctx, "SERIALNO", serial);
314   xfree (serial);
315   return rc;
316 }
317
318
319 static const char hlp_learn[] =
320   "LEARN [--force] [--keypairinfo]\n"
321   "\n"
322   "Learn all useful information of the currently inserted card.  When\n"
323   "used without the force options, the command might do an INQUIRE\n"
324   "like this:\n"
325   "\n"
326   "   INQUIRE KNOWNCARDP <hexstring_with_serialNumber>\n"
327   "\n"
328   "The client should just send an \"END\" if the processing should go on\n"
329   "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
330   "error message.\n"
331   "\n"
332   "With the option --keypairinfo only KEYPARIINFO lstatus lines are\n"
333   "returned.\n"
334   "\n"
335   "The response of this command is a list of status lines formatted as\n"
336   "this:\n"
337   "\n"
338   "  S APPTYPE <apptype>\n"
339   "\n"
340   "This returns the type of the application, currently the strings:\n"
341   "\n"
342   "    P15     = PKCS-15 structure used\n"
343   "    DINSIG  = DIN SIG\n"
344   "    OPENPGP = OpenPGP card\n"
345   "    NKS     = NetKey card\n"
346   "\n"
347   "are implemented.  These strings are aliases for the AID\n"
348   "\n"
349   "  S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>\n"
350   "\n"
351   "If there is no certificate yet stored on the card a single 'X' is\n"
352   "returned as the keygrip.  In addition to the keypair info, information\n"
353   "about all certificates stored on the card is also returned:\n"
354   "\n"
355   "  S CERTINFO <certtype> <hexstring_with_id>\n"
356   "\n"
357   "Where CERTTYPE is a number indicating the type of certificate:\n"
358   "   0   := Unknown\n"
359   "   100 := Regular X.509 cert\n"
360   "   101 := Trusted X.509 cert\n"
361   "   102 := Useful X.509 cert\n"
362   "   110 := Root CA cert in a special format (e.g. DINSIG)\n"
363   "   111 := Root CA cert as standard X509 cert.\n"
364   "\n"
365   "For certain cards, more information will be returned:\n"
366   "\n"
367   "  S KEY-FPR <no> <hexstring>\n"
368   "\n"
369   "For OpenPGP cards this returns the stored fingerprints of the\n"
370   "keys. This can be used check whether a key is available on the\n"
371   "card.  NO may be 1, 2 or 3.\n"
372   "\n"
373   "  S CA-FPR <no> <hexstring>\n"
374   "\n"
375   "Similar to above, these are the fingerprints of keys assumed to be\n"
376   "ultimately trusted.\n"
377   "\n"
378   "  S DISP-NAME <name_of_card_holder>\n"
379   "\n"
380   "The name of the card holder as stored on the card; percent\n"
381   "escaping takes place, spaces are encoded as '+'\n"
382   "\n"
383   "  S PUBKEY-URL <url>\n"
384   "\n"
385   "The URL to be used for locating the entire public key.\n"
386   "  \n"
387   "Note, that this function may even be used on a locked card.";
388 static gpg_error_t
389 cmd_learn (assuan_context_t ctx, char *line)
390 {
391   ctrl_t ctrl = assuan_get_pointer (ctx);
392   int rc = 0;
393   int only_keypairinfo = has_option (line, "--keypairinfo");
394
395   if ((rc = open_card (ctrl)))
396     return rc;
397
398   /* Unless the force option is used we try a shortcut by identifying
399      the card using a serial number and inquiring the client with
400      that. The client may choose to cancel the operation if he already
401      knows about this card */
402   if (!only_keypairinfo)
403     {
404       const char *reader;
405       char *serial;
406       app_t app = ctrl->app_ctx;
407
408       if (!app)
409         return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
410
411       reader = apdu_get_reader_name (app->slot);
412       if (!reader)
413         return out_of_core ();
414       send_status_direct (ctrl, "READER", reader);
415       /* No need to free the string of READER.  */
416
417       serial = app_get_serialno (ctrl->app_ctx);
418       if (!serial)
419         return gpg_error (GPG_ERR_INV_VALUE);
420
421       rc = assuan_write_status (ctx, "SERIALNO", serial);
422       if (rc < 0)
423         {
424           xfree (serial);
425           return out_of_core ();
426         }
427
428       if (!has_option (line, "--force"))
429         {
430           char *command;
431
432           rc = gpgrt_asprintf (&command, "KNOWNCARDP %s", serial);
433           if (rc < 0)
434             {
435               xfree (serial);
436               return out_of_core ();
437             }
438           rc = assuan_inquire (ctx, command, NULL, NULL, 0);
439           xfree (command);
440           if (rc)
441             {
442               if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
443                 log_error ("inquire KNOWNCARDP failed: %s\n",
444                            gpg_strerror (rc));
445               xfree (serial);
446               return rc;
447             }
448           /* Not canceled, so we have to proceeed.  */
449         }
450       xfree (serial);
451     }
452
453   /* Let the application print out its collection of useful status
454      information. */
455   if (!rc)
456     rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
457
458   return rc;
459 }
460
461
462 \f
463 static const char hlp_readcert[] =
464   "READCERT <hexified_certid>|<keyid>\n"
465   "\n"
466   "Note, that this function may even be used on a locked card.";
467 static gpg_error_t
468 cmd_readcert (assuan_context_t ctx, char *line)
469 {
470   ctrl_t ctrl = assuan_get_pointer (ctx);
471   int rc;
472   unsigned char *cert;
473   size_t ncert;
474
475   if ((rc = open_card (ctrl)))
476     return rc;
477
478   line = xstrdup (line); /* Need a copy of the line. */
479   rc = app_readcert (ctrl->app_ctx, ctrl, line, &cert, &ncert);
480   if (rc)
481     log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
482   xfree (line);
483   line = NULL;
484   if (!rc)
485     {
486       rc = assuan_send_data (ctx, cert, ncert);
487       xfree (cert);
488       if (rc)
489         return rc;
490     }
491
492   return rc;
493 }
494
495
496 static const char hlp_readkey[] =
497   "READKEY [--advanced] <keyid>\n"
498   "\n"
499   "Return the public key for the given cert or key ID as a standard\n"
500   "S-expression.\n"
501   "In --advanced mode it returns the S-expression in advanced format.\n"
502   "\n"
503   "Note that this function may even be used on a locked card.";
504 static gpg_error_t
505 cmd_readkey (assuan_context_t ctx, char *line)
506 {
507   ctrl_t ctrl = assuan_get_pointer (ctx);
508   int rc;
509   int advanced = 0;
510   unsigned char *cert = NULL;
511   size_t ncert, n;
512   ksba_cert_t kc = NULL;
513   ksba_sexp_t p;
514   unsigned char *pk;
515   size_t pklen;
516
517   if ((rc = open_card (ctrl)))
518     return rc;
519
520   if (has_option (line, "--advanced"))
521     advanced = 1;
522
523   line = skip_options (line);
524
525   line = xstrdup (line); /* Need a copy of the line. */
526   /* If the application supports the READKEY function we use that.
527      Otherwise we use the old way by extracting it from the
528      certificate.  */
529   rc = app_readkey (ctrl->app_ctx, ctrl, advanced, line, &pk, &pklen);
530   if (!rc)
531     { /* Yeah, got that key - send it back.  */
532       rc = assuan_send_data (ctx, pk, pklen);
533       xfree (pk);
534       xfree (line);
535       line = NULL;
536       goto leave;
537     }
538
539   if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
540     log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
541   else
542     {
543       rc = app_readcert (ctrl->app_ctx, ctrl, line, &cert, &ncert);
544       if (rc)
545         log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
546     }
547   xfree (line);
548   line = NULL;
549   if (rc)
550     goto leave;
551
552   rc = ksba_cert_new (&kc);
553   if (rc)
554     goto leave;
555
556   rc = ksba_cert_init_from_mem (kc, cert, ncert);
557   if (rc)
558     {
559       log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
560       goto leave;
561     }
562
563   p = ksba_cert_get_public_key (kc);
564   if (!p)
565     {
566       rc = gpg_error (GPG_ERR_NO_PUBKEY);
567       goto leave;
568     }
569
570   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
571   rc = assuan_send_data (ctx, p, n);
572   xfree (p);
573
574
575  leave:
576   ksba_cert_release (kc);
577   xfree (cert);
578   return rc;
579 }
580
581
582 \f
583 static const char hlp_setdata[] =
584   "SETDATA [--append] <hexstring>\n"
585   "\n"
586   "The client should use this command to tell us the data he want to sign.\n"
587   "With the option --append, the data is appended to the data set by a\n"
588   "previous SETDATA command.";
589 static gpg_error_t
590 cmd_setdata (assuan_context_t ctx, char *line)
591 {
592   ctrl_t ctrl = assuan_get_pointer (ctx);
593   int append;
594   int n, i, off;
595   char *p;
596   unsigned char *buf;
597
598   append = (ctrl->in_data.value && has_option (line, "--append"));
599
600   line = skip_options (line);
601
602   if (locked_session && locked_session != ctrl->server_local)
603     return gpg_error (GPG_ERR_LOCKED);
604
605   /* Parse the hexstring. */
606   for (p=line,n=0; hexdigitp (p); p++, n++)
607     ;
608   if (*p)
609     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
610   if (!n)
611     return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
612   if ((n&1))
613     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
614   n /= 2;
615   if (append)
616     {
617       if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
618         return set_error (GPG_ERR_TOO_LARGE,
619                           "limit on total size of data reached");
620       buf = xtrymalloc (ctrl->in_data.valuelen + n);
621     }
622   else
623     buf = xtrymalloc (n);
624   if (!buf)
625     return out_of_core ();
626
627   if (append)
628     {
629       memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
630       off = ctrl->in_data.valuelen;
631     }
632   else
633     off = 0;
634   for (p=line, i=0; i < n; p += 2, i++)
635     buf[off+i] = xtoi_2 (p);
636
637   xfree (ctrl->in_data.value);
638   ctrl->in_data.value = buf;
639   ctrl->in_data.valuelen = off+n;
640   return 0;
641 }
642
643
644
645 static gpg_error_t
646 pin_cb (void *opaque, const char *info, char **retstr)
647 {
648   assuan_context_t ctx = opaque;
649   char *command;
650   int rc;
651   unsigned char *value;
652   size_t valuelen;
653
654   if (!retstr)
655     {
656       /* We prompt for pinpad entry.  To make sure that the popup has
657          been show we use an inquire and not just a status message.
658          We ignore any value returned.  */
659       if (info)
660         {
661           log_debug ("prompting for pinpad entry '%s'\n", info);
662           rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
663           if (rc < 0)
664             return gpg_error (gpg_err_code_from_errno (errno));
665           rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
666           xfree (command);
667         }
668       else
669         {
670           log_debug ("dismiss pinpad entry prompt\n");
671           rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT",
672                                &value, &valuelen, MAXLEN_PIN);
673         }
674       if (!rc)
675         xfree (value);
676       return rc;
677     }
678
679   *retstr = NULL;
680   log_debug ("asking for PIN '%s'\n", info);
681
682   rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
683   if (rc < 0)
684     return gpg_error (gpg_err_code_from_errno (errno));
685
686   /* Fixme: Write an inquire function which returns the result in
687      secure memory and check all further handling of the PIN. */
688   rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
689   xfree (command);
690   if (rc)
691     return rc;
692
693   if (!valuelen || value[valuelen-1])
694     {
695       /* We require that the returned value is an UTF-8 string */
696       xfree (value);
697       return gpg_error (GPG_ERR_INV_RESPONSE);
698     }
699   *retstr = (char*)value;
700   return 0;
701 }
702
703
704 static const char hlp_pksign[] =
705   "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>\n"
706   "\n"
707   "The --hash option is optional; the default is SHA1.";
708 static gpg_error_t
709 cmd_pksign (assuan_context_t ctx, char *line)
710 {
711   ctrl_t ctrl = assuan_get_pointer (ctx);
712   int rc;
713   unsigned char *outdata;
714   size_t outdatalen;
715   char *keyidstr;
716   int hash_algo;
717
718   if (has_option (line, "--hash=rmd160"))
719     hash_algo = GCRY_MD_RMD160;
720   else if (has_option (line, "--hash=sha1"))
721     hash_algo = GCRY_MD_SHA1;
722   else if (has_option (line, "--hash=sha224"))
723     hash_algo = GCRY_MD_SHA224;
724   else if (has_option (line, "--hash=sha256"))
725     hash_algo = GCRY_MD_SHA256;
726   else if (has_option (line, "--hash=sha384"))
727     hash_algo = GCRY_MD_SHA384;
728   else if (has_option (line, "--hash=sha512"))
729     hash_algo = GCRY_MD_SHA512;
730   else if (has_option (line, "--hash=md5"))
731     hash_algo = GCRY_MD_MD5;
732   else if (!strstr (line, "--"))
733     hash_algo = GCRY_MD_SHA1;
734   else
735     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
736
737   line = skip_options (line);
738
739   if ((rc = open_card (ctrl)))
740     return rc;
741
742   /* We have to use a copy of the key ID because the function may use
743      the pin_cb which in turn uses the assuan line buffer and thus
744      overwriting the original line with the keyid */
745   keyidstr = xtrystrdup (line);
746   if (!keyidstr)
747     return out_of_core ();
748
749   rc = app_sign (ctrl->app_ctx, ctrl,
750                  keyidstr, hash_algo,
751                  pin_cb, ctx,
752                  ctrl->in_data.value, ctrl->in_data.valuelen,
753                  &outdata, &outdatalen);
754
755   xfree (keyidstr);
756   if (rc)
757     {
758       log_error ("app_sign failed: %s\n", gpg_strerror (rc));
759     }
760   else
761     {
762       rc = assuan_send_data (ctx, outdata, outdatalen);
763       xfree (outdata);
764       if (rc)
765         return rc; /* that is already an assuan error code */
766     }
767
768   return rc;
769 }
770
771
772 static const char hlp_pkauth[] =
773   "PKAUTH <hexified_id>";
774 static gpg_error_t
775 cmd_pkauth (assuan_context_t ctx, char *line)
776 {
777   ctrl_t ctrl = assuan_get_pointer (ctx);
778   int rc;
779   unsigned char *outdata;
780   size_t outdatalen;
781   char *keyidstr;
782
783   if ((rc = open_card (ctrl)))
784     return rc;
785
786   if (!ctrl->app_ctx)
787     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
788
789  /* We have to use a copy of the key ID because the function may use
790      the pin_cb which in turn uses the assuan line buffer and thus
791      overwriting the original line with the keyid */
792   keyidstr = xtrystrdup (line);
793   if (!keyidstr)
794     return out_of_core ();
795
796   rc = app_auth (ctrl->app_ctx, ctrl, keyidstr, pin_cb, ctx,
797                  ctrl->in_data.value, ctrl->in_data.valuelen,
798                  &outdata, &outdatalen);
799   xfree (keyidstr);
800   if (rc)
801     {
802       log_error ("app_auth failed: %s\n", gpg_strerror (rc));
803     }
804   else
805     {
806       rc = assuan_send_data (ctx, outdata, outdatalen);
807       xfree (outdata);
808       if (rc)
809         return rc; /* that is already an assuan error code */
810     }
811
812   return rc;
813 }
814
815
816 static const char hlp_pkdecrypt[] =
817   "PKDECRYPT <hexified_id>";
818 static gpg_error_t
819 cmd_pkdecrypt (assuan_context_t ctx, char *line)
820 {
821   ctrl_t ctrl = assuan_get_pointer (ctx);
822   int rc;
823   unsigned char *outdata;
824   size_t outdatalen;
825   char *keyidstr;
826   unsigned int infoflags;
827
828   if ((rc = open_card (ctrl)))
829     return rc;
830
831   keyidstr = xtrystrdup (line);
832   if (!keyidstr)
833     return out_of_core ();
834   rc = app_decipher (ctrl->app_ctx, ctrl, keyidstr, pin_cb, ctx,
835                      ctrl->in_data.value, ctrl->in_data.valuelen,
836                      &outdata, &outdatalen, &infoflags);
837
838   xfree (keyidstr);
839   if (rc)
840     {
841       log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
842     }
843   else
844     {
845       /* If the card driver told us that there is no padding, send a
846          status line.  If there is a padding it is assumed that the
847          caller knows what padding is used.  It would have been better
848          to always send that information but for backward
849          compatibility we can't do that.  */
850       if ((infoflags & APP_DECIPHER_INFO_NOPAD))
851         send_status_direct (ctrl, "PADDING", "0");
852       rc = assuan_send_data (ctx, outdata, outdatalen);
853       xfree (outdata);
854       if (rc)
855         return rc; /* that is already an assuan error code */
856     }
857
858   return rc;
859 }
860
861
862 static const char hlp_getattr[] =
863   "GETATTR <name>\n"
864   "\n"
865   "This command is used to retrieve data from a smartcard.  The\n"
866   "allowed names depend on the currently selected smartcard\n"
867   "application.  NAME must be percent and '+' escaped.  The value is\n"
868   "returned through status message, see the LEARN command for details.\n"
869   "\n"
870   "However, the current implementation assumes that Name is not escaped;\n"
871   "this works as long as no one uses arbitrary escaping. \n"
872   "\n"
873   "Note, that this function may even be used on a locked card.";
874 static gpg_error_t
875 cmd_getattr (assuan_context_t ctx, char *line)
876 {
877   ctrl_t ctrl = assuan_get_pointer (ctx);
878   int rc;
879   const char *keyword;
880
881   if ((rc = open_card (ctrl)))
882     return rc;
883
884   keyword = line;
885   for (; *line && !spacep (line); line++)
886     ;
887   if (*line)
888       *line++ = 0;
889
890   /* (We ignore any garbage for now.) */
891
892   /* FIXME: Applications should not return sensitive data if the card
893      is locked.  */
894   rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
895
896   return rc;
897 }
898
899
900 static const char hlp_setattr[] =
901   "SETATTR <name> <value> \n"
902   "\n"
903   "This command is used to store data on a smartcard.  The allowed\n"
904   "names and values are depend on the currently selected smartcard\n"
905   "application.  NAME and VALUE must be percent and '+' escaped.\n"
906   "\n"
907   "However, the current implementation assumes that NAME is not\n"
908   "escaped; this works as long as no one uses arbitrary escaping.\n"
909   "\n"
910   "A PIN will be requested for most NAMEs.  See the corresponding\n"
911   "setattr function of the actually used application (app-*.c) for\n"
912   "details.";
913 static gpg_error_t
914 cmd_setattr (assuan_context_t ctx, char *orig_line)
915 {
916   ctrl_t ctrl = assuan_get_pointer (ctx);
917   int rc;
918   char *keyword;
919   int keywordlen;
920   size_t nbytes;
921   char *line, *linebuf;
922
923   if ((rc = open_card (ctrl)))
924     return rc;
925
926   /* We need to use a copy of LINE, because PIN_CB uses the same
927      context and thus reuses the Assuan provided LINE. */
928   line = linebuf = xtrystrdup (orig_line);
929   if (!line)
930     return out_of_core ();
931
932   keyword = line;
933   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
934     ;
935   if (*line)
936       *line++ = 0;
937   while (spacep (line))
938     line++;
939   nbytes = percent_plus_unescape_inplace (line, 0);
940
941   rc = app_setattr (ctrl->app_ctx, ctrl, keyword, pin_cb, ctx,
942                     (const unsigned char*)line, nbytes);
943   xfree (linebuf);
944
945   return rc;
946 }
947
948
949 static const char hlp_writecert[] =
950   "WRITECERT <hexified_certid>\n"
951   "\n"
952   "This command is used to store a certifciate on a smartcard.  The\n"
953   "allowed certids depend on the currently selected smartcard\n"
954   "application. The actual certifciate is requested using the inquiry\n"
955   "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
956   "\n"
957   "In almost all cases a PIN will be requested.  See the related\n"
958   "writecert function of the actually used application (app-*.c) for\n"
959   "details.";
960 static gpg_error_t
961 cmd_writecert (assuan_context_t ctx, char *line)
962 {
963   ctrl_t ctrl = assuan_get_pointer (ctx);
964   int rc;
965   char *certid;
966   unsigned char *certdata;
967   size_t certdatalen;
968
969   line = skip_options (line);
970
971   if (!*line)
972     return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
973   certid = line;
974   while (*line && !spacep (line))
975     line++;
976   *line = 0;
977
978   if ((rc = open_card (ctrl)))
979     return rc;
980
981   if (!ctrl->app_ctx)
982     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
983
984   certid = xtrystrdup (certid);
985   if (!certid)
986     return out_of_core ();
987
988   /* Now get the actual keydata. */
989   rc = assuan_inquire (ctx, "CERTDATA",
990                        &certdata, &certdatalen, MAXLEN_CERTDATA);
991   if (rc)
992     {
993       xfree (certid);
994       return rc;
995     }
996
997   /* Write the certificate to the card. */
998   rc = app_writecert (ctrl->app_ctx, ctrl, certid,
999                       pin_cb, ctx, certdata, certdatalen);
1000   xfree (certid);
1001   xfree (certdata);
1002
1003   return rc;
1004 }
1005
1006
1007 static const char hlp_writekey[] =
1008   "WRITEKEY [--force] <keyid> \n"
1009   "\n"
1010   "This command is used to store a secret key on a smartcard.  The\n"
1011   "allowed keyids depend on the currently selected smartcard\n"
1012   "application. The actual keydata is requested using the inquiry\n"
1013   "\"KEYDATA\" and need to be provided without any protection.  With\n"
1014   "--force set an existing key under this KEYID will get overwritten.\n"
1015   "The keydata is expected to be the usual canonical encoded\n"
1016   "S-expression.\n"
1017   "\n"
1018   "A PIN will be requested for most NAMEs.  See the corresponding\n"
1019   "writekey function of the actually used application (app-*.c) for\n"
1020   "details.";
1021 static gpg_error_t
1022 cmd_writekey (assuan_context_t ctx, char *line)
1023 {
1024   ctrl_t ctrl = assuan_get_pointer (ctx);
1025   int rc;
1026   char *keyid;
1027   int force = has_option (line, "--force");
1028   unsigned char *keydata;
1029   size_t keydatalen;
1030
1031   line = skip_options (line);
1032
1033   if (!*line)
1034     return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1035   keyid = line;
1036   while (*line && !spacep (line))
1037     line++;
1038   *line = 0;
1039
1040   if ((rc = open_card (ctrl)))
1041     return rc;
1042
1043   if (!ctrl->app_ctx)
1044     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1045
1046   keyid = xtrystrdup (keyid);
1047   if (!keyid)
1048     return out_of_core ();
1049
1050   /* Now get the actual keydata. */
1051   assuan_begin_confidential (ctx);
1052   rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1053   assuan_end_confidential (ctx);
1054   if (rc)
1055     {
1056       xfree (keyid);
1057       return rc;
1058     }
1059
1060   /* Write the key to the card. */
1061   rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1062                      pin_cb, ctx, keydata, keydatalen);
1063   xfree (keyid);
1064   xfree (keydata);
1065
1066   return rc;
1067 }
1068
1069
1070 static const char hlp_genkey[] =
1071   "GENKEY [--force] [--timestamp=<isodate>] <no>\n"
1072   "\n"
1073   "Generate a key on-card identified by NO, which is application\n"
1074   "specific.  Return values are application specific.  For OpenPGP\n"
1075   "cards 3 status lines are returned:\n"
1076   "\n"
1077   "  S KEY-FPR  <hexstring>\n"
1078   "  S KEY-CREATED-AT <seconds_since_epoch>\n"
1079   "  S KEY-DATA [-|p|n] <hexdata>\n"
1080   "\n"
1081   "  'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
1082   "  indicate that HEXDATA is the first chunk of a parameter given\n"
1083   "  by the next KEY-DATA.\n"
1084   "\n"
1085   "--force is required to overwrite an already existing key.  The\n"
1086   "KEY-CREATED-AT is required for further processing because it is\n"
1087   "part of the hashed key material for the fingerprint.\n"
1088   "\n"
1089   "If --timestamp is given an OpenPGP key will be created using this\n"
1090   "value.  The value needs to be in ISO Format; e.g.\n"
1091   "\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
1092   "\n"
1093   "The public part of the key can also later be retrieved using the\n"
1094   "READKEY command.";
1095 static gpg_error_t
1096 cmd_genkey (assuan_context_t ctx, char *line)
1097 {
1098   ctrl_t ctrl = assuan_get_pointer (ctx);
1099   int rc;
1100   char *keyno;
1101   int force;
1102   const char *s;
1103   time_t timestamp;
1104
1105   force = has_option (line, "--force");
1106
1107   if ((s=has_option_name (line, "--timestamp")))
1108     {
1109       if (*s != '=')
1110         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1111       timestamp = isotime2epoch (s+1);
1112       if (timestamp < 1)
1113         return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1114     }
1115   else
1116     timestamp = 0;
1117
1118
1119   line = skip_options (line);
1120   if (!*line)
1121     return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1122   keyno = line;
1123   while (*line && !spacep (line))
1124     line++;
1125   *line = 0;
1126
1127   if ((rc = open_card (ctrl)))
1128     return rc;
1129
1130   if (!ctrl->app_ctx)
1131     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1132
1133   keyno = xtrystrdup (keyno);
1134   if (!keyno)
1135     return out_of_core ();
1136   rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1137                    timestamp, pin_cb, ctx);
1138   xfree (keyno);
1139
1140   return rc;
1141 }
1142
1143
1144 static const char hlp_random[] =
1145   "RANDOM <nbytes>\n"
1146   "\n"
1147   "Get NBYTES of random from the card and send them back as data.\n"
1148   "This usually involves EEPROM write on the card and thus excessive\n"
1149   "use of this command may destroy the card.\n"
1150   "\n"
1151   "Note, that this function may be even be used on a locked card.";
1152 static gpg_error_t
1153 cmd_random (assuan_context_t ctx, char *line)
1154 {
1155   ctrl_t ctrl = assuan_get_pointer (ctx);
1156   int rc;
1157   size_t nbytes;
1158   unsigned char *buffer;
1159
1160   if (!*line)
1161     return set_error (GPG_ERR_ASS_PARAMETER,
1162                       "number of requested bytes missing");
1163   nbytes = strtoul (line, NULL, 0);
1164
1165   if ((rc = open_card (ctrl)))
1166     return rc;
1167
1168   if (!ctrl->app_ctx)
1169     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1170
1171   buffer = xtrymalloc (nbytes);
1172   if (!buffer)
1173     return out_of_core ();
1174
1175   rc = app_get_challenge (ctrl->app_ctx, ctrl, nbytes, buffer);
1176   if (!rc)
1177     {
1178       rc = assuan_send_data (ctx, buffer, nbytes);
1179       xfree (buffer);
1180       return rc; /* that is already an assuan error code */
1181     }
1182   xfree (buffer);
1183
1184   return rc;
1185 }
1186
1187
1188 \f
1189 static const char hlp_passwd[] =
1190   "PASSWD [--reset] [--nullpin] <chvno>\n"
1191   "\n"
1192   "Change the PIN or, if --reset is given, reset the retry counter of\n"
1193   "the card holder verification vector CHVNO.  The option --nullpin is\n"
1194   "used for TCOS cards to set the initial PIN.  The format of CHVNO\n"
1195   "depends on the card application.";
1196 static gpg_error_t
1197 cmd_passwd (assuan_context_t ctx, char *line)
1198 {
1199   ctrl_t ctrl = assuan_get_pointer (ctx);
1200   int rc;
1201   char *chvnostr;
1202   unsigned int flags = 0;
1203
1204   if (has_option (line, "--reset"))
1205     flags |= APP_CHANGE_FLAG_RESET;
1206   if (has_option (line, "--nullpin"))
1207     flags |= APP_CHANGE_FLAG_NULLPIN;
1208
1209   line = skip_options (line);
1210
1211   if (!*line)
1212     return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1213   chvnostr = line;
1214   while (*line && !spacep (line))
1215     line++;
1216   *line = 0;
1217
1218   if ((rc = open_card (ctrl)))
1219     return rc;
1220
1221   if (!ctrl->app_ctx)
1222     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1223
1224   chvnostr = xtrystrdup (chvnostr);
1225   if (!chvnostr)
1226     return out_of_core ();
1227   rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1228   if (rc)
1229     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1230   xfree (chvnostr);
1231
1232   return rc;
1233 }
1234
1235
1236 static const char hlp_checkpin[] =
1237   "CHECKPIN <idstr>\n"
1238   "\n"
1239   "Perform a VERIFY operation without doing anything else.  This may\n"
1240   "be used to initialize a the PIN cache earlier to long lasting\n"
1241   "operations.  Its use is highly application dependent.\n"
1242   "\n"
1243   "For OpenPGP:\n"
1244   "\n"
1245   "   Perform a simple verify operation for CHV1 and CHV2, so that\n"
1246   "   further operations won't ask for CHV2 and it is possible to do a\n"
1247   "   cheap check on the PIN: If there is something wrong with the PIN\n"
1248   "   entry system, only the regular CHV will get blocked and not the\n"
1249   "   dangerous CHV3.  IDSTR is the usual card's serial number in hex\n"
1250   "   notation; an optional fingerprint part will get ignored.  There\n"
1251   "   is however a special mode if the IDSTR is sffixed with the\n"
1252   "   literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1253   "   if and only if the retry counter is still at 3.\n"
1254   "\n"
1255   "For Netkey:\n"
1256   "\n"
1257   "   Any of the valid PIN Ids may be used.  These are the strings:\n"
1258   "\n"
1259   "     PW1.CH       - Global password 1\n"
1260   "     PW2.CH       - Global password 2\n"
1261   "     PW1.CH.SIG   - SigG password 1\n"
1262   "     PW2.CH.SIG   - SigG password 2\n"
1263   "\n"
1264   "   For a definitive list, see the implementation in app-nks.c.\n"
1265   "   Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1266   "   3.0 they are technically alternative PINs used to mutally\n"
1267   "   unblock each other.";
1268 static gpg_error_t
1269 cmd_checkpin (assuan_context_t ctx, char *line)
1270 {
1271   ctrl_t ctrl = assuan_get_pointer (ctx);
1272   int rc;
1273   char *idstr;
1274
1275   if ((rc = open_card (ctrl)))
1276     return rc;
1277
1278   if (!ctrl->app_ctx)
1279     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1280
1281   /* We have to use a copy of the key ID because the function may use
1282      the pin_cb which in turn uses the assuan line buffer and thus
1283      overwriting the original line with the keyid. */
1284   idstr = xtrystrdup (line);
1285   if (!idstr)
1286     return out_of_core ();
1287
1288   rc = app_check_pin (ctrl->app_ctx, ctrl, idstr, pin_cb, ctx);
1289   xfree (idstr);
1290   if (rc)
1291     log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1292
1293   return rc;
1294 }
1295
1296
1297 static const char hlp_lock[] =
1298   "LOCK [--wait]\n"
1299   "\n"
1300   "Grant exclusive card access to this session.  Note that there is\n"
1301   "no lock counter used and a second lock from the same session will\n"
1302   "be ignored.  A single unlock (or RESET) unlocks the session.\n"
1303   "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1304   "\n"
1305   "If the option --wait is given the command will wait until a\n"
1306   "lock has been released.";
1307 static gpg_error_t
1308 cmd_lock (assuan_context_t ctx, char *line)
1309 {
1310   ctrl_t ctrl = assuan_get_pointer (ctx);
1311   int rc = 0;
1312
1313  retry:
1314   if (locked_session)
1315     {
1316       if (locked_session != ctrl->server_local)
1317         rc = gpg_error (GPG_ERR_LOCKED);
1318     }
1319   else
1320     locked_session = ctrl->server_local;
1321
1322 #ifdef USE_NPTH
1323   if (rc && has_option (line, "--wait"))
1324     {
1325       rc = 0;
1326       npth_sleep (1); /* Better implement an event mechanism. However,
1327                          for card operations this should be
1328                          sufficient. */
1329       /* FIXME: Need to check that the connection is still alive.
1330          This can be done by issuing status messages. */
1331       goto retry;
1332     }
1333 #endif /*USE_NPTH*/
1334
1335   if (rc)
1336     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1337   return rc;
1338 }
1339
1340
1341 static const char hlp_unlock[] =
1342   "UNLOCK\n"
1343   "\n"
1344   "Release exclusive card access.";
1345 static gpg_error_t
1346 cmd_unlock (assuan_context_t ctx, char *line)
1347 {
1348   ctrl_t ctrl = assuan_get_pointer (ctx);
1349   int rc = 0;
1350
1351   (void)line;
1352
1353   if (locked_session)
1354     {
1355       if (locked_session != ctrl->server_local)
1356         rc = gpg_error (GPG_ERR_LOCKED);
1357       else
1358         locked_session = NULL;
1359     }
1360   else
1361     rc = gpg_error (GPG_ERR_NOT_LOCKED);
1362
1363   if (rc)
1364     log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1365   return rc;
1366 }
1367
1368
1369 static const char hlp_getinfo[] =
1370   "GETINFO <what>\n"
1371   "\n"
1372   "Multi purpose command to return certain information.  \n"
1373   "Supported values of WHAT are:\n"
1374   "\n"
1375   "  version     - Return the version of the program.\n"
1376   "  pid         - Return the process id of the server.\n"
1377   "  socket_name - Return the name of the socket.\n"
1378   "  connections - Return number of active connections.\n"
1379   "  status      - Return the status of the current reader (in the future,\n"
1380   "                may also return the status of all readers).  The status\n"
1381   "                is a list of one-character flags.  The following flags\n"
1382   "                are currently defined:\n"
1383   "                  'u'  Usable card present.\n"
1384   "                  'r'  Card removed.  A reset is necessary.\n"
1385   "                These flags are exclusive.\n"
1386   "  reader_list - Return a list of detected card readers.  Does\n"
1387   "                currently only work with the internal CCID driver.\n"
1388   "  deny_admin  - Returns OK if admin commands are not allowed or\n"
1389   "                GPG_ERR_GENERAL if admin commands are allowed.\n"
1390   "  app_list    - Return a list of supported applications.  One\n"
1391   "                application per line, fields delimited by colons,\n"
1392   "                first field is the name.\n"
1393   "  card_list   - Return a list of serial numbers of active cards,\n"
1394   "                using a status response.";
1395 static gpg_error_t
1396 cmd_getinfo (assuan_context_t ctx, char *line)
1397 {
1398   int rc = 0;
1399
1400   if (!strcmp (line, "version"))
1401     {
1402       const char *s = VERSION;
1403       rc = assuan_send_data (ctx, s, strlen (s));
1404     }
1405   else if (!strcmp (line, "pid"))
1406     {
1407       char numbuf[50];
1408
1409       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1410       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1411     }
1412   else if (!strcmp (line, "socket_name"))
1413     {
1414       const char *s = scd_get_socket_name ();
1415
1416       if (s)
1417         rc = assuan_send_data (ctx, s, strlen (s));
1418       else
1419         rc = gpg_error (GPG_ERR_NO_DATA);
1420     }
1421   else if (!strcmp (line, "connections"))
1422     {
1423       char numbuf[20];
1424
1425       snprintf (numbuf, sizeof numbuf, "%d", get_active_connection_count ());
1426       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1427     }
1428   else if (!strcmp (line, "status"))
1429     {
1430       ctrl_t ctrl = assuan_get_pointer (ctx);
1431       char flag;
1432
1433       if (open_card (ctrl))
1434         flag = 'r';
1435       else
1436         flag = 'u';
1437
1438       rc = assuan_send_data (ctx, &flag, 1);
1439     }
1440   else if (!strcmp (line, "reader_list"))
1441     {
1442 #ifdef HAVE_LIBUSB
1443       char *s = ccid_get_reader_list ();
1444 #else
1445       char *s = NULL;
1446 #endif
1447
1448       if (s)
1449         rc = assuan_send_data (ctx, s, strlen (s));
1450       else
1451         rc = gpg_error (GPG_ERR_NO_DATA);
1452       xfree (s);
1453     }
1454   else if (!strcmp (line, "deny_admin"))
1455     rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1456   else if (!strcmp (line, "app_list"))
1457     {
1458       char *s = get_supported_applications ();
1459       if (s)
1460         rc = assuan_send_data (ctx, s, strlen (s));
1461       else
1462         rc = 0;
1463       xfree (s);
1464     }
1465   else if (!strcmp (line, "card_list"))
1466     {
1467       ctrl_t ctrl = assuan_get_pointer (ctx);
1468
1469       app_send_card_list (ctrl);
1470     }
1471   else
1472     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1473   return rc;
1474 }
1475
1476
1477 static const char hlp_restart[] =
1478   "RESTART\n"
1479   "\n"
1480   "Restart the current connection; this is a kind of warm reset.  It\n"
1481   "deletes the context used by this connection but does not send a\n"
1482   "RESET to the card.  Thus the card itself won't get reset. \n"
1483   "\n"
1484   "This is used by gpg-agent to reuse a primary pipe connection and\n"
1485   "may be used by clients to backup from a conflict in the serial\n"
1486   "command; i.e. to select another application.";
1487 static gpg_error_t
1488 cmd_restart (assuan_context_t ctx, char *line)
1489 {
1490   ctrl_t ctrl = assuan_get_pointer (ctx);
1491   app_t app = ctrl->app_ctx;
1492
1493   (void)line;
1494
1495   if (app)
1496     {
1497       ctrl->app_ctx = NULL;
1498       release_application (app, 0);
1499     }
1500   if (locked_session && ctrl->server_local == locked_session)
1501     {
1502       locked_session = NULL;
1503       log_info ("implicitly unlocking due to RESTART\n");
1504     }
1505   return 0;
1506 }
1507
1508
1509 static const char hlp_disconnect[] =
1510   "DISCONNECT\n"
1511   "\n"
1512   "Disconnect the card if the backend supports a disconnect operation.";
1513 static gpg_error_t
1514 cmd_disconnect (assuan_context_t ctx, char *line)
1515 {
1516   ctrl_t ctrl = assuan_get_pointer (ctx);
1517
1518   (void)line;
1519
1520   if (!ctrl->app_ctx)
1521     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1522
1523   apdu_disconnect (ctrl->app_ctx->slot);
1524   return 0;
1525 }
1526
1527
1528
1529 static const char hlp_apdu[] =
1530   "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1531   "\n"
1532   "Send an APDU to the current reader.  This command bypasses the high\n"
1533   "level functions and sends the data directly to the card.  HEXSTRING\n"
1534   "is expected to be a proper APDU.  If HEXSTRING is not given no\n"
1535   "commands are set to the card but the command will implictly check\n"
1536   "whether the card is ready for use. \n"
1537   "\n"
1538   "Using the option \"--atr\" returns the ATR of the card as a status\n"
1539   "message before any data like this:\n"
1540   "  S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1541   "\n"
1542   "Using the option --more handles the card status word MORE_DATA\n"
1543   "(61xx) and concatenates all responses to one block.\n"
1544   "\n"
1545   "Using the option \"--exlen\" the returned APDU may use extended\n"
1546   "length up to N bytes.  If N is not given a default value is used\n"
1547   "(currently 4096).";
1548 static gpg_error_t
1549 cmd_apdu (assuan_context_t ctx, char *line)
1550 {
1551   ctrl_t ctrl = assuan_get_pointer (ctx);
1552   app_t app;
1553   int rc;
1554   unsigned char *apdu;
1555   size_t apdulen;
1556   int with_atr;
1557   int handle_more;
1558   const char *s;
1559   size_t exlen;
1560
1561   if (has_option (line, "--dump-atr"))
1562     with_atr = 2;
1563   else
1564     with_atr = has_option (line, "--atr");
1565   handle_more = has_option (line, "--more");
1566
1567   if ((s=has_option_name (line, "--exlen")))
1568     {
1569       if (*s == '=')
1570         exlen = strtoul (s+1, NULL, 0);
1571       else
1572         exlen = 4096;
1573     }
1574   else
1575     exlen = 0;
1576
1577   line = skip_options (line);
1578
1579   if ((rc = open_card (ctrl)))
1580     return rc;
1581
1582   app = ctrl->app_ctx;
1583   if (!app)
1584     return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
1585
1586   if (with_atr)
1587     {
1588       unsigned char *atr;
1589       size_t atrlen;
1590       char hexbuf[400];
1591
1592       atr = apdu_get_atr (app->slot, &atrlen);
1593       if (!atr || atrlen > sizeof hexbuf - 2 )
1594         {
1595           rc = gpg_error (GPG_ERR_INV_CARD);
1596           goto leave;
1597         }
1598       if (with_atr == 2)
1599         {
1600           char *string, *p, *pend;
1601
1602           string = atr_dump (atr, atrlen);
1603           if (string)
1604             {
1605               for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1606                 {
1607                   rc = assuan_send_data (ctx, p, pend - p + 1);
1608                   if (!rc)
1609                     rc = assuan_send_data (ctx, NULL, 0);
1610                 }
1611               if (!rc && *p)
1612                 rc = assuan_send_data (ctx, p, strlen (p));
1613               es_free (string);
1614               if (rc)
1615                 goto leave;
1616             }
1617         }
1618       else
1619         {
1620           bin2hex (atr, atrlen, hexbuf);
1621           send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1622         }
1623       xfree (atr);
1624     }
1625
1626   apdu = hex_to_buffer (line, &apdulen);
1627   if (!apdu)
1628     {
1629       rc = gpg_error_from_syserror ();
1630       goto leave;
1631     }
1632   if (apdulen)
1633     {
1634       unsigned char *result = NULL;
1635       size_t resultlen;
1636
1637       rc = apdu_send_direct (app->slot, exlen,
1638                              apdu, apdulen, handle_more,
1639                              &result, &resultlen);
1640       if (rc)
1641         log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1642       else
1643         {
1644           rc = assuan_send_data (ctx, result, resultlen);
1645           xfree (result);
1646         }
1647     }
1648   xfree (apdu);
1649
1650  leave:
1651   return rc;
1652 }
1653
1654
1655 static const char hlp_killscd[] =
1656   "KILLSCD\n"
1657   "\n"
1658   "Commit suicide.";
1659 static gpg_error_t
1660 cmd_killscd (assuan_context_t ctx, char *line)
1661 {
1662   ctrl_t ctrl = assuan_get_pointer (ctx);
1663
1664   (void)line;
1665
1666   ctrl->server_local->stopme = 1;
1667   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1668   return 0;
1669 }
1670
1671
1672 \f
1673 /* Tell the assuan library about our commands */
1674 static int
1675 register_commands (assuan_context_t ctx)
1676 {
1677   static struct {
1678     const char *name;
1679     assuan_handler_t handler;
1680     const char * const help;
1681   } table[] = {
1682     { "SERIALNO",     cmd_serialno, hlp_serialno },
1683     { "LEARN",        cmd_learn,    hlp_learn },
1684     { "READCERT",     cmd_readcert, hlp_readcert },
1685     { "READKEY",      cmd_readkey,  hlp_readkey },
1686     { "SETDATA",      cmd_setdata,  hlp_setdata },
1687     { "PKSIGN",       cmd_pksign,   hlp_pksign },
1688     { "PKAUTH",       cmd_pkauth,   hlp_pkauth },
1689     { "PKDECRYPT",    cmd_pkdecrypt,hlp_pkdecrypt },
1690     { "INPUT",        NULL },
1691     { "OUTPUT",       NULL },
1692     { "GETATTR",      cmd_getattr,  hlp_getattr },
1693     { "SETATTR",      cmd_setattr,  hlp_setattr },
1694     { "WRITECERT",    cmd_writecert,hlp_writecert },
1695     { "WRITEKEY",     cmd_writekey, hlp_writekey },
1696     { "GENKEY",       cmd_genkey,   hlp_genkey },
1697     { "RANDOM",       cmd_random,   hlp_random },
1698     { "PASSWD",       cmd_passwd,   hlp_passwd },
1699     { "CHECKPIN",     cmd_checkpin, hlp_checkpin },
1700     { "LOCK",         cmd_lock,     hlp_lock },
1701     { "UNLOCK",       cmd_unlock,   hlp_unlock },
1702     { "GETINFO",      cmd_getinfo,  hlp_getinfo },
1703     { "RESTART",      cmd_restart,  hlp_restart },
1704     { "DISCONNECT",   cmd_disconnect,hlp_disconnect },
1705     { "APDU",         cmd_apdu,     hlp_apdu },
1706     { "KILLSCD",      cmd_killscd,  hlp_killscd },
1707     { NULL }
1708   };
1709   int i, rc;
1710
1711   for (i=0; table[i].name; i++)
1712     {
1713       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1714                                     table[i].help);
1715       if (rc)
1716         return rc;
1717     }
1718   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1719
1720   assuan_register_reset_notify (ctx, reset_notify);
1721   assuan_register_option_handler (ctx, option_handler);
1722   return 0;
1723 }
1724
1725
1726 /* Startup the server.  If FD is given as -1 this is simple pipe
1727    server, otherwise it is a regular server.  Returns true if there
1728    are no more active asessions.  */
1729 int
1730 scd_command_handler (ctrl_t ctrl, int fd)
1731 {
1732   int rc;
1733   assuan_context_t ctx = NULL;
1734   int stopme;
1735
1736   rc = assuan_new (&ctx);
1737   if (rc)
1738     {
1739       log_error ("failed to allocate assuan context: %s\n",
1740                  gpg_strerror (rc));
1741       scd_exit (2);
1742     }
1743
1744   if (fd == -1)
1745     {
1746       assuan_fd_t filedes[2];
1747
1748       filedes[0] = assuan_fdopen (0);
1749       filedes[1] = assuan_fdopen (1);
1750       rc = assuan_init_pipe_server (ctx, filedes);
1751     }
1752   else
1753     {
1754       rc = assuan_init_socket_server (ctx, INT2FD(fd),
1755                                       ASSUAN_SOCKET_SERVER_ACCEPTED);
1756     }
1757   if (rc)
1758     {
1759       log_error ("failed to initialize the server: %s\n",
1760                  gpg_strerror(rc));
1761       scd_exit (2);
1762     }
1763   rc = register_commands (ctx);
1764   if (rc)
1765     {
1766       log_error ("failed to register commands with Assuan: %s\n",
1767                  gpg_strerror(rc));
1768       scd_exit (2);
1769     }
1770   assuan_set_pointer (ctx, ctrl);
1771
1772   /* Allocate and initialize the server object.  Put it into the list
1773      of active sessions. */
1774   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1775   ctrl->server_local->next_session = session_list;
1776   session_list = ctrl->server_local;
1777   ctrl->server_local->ctrl_backlink = ctrl;
1778   ctrl->server_local->assuan_ctx = ctx;
1779
1780   /* Command processing loop. */
1781   for (;;)
1782     {
1783       rc = assuan_accept (ctx);
1784       if (rc == -1)
1785         {
1786           break;
1787         }
1788       else if (rc)
1789         {
1790           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1791           break;
1792         }
1793
1794       rc = assuan_process (ctx);
1795       if (rc)
1796         {
1797           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1798           continue;
1799         }
1800     }
1801
1802   /* Cleanup.  We don't send an explicit reset to the card.  */
1803   do_reset (ctrl, 0);
1804
1805   /* Release the server object.  */
1806   if (session_list == ctrl->server_local)
1807     session_list = ctrl->server_local->next_session;
1808   else
1809     {
1810       struct server_local_s *sl;
1811
1812       for (sl=session_list; sl->next_session; sl = sl->next_session)
1813         if (sl->next_session == ctrl->server_local)
1814           break;
1815       if (!sl->next_session)
1816           BUG ();
1817       sl->next_session = ctrl->server_local->next_session;
1818     }
1819   stopme = ctrl->server_local->stopme;
1820   xfree (ctrl->server_local);
1821   ctrl->server_local = NULL;
1822
1823   /* Release the Assuan context.  */
1824   assuan_release (ctx);
1825
1826   if (stopme)
1827     scd_exit (0);
1828
1829   /* If there are no more sessions return true.  */
1830   return !session_list;
1831 }
1832
1833
1834 /* Send a line with status information via assuan and escape all given
1835    buffers. The variable elements are pairs of (char *, size_t),
1836    terminated with a (NULL, 0). */
1837 void
1838 send_status_info (ctrl_t ctrl, const char *keyword, ...)
1839 {
1840   va_list arg_ptr;
1841   const unsigned char *value;
1842   size_t valuelen;
1843   char buf[950], *p;
1844   size_t n;
1845   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1846
1847   va_start (arg_ptr, keyword);
1848
1849   p = buf;
1850   n = 0;
1851   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1852     {
1853       valuelen = va_arg (arg_ptr, size_t);
1854       if (!valuelen)
1855         continue; /* empty buffer */
1856       if (n)
1857         {
1858           *p++ = ' ';
1859           n++;
1860         }
1861       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1862         {
1863           if (*value == '+' || *value == '\"' || *value == '%'
1864               || *value < ' ')
1865             {
1866               sprintf (p, "%%%02X", *value);
1867               p += 3;
1868             }
1869           else if (*value == ' ')
1870             *p++ = '+';
1871           else
1872             *p++ = *value;
1873         }
1874     }
1875   *p = 0;
1876   assuan_write_status (ctx, keyword, buf);
1877
1878   va_end (arg_ptr);
1879 }
1880
1881
1882 /* Send a ready formatted status line via assuan.  */
1883 void
1884 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
1885 {
1886   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1887
1888   if (strchr (args, '\n'))
1889     log_error ("error: LF detected in status line - not sending\n");
1890   else
1891     assuan_write_status (ctx, keyword, args);
1892 }
1893
1894
1895 /* Helper to send the clients a status change notification.  */
1896 void
1897 send_client_notifications (app_t app, int removal)
1898 {
1899   struct {
1900     pid_t pid;
1901 #ifdef HAVE_W32_SYSTEM
1902     HANDLE handle;
1903 #else
1904     int signo;
1905 #endif
1906   } killed[50];
1907   int killidx = 0;
1908   int kidx;
1909   struct server_local_s *sl;
1910
1911   for (sl=session_list; sl; sl = sl->next_session)
1912     if (sl->ctrl_backlink && sl->ctrl_backlink->app_ctx == app)
1913       {
1914         pid_t pid;
1915 #ifdef HAVE_W32_SYSTEM
1916         HANDLE handle;
1917 #else
1918         int signo;
1919 #endif
1920
1921         if (removal)
1922           {
1923             sl->ctrl_backlink->app_ctx = NULL;
1924             sl->card_removed = 1;
1925             release_application (app, 1);
1926           }
1927
1928         if (!sl->event_signal || !sl->assuan_ctx)
1929           continue;
1930
1931         pid = assuan_get_pid (sl->assuan_ctx);
1932
1933 #ifdef HAVE_W32_SYSTEM
1934         handle = (void *)sl->event_signal;
1935         for (kidx=0; kidx < killidx; kidx++)
1936           if (killed[kidx].pid == pid
1937               && killed[kidx].handle == handle)
1938             break;
1939         if (kidx < killidx)
1940           log_info ("event %lx (%p) already triggered for client %d\n",
1941                     sl->event_signal, handle, (int)pid);
1942         else
1943           {
1944             log_info ("triggering event %lx (%p) for client %d\n",
1945                       sl->event_signal, handle, (int)pid);
1946             if (!SetEvent (handle))
1947               log_error ("SetEvent(%lx) failed: %s\n",
1948                          sl->event_signal, w32_strerror (-1));
1949             if (killidx < DIM (killed))
1950               {
1951                 killed[killidx].pid = pid;
1952                 killed[killidx].handle = handle;
1953                 killidx++;
1954               }
1955           }
1956 #else /*!HAVE_W32_SYSTEM*/
1957         signo = sl->event_signal;
1958
1959         if (pid != (pid_t)(-1) && pid && signo > 0)
1960           {
1961             for (kidx=0; kidx < killidx; kidx++)
1962               if (killed[kidx].pid == pid
1963                   && killed[kidx].signo == signo)
1964                 break;
1965             if (kidx < killidx)
1966               log_info ("signal %d already sent to client %d\n",
1967                         signo, (int)pid);
1968             else
1969               {
1970                 log_info ("sending signal %d to client %d\n",
1971                           signo, (int)pid);
1972                 kill (pid, signo);
1973                 if (killidx < DIM (killed))
1974                   {
1975                     killed[killidx].pid = pid;
1976                     killed[killidx].signo = signo;
1977                     killidx++;
1978                   }
1979               }
1980           }
1981 #endif /*!HAVE_W32_SYSTEM*/
1982       }
1983 }