* app-openpgp.c (app_local_s): New field PK.
[gnupg.git] / scd / command.c
1 /* command.c - SCdaemon command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
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
30 #include <assuan.h>
31
32 #include "scdaemon.h"
33 #include <ksba.h>
34 #include "app-common.h"
35 #include "apdu.h" /* Required for apdu_*_reader (). */
36
37 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
38 #define MAXLEN_PIN 100
39
40
41 /* We keep track of the primary client using scdaemon.  This one will
42    for example receive signal on card change. */
43 static ctrl_t primary_connection;
44
45
46 #define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
47
48 /* Data used to associate an Assuan context with local server data */
49 struct server_local_s {
50   ASSUAN_CONTEXT assuan_ctx;
51   int event_signal;        /* Or 0 if not used. */
52 };
53
54
55 /* Check whether the option NAME appears in LINE */
56 static int
57 has_option (const char *line, const char *name)
58 {
59   const char *s;
60   int n = strlen (name);
61
62   s = strstr (line, name);
63   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
64 }
65
66
67 /* Reset the card and free the application context.  With DO_CLOSE set
68    to true, close the reader and don't do just a reset. */
69 static void
70 do_reset (ctrl_t ctrl, int do_close)
71 {
72   if (ctrl->card_ctx)
73     {
74       card_close (ctrl->card_ctx);
75       ctrl->card_ctx = NULL;
76       xfree (ctrl->in_data.value);
77       ctrl->in_data.value = NULL;
78     }
79   if (ctrl->app_ctx)
80     {
81       release_application (ctrl->app_ctx);
82       ctrl->app_ctx = NULL;
83     }
84   if (ctrl->reader_slot != -1)
85     {
86       if (do_close || apdu_reset (ctrl->reader_slot))
87         {
88           apdu_close_reader (ctrl->reader_slot);
89           ctrl->reader_slot = -1;
90         }
91     }
92 }
93
94 \f
95 static void
96 reset_notify (ASSUAN_CONTEXT ctx)
97 {
98   CTRL ctrl = assuan_get_pointer (ctx); 
99
100   do_reset (ctrl, 0);
101 }
102
103
104 static int
105 option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
106 {
107   ctrl_t ctrl = assuan_get_pointer (ctx);
108
109   if (!strcmp (key, "event-signal"))
110     {
111       /* A value of 0 is allowed to reset the event signal. */
112       int i = *value? atoi (value) : -1;
113       if (i < 0)
114         return ASSUAN_Parameter_Error;
115       ctrl->server_local->event_signal = i;
116     }
117
118  return 0;
119 }
120
121
122 /* If the card has not yet been opened, do it.  Note that this
123    function returns an Assuan error, so don't map the error a second
124    time */
125 static AssuanError
126 open_card (ctrl_t ctrl, const char *apptype)
127 {
128   int slot;
129
130   if (ctrl->app_ctx)
131     return 0; /* Already initialized for one specific application. */
132   if (ctrl->card_ctx)
133     return 0; /* Already initialized using a card context. */
134
135   if (ctrl->reader_slot != -1)
136     slot = ctrl->reader_slot;
137   else
138     slot = apdu_open_reader (opt.reader_port);
139   ctrl->reader_slot = slot;
140   if (slot != -1)
141     ctrl->app_ctx = select_application (ctrl, slot, apptype);
142   if (!ctrl->app_ctx)
143     { /* No application found - fall back to old mode. */
144       /* Note that we should rework the old code to use the
145          application paradigma too. */
146       int rc;
147       
148       /* If an APPTYPE was requested and it is not pkcs#15, we return
149          an error here. */
150       if (apptype && !(!strcmp (apptype, "P15") || !strcmp (apptype, "p15")))
151         rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
152       else 
153         rc = card_open (&ctrl->card_ctx);
154       if (rc)
155         return map_to_assuan_status (rc);
156     }
157   return 0;
158 }
159
160
161 /* Do the percent and plus/space unescaping in place and return the
162    length of the valid buffer. */
163 static size_t
164 percent_plus_unescape (unsigned char *string)
165 {
166   unsigned char *p = string;
167   size_t n = 0;
168
169   while (*string)
170     {
171       if (*string == '%' && string[1] && string[2])
172         { 
173           string++;
174           *p++ = xtoi_2 (string);
175           n++;
176           string+= 2;
177         }
178       else if (*string == '+')
179         {
180           *p++ = ' ';
181           n++;
182           string++;
183         }
184       else
185         {
186           *p++ = *string++;
187           n++;
188         }
189     }
190
191   return n;
192 }
193
194
195
196 /* SERIALNO [APPTYPE] 
197
198    Return the serial number of the card using a status reponse.  This
199    functon should be used to check for the presence of a card.
200
201    If APPTYPE is given, an application of that type is selected and an
202    error is returned if the application is not supported or available.
203    The default is to auto-select the application using a hardwired
204    preference system.  Note, that a future extension to this function
205    may allow to specify a list and order of applications to try.
206
207    This function is special in that it can be used to reset the card.
208    Most other functions will return an error when a card change has
209    been detected and the use of this function is therefore required.
210
211    Background: We want to keep the client clear of handling card
212    changes between operations; i.e. the client can assume that all
213    operations are done on the same card unless he calls this function.
214  */
215 static int
216 cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
217 {
218   CTRL ctrl = assuan_get_pointer (ctx);
219   int rc = 0;
220   char *serial_and_stamp;
221   char *serial;
222   time_t stamp;
223
224   if ((rc = open_card (ctrl, *line? line:NULL)))
225     return rc;
226
227   if (ctrl->app_ctx)
228     rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
229   else
230     rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
231   if (rc)
232     return map_to_assuan_status (rc);
233   rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
234   xfree (serial);
235   if (rc < 0)
236     return ASSUAN_Out_Of_Core;
237   rc = 0;
238   assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
239   free (serial_and_stamp);
240   return 0;
241 }
242
243
244
245
246 /* LEARN [--force]
247
248    Learn all useful information of the currently inserted card.  When
249    used without the force options, the command might do an INQUIRE
250    like this:
251
252       INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
253
254    The client should just send an "END" if the processing should go on
255    or a "CANCEL" to force the function to terminate with a Cancel
256    error message.  The response of this command is a list of status
257    lines formatted as this:
258
259      S APPTYPE <apptype>
260
261    This returns the type of the application, currently the strings:
262
263        P15     = PKCS-15 structure used
264        DINSIG  = DIN SIG
265        OPENPGP = OpenPGP card
266  
267    are implemented.  These strings are aliases for the AID
268
269      S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
270
271    If there is no certificate yet stored on the card a single "X" is
272    returned as the keygrip.  In addition to the keypair info, information
273    about all certificates stored on the card is also returned:
274
275      S CERTINFO <certtype> <hexstring_with_id>
276
277    Where CERTTYPE is a number indicating the type of certificate:
278       0   := Unknown
279       100 := Regular X.509 cert
280       101 := Trusted X.509 cert
281       102 := Useful X.509 cert
282       110 := Root CA cert (DINSIG)
283
284    For certain cards, more information will be returned:
285
286      S KEY-FPR <no> <hexstring>
287
288    For OpenPGP cards this returns the stored fingerprints of the
289    keys. This can be used check whether a key is available on the
290    card.  NO may be 1, 2 or 3.
291
292      S CA-FPR <no> <hexstring>
293
294    Similar to above, these are the fingerprints of keys assumed to be
295    ultimately trusted.
296
297      S DISP-NAME <name_of_card_holder>
298
299    The name of the card holder as stored on the card; percent
300    escaping takes place, spaces are encoded as '+'
301
302      S PUBKEY-URL <url>
303
304    The URL to be used for locating the entire public key.
305      
306 */
307 static int
308 cmd_learn (ASSUAN_CONTEXT ctx, char *line)
309 {
310   CTRL ctrl = assuan_get_pointer (ctx);
311   int rc = 0;
312   int idx;
313
314   if ((rc = open_card (ctrl, NULL)))
315     return rc;
316
317   /* Unless the force option is used we try a shortcut by identifying
318      the card using a serial number and inquiring the client with
319      that. The client may choose to cancel the operation if he already
320      knows about this card */
321   {
322     char *serial_and_stamp;
323     char *serial;
324     time_t stamp;
325
326     if (ctrl->app_ctx)
327       rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
328     else
329       rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
330     if (rc)
331       return map_to_assuan_status (rc);
332     rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
333     xfree (serial);
334     if (rc < 0)
335       return ASSUAN_Out_Of_Core;
336     rc = 0;
337     assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
338
339     if (!has_option (line, "--force"))
340       {
341         char *command;
342
343         rc = asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
344         if (rc < 0)
345           {
346             free (serial_and_stamp);
347             return ASSUAN_Out_Of_Core;
348           }
349         rc = 0;
350         rc = assuan_inquire (ctx, command, NULL, NULL, 0); 
351         free (command);  /* (must use standard free here) */
352         if (rc)
353           {
354             if (rc != ASSUAN_Canceled)
355               log_error ("inquire KNOWNCARDP failed: %s\n",
356                          assuan_strerror (rc));
357             free (serial_and_stamp);
358             return rc; 
359           }
360         /* not canceled, so we have to proceeed */
361       }
362     free (serial_and_stamp);
363   }
364
365   /* If we are using the modern application paradigma, let the
366      application print out its collection of useful status
367      information. */
368   if (!rc && ctrl->app_ctx)
369     rc = app_write_learn_status (ctrl->app_ctx, ctrl);
370
371   /* Return information about the certificates.  FIXME: Move this into
372      an app-p15.c*/
373   for (idx=0; !rc && !ctrl->app_ctx; idx++)
374     {
375       char *certid;
376       int certtype;
377
378       rc = card_enum_certs (ctrl->card_ctx, idx, &certid, &certtype);
379       if (!rc)
380         {
381           char *buf;
382
383           buf = xtrymalloc (40 + 1 + strlen (certid) + 1);
384           if (!buf)
385             rc = gpg_error (gpg_err_code_from_errno (errno));
386           else
387             {
388               sprintf (buf, "%d %s", certtype, certid);
389               assuan_write_status (ctx, "CERTINFO", buf);
390               xfree (buf);
391             }
392         }
393       xfree (certid);
394     }
395   if (rc == -1)
396     rc = 0;
397
398   /* Return information about the keys. FIXME: Move this into an
399      app-p15.c */
400   for (idx=0; !rc && !ctrl->app_ctx; idx++)
401     {
402       unsigned char keygrip[20];
403       char *keyid;
404       int no_cert = 0;
405
406       rc = card_enum_keypairs (ctrl->card_ctx, idx, keygrip, &keyid);
407       if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT && keyid)
408         {
409           /* This does happen with an incomplete personalized
410              card; i.e. during the time we have stored the key on the
411              card but not stored the certificate; probably becuase it
412              has not yet been received back from the CA.  Note that we
413              must release KEYID in this case. */
414           rc = 0; 
415           no_cert = 1;
416         }
417       if (!rc)
418         {
419           char *buf, *p;
420
421           buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1);
422           if (!buf)
423             rc = gpg_error (gpg_err_code_from_errno (errno));
424           else
425             {
426               int i;
427               
428               if (no_cert)
429                 *p++ = 'X';
430               else
431                 {
432                   for (i=0; i < 20; i++, p += 2)
433                     sprintf (p, "%02X", keygrip[i]);
434                 }
435               *p++ = ' ';
436               strcpy (p, keyid);
437               assuan_write_status (ctx, "KEYPAIRINFO", buf);
438               xfree (buf);
439             }
440         }
441       xfree (keyid);
442     }
443   if (rc == -1)
444     rc = 0;
445
446   return map_to_assuan_status (rc);
447 }
448
449
450 \f
451 /* READCERT <hexified_certid>
452
453  */
454 static int
455 cmd_readcert (ASSUAN_CONTEXT ctx, char *line)
456 {
457   CTRL ctrl = assuan_get_pointer (ctx);
458   int rc;
459   unsigned char *cert;
460   size_t ncert;
461
462   if ((rc = open_card (ctrl, NULL)))
463     return rc;
464
465   line = xstrdup (line); /* Need a copy of the line. */
466   if (ctrl->app_ctx)
467     {
468       rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
469       if (rc)
470         log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
471     }
472   else
473     {
474       rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
475       if (rc)
476         log_error ("card_read_cert failed: %s\n", gpg_strerror (rc));
477     }
478   xfree (line);
479   line = NULL;
480   if (!rc)
481     {
482       rc = assuan_send_data (ctx, cert, ncert);
483       xfree (cert);
484       if (rc)
485         return rc;
486     }
487
488   return map_to_assuan_status (rc);
489 }
490
491
492 /* READKEY <hexified_certid>
493
494    Return the public key for the given cert or key ID as an standard
495    S-Expression.  */
496 static int
497 cmd_readkey (assuan_context_t ctx, char *line)
498 {
499   ctrl_t ctrl = assuan_get_pointer (ctx);
500   int rc;
501   unsigned char *cert = NULL;
502   size_t ncert, n;
503   ksba_cert_t kc = NULL;
504   ksba_sexp_t p;
505
506   if ((rc = open_card (ctrl, NULL)))
507     return rc;
508
509   line = xstrdup (line); /* Need a copy of the line. */
510   if (ctrl->app_ctx)
511     {
512       unsigned char *pk;
513       size_t pklen;
514
515       /* If the application supports the READKEY function we use that.
516          Otherwise we use the old way by extracting it from the
517          certificate.  */
518       rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
519       if (!rc)
520         { /* Yeah, got that key - send it back.  */
521           rc = assuan_send_data (ctx, pk, pklen);
522           xfree (pk);
523           rc = map_assuan_err (rc);
524           xfree (line);
525           line = NULL;
526           goto leave;
527         }
528
529       if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
530         log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
531       else  
532         {
533           rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
534           if (rc)
535             log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
536         }
537     }
538   else
539     {
540       rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
541       if (rc)
542         log_error ("card_read_cert failed: %s\n", gpg_strerror (rc));
543     }
544   xfree (line);
545   line = NULL;
546   if (rc)
547     goto leave;
548       
549   rc = ksba_cert_new (&kc);
550   if (rc)
551     {
552       xfree (cert);
553       goto leave;
554     }
555   rc = ksba_cert_init_from_mem (kc, cert, ncert);
556   if (rc)
557     {
558       log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
559       goto leave;
560     }
561
562   p = ksba_cert_get_public_key (kc);
563   if (!p)
564     {
565       rc = gpg_error (GPG_ERR_NO_PUBKEY);
566       goto leave;
567     }
568
569   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
570   rc = assuan_send_data (ctx, p, n);
571   rc = map_assuan_err (rc);
572   xfree (p);
573
574
575  leave:
576   ksba_cert_release (kc);
577   xfree (cert);
578   return map_to_assuan_status (rc);
579 }
580
581
582 \f
583
584 /* SETDATA <hexstring> 
585
586    The client should use this command to tell us the data he want to
587    sign.  */
588 static int
589 cmd_setdata (ASSUAN_CONTEXT ctx, char *line)
590 {
591   CTRL ctrl = assuan_get_pointer (ctx);
592   int n;
593   char *p;
594   unsigned char *buf;
595
596   /* parse the hexstring */
597   for (p=line,n=0; hexdigitp (p); p++, n++)
598     ;
599   if (*p)
600     return set_error (Parameter_Error, "invalid hexstring");
601   if (!n)
602     return set_error (Parameter_Error, "no data given");
603   if ((n&1))
604     return set_error (Parameter_Error, "odd number of digits");
605   n /= 2;
606   buf = xtrymalloc (n);
607   if (!buf)
608     return ASSUAN_Out_Of_Core;
609
610   ctrl->in_data.value = buf;
611   ctrl->in_data.valuelen = n;
612   for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++)
613     buf[n] = xtoi_2 (p);
614   return 0;
615 }
616
617
618
619 static int 
620 pin_cb (void *opaque, const char *info, char **retstr)
621 {
622   ASSUAN_CONTEXT ctx = opaque;
623   char *command;
624   int rc;
625   unsigned char *value;
626   size_t valuelen;
627
628   *retstr = NULL;
629   log_debug ("asking for PIN '%s'\n", info);
630
631   rc = asprintf (&command, "NEEDPIN %s", info);
632   if (rc < 0)
633     return gpg_error (gpg_err_code_from_errno (errno));
634
635   /* FIXME: Write an inquire function which returns the result in
636      secure memory */
637   rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); 
638   free (command);  
639   if (rc)
640     return map_assuan_err (rc);
641
642   if (!valuelen || value[valuelen-1])
643     {
644       /* We require that the returned value is an UTF-8 string */
645       xfree (value);
646       return gpg_error (GPG_ERR_INV_RESPONSE);
647     }
648   *retstr = value;
649   return 0;
650 }
651
652
653 /* PKSIGN <hexified_id>
654
655  */
656 static int
657 cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
658 {
659   CTRL ctrl = assuan_get_pointer (ctx);
660   int rc;
661   unsigned char *outdata;
662   size_t outdatalen;
663   char *keyidstr;
664
665   if ((rc = open_card (ctrl, NULL)))
666     return rc;
667
668   /* We have to use a copy of the key ID because the function may use
669      the pin_cb which in turn uses the assuan line buffer and thus
670      overwriting the original line with the keyid */
671   keyidstr = xtrystrdup (line);
672   if (!keyidstr)
673     return ASSUAN_Out_Of_Core;
674   
675   if (ctrl->app_ctx)
676     rc = app_sign (ctrl->app_ctx,
677                     keyidstr, GCRY_MD_SHA1,
678                     pin_cb, ctx,
679                     ctrl->in_data.value, ctrl->in_data.valuelen,
680                     &outdata, &outdatalen);
681   else  
682     rc = card_sign (ctrl->card_ctx,
683                     keyidstr, GCRY_MD_SHA1,
684                     pin_cb, ctx,
685                     ctrl->in_data.value, ctrl->in_data.valuelen,
686                     &outdata, &outdatalen);
687   xfree (keyidstr);
688   if (rc)
689     {
690       log_error ("card_sign failed: %s\n", gpg_strerror (rc));
691     }
692   else
693     {
694       rc = assuan_send_data (ctx, outdata, outdatalen);
695       xfree (outdata);
696       if (rc)
697         return rc; /* that is already an assuan error code */
698     }
699
700   return map_to_assuan_status (rc);
701 }
702
703 /* PKAUTH <hexified_id>
704
705  */
706 static int
707 cmd_pkauth (ASSUAN_CONTEXT ctx, char *line)
708 {
709   CTRL ctrl = assuan_get_pointer (ctx);
710   int rc;
711   unsigned char *outdata;
712   size_t outdatalen;
713   char *keyidstr;
714
715   if ((rc = open_card (ctrl, NULL)))
716     return rc;
717
718   if (!ctrl->app_ctx)
719     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
720
721   /* We have to use a copy of the key ID because the function may use
722      the pin_cb which in turn uses the assuan line buffer and thus
723      overwriting the original line with the keyid */
724   keyidstr = xtrystrdup (line);
725   if (!keyidstr)
726     return ASSUAN_Out_Of_Core;
727   
728   rc = app_auth (ctrl->app_ctx,
729                  keyidstr,
730                  pin_cb, ctx,
731                  ctrl->in_data.value, ctrl->in_data.valuelen,
732                  &outdata, &outdatalen);
733   xfree (keyidstr);
734   if (rc)
735     {
736       log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc));
737     }
738   else
739     {
740       rc = assuan_send_data (ctx, outdata, outdatalen);
741       xfree (outdata);
742       if (rc)
743         return rc; /* that is already an assuan error code */
744     }
745
746   return map_to_assuan_status (rc);
747 }
748
749 /* PKDECRYPT <hexified_id>
750
751  */
752 static int
753 cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
754 {
755   CTRL ctrl = assuan_get_pointer (ctx);
756   int rc;
757   unsigned char *outdata;
758   size_t outdatalen;
759   char *keyidstr;
760
761   if ((rc = open_card (ctrl, NULL)))
762     return rc;
763
764   keyidstr = xtrystrdup (line);
765   if (!keyidstr)
766     return ASSUAN_Out_Of_Core;
767   if (ctrl->app_ctx)
768     rc = app_decipher (ctrl->app_ctx,
769                         keyidstr, 
770                         pin_cb, ctx,
771                         ctrl->in_data.value, ctrl->in_data.valuelen,
772                         &outdata, &outdatalen);
773   else
774     rc = card_decipher (ctrl->card_ctx,
775                         keyidstr, 
776                         pin_cb, ctx,
777                         ctrl->in_data.value, ctrl->in_data.valuelen,
778                         &outdata, &outdatalen);
779   xfree (keyidstr);
780   if (rc)
781     {
782       log_error ("card_create_signature failed: %s\n", gpg_strerror (rc));
783     }
784   else
785     {
786       rc = assuan_send_data (ctx, outdata, outdatalen);
787       xfree (outdata);
788       if (rc)
789         return rc; /* that is already an assuan error code */
790     }
791
792   return map_to_assuan_status (rc);
793 }
794
795
796 /* GETATTR <name>
797
798    This command is used to retrieve data from a smartcard.  The
799    allowed names depend on the currently selected smartcard
800    application.  NAME must be percent and '+' escaped.  The value is
801    returned through status message, see the LESRN command for details.
802
803    However, the current implementation assumes that Name is not escaped;
804    this works as long as noone uses arbitrary escaping. 
805  
806 */
807 static int
808 cmd_getattr (ASSUAN_CONTEXT ctx, char *line)
809 {
810   CTRL ctrl = assuan_get_pointer (ctx);
811   int rc;
812   char *keyword;
813
814   if ((rc = open_card (ctrl, NULL)))
815     return rc;
816
817   keyword = line;
818   for (; *line && !spacep (line); line++)
819     ;
820   if (*line)
821       *line++ = 0;
822
823   /* (We ignore any garbage for now.) */
824
825   rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
826
827   return map_to_assuan_status (rc);
828 }
829
830
831 /* SETATTR <name> <value> 
832
833    This command is used to store data on a a smartcard.  The allowed
834    names and values are depend on the currently selected smartcard
835    application.  NAME and VALUE must be percent and '+' escaped.
836
837    However, the curent implementation assumes that Name is not escaped;
838    this works as long as noone uses arbitrary escaping. 
839  
840    A PIN will be requested for most NAMEs.  See the corresponding
841    setattr function of the actually used application (app-*.c) for
842    details.  */
843 static int
844 cmd_setattr (ASSUAN_CONTEXT ctx, char *orig_line)
845 {
846   CTRL ctrl = assuan_get_pointer (ctx);
847   int rc;
848   char *keyword;
849   int keywordlen;
850   size_t nbytes;
851   char *line, *linebuf;
852
853   if ((rc = open_card (ctrl, NULL)))
854     return rc;
855
856   /* We need to use a copy of LINE, because PIN_CB uses the same
857      context and thus reuses the Assuan provided LINE. */
858   line = linebuf = xtrystrdup (orig_line);
859   if (!line)
860     return ASSUAN_Out_Of_Core;
861
862   keyword = line;
863   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
864     ;
865   if (*line)
866       *line++ = 0;
867   while (spacep (line))
868     line++;
869   nbytes = percent_plus_unescape (line);
870
871   rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes);
872   xfree (linebuf);
873
874   return map_to_assuan_status (rc);
875 }
876
877 /* GENKEY [--force] <no>
878
879    Generate a key on-card identified by NO, which is application
880    specific.  Return values are application specific.  For OpenPGP
881    cards 2 status lines are returned:
882
883      S KEY-FPR  <hexstring>
884      S KEY-CREATED-AT <seconds_since_epoch>
885      S KEY-DATA [p|n] <hexdata>
886      
887
888    --force is required to overwriet an already existing key.  The
889    KEY-CREATED-AT is required for further processing because it is
890    part of the hashed key material for the fingerprint.
891
892    The public part of the key can also later be retrieved using the
893    READKEY command.
894
895  */
896 static int
897 cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
898 {
899   CTRL ctrl = assuan_get_pointer (ctx);
900   int rc;
901   char *keyno;
902   int force = has_option (line, "--force");
903
904   /* Skip over options. */
905   while ( *line == '-' && line[1] == '-' )
906     {
907       while (*line && !spacep (line))
908         line++;
909       while (spacep (line))
910         line++;
911     }
912   if (!*line)
913     return set_error (Parameter_Error, "no key number given");
914   keyno = line;
915   while (*line && !spacep (line))
916     line++;
917   *line = 0;
918
919   if ((rc = open_card (ctrl, NULL)))
920     return rc;
921
922   if (!ctrl->app_ctx)
923     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
924
925   keyno = xtrystrdup (keyno);
926   if (!keyno)
927     return ASSUAN_Out_Of_Core;
928   rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
929   xfree (keyno);
930   return map_to_assuan_status (rc);
931 }
932
933
934 /* RANDOM <nbytes>
935
936    Get NBYTES of random from the card and send them back as data. 
937 */
938 static int
939 cmd_random (ASSUAN_CONTEXT ctx, char *line)
940 {
941   CTRL ctrl = assuan_get_pointer (ctx);
942   int rc;
943   size_t nbytes;
944   unsigned char *buffer;
945
946   if (!*line)
947     return set_error (Parameter_Error, "number of requested bytes missing");
948   nbytes = strtoul (line, NULL, 0);
949
950   if ((rc = open_card (ctrl, NULL)))
951     return rc;
952
953   if (!ctrl->app_ctx)
954     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
955
956   buffer = xtrymalloc (nbytes);
957   if (!buffer)
958     return ASSUAN_Out_Of_Core;
959
960   rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
961   if (!rc)
962     {
963       rc = assuan_send_data (ctx, buffer, nbytes);
964       xfree (buffer);
965       return rc; /* that is already an assuan error code */
966     }
967   xfree (buffer);
968
969   return map_to_assuan_status (rc);
970 }
971
972 \f
973 /* PASSWD [--reset] <chvno>
974   
975    Change the PIN or reset thye retry counter of the card holder
976    verfication vector CHVNO. */
977 static int
978 cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
979 {
980   CTRL ctrl = assuan_get_pointer (ctx);
981   int rc;
982   char *chvnostr;
983   int reset_mode = has_option (line, "--reset");
984
985   /* Skip over options. */
986   while (*line == '-' && line[1] == '-')
987     {
988       while (*line && !spacep (line))
989         line++;
990       while (spacep (line))
991         line++;
992     }
993   if (!*line)
994     return set_error (Parameter_Error, "no CHV number given");
995   chvnostr = line;
996   while (*line && !spacep (line))
997     line++;
998   *line = 0;
999
1000   if ((rc = open_card (ctrl, NULL)))
1001     return rc;
1002
1003   if (!ctrl->app_ctx)
1004     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1005   
1006   chvnostr = xtrystrdup (chvnostr);
1007   if (!chvnostr)
1008     return ASSUAN_Out_Of_Core;
1009   rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx);
1010   if (rc)
1011     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1012   xfree (chvnostr);
1013   return map_to_assuan_status (rc);
1014 }
1015
1016
1017 /* CHECKPIN <hexified_id>
1018
1019  */
1020 static int
1021 cmd_checkpin (ASSUAN_CONTEXT ctx, char *line)
1022 {
1023   CTRL ctrl = assuan_get_pointer (ctx);
1024   int rc;
1025   char *keyidstr;
1026
1027   if ((rc = open_card (ctrl, NULL)))
1028     return rc;
1029
1030   if (!ctrl->app_ctx)
1031     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1032
1033   /* We have to use a copy of the key ID because the function may use
1034      the pin_cb which in turn uses the assuan line buffer and thus
1035      overwriting the original line with the keyid. */
1036   keyidstr = xtrystrdup (line);
1037   if (!keyidstr)
1038     return ASSUAN_Out_Of_Core;
1039   
1040   rc = app_check_pin (ctrl->app_ctx,
1041                       keyidstr,
1042                       pin_cb, ctx);
1043   xfree (keyidstr);
1044   if (rc)
1045     log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1046
1047   return map_to_assuan_status (rc);
1048 }
1049
1050
1051
1052
1053 \f
1054 /* Tell the assuan library about our commands */
1055 static int
1056 register_commands (ASSUAN_CONTEXT ctx)
1057 {
1058   static struct {
1059     const char *name;
1060     int (*handler)(ASSUAN_CONTEXT, char *line);
1061   } table[] = {
1062     { "SERIALNO",     cmd_serialno },
1063     { "LEARN",        cmd_learn },
1064     { "READCERT",     cmd_readcert },
1065     { "READKEY",      cmd_readkey },
1066     { "SETDATA",      cmd_setdata },
1067     { "PKSIGN",       cmd_pksign },
1068     { "PKAUTH",       cmd_pkauth },
1069     { "PKDECRYPT",    cmd_pkdecrypt },
1070     { "INPUT",        NULL }, 
1071     { "OUTPUT",       NULL }, 
1072     { "GETATTR",      cmd_getattr },
1073     { "SETATTR",      cmd_setattr },
1074     { "GENKEY",       cmd_genkey },
1075     { "RANDOM",       cmd_random },
1076     { "PASSWD",       cmd_passwd },
1077     { "CHECKPIN",     cmd_checkpin },
1078     { NULL }
1079   };
1080   int i, rc;
1081
1082   for (i=0; table[i].name; i++)
1083     {
1084       rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1085       if (rc)
1086         return rc;
1087     } 
1088   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1089
1090   assuan_register_reset_notify (ctx, reset_notify);
1091   assuan_register_option_handler (ctx, option_handler);
1092   return 0;
1093 }
1094
1095
1096 /* Startup the server.  If LISTEN_FD is given as -1, this is simple
1097    piper server, otherwise it is a regular server */
1098 void
1099 scd_command_handler (int listen_fd)
1100 {
1101   int rc;
1102   ASSUAN_CONTEXT ctx;
1103   struct server_control_s ctrl;
1104
1105   memset (&ctrl, 0, sizeof ctrl);
1106   scd_init_default_ctrl (&ctrl);
1107   
1108   if (listen_fd == -1)
1109     {
1110       int filedes[2];
1111
1112       filedes[0] = 0;
1113       filedes[1] = 1;
1114       rc = assuan_init_pipe_server (&ctx, filedes);
1115     }
1116   else
1117     {
1118       rc = assuan_init_socket_server (&ctx, listen_fd);
1119     }
1120   if (rc)
1121     {
1122       log_error ("failed to initialize the server: %s\n",
1123                  assuan_strerror(rc));
1124       scd_exit (2);
1125     }
1126   rc = register_commands (ctx);
1127   if (rc)
1128     {
1129       log_error ("failed to register commands with Assuan: %s\n",
1130                  assuan_strerror(rc));
1131       scd_exit (2);
1132     }
1133   assuan_set_pointer (ctx, &ctrl);
1134   ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
1135   ctrl.server_local->assuan_ctx = ctx;
1136
1137   if (DBG_ASSUAN)
1138     assuan_set_log_stream (ctx, log_get_stream ());
1139
1140   /* Store the primary connection's assuan context. */
1141   if (!primary_connection)
1142     primary_connection = &ctrl;
1143
1144   /* We open the reader right at startup so that the ticker is able to
1145      update the status file. */
1146   if (ctrl.reader_slot == -1)
1147     ctrl.reader_slot = apdu_open_reader (opt.reader_port);
1148
1149   /* Command processing loop. */
1150   for (;;)
1151     {
1152       rc = assuan_accept (ctx);
1153       if (rc == -1)
1154         {
1155           break;
1156         }
1157       else if (rc)
1158         {
1159           log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
1160           break;
1161         }
1162       
1163       rc = assuan_process (ctx);
1164       if (rc)
1165         {
1166           log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
1167           continue;
1168         }
1169     }
1170
1171   /* The next client will be the primary conenction if this one
1172      terminates. */
1173   if (primary_connection == &ctrl)
1174     primary_connection = NULL;
1175
1176   do_reset (&ctrl, 1); /* Cleanup. */
1177
1178   assuan_deinit_server (ctx);
1179 }
1180
1181
1182 /* Send a line with status information via assuan and escape all given
1183    buffers. The variable elements are pairs of (char *, size_t),
1184    terminated with a (NULL, 0). */
1185 void
1186 send_status_info (CTRL ctrl, const char *keyword, ...)
1187 {
1188   va_list arg_ptr;
1189   const unsigned char *value;
1190   size_t valuelen;
1191   char buf[950], *p;
1192   size_t n;
1193   ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx;
1194   
1195   va_start (arg_ptr, keyword);
1196
1197   p = buf; 
1198   n = 0;
1199   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1200     {
1201       valuelen = va_arg (arg_ptr, size_t);
1202       if (!valuelen)
1203         continue; /* empty buffer */
1204       if (n)
1205         {
1206           *p++ = ' ';
1207           n++;
1208         }
1209       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1210         {
1211           if (*value < ' ' || *value == '+')
1212             {
1213               sprintf (p, "%%%02X", *value);
1214               p += 3;
1215             }
1216           else if (*value == ' ')
1217             *p++ = '+';
1218           else
1219             *p++ = *value;
1220         }
1221     }
1222   *p = 0;
1223   assuan_write_status (ctx, keyword, buf);
1224
1225   va_end (arg_ptr);
1226 }
1227
1228
1229
1230 void
1231 scd_update_reader_status_file (void)
1232 {
1233   static struct {
1234     int any;
1235     unsigned int status;
1236     unsigned int changed;
1237   } last[10];
1238   int slot;
1239   int used;
1240   unsigned int status, changed;
1241
1242   /* Note, that we only try to get the status, becuase it does not
1243      make sense to wait here for a operation to complete.  If we are
1244      so busy working with the card, delays in the status file updated
1245      are should be acceptable. */
1246   for (slot=0; (slot < DIM(last)
1247                 &&!apdu_enum_reader (slot, &used)); slot++)
1248     if (used && !apdu_get_status (slot, 0, &status, &changed))
1249       {
1250         if (!last[slot].any || last[slot].status != status
1251             || last[slot].changed != changed )
1252           {
1253             char *fname;
1254             char templ[50];
1255             FILE *fp;
1256
1257             last[slot].any = 1;
1258             last[slot].status = status;
1259             last[slot].changed = changed;
1260
1261             log_info ("updating status of slot %d to 0x%04X\n", slot, status);
1262             
1263             sprintf (templ, "reader_%d.status", slot);
1264             fname = make_filename (opt.homedir, templ, NULL );
1265             fp = fopen (fname, "w");
1266             if (fp)
1267               {
1268                 fprintf (fp, "%s\n",
1269                          (status & 1)? "USABLE":
1270                          (status & 4)? "ACTIVE":
1271                          (status & 2)? "PRESENT": "NOCARD");
1272                 fclose (fp);
1273               }
1274             xfree (fname);
1275
1276             /* Send a signal to the primary client, if any. */
1277             if (primary_connection && primary_connection->server_local
1278                 && primary_connection->server_local->assuan_ctx)
1279               {
1280                 pid_t pid = assuan_get_pid (primary_connection
1281                                             ->server_local->assuan_ctx);
1282                 int signo = primary_connection->server_local->event_signal;
1283
1284                 log_info ("client pid is %d, sending signal %d\n", pid, signo);
1285
1286 #ifndef HAVE_W32_SYSTEM
1287                 if (pid != (pid_t)(-1) && pid && signo > 0)
1288                   kill (pid, signo);
1289 #endif
1290               }
1291           }
1292       }
1293 }