chiark / gitweb /
gpg: Make sure the conflict set includes the current key.
[gnupg2.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 "asshelp.h"
44 #include "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 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 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 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   "\n"
1378   "socket_name - Return the name of the socket.\n"
1379   "\n"
1380   "status - Return the status of the current reader (in the future, may\n"
1381   "also return the status of all readers).  The status is a list of\n"
1382   "one-character flags.  The following flags are currently defined:\n"
1383   "  'u'  Usable card present.  This is the normal state during operation.\n"
1384   "  'r'  Card removed.  A reset is necessary.\n"
1385   "These flags are exclusive.\n"
1386   "\n"
1387   "reader_list - Return a list of detected card readers.  Does\n"
1388   "              currently only work with the internal CCID driver.\n"
1389   "\n"
1390   "deny_admin  - Returns OK if admin commands are not allowed or\n"
1391   "              GPG_ERR_GENERAL if admin commands are allowed.\n"
1392   "\n"
1393   "app_list    - Return a list of supported applications.  One\n"
1394   "              application per line, fields delimited by colons,\n"
1395   "              first field is the name.\n"
1396   "\n"
1397   "card_list   - Return a list of serial numbers of active cards,\n"
1398   "              using a status response.";
1399 static gpg_error_t
1400 cmd_getinfo (assuan_context_t ctx, char *line)
1401 {
1402   int rc = 0;
1403
1404   if (!strcmp (line, "version"))
1405     {
1406       const char *s = VERSION;
1407       rc = assuan_send_data (ctx, s, strlen (s));
1408     }
1409   else if (!strcmp (line, "pid"))
1410     {
1411       char numbuf[50];
1412
1413       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1414       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1415     }
1416   else if (!strcmp (line, "socket_name"))
1417     {
1418       const char *s = scd_get_socket_name ();
1419
1420       if (s)
1421         rc = assuan_send_data (ctx, s, strlen (s));
1422       else
1423         rc = gpg_error (GPG_ERR_NO_DATA);
1424     }
1425   else if (!strcmp (line, "status"))
1426     {
1427       ctrl_t ctrl = assuan_get_pointer (ctx);
1428       char flag;
1429
1430       if (open_card (ctrl))
1431         flag = 'r';
1432       else
1433         flag = 'u';
1434
1435       rc = assuan_send_data (ctx, &flag, 1);
1436     }
1437   else if (!strcmp (line, "reader_list"))
1438     {
1439 #ifdef HAVE_LIBUSB
1440       char *s = ccid_get_reader_list ();
1441 #else
1442       char *s = NULL;
1443 #endif
1444
1445       if (s)
1446         rc = assuan_send_data (ctx, s, strlen (s));
1447       else
1448         rc = gpg_error (GPG_ERR_NO_DATA);
1449       xfree (s);
1450     }
1451   else if (!strcmp (line, "deny_admin"))
1452     rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1453   else if (!strcmp (line, "app_list"))
1454     {
1455       char *s = get_supported_applications ();
1456       if (s)
1457         rc = assuan_send_data (ctx, s, strlen (s));
1458       else
1459         rc = 0;
1460       xfree (s);
1461     }
1462   else if (!strcmp (line, "card_list"))
1463     {
1464       ctrl_t ctrl = assuan_get_pointer (ctx);
1465
1466       app_send_card_list (ctrl);
1467     }
1468   else
1469     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1470   return rc;
1471 }
1472
1473
1474 static const char hlp_restart[] =
1475   "RESTART\n"
1476   "\n"
1477   "Restart the current connection; this is a kind of warm reset.  It\n"
1478   "deletes the context used by this connection but does not send a\n"
1479   "RESET to the card.  Thus the card itself won't get reset. \n"
1480   "\n"
1481   "This is used by gpg-agent to reuse a primary pipe connection and\n"
1482   "may be used by clients to backup from a conflict in the serial\n"
1483   "command; i.e. to select another application.";
1484 static gpg_error_t
1485 cmd_restart (assuan_context_t ctx, char *line)
1486 {
1487   ctrl_t ctrl = assuan_get_pointer (ctx);
1488   app_t app = ctrl->app_ctx;
1489
1490   (void)line;
1491
1492   if (app)
1493     {
1494       ctrl->app_ctx = NULL;
1495       release_application (app, 0);
1496     }
1497   if (locked_session && ctrl->server_local == locked_session)
1498     {
1499       locked_session = NULL;
1500       log_info ("implicitly unlocking due to RESTART\n");
1501     }
1502   return 0;
1503 }
1504
1505
1506 static const char hlp_disconnect[] =
1507   "DISCONNECT\n"
1508   "\n"
1509   "Disconnect the card if the backend supports a disconnect operation.";
1510 static gpg_error_t
1511 cmd_disconnect (assuan_context_t ctx, char *line)
1512 {
1513   ctrl_t ctrl = assuan_get_pointer (ctx);
1514
1515   (void)line;
1516
1517   if (!ctrl->app_ctx)
1518     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1519
1520   apdu_disconnect (ctrl->app_ctx->slot);
1521   return 0;
1522 }
1523
1524
1525
1526 static const char hlp_apdu[] =
1527   "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1528   "\n"
1529   "Send an APDU to the current reader.  This command bypasses the high\n"
1530   "level functions and sends the data directly to the card.  HEXSTRING\n"
1531   "is expected to be a proper APDU.  If HEXSTRING is not given no\n"
1532   "commands are set to the card but the command will implictly check\n"
1533   "whether the card is ready for use. \n"
1534   "\n"
1535   "Using the option \"--atr\" returns the ATR of the card as a status\n"
1536   "message before any data like this:\n"
1537   "  S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1538   "\n"
1539   "Using the option --more handles the card status word MORE_DATA\n"
1540   "(61xx) and concatenates all responses to one block.\n"
1541   "\n"
1542   "Using the option \"--exlen\" the returned APDU may use extended\n"
1543   "length up to N bytes.  If N is not given a default value is used\n"
1544   "(currently 4096).";
1545 static gpg_error_t
1546 cmd_apdu (assuan_context_t ctx, char *line)
1547 {
1548   ctrl_t ctrl = assuan_get_pointer (ctx);
1549   app_t app;
1550   int rc;
1551   unsigned char *apdu;
1552   size_t apdulen;
1553   int with_atr;
1554   int handle_more;
1555   const char *s;
1556   size_t exlen;
1557
1558   if (has_option (line, "--dump-atr"))
1559     with_atr = 2;
1560   else
1561     with_atr = has_option (line, "--atr");
1562   handle_more = has_option (line, "--more");
1563
1564   if ((s=has_option_name (line, "--exlen")))
1565     {
1566       if (*s == '=')
1567         exlen = strtoul (s+1, NULL, 0);
1568       else
1569         exlen = 4096;
1570     }
1571   else
1572     exlen = 0;
1573
1574   line = skip_options (line);
1575
1576   if ((rc = open_card (ctrl)))
1577     return rc;
1578
1579   app = ctrl->app_ctx;
1580   if (!app)
1581     return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
1582
1583   if (with_atr)
1584     {
1585       unsigned char *atr;
1586       size_t atrlen;
1587       char hexbuf[400];
1588
1589       atr = apdu_get_atr (app->slot, &atrlen);
1590       if (!atr || atrlen > sizeof hexbuf - 2 )
1591         {
1592           rc = gpg_error (GPG_ERR_INV_CARD);
1593           goto leave;
1594         }
1595       if (with_atr == 2)
1596         {
1597           char *string, *p, *pend;
1598
1599           string = atr_dump (atr, atrlen);
1600           if (string)
1601             {
1602               for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1603                 {
1604                   rc = assuan_send_data (ctx, p, pend - p + 1);
1605                   if (!rc)
1606                     rc = assuan_send_data (ctx, NULL, 0);
1607                 }
1608               if (!rc && *p)
1609                 rc = assuan_send_data (ctx, p, strlen (p));
1610               es_free (string);
1611               if (rc)
1612                 goto leave;
1613             }
1614         }
1615       else
1616         {
1617           bin2hex (atr, atrlen, hexbuf);
1618           send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1619         }
1620       xfree (atr);
1621     }
1622
1623   apdu = hex_to_buffer (line, &apdulen);
1624   if (!apdu)
1625     {
1626       rc = gpg_error_from_syserror ();
1627       goto leave;
1628     }
1629   if (apdulen)
1630     {
1631       unsigned char *result = NULL;
1632       size_t resultlen;
1633
1634       rc = apdu_send_direct (app->slot, exlen,
1635                              apdu, apdulen, handle_more,
1636                              &result, &resultlen);
1637       if (rc)
1638         log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1639       else
1640         {
1641           rc = assuan_send_data (ctx, result, resultlen);
1642           xfree (result);
1643         }
1644     }
1645   xfree (apdu);
1646
1647  leave:
1648   return rc;
1649 }
1650
1651
1652 static const char hlp_killscd[] =
1653   "KILLSCD\n"
1654   "\n"
1655   "Commit suicide.";
1656 static gpg_error_t
1657 cmd_killscd (assuan_context_t ctx, char *line)
1658 {
1659   ctrl_t ctrl = assuan_get_pointer (ctx);
1660
1661   (void)line;
1662
1663   ctrl->server_local->stopme = 1;
1664   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1665   return 0;
1666 }
1667
1668
1669 \f
1670 /* Tell the assuan library about our commands */
1671 static int
1672 register_commands (assuan_context_t ctx)
1673 {
1674   static struct {
1675     const char *name;
1676     assuan_handler_t handler;
1677     const char * const help;
1678   } table[] = {
1679     { "SERIALNO",     cmd_serialno, hlp_serialno },
1680     { "LEARN",        cmd_learn,    hlp_learn },
1681     { "READCERT",     cmd_readcert, hlp_readcert },
1682     { "READKEY",      cmd_readkey,  hlp_readkey },
1683     { "SETDATA",      cmd_setdata,  hlp_setdata },
1684     { "PKSIGN",       cmd_pksign,   hlp_pksign },
1685     { "PKAUTH",       cmd_pkauth,   hlp_pkauth },
1686     { "PKDECRYPT",    cmd_pkdecrypt,hlp_pkdecrypt },
1687     { "INPUT",        NULL },
1688     { "OUTPUT",       NULL },
1689     { "GETATTR",      cmd_getattr,  hlp_getattr },
1690     { "SETATTR",      cmd_setattr,  hlp_setattr },
1691     { "WRITECERT",    cmd_writecert,hlp_writecert },
1692     { "WRITEKEY",     cmd_writekey, hlp_writekey },
1693     { "GENKEY",       cmd_genkey,   hlp_genkey },
1694     { "RANDOM",       cmd_random,   hlp_random },
1695     { "PASSWD",       cmd_passwd,   hlp_passwd },
1696     { "CHECKPIN",     cmd_checkpin, hlp_checkpin },
1697     { "LOCK",         cmd_lock,     hlp_lock },
1698     { "UNLOCK",       cmd_unlock,   hlp_unlock },
1699     { "GETINFO",      cmd_getinfo,  hlp_getinfo },
1700     { "RESTART",      cmd_restart,  hlp_restart },
1701     { "DISCONNECT",   cmd_disconnect,hlp_disconnect },
1702     { "APDU",         cmd_apdu,     hlp_apdu },
1703     { "KILLSCD",      cmd_killscd,  hlp_killscd },
1704     { NULL }
1705   };
1706   int i, rc;
1707
1708   for (i=0; table[i].name; i++)
1709     {
1710       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1711                                     table[i].help);
1712       if (rc)
1713         return rc;
1714     }
1715   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1716
1717   assuan_register_reset_notify (ctx, reset_notify);
1718   assuan_register_option_handler (ctx, option_handler);
1719   return 0;
1720 }
1721
1722
1723 /* Startup the server.  If FD is given as -1 this is simple pipe
1724    server, otherwise it is a regular server.  Returns true if there
1725    are no more active asessions.  */
1726 int
1727 scd_command_handler (ctrl_t ctrl, int fd)
1728 {
1729   int rc;
1730   assuan_context_t ctx = NULL;
1731   int stopme;
1732
1733   rc = assuan_new (&ctx);
1734   if (rc)
1735     {
1736       log_error ("failed to allocate assuan context: %s\n",
1737                  gpg_strerror (rc));
1738       scd_exit (2);
1739     }
1740
1741   if (fd == -1)
1742     {
1743       assuan_fd_t filedes[2];
1744
1745       filedes[0] = assuan_fdopen (0);
1746       filedes[1] = assuan_fdopen (1);
1747       rc = assuan_init_pipe_server (ctx, filedes);
1748     }
1749   else
1750     {
1751       rc = assuan_init_socket_server (ctx, INT2FD(fd),
1752                                       ASSUAN_SOCKET_SERVER_ACCEPTED);
1753     }
1754   if (rc)
1755     {
1756       log_error ("failed to initialize the server: %s\n",
1757                  gpg_strerror(rc));
1758       scd_exit (2);
1759     }
1760   rc = register_commands (ctx);
1761   if (rc)
1762     {
1763       log_error ("failed to register commands with Assuan: %s\n",
1764                  gpg_strerror(rc));
1765       scd_exit (2);
1766     }
1767   assuan_set_pointer (ctx, ctrl);
1768
1769   /* Allocate and initialize the server object.  Put it into the list
1770      of active sessions. */
1771   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1772   ctrl->server_local->next_session = session_list;
1773   session_list = ctrl->server_local;
1774   ctrl->server_local->ctrl_backlink = ctrl;
1775   ctrl->server_local->assuan_ctx = ctx;
1776
1777   /* Command processing loop. */
1778   for (;;)
1779     {
1780       rc = assuan_accept (ctx);
1781       if (rc == -1)
1782         {
1783           break;
1784         }
1785       else if (rc)
1786         {
1787           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1788           break;
1789         }
1790
1791       rc = assuan_process (ctx);
1792       if (rc)
1793         {
1794           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1795           continue;
1796         }
1797     }
1798
1799   /* Cleanup.  We don't send an explicit reset to the card.  */
1800   do_reset (ctrl, 0);
1801
1802   /* Release the server object.  */
1803   if (session_list == ctrl->server_local)
1804     session_list = ctrl->server_local->next_session;
1805   else
1806     {
1807       struct server_local_s *sl;
1808
1809       for (sl=session_list; sl->next_session; sl = sl->next_session)
1810         if (sl->next_session == ctrl->server_local)
1811           break;
1812       if (!sl->next_session)
1813           BUG ();
1814       sl->next_session = ctrl->server_local->next_session;
1815     }
1816   stopme = ctrl->server_local->stopme;
1817   xfree (ctrl->server_local);
1818   ctrl->server_local = NULL;
1819
1820   /* Release the Assuan context.  */
1821   assuan_release (ctx);
1822
1823   if (stopme)
1824     scd_exit (0);
1825
1826   /* If there are no more sessions return true.  */
1827   return !session_list;
1828 }
1829
1830
1831 /* Send a line with status information via assuan and escape all given
1832    buffers. The variable elements are pairs of (char *, size_t),
1833    terminated with a (NULL, 0). */
1834 void
1835 send_status_info (ctrl_t ctrl, const char *keyword, ...)
1836 {
1837   va_list arg_ptr;
1838   const unsigned char *value;
1839   size_t valuelen;
1840   char buf[950], *p;
1841   size_t n;
1842   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1843
1844   va_start (arg_ptr, keyword);
1845
1846   p = buf;
1847   n = 0;
1848   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1849     {
1850       valuelen = va_arg (arg_ptr, size_t);
1851       if (!valuelen)
1852         continue; /* empty buffer */
1853       if (n)
1854         {
1855           *p++ = ' ';
1856           n++;
1857         }
1858       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1859         {
1860           if (*value == '+' || *value == '\"' || *value == '%'
1861               || *value < ' ')
1862             {
1863               sprintf (p, "%%%02X", *value);
1864               p += 3;
1865             }
1866           else if (*value == ' ')
1867             *p++ = '+';
1868           else
1869             *p++ = *value;
1870         }
1871     }
1872   *p = 0;
1873   assuan_write_status (ctx, keyword, buf);
1874
1875   va_end (arg_ptr);
1876 }
1877
1878
1879 /* Send a ready formatted status line via assuan.  */
1880 void
1881 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
1882 {
1883   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1884
1885   if (strchr (args, '\n'))
1886     log_error ("error: LF detected in status line - not sending\n");
1887   else
1888     assuan_write_status (ctx, keyword, args);
1889 }
1890
1891
1892 /* Helper to send the clients a status change notification.  */
1893 void
1894 send_client_notifications (app_t app, int removal)
1895 {
1896   struct {
1897     pid_t pid;
1898 #ifdef HAVE_W32_SYSTEM
1899     HANDLE handle;
1900 #else
1901     int signo;
1902 #endif
1903   } killed[50];
1904   int killidx = 0;
1905   int kidx;
1906   struct server_local_s *sl;
1907
1908   for (sl=session_list; sl; sl = sl->next_session)
1909     if (sl->ctrl_backlink && sl->ctrl_backlink->app_ctx == app)
1910       {
1911         pid_t pid;
1912 #ifdef HAVE_W32_SYSTEM
1913         HANDLE handle;
1914 #else
1915         int signo;
1916 #endif
1917
1918         if (removal)
1919           {
1920             sl->ctrl_backlink->app_ctx = NULL;
1921             sl->card_removed = 1;
1922             release_application (app, 1);
1923           }
1924
1925         if (!sl->event_signal || !sl->assuan_ctx)
1926           continue;
1927
1928         pid = assuan_get_pid (sl->assuan_ctx);
1929
1930 #ifdef HAVE_W32_SYSTEM
1931         handle = (void *)sl->event_signal;
1932         for (kidx=0; kidx < killidx; kidx++)
1933           if (killed[kidx].pid == pid
1934               && killed[kidx].handle == handle)
1935             break;
1936         if (kidx < killidx)
1937           log_info ("event %lx (%p) already triggered for client %d\n",
1938                     sl->event_signal, handle, (int)pid);
1939         else
1940           {
1941             log_info ("triggering event %lx (%p) for client %d\n",
1942                       sl->event_signal, handle, (int)pid);
1943             if (!SetEvent (handle))
1944               log_error ("SetEvent(%lx) failed: %s\n",
1945                          sl->event_signal, w32_strerror (-1));
1946             if (killidx < DIM (killed))
1947               {
1948                 killed[killidx].pid = pid;
1949                 killed[killidx].handle = handle;
1950                 killidx++;
1951               }
1952           }
1953 #else /*!HAVE_W32_SYSTEM*/
1954         signo = sl->event_signal;
1955
1956         if (pid != (pid_t)(-1) && pid && signo > 0)
1957           {
1958             for (kidx=0; kidx < killidx; kidx++)
1959               if (killed[kidx].pid == pid
1960                   && killed[kidx].signo == signo)
1961                 break;
1962             if (kidx < killidx)
1963               log_info ("signal %d already sent to client %d\n",
1964                         signo, (int)pid);
1965             else
1966               {
1967                 log_info ("sending signal %d to client %d\n",
1968                           signo, (int)pid);
1969                 kill (pid, signo);
1970                 if (killidx < DIM (killed))
1971                   {
1972                     killed[killidx].pid = pid;
1973                     killed[killidx].signo = signo;
1974                     killidx++;
1975                   }
1976               }
1977           }
1978 #endif /*!HAVE_W32_SYSTEM*/
1979       }
1980 }