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