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