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