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