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