scd: Add option --clear to PASSWD.
[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] [--clear] <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 option --clear clears\n"
1223   "the security status associated with the PIN so that the PIN needs to\n"
1224   "be presented again. The format of CHVNO depends on the card application.";
1225 static gpg_error_t
1226 cmd_passwd (assuan_context_t ctx, char *line)
1227 {
1228   ctrl_t ctrl = assuan_get_pointer (ctx);
1229   int rc;
1230   char *chvnostr;
1231   unsigned int flags = 0;
1232
1233   if (has_option (line, "--reset"))
1234     flags |= APP_CHANGE_FLAG_RESET;
1235   if (has_option (line, "--nullpin"))
1236     flags |= APP_CHANGE_FLAG_NULLPIN;
1237   if (has_option (line, "--clear"))
1238     flags |= APP_CHANGE_FLAG_CLEAR;
1239
1240   line = skip_options (line);
1241
1242   if (!*line)
1243     return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1244   chvnostr = line;
1245   while (*line && !spacep (line))
1246     line++;
1247   *line = 0;
1248
1249   /* Do not allow other flags aside of --clear. */
1250   if ((flags & APP_CHANGE_FLAG_CLEAR) && (flags & ~APP_CHANGE_FLAG_CLEAR))
1251     return set_error (GPG_ERR_UNSUPPORTED_OPERATION,
1252                       "--clear used with other options");
1253
1254   if ((rc = open_card (ctrl)))
1255     return rc;
1256
1257   if (!ctrl->app_ctx)
1258     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1259
1260   chvnostr = xtrystrdup (chvnostr);
1261   if (!chvnostr)
1262     return out_of_core ();
1263   rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1264   if (rc)
1265     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1266   xfree (chvnostr);
1267
1268   return rc;
1269 }
1270
1271
1272 static const char hlp_checkpin[] =
1273   "CHECKPIN <idstr>\n"
1274   "\n"
1275   "Perform a VERIFY operation without doing anything else.  This may\n"
1276   "be used to initialize a the PIN cache earlier to long lasting\n"
1277   "operations.  Its use is highly application dependent.\n"
1278   "\n"
1279   "For OpenPGP:\n"
1280   "\n"
1281   "   Perform a simple verify operation for CHV1 and CHV2, so that\n"
1282   "   further operations won't ask for CHV2 and it is possible to do a\n"
1283   "   cheap check on the PIN: If there is something wrong with the PIN\n"
1284   "   entry system, only the regular CHV will get blocked and not the\n"
1285   "   dangerous CHV3.  IDSTR is the usual card's serial number in hex\n"
1286   "   notation; an optional fingerprint part will get ignored.  There\n"
1287   "   is however a special mode if the IDSTR is sffixed with the\n"
1288   "   literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1289   "   if and only if the retry counter is still at 3.\n"
1290   "\n"
1291   "For Netkey:\n"
1292   "\n"
1293   "   Any of the valid PIN Ids may be used.  These are the strings:\n"
1294   "\n"
1295   "     PW1.CH       - Global password 1\n"
1296   "     PW2.CH       - Global password 2\n"
1297   "     PW1.CH.SIG   - SigG password 1\n"
1298   "     PW2.CH.SIG   - SigG password 2\n"
1299   "\n"
1300   "   For a definitive list, see the implementation in app-nks.c.\n"
1301   "   Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1302   "   3.0 they are technically alternative PINs used to mutally\n"
1303   "   unblock each other.";
1304 static gpg_error_t
1305 cmd_checkpin (assuan_context_t ctx, char *line)
1306 {
1307   ctrl_t ctrl = assuan_get_pointer (ctx);
1308   int rc;
1309   char *idstr;
1310
1311   if ((rc = open_card (ctrl)))
1312     return rc;
1313
1314   if (!ctrl->app_ctx)
1315     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1316
1317   /* We have to use a copy of the key ID because the function may use
1318      the pin_cb which in turn uses the assuan line buffer and thus
1319      overwriting the original line with the keyid. */
1320   idstr = xtrystrdup (line);
1321   if (!idstr)
1322     return out_of_core ();
1323
1324   rc = app_check_pin (ctrl->app_ctx, ctrl, idstr, pin_cb, ctx);
1325   xfree (idstr);
1326   if (rc)
1327     log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1328
1329   return rc;
1330 }
1331
1332
1333 static const char hlp_lock[] =
1334   "LOCK [--wait]\n"
1335   "\n"
1336   "Grant exclusive card access to this session.  Note that there is\n"
1337   "no lock counter used and a second lock from the same session will\n"
1338   "be ignored.  A single unlock (or RESET) unlocks the session.\n"
1339   "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1340   "\n"
1341   "If the option --wait is given the command will wait until a\n"
1342   "lock has been released.";
1343 static gpg_error_t
1344 cmd_lock (assuan_context_t ctx, char *line)
1345 {
1346   ctrl_t ctrl = assuan_get_pointer (ctx);
1347   int rc = 0;
1348
1349  retry:
1350   if (locked_session)
1351     {
1352       if (locked_session != ctrl->server_local)
1353         rc = gpg_error (GPG_ERR_LOCKED);
1354     }
1355   else
1356     locked_session = ctrl->server_local;
1357
1358 #ifdef USE_NPTH
1359   if (rc && has_option (line, "--wait"))
1360     {
1361       rc = 0;
1362       npth_sleep (1); /* Better implement an event mechanism. However,
1363                          for card operations this should be
1364                          sufficient. */
1365       /* FIXME: Need to check that the connection is still alive.
1366          This can be done by issuing status messages. */
1367       goto retry;
1368     }
1369 #endif /*USE_NPTH*/
1370
1371   if (rc)
1372     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1373   return rc;
1374 }
1375
1376
1377 static const char hlp_unlock[] =
1378   "UNLOCK\n"
1379   "\n"
1380   "Release exclusive card access.";
1381 static gpg_error_t
1382 cmd_unlock (assuan_context_t ctx, char *line)
1383 {
1384   ctrl_t ctrl = assuan_get_pointer (ctx);
1385   int rc = 0;
1386
1387   (void)line;
1388
1389   if (locked_session)
1390     {
1391       if (locked_session != ctrl->server_local)
1392         rc = gpg_error (GPG_ERR_LOCKED);
1393       else
1394         locked_session = NULL;
1395     }
1396   else
1397     rc = gpg_error (GPG_ERR_NOT_LOCKED);
1398
1399   if (rc)
1400     log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1401   return rc;
1402 }
1403
1404
1405 static const char hlp_getinfo[] =
1406   "GETINFO <what>\n"
1407   "\n"
1408   "Multi purpose command to return certain information.  \n"
1409   "Supported values of WHAT are:\n"
1410   "\n"
1411   "  version     - Return the version of the program.\n"
1412   "  pid         - Return the process id of the server.\n"
1413   "  socket_name - Return the name of the socket.\n"
1414   "  connections - Return number of active connections.\n"
1415   "  status      - Return the status of the current reader (in the future,\n"
1416   "                may also return the status of all readers).  The status\n"
1417   "                is a list of one-character flags.  The following flags\n"
1418   "                are currently defined:\n"
1419   "                  'u'  Usable card present.\n"
1420   "                  'r'  Card removed.  A reset is necessary.\n"
1421   "                These flags are exclusive.\n"
1422   "  reader_list - Return a list of detected card readers.  Does\n"
1423   "                currently only work with the internal CCID driver.\n"
1424   "  deny_admin  - Returns OK if admin commands are not allowed or\n"
1425   "                GPG_ERR_GENERAL if admin commands are allowed.\n"
1426   "  app_list    - Return a list of supported applications.  One\n"
1427   "                application per line, fields delimited by colons,\n"
1428   "                first field is the name.\n"
1429   "  card_list   - Return a list of serial numbers of active cards,\n"
1430   "                using a status response.";
1431 static gpg_error_t
1432 cmd_getinfo (assuan_context_t ctx, char *line)
1433 {
1434   int rc = 0;
1435
1436   if (!strcmp (line, "version"))
1437     {
1438       const char *s = VERSION;
1439       rc = assuan_send_data (ctx, s, strlen (s));
1440     }
1441   else if (!strcmp (line, "pid"))
1442     {
1443       char numbuf[50];
1444
1445       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1446       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1447     }
1448   else if (!strcmp (line, "socket_name"))
1449     {
1450       const char *s = scd_get_socket_name ();
1451
1452       if (s)
1453         rc = assuan_send_data (ctx, s, strlen (s));
1454       else
1455         rc = gpg_error (GPG_ERR_NO_DATA);
1456     }
1457   else if (!strcmp (line, "connections"))
1458     {
1459       char numbuf[20];
1460
1461       snprintf (numbuf, sizeof numbuf, "%d", get_active_connection_count ());
1462       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1463     }
1464   else if (!strcmp (line, "status"))
1465     {
1466       ctrl_t ctrl = assuan_get_pointer (ctx);
1467       char flag;
1468
1469       if (open_card (ctrl))
1470         flag = 'r';
1471       else
1472         flag = 'u';
1473
1474       rc = assuan_send_data (ctx, &flag, 1);
1475     }
1476   else if (!strcmp (line, "reader_list"))
1477     {
1478 #ifdef HAVE_LIBUSB
1479       char *s = ccid_get_reader_list ();
1480 #else
1481       char *s = NULL;
1482 #endif
1483
1484       if (s)
1485         rc = assuan_send_data (ctx, s, strlen (s));
1486       else
1487         rc = gpg_error (GPG_ERR_NO_DATA);
1488       xfree (s);
1489     }
1490   else if (!strcmp (line, "deny_admin"))
1491     rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1492   else if (!strcmp (line, "app_list"))
1493     {
1494       char *s = get_supported_applications ();
1495       if (s)
1496         rc = assuan_send_data (ctx, s, strlen (s));
1497       else
1498         rc = 0;
1499       xfree (s);
1500     }
1501   else if (!strcmp (line, "card_list"))
1502     {
1503       ctrl_t ctrl = assuan_get_pointer (ctx);
1504
1505       app_send_card_list (ctrl);
1506     }
1507   else
1508     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1509   return rc;
1510 }
1511
1512
1513 static const char hlp_restart[] =
1514   "RESTART\n"
1515   "\n"
1516   "Restart the current connection; this is a kind of warm reset.  It\n"
1517   "deletes the context used by this connection but does not send a\n"
1518   "RESET to the card.  Thus the card itself won't get reset. \n"
1519   "\n"
1520   "This is used by gpg-agent to reuse a primary pipe connection and\n"
1521   "may be used by clients to backup from a conflict in the serial\n"
1522   "command; i.e. to select another application.";
1523 static gpg_error_t
1524 cmd_restart (assuan_context_t ctx, char *line)
1525 {
1526   ctrl_t ctrl = assuan_get_pointer (ctx);
1527   app_t app = ctrl->app_ctx;
1528
1529   (void)line;
1530
1531   if (app)
1532     {
1533       ctrl->app_ctx = NULL;
1534       release_application (app, 0);
1535     }
1536   if (locked_session && ctrl->server_local == locked_session)
1537     {
1538       locked_session = NULL;
1539       log_info ("implicitly unlocking due to RESTART\n");
1540     }
1541   return 0;
1542 }
1543
1544
1545 static const char hlp_disconnect[] =
1546   "DISCONNECT\n"
1547   "\n"
1548   "Disconnect the card if the backend supports a disconnect operation.";
1549 static gpg_error_t
1550 cmd_disconnect (assuan_context_t ctx, char *line)
1551 {
1552   ctrl_t ctrl = assuan_get_pointer (ctx);
1553
1554   (void)line;
1555
1556   if (!ctrl->app_ctx)
1557     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1558
1559   apdu_disconnect (ctrl->app_ctx->slot);
1560   return 0;
1561 }
1562
1563
1564
1565 static const char hlp_apdu[] =
1566   "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1567   "\n"
1568   "Send an APDU to the current reader.  This command bypasses the high\n"
1569   "level functions and sends the data directly to the card.  HEXSTRING\n"
1570   "is expected to be a proper APDU.  If HEXSTRING is not given no\n"
1571   "commands are set to the card but the command will implictly check\n"
1572   "whether the card is ready for use. \n"
1573   "\n"
1574   "Using the option \"--atr\" returns the ATR of the card as a status\n"
1575   "message before any data like this:\n"
1576   "  S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1577   "\n"
1578   "Using the option --more handles the card status word MORE_DATA\n"
1579   "(61xx) and concatenates all responses to one block.\n"
1580   "\n"
1581   "Using the option \"--exlen\" the returned APDU may use extended\n"
1582   "length up to N bytes.  If N is not given a default value is used\n"
1583   "(currently 4096).";
1584 static gpg_error_t
1585 cmd_apdu (assuan_context_t ctx, char *line)
1586 {
1587   ctrl_t ctrl = assuan_get_pointer (ctx);
1588   app_t app;
1589   int rc;
1590   unsigned char *apdu;
1591   size_t apdulen;
1592   int with_atr;
1593   int handle_more;
1594   const char *s;
1595   size_t exlen;
1596
1597   if (has_option (line, "--dump-atr"))
1598     with_atr = 2;
1599   else
1600     with_atr = has_option (line, "--atr");
1601   handle_more = has_option (line, "--more");
1602
1603   if ((s=has_option_name (line, "--exlen")))
1604     {
1605       if (*s == '=')
1606         exlen = strtoul (s+1, NULL, 0);
1607       else
1608         exlen = 4096;
1609     }
1610   else
1611     exlen = 0;
1612
1613   line = skip_options (line);
1614
1615   if ((rc = open_card (ctrl)))
1616     return rc;
1617
1618   app = ctrl->app_ctx;
1619   if (!app)
1620     return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
1621
1622   if (with_atr)
1623     {
1624       unsigned char *atr;
1625       size_t atrlen;
1626       char hexbuf[400];
1627
1628       atr = apdu_get_atr (app->slot, &atrlen);
1629       if (!atr || atrlen > sizeof hexbuf - 2 )
1630         {
1631           rc = gpg_error (GPG_ERR_INV_CARD);
1632           goto leave;
1633         }
1634       if (with_atr == 2)
1635         {
1636           char *string, *p, *pend;
1637
1638           string = atr_dump (atr, atrlen);
1639           if (string)
1640             {
1641               for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1642                 {
1643                   rc = assuan_send_data (ctx, p, pend - p + 1);
1644                   if (!rc)
1645                     rc = assuan_send_data (ctx, NULL, 0);
1646                 }
1647               if (!rc && *p)
1648                 rc = assuan_send_data (ctx, p, strlen (p));
1649               es_free (string);
1650               if (rc)
1651                 goto leave;
1652             }
1653         }
1654       else
1655         {
1656           bin2hex (atr, atrlen, hexbuf);
1657           send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1658         }
1659       xfree (atr);
1660     }
1661
1662   apdu = hex_to_buffer (line, &apdulen);
1663   if (!apdu)
1664     {
1665       rc = gpg_error_from_syserror ();
1666       goto leave;
1667     }
1668   if (apdulen)
1669     {
1670       unsigned char *result = NULL;
1671       size_t resultlen;
1672
1673       rc = apdu_send_direct (app->slot, exlen,
1674                              apdu, apdulen, handle_more,
1675                              NULL, &result, &resultlen);
1676       if (rc)
1677         log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1678       else
1679         {
1680           rc = assuan_send_data (ctx, result, resultlen);
1681           xfree (result);
1682         }
1683     }
1684   xfree (apdu);
1685
1686  leave:
1687   return rc;
1688 }
1689
1690
1691 static const char hlp_killscd[] =
1692   "KILLSCD\n"
1693   "\n"
1694   "Commit suicide.";
1695 static gpg_error_t
1696 cmd_killscd (assuan_context_t ctx, char *line)
1697 {
1698   ctrl_t ctrl = assuan_get_pointer (ctx);
1699
1700   (void)line;
1701
1702   ctrl->server_local->stopme = 1;
1703   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1704   return 0;
1705 }
1706
1707
1708 \f
1709 /* Tell the assuan library about our commands */
1710 static int
1711 register_commands (assuan_context_t ctx)
1712 {
1713   static struct {
1714     const char *name;
1715     assuan_handler_t handler;
1716     const char * const help;
1717   } table[] = {
1718     { "SERIALNO",     cmd_serialno, hlp_serialno },
1719     { "LEARN",        cmd_learn,    hlp_learn },
1720     { "READCERT",     cmd_readcert, hlp_readcert },
1721     { "READKEY",      cmd_readkey,  hlp_readkey },
1722     { "SETDATA",      cmd_setdata,  hlp_setdata },
1723     { "PKSIGN",       cmd_pksign,   hlp_pksign },
1724     { "PKAUTH",       cmd_pkauth,   hlp_pkauth },
1725     { "PKDECRYPT",    cmd_pkdecrypt,hlp_pkdecrypt },
1726     { "INPUT",        NULL },
1727     { "OUTPUT",       NULL },
1728     { "GETATTR",      cmd_getattr,  hlp_getattr },
1729     { "SETATTR",      cmd_setattr,  hlp_setattr },
1730     { "WRITECERT",    cmd_writecert,hlp_writecert },
1731     { "WRITEKEY",     cmd_writekey, hlp_writekey },
1732     { "GENKEY",       cmd_genkey,   hlp_genkey },
1733     { "RANDOM",       cmd_random,   hlp_random },
1734     { "PASSWD",       cmd_passwd,   hlp_passwd },
1735     { "CHECKPIN",     cmd_checkpin, hlp_checkpin },
1736     { "LOCK",         cmd_lock,     hlp_lock },
1737     { "UNLOCK",       cmd_unlock,   hlp_unlock },
1738     { "GETINFO",      cmd_getinfo,  hlp_getinfo },
1739     { "RESTART",      cmd_restart,  hlp_restart },
1740     { "DISCONNECT",   cmd_disconnect,hlp_disconnect },
1741     { "APDU",         cmd_apdu,     hlp_apdu },
1742     { "KILLSCD",      cmd_killscd,  hlp_killscd },
1743     { NULL }
1744   };
1745   int i, rc;
1746
1747   for (i=0; table[i].name; i++)
1748     {
1749       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1750                                     table[i].help);
1751       if (rc)
1752         return rc;
1753     }
1754   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1755
1756   assuan_register_reset_notify (ctx, reset_notify);
1757   assuan_register_option_handler (ctx, option_handler);
1758   return 0;
1759 }
1760
1761
1762 /* Startup the server.  If FD is given as -1 this is simple pipe
1763    server, otherwise it is a regular server.  Returns true if there
1764    are no more active asessions.  */
1765 int
1766 scd_command_handler (ctrl_t ctrl, int fd)
1767 {
1768   int rc;
1769   assuan_context_t ctx = NULL;
1770   int stopme;
1771
1772   rc = assuan_new (&ctx);
1773   if (rc)
1774     {
1775       log_error ("failed to allocate assuan context: %s\n",
1776                  gpg_strerror (rc));
1777       scd_exit (2);
1778     }
1779
1780   if (fd == -1)
1781     {
1782       assuan_fd_t filedes[2];
1783
1784       filedes[0] = assuan_fdopen (0);
1785       filedes[1] = assuan_fdopen (1);
1786       rc = assuan_init_pipe_server (ctx, filedes);
1787     }
1788   else
1789     {
1790       rc = assuan_init_socket_server (ctx, INT2FD(fd),
1791                                       ASSUAN_SOCKET_SERVER_ACCEPTED);
1792     }
1793   if (rc)
1794     {
1795       log_error ("failed to initialize the server: %s\n",
1796                  gpg_strerror(rc));
1797       scd_exit (2);
1798     }
1799   rc = register_commands (ctx);
1800   if (rc)
1801     {
1802       log_error ("failed to register commands with Assuan: %s\n",
1803                  gpg_strerror(rc));
1804       scd_exit (2);
1805     }
1806   assuan_set_pointer (ctx, ctrl);
1807
1808   /* Allocate and initialize the server object.  Put it into the list
1809      of active sessions. */
1810   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1811   ctrl->server_local->next_session = session_list;
1812   session_list = ctrl->server_local;
1813   ctrl->server_local->ctrl_backlink = ctrl;
1814   ctrl->server_local->assuan_ctx = ctx;
1815
1816   /* Command processing loop. */
1817   for (;;)
1818     {
1819       rc = assuan_accept (ctx);
1820       if (rc == -1)
1821         {
1822           break;
1823         }
1824       else if (rc)
1825         {
1826           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1827           break;
1828         }
1829
1830       rc = assuan_process (ctx);
1831       if (rc)
1832         {
1833           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1834           continue;
1835         }
1836     }
1837
1838   /* Cleanup.  We don't send an explicit reset to the card.  */
1839   do_reset (ctrl, 0);
1840
1841   /* Release the server object.  */
1842   if (session_list == ctrl->server_local)
1843     session_list = ctrl->server_local->next_session;
1844   else
1845     {
1846       struct server_local_s *sl;
1847
1848       for (sl=session_list; sl->next_session; sl = sl->next_session)
1849         if (sl->next_session == ctrl->server_local)
1850           break;
1851       if (!sl->next_session)
1852           BUG ();
1853       sl->next_session = ctrl->server_local->next_session;
1854     }
1855   stopme = ctrl->server_local->stopme;
1856   xfree (ctrl->server_local);
1857   ctrl->server_local = NULL;
1858
1859   /* Release the Assuan context.  */
1860   assuan_release (ctx);
1861
1862   if (stopme)
1863     scd_exit (0);
1864
1865   /* If there are no more sessions return true.  */
1866   return !session_list;
1867 }
1868
1869
1870 /* Send a line with status information via assuan and escape all given
1871    buffers. The variable elements are pairs of (char *, size_t),
1872    terminated with a (NULL, 0). */
1873 void
1874 send_status_info (ctrl_t ctrl, const char *keyword, ...)
1875 {
1876   va_list arg_ptr;
1877   const unsigned char *value;
1878   size_t valuelen;
1879   char buf[950], *p;
1880   size_t n;
1881   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1882
1883   va_start (arg_ptr, keyword);
1884
1885   p = buf;
1886   n = 0;
1887   while ( (value = va_arg (arg_ptr, const unsigned char *))
1888            && n < DIM (buf)-2 )
1889     {
1890       valuelen = va_arg (arg_ptr, size_t);
1891       if (!valuelen)
1892         continue; /* empty buffer */
1893       if (n)
1894         {
1895           *p++ = ' ';
1896           n++;
1897         }
1898       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1899         {
1900           if (*value == '+' || *value == '\"' || *value == '%'
1901               || *value < ' ')
1902             {
1903               sprintf (p, "%%%02X", *value);
1904               p += 3;
1905               n += 2;
1906             }
1907           else if (*value == ' ')
1908             *p++ = '+';
1909           else
1910             *p++ = *value;
1911         }
1912     }
1913   *p = 0;
1914   assuan_write_status (ctx, keyword, buf);
1915
1916   va_end (arg_ptr);
1917 }
1918
1919
1920 /* Send a ready formatted status line via assuan.  */
1921 void
1922 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
1923 {
1924   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1925
1926   if (strchr (args, '\n'))
1927     log_error ("error: LF detected in status line - not sending\n");
1928   else
1929     assuan_write_status (ctx, keyword, args);
1930 }
1931
1932
1933 /* This status functions expects a printf style format string.  No
1934  * filtering of the data is done instead the orintf formatted data is
1935  * send using assuan_send_status. */
1936 gpg_error_t
1937 send_status_printf (ctrl_t ctrl, const char *keyword, const char *format, ...)
1938 {
1939   gpg_error_t err;
1940   va_list arg_ptr;
1941   assuan_context_t ctx;
1942
1943   if (!ctrl || !ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
1944     return 0;
1945
1946   va_start (arg_ptr, format);
1947   err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
1948   va_end (arg_ptr);
1949   return err;
1950 }
1951
1952
1953 void
1954 popup_prompt (void *opaque, int on)
1955 {
1956   ctrl_t ctrl = opaque;
1957
1958   if (ctrl)
1959     {
1960       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1961
1962       if (ctx)
1963         {
1964           const char *cmd;
1965           gpg_error_t err;
1966           unsigned char *value;
1967           size_t valuelen;
1968
1969           if (on)
1970             cmd = "POPUPPINPADPROMPT --ack";
1971           else
1972             cmd = "DISMISSPINPADPROMPT";
1973           err = assuan_inquire (ctx, cmd, &value, &valuelen, 100);
1974           if (!err)
1975             xfree (value);
1976         }
1977     }
1978 }
1979
1980
1981 /* Helper to send the clients a status change notification.  */
1982 void
1983 send_client_notifications (app_t app, int removal)
1984 {
1985   struct {
1986     pid_t pid;
1987 #ifdef HAVE_W32_SYSTEM
1988     HANDLE handle;
1989 #else
1990     int signo;
1991 #endif
1992   } killed[50];
1993   int killidx = 0;
1994   int kidx;
1995   struct server_local_s *sl;
1996
1997   for (sl=session_list; sl; sl = sl->next_session)
1998     if (sl->ctrl_backlink && sl->ctrl_backlink->app_ctx == app)
1999       {
2000         pid_t pid;
2001 #ifdef HAVE_W32_SYSTEM
2002         HANDLE handle;
2003 #else
2004         int signo;
2005 #endif
2006
2007         if (removal)
2008           {
2009             sl->ctrl_backlink->app_ctx = NULL;
2010             sl->card_removed = 1;
2011             release_application (app, 1);
2012           }
2013
2014         if (!sl->event_signal || !sl->assuan_ctx)
2015           continue;
2016
2017         pid = assuan_get_pid (sl->assuan_ctx);
2018
2019 #ifdef HAVE_W32_SYSTEM
2020         handle = sl->event_signal;
2021         for (kidx=0; kidx < killidx; kidx++)
2022           if (killed[kidx].pid == pid
2023               && killed[kidx].handle == handle)
2024             break;
2025         if (kidx < killidx)
2026           log_info ("event %p (%p) already triggered for client %d\n",
2027                     sl->event_signal, handle, (int)pid);
2028         else
2029           {
2030             log_info ("triggering event %p (%p) for client %d\n",
2031                       sl->event_signal, handle, (int)pid);
2032             if (!SetEvent (handle))
2033               log_error ("SetEvent(%p) failed: %s\n",
2034                          sl->event_signal, w32_strerror (-1));
2035             if (killidx < DIM (killed))
2036               {
2037                 killed[killidx].pid = pid;
2038                 killed[killidx].handle = handle;
2039                 killidx++;
2040               }
2041           }
2042 #else /*!HAVE_W32_SYSTEM*/
2043         signo = sl->event_signal;
2044
2045         if (pid != (pid_t)(-1) && pid && signo > 0)
2046           {
2047             for (kidx=0; kidx < killidx; kidx++)
2048               if (killed[kidx].pid == pid
2049                   && killed[kidx].signo == signo)
2050                 break;
2051             if (kidx < killidx)
2052               log_info ("signal %d already sent to client %d\n",
2053                         signo, (int)pid);
2054             else
2055               {
2056                 log_info ("sending signal %d to client %d\n",
2057                           signo, (int)pid);
2058                 kill (pid, signo);
2059                 if (killidx < DIM (killed))
2060                   {
2061                     killed[killidx].pid = pid;
2062                     killed[killidx].signo = signo;
2063                     killidx++;
2064                   }
2065               }
2066           }
2067 #endif /*!HAVE_W32_SYSTEM*/
2068       }
2069 }