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