2005-04-15 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / scd / command.c
blob9881b1be026ece8ecc773b6d081a653463cc22b5
1 /* command.c - SCdaemon command handler
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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
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_GNU_PTH
30 # include <pth.h>
31 #endif
33 #include <assuan.h>
35 #include "scdaemon.h"
36 #include <ksba.h>
37 #include "app-common.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
40 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
41 #define MAXLEN_PIN 100
44 #define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
47 /* Macro to flag a a removed card. */
48 #define TEST_CARD_REMOVAL(c,r) \
49 do { \
50 int _r = (r); \
51 if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
52 || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED) \
53 update_card_removed ((c)->reader_slot, 1); \
54 } while (0)
56 #define IS_LOCKED(c) \
57 (locked_session && locked_session != (c)->server_local \
58 && (c)->reader_slot != -1 && locked_session->ctrl_backlink \
59 && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
62 /* Data used to associate an Assuan context with local server data.
63 This object describes the local properties of one session. */
64 struct server_local_s {
65 /* We keep a list of all active sessions with the anchor at
66 SESSION_LIST (see below). This field is used for linking. */
67 struct server_local_s *next_session;
69 /* This object is usually assigned to a CTRL object (which is
70 globally visible). While enumeratin all sessions we sometimes
71 need to access data of the CTRL object; thus we keep a
72 backpointer here. */
73 ctrl_t ctrl_backlink;
75 /* The Assuan context used by this session/server. */
76 assuan_context_t assuan_ctx;
78 int event_signal; /* Or 0 if not used. */
80 /* True if the card has been removed and a reset is required to
81 continue operation. */
82 int card_removed;
86 /* To keep track of all running sessions, we link all active server
87 contexts and the anchor in this variable. */
88 static struct server_local_s *session_list;
90 /* If a session has been locked we store a link to its server object
91 in this variable. */
92 static struct server_local_s *locked_session;
97 /* Update the CARD_REMOVED element of all sessions using the reader
98 given by SLOT to VALUE */
99 static void
100 update_card_removed (int slot, int value)
102 struct server_local_s *sl;
104 for (sl=session_list; sl; sl = sl->next_session)
105 if (sl->ctrl_backlink
106 && sl->ctrl_backlink->reader_slot == slot)
107 sl->card_removed = value;
112 /* Check whether the option NAME appears in LINE */
113 static int
114 has_option (const char *line, const char *name)
116 const char *s;
117 int n = strlen (name);
119 s = strstr (line, name);
120 return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
124 /* Reset the card and free the application context. With DO_CLOSE set
125 to true and this is the last session with a reference to teh
126 reader, close the reader and don't do just a reset. */
127 static void
128 do_reset (ctrl_t ctrl, int do_close)
130 int slot = ctrl->reader_slot;
132 if (ctrl->card_ctx)
134 card_close (ctrl->card_ctx);
135 ctrl->card_ctx = NULL;
136 xfree (ctrl->in_data.value);
137 ctrl->in_data.value = NULL;
139 if (ctrl->app_ctx)
141 release_application (ctrl->app_ctx);
142 ctrl->app_ctx = NULL;
144 if (ctrl->reader_slot != -1)
146 struct server_local_s *sl;
148 /* If we are the only session with the reader open we may close
149 it. If not, do a reset unless the a lock is held on the
150 reader. */
151 for (sl=session_list; sl; sl = sl->next_session)
152 if (sl != ctrl->server_local
153 && sl->ctrl_backlink->reader_slot == ctrl->reader_slot)
154 break;
155 if (sl) /* There is another session with the reader open. */
157 if ( IS_LOCKED (ctrl) ) /* If it is locked, release it. */
158 ctrl->reader_slot = -1;
159 else
161 if (do_close) /* Always mark reader unused. */
162 ctrl->reader_slot = -1;
163 else if (apdu_reset (ctrl->reader_slot)) /* Reset only if
164 not locked */
166 /* The reset failed. Mark the reader as closed. */
167 ctrl->reader_slot = -1;
170 if (locked_session && ctrl->server_local == locked_session)
172 locked_session = NULL;
173 log_debug ("implicitly unlocking due to RESET\n");
177 else /* No other session has the reader open. */
179 if (do_close || apdu_reset (ctrl->reader_slot))
181 apdu_close_reader (ctrl->reader_slot);
182 ctrl->reader_slot = -1;
184 if ( IS_LOCKED (ctrl) )
186 log_debug ("WARNING: cleaning up stale session lock\n");
187 locked_session = NULL;
192 /* Reset card removed flag for the current reader. */
193 update_card_removed (slot, 0);
197 static void
198 reset_notify (assuan_context_t ctx)
200 ctrl_t ctrl = assuan_get_pointer (ctx);
202 do_reset (ctrl, 0);
206 static int
207 option_handler (assuan_context_t ctx, const char *key, const char *value)
209 ctrl_t ctrl = assuan_get_pointer (ctx);
211 if (!strcmp (key, "event-signal"))
213 /* A value of 0 is allowed to reset the event signal. */
214 int i = *value? atoi (value) : -1;
215 if (i < 0)
216 return ASSUAN_Parameter_Error;
217 ctrl->server_local->event_signal = i;
220 return 0;
224 /* Return the slot of the current reader or open the reader if no
225 other sessions are using a reader. Note, that we currently support
226 only one reader but most of the code (except for this function)
227 should be able to cope with several readers. */
228 static int
229 get_reader_slot (void)
231 struct server_local_s *sl;
232 int slot= -1;
234 for (sl=session_list; sl; sl = sl->next_session)
235 if (sl->ctrl_backlink
236 && (slot = sl->ctrl_backlink->reader_slot) != -1)
237 break;
239 if (slot == -1)
240 slot = apdu_open_reader (opt.reader_port);
242 return slot;
245 /* If the card has not yet been opened, do it. Note that this
246 function returns an Assuan error, so don't map the error a second
247 time */
248 static assuan_error_t
249 open_card (ctrl_t ctrl, const char *apptype)
251 gpg_error_t err;
252 int slot;
254 /* If we ever got a card not present error code, return that. Only
255 the SERIALNO command and a reset are able to clear from that
256 state. */
257 if (ctrl->server_local->card_removed)
258 return map_to_assuan_status (gpg_error (GPG_ERR_CARD_REMOVED));
260 if (ctrl->app_ctx)
261 return 0; /* Already initialized for one specific application. */
262 if (ctrl->card_ctx)
263 return 0; /* Already initialized using a card context. */
265 if ( IS_LOCKED (ctrl) )
266 return gpg_error (GPG_ERR_EBUSY);
268 if (ctrl->reader_slot != -1)
269 slot = ctrl->reader_slot;
270 else
271 slot = get_reader_slot ();
272 ctrl->reader_slot = slot;
273 if (slot == -1)
274 err = gpg_error (GPG_ERR_CARD);
275 else
276 err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
277 if (!ctrl->app_ctx
278 && gpg_err_code (err) != GPG_ERR_CARD_NOT_PRESENT)
280 /* No application found - fall back to old mode. */
281 /* Note that we should rework the old code to use the
282 application paradigma too. */
283 /* If an APPTYPE was requested and it is not pkcs#15, we return
284 an error here. */
285 if (apptype && !(!strcmp (apptype, "P15") || !strcmp (apptype, "p15")))
286 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
287 else
288 err = card_open (&ctrl->card_ctx);
291 TEST_CARD_REMOVAL (ctrl, err);
292 return map_to_assuan_status (err);
296 /* Do the percent and plus/space unescaping in place and return the
297 length of the valid buffer. */
298 static size_t
299 percent_plus_unescape (unsigned char *string)
301 unsigned char *p = string;
302 size_t n = 0;
304 while (*string)
306 if (*string == '%' && string[1] && string[2])
308 string++;
309 *p++ = xtoi_2 (string);
310 n++;
311 string+= 2;
313 else if (*string == '+')
315 *p++ = ' ';
316 n++;
317 string++;
319 else
321 *p++ = *string++;
322 n++;
326 return n;
331 /* SERIALNO [APPTYPE]
333 Return the serial number of the card using a status reponse. This
334 functon should be used to check for the presence of a card.
336 If APPTYPE is given, an application of that type is selected and an
337 error is returned if the application is not supported or available.
338 The default is to auto-select the application using a hardwired
339 preference system. Note, that a future extension to this function
340 may allow to specify a list and order of applications to try.
342 This function is special in that it can be used to reset the card.
343 Most other functions will return an error when a card change has
344 been detected and the use of this function is therefore required.
346 Background: We want to keep the client clear of handling card
347 changes between operations; i.e. the client can assume that all
348 operations are done on the same card unless he calls this function.
350 static int
351 cmd_serialno (assuan_context_t ctx, char *line)
353 ctrl_t ctrl = assuan_get_pointer (ctx);
354 int rc = 0;
355 char *serial_and_stamp;
356 char *serial;
357 time_t stamp;
359 /* Clear the remove flag so that the open_card is able to reread it. */
360 if (ctrl->server_local->card_removed)
362 if ( IS_LOCKED (ctrl) )
363 return gpg_error (GPG_ERR_EBUSY);
364 do_reset (ctrl, 0);
367 if ((rc = open_card (ctrl, *line? line:NULL)))
368 return rc;
370 if (ctrl->app_ctx)
371 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
372 else
373 rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
374 if (rc)
375 return map_to_assuan_status (rc);
376 rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
377 xfree (serial);
378 if (rc < 0)
379 return ASSUAN_Out_Of_Core;
380 rc = 0;
381 assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
382 free (serial_and_stamp);
383 return 0;
389 /* LEARN [--force]
391 Learn all useful information of the currently inserted card. When
392 used without the force options, the command might do an INQUIRE
393 like this:
395 INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
397 The client should just send an "END" if the processing should go on
398 or a "CANCEL" to force the function to terminate with a Cancel
399 error message. The response of this command is a list of status
400 lines formatted as this:
402 S APPTYPE <apptype>
404 This returns the type of the application, currently the strings:
406 P15 = PKCS-15 structure used
407 DINSIG = DIN SIG
408 OPENPGP = OpenPGP card
410 are implemented. These strings are aliases for the AID
412 S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
414 If there is no certificate yet stored on the card a single "X" is
415 returned as the keygrip. In addition to the keypair info, information
416 about all certificates stored on the card is also returned:
418 S CERTINFO <certtype> <hexstring_with_id>
420 Where CERTTYPE is a number indicating the type of certificate:
421 0 := Unknown
422 100 := Regular X.509 cert
423 101 := Trusted X.509 cert
424 102 := Useful X.509 cert
425 110 := Root CA cert (DINSIG)
427 For certain cards, more information will be returned:
429 S KEY-FPR <no> <hexstring>
431 For OpenPGP cards this returns the stored fingerprints of the
432 keys. This can be used check whether a key is available on the
433 card. NO may be 1, 2 or 3.
435 S CA-FPR <no> <hexstring>
437 Similar to above, these are the fingerprints of keys assumed to be
438 ultimately trusted.
440 S DISP-NAME <name_of_card_holder>
442 The name of the card holder as stored on the card; percent
443 escaping takes place, spaces are encoded as '+'
445 S PUBKEY-URL <url>
447 The URL to be used for locating the entire public key.
449 Note, that this function may be even be used on a locked card.
451 static int
452 cmd_learn (assuan_context_t ctx, char *line)
454 ctrl_t ctrl = assuan_get_pointer (ctx);
455 int rc = 0;
456 int idx;
458 if ((rc = open_card (ctrl, NULL)))
459 return rc;
461 /* Unless the force option is used we try a shortcut by identifying
462 the card using a serial number and inquiring the client with
463 that. The client may choose to cancel the operation if he already
464 knows about this card */
466 char *serial_and_stamp;
467 char *serial;
468 time_t stamp;
470 if (ctrl->app_ctx)
471 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
472 else
473 rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
474 if (rc)
475 return map_to_assuan_status (rc);
476 rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
477 xfree (serial);
478 if (rc < 0)
479 return ASSUAN_Out_Of_Core;
480 rc = 0;
481 assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
483 if (!has_option (line, "--force"))
485 char *command;
487 rc = asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
488 if (rc < 0)
490 free (serial_and_stamp);
491 return ASSUAN_Out_Of_Core;
493 rc = 0;
494 rc = assuan_inquire (ctx, command, NULL, NULL, 0);
495 free (command); /* (must use standard free here) */
496 if (rc)
498 if (rc != ASSUAN_Canceled)
499 log_error ("inquire KNOWNCARDP failed: %s\n",
500 assuan_strerror (rc));
501 free (serial_and_stamp);
502 return rc;
504 /* not canceled, so we have to proceeed */
506 free (serial_and_stamp);
509 /* If we are using the modern application paradigma, let the
510 application print out its collection of useful status
511 information. */
512 if (!rc && ctrl->app_ctx)
513 rc = app_write_learn_status (ctrl->app_ctx, ctrl);
515 /* Return information about the certificates. FIXME: Move this into
516 an app-p15.c*/
517 for (idx=0; !rc && !ctrl->app_ctx; idx++)
519 char *certid;
520 int certtype;
522 rc = card_enum_certs (ctrl->card_ctx, idx, &certid, &certtype);
523 if (!rc)
525 char *buf;
527 buf = xtrymalloc (40 + 1 + strlen (certid) + 1);
528 if (!buf)
529 rc = gpg_error (gpg_err_code_from_errno (errno));
530 else
532 sprintf (buf, "%d %s", certtype, certid);
533 assuan_write_status (ctx, "CERTINFO", buf);
534 xfree (buf);
537 xfree (certid);
539 if (rc == -1)
540 rc = 0;
542 /* Return information about the keys. FIXME: Move this into an
543 app-p15.c */
544 for (idx=0; !rc && !ctrl->app_ctx; idx++)
546 unsigned char keygrip[20];
547 char *keyid;
548 int no_cert = 0;
550 rc = card_enum_keypairs (ctrl->card_ctx, idx, keygrip, &keyid);
551 if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT && keyid)
553 /* This does happen with an incomplete personalized
554 card; i.e. during the time we have stored the key on the
555 card but not stored the certificate; probably becuase it
556 has not yet been received back from the CA. Note that we
557 must release KEYID in this case. */
558 rc = 0;
559 no_cert = 1;
561 if (!rc)
563 char *buf, *p;
565 buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1);
566 if (!buf)
567 rc = gpg_error (gpg_err_code_from_errno (errno));
568 else
570 int i;
572 if (no_cert)
573 *p++ = 'X';
574 else
576 for (i=0; i < 20; i++, p += 2)
577 sprintf (p, "%02X", keygrip[i]);
579 *p++ = ' ';
580 strcpy (p, keyid);
581 assuan_write_status (ctx, "KEYPAIRINFO", buf);
582 xfree (buf);
585 xfree (keyid);
587 if (rc == -1)
588 rc = 0;
590 TEST_CARD_REMOVAL (ctrl, rc);
591 return map_to_assuan_status (rc);
596 /* READCERT <hexified_certid>
598 Note, that this function may be even be used on a locked card.
600 static int
601 cmd_readcert (assuan_context_t ctx, char *line)
603 ctrl_t ctrl = assuan_get_pointer (ctx);
604 int rc;
605 unsigned char *cert;
606 size_t ncert;
608 if ((rc = open_card (ctrl, NULL)))
609 return rc;
611 line = xstrdup (line); /* Need a copy of the line. */
612 if (ctrl->app_ctx)
614 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
615 if (rc)
616 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
618 else
620 rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
621 if (rc)
622 log_error ("card_read_cert failed: %s\n", gpg_strerror (rc));
624 xfree (line);
625 line = NULL;
626 if (!rc)
628 rc = assuan_send_data (ctx, cert, ncert);
629 xfree (cert);
630 if (rc)
631 return rc;
634 TEST_CARD_REMOVAL (ctrl, rc);
635 return map_to_assuan_status (rc);
639 /* READKEY <hexified_certid>
641 Return the public key for the given cert or key ID as an standard
642 S-Expression.
644 Note, that this function may be even be used on a locked card.
646 static int
647 cmd_readkey (assuan_context_t ctx, char *line)
649 ctrl_t ctrl = assuan_get_pointer (ctx);
650 int rc;
651 unsigned char *cert = NULL;
652 size_t ncert, n;
653 ksba_cert_t kc = NULL;
654 ksba_sexp_t p;
656 if ((rc = open_card (ctrl, NULL)))
657 return rc;
659 line = xstrdup (line); /* Need a copy of the line. */
660 if (ctrl->app_ctx)
662 unsigned char *pk;
663 size_t pklen;
665 /* If the application supports the READKEY function we use that.
666 Otherwise we use the old way by extracting it from the
667 certificate. */
668 rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
669 if (!rc)
670 { /* Yeah, got that key - send it back. */
671 rc = assuan_send_data (ctx, pk, pklen);
672 xfree (pk);
673 rc = map_assuan_err (rc);
674 xfree (line);
675 line = NULL;
676 goto leave;
679 if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
680 log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
681 else
683 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
684 if (rc)
685 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
688 else
690 rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
691 if (rc)
692 log_error ("card_read_cert failed: %s\n", gpg_strerror (rc));
694 xfree (line);
695 line = NULL;
696 if (rc)
697 goto leave;
699 rc = ksba_cert_new (&kc);
700 if (rc)
702 xfree (cert);
703 goto leave;
705 rc = ksba_cert_init_from_mem (kc, cert, ncert);
706 if (rc)
708 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
709 goto leave;
712 p = ksba_cert_get_public_key (kc);
713 if (!p)
715 rc = gpg_error (GPG_ERR_NO_PUBKEY);
716 goto leave;
719 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
720 rc = assuan_send_data (ctx, p, n);
721 rc = map_assuan_err (rc);
722 xfree (p);
725 leave:
726 ksba_cert_release (kc);
727 xfree (cert);
728 TEST_CARD_REMOVAL (ctrl, rc);
729 return map_to_assuan_status (rc);
735 /* SETDATA <hexstring>
737 The client should use this command to tell us the data he want to
738 sign. */
739 static int
740 cmd_setdata (assuan_context_t ctx, char *line)
742 ctrl_t ctrl = assuan_get_pointer (ctx);
743 int n;
744 char *p;
745 unsigned char *buf;
747 if (locked_session && locked_session != ctrl->server_local)
748 return gpg_error (GPG_ERR_EBUSY);
750 /* Parse the hexstring. */
751 for (p=line,n=0; hexdigitp (p); p++, n++)
753 if (*p)
754 return set_error (Parameter_Error, "invalid hexstring");
755 if (!n)
756 return set_error (Parameter_Error, "no data given");
757 if ((n&1))
758 return set_error (Parameter_Error, "odd number of digits");
759 n /= 2;
760 buf = xtrymalloc (n);
761 if (!buf)
762 return ASSUAN_Out_Of_Core;
764 ctrl->in_data.value = buf;
765 ctrl->in_data.valuelen = n;
766 for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++)
767 buf[n] = xtoi_2 (p);
768 return 0;
773 static int
774 pin_cb (void *opaque, const char *info, char **retstr)
776 assuan_context_t ctx = opaque;
777 char *command;
778 int rc;
779 unsigned char *value;
780 size_t valuelen;
782 *retstr = NULL;
783 log_debug ("asking for PIN '%s'\n", info);
785 rc = asprintf (&command, "NEEDPIN %s", info);
786 if (rc < 0)
787 return gpg_error (gpg_err_code_from_errno (errno));
789 /* FIXME: Write an inquire function which returns the result in
790 secure memory */
791 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
792 free (command);
793 if (rc)
794 return map_assuan_err (rc);
796 if (!valuelen || value[valuelen-1])
798 /* We require that the returned value is an UTF-8 string */
799 xfree (value);
800 return gpg_error (GPG_ERR_INV_RESPONSE);
802 *retstr = value;
803 return 0;
807 /* PKSIGN <hexified_id>
810 static int
811 cmd_pksign (assuan_context_t ctx, char *line)
813 ctrl_t ctrl = assuan_get_pointer (ctx);
814 int rc;
815 unsigned char *outdata;
816 size_t outdatalen;
817 char *keyidstr;
819 if ( IS_LOCKED (ctrl) )
820 return gpg_error (GPG_ERR_EBUSY);
822 if ((rc = open_card (ctrl, NULL)))
823 return rc;
825 /* We have to use a copy of the key ID because the function may use
826 the pin_cb which in turn uses the assuan line buffer and thus
827 overwriting the original line with the keyid */
828 keyidstr = xtrystrdup (line);
829 if (!keyidstr)
830 return ASSUAN_Out_Of_Core;
832 if (ctrl->app_ctx)
833 rc = app_sign (ctrl->app_ctx,
834 keyidstr, GCRY_MD_SHA1,
835 pin_cb, ctx,
836 ctrl->in_data.value, ctrl->in_data.valuelen,
837 &outdata, &outdatalen);
838 else
839 rc = card_sign (ctrl->card_ctx,
840 keyidstr, GCRY_MD_SHA1,
841 pin_cb, ctx,
842 ctrl->in_data.value, ctrl->in_data.valuelen,
843 &outdata, &outdatalen);
844 xfree (keyidstr);
845 if (rc)
847 log_error ("card_sign failed: %s\n", gpg_strerror (rc));
849 else
851 rc = assuan_send_data (ctx, outdata, outdatalen);
852 xfree (outdata);
853 if (rc)
854 return rc; /* that is already an assuan error code */
857 TEST_CARD_REMOVAL (ctrl, rc);
858 return map_to_assuan_status (rc);
861 /* PKAUTH <hexified_id>
864 static int
865 cmd_pkauth (assuan_context_t ctx, char *line)
867 ctrl_t ctrl = assuan_get_pointer (ctx);
868 int rc;
869 unsigned char *outdata;
870 size_t outdatalen;
871 char *keyidstr;
873 if ( IS_LOCKED (ctrl) )
874 return gpg_error (GPG_ERR_EBUSY);
876 if ((rc = open_card (ctrl, NULL)))
877 return rc;
879 if (!ctrl->app_ctx)
880 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
882 /* We have to use a copy of the key ID because the function may use
883 the pin_cb which in turn uses the assuan line buffer and thus
884 overwriting the original line with the keyid */
885 keyidstr = xtrystrdup (line);
886 if (!keyidstr)
887 return ASSUAN_Out_Of_Core;
889 rc = app_auth (ctrl->app_ctx,
890 keyidstr,
891 pin_cb, ctx,
892 ctrl->in_data.value, ctrl->in_data.valuelen,
893 &outdata, &outdatalen);
894 xfree (keyidstr);
895 if (rc)
897 log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc));
899 else
901 rc = assuan_send_data (ctx, outdata, outdatalen);
902 xfree (outdata);
903 if (rc)
904 return rc; /* that is already an assuan error code */
907 TEST_CARD_REMOVAL (ctrl, rc);
908 return map_to_assuan_status (rc);
911 /* PKDECRYPT <hexified_id>
914 static int
915 cmd_pkdecrypt (assuan_context_t ctx, char *line)
917 ctrl_t ctrl = assuan_get_pointer (ctx);
918 int rc;
919 unsigned char *outdata;
920 size_t outdatalen;
921 char *keyidstr;
923 if ( IS_LOCKED (ctrl) )
924 return gpg_error (GPG_ERR_EBUSY);
926 if ((rc = open_card (ctrl, NULL)))
927 return rc;
929 keyidstr = xtrystrdup (line);
930 if (!keyidstr)
931 return ASSUAN_Out_Of_Core;
932 if (ctrl->app_ctx)
933 rc = app_decipher (ctrl->app_ctx,
934 keyidstr,
935 pin_cb, ctx,
936 ctrl->in_data.value, ctrl->in_data.valuelen,
937 &outdata, &outdatalen);
938 else
939 rc = card_decipher (ctrl->card_ctx,
940 keyidstr,
941 pin_cb, ctx,
942 ctrl->in_data.value, ctrl->in_data.valuelen,
943 &outdata, &outdatalen);
944 xfree (keyidstr);
945 if (rc)
947 log_error ("card_create_signature failed: %s\n", gpg_strerror (rc));
949 else
951 rc = assuan_send_data (ctx, outdata, outdatalen);
952 xfree (outdata);
953 if (rc)
954 return rc; /* that is already an assuan error code */
957 TEST_CARD_REMOVAL (ctrl, rc);
958 return map_to_assuan_status (rc);
962 /* GETATTR <name>
964 This command is used to retrieve data from a smartcard. The
965 allowed names depend on the currently selected smartcard
966 application. NAME must be percent and '+' escaped. The value is
967 returned through status message, see the LEARN command for details.
969 However, the current implementation assumes that Name is not escaped;
970 this works as long as noone uses arbitrary escaping.
972 Note, that this function may even be used on a locked card.
974 static int
975 cmd_getattr (assuan_context_t ctx, char *line)
977 ctrl_t ctrl = assuan_get_pointer (ctx);
978 int rc;
979 char *keyword;
981 if ((rc = open_card (ctrl, NULL)))
982 return rc;
984 keyword = line;
985 for (; *line && !spacep (line); line++)
987 if (*line)
988 *line++ = 0;
990 /* (We ignore any garbage for now.) */
992 /* FIXME: Applications should not return sensistive data if the card
993 is locked. */
994 rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
996 TEST_CARD_REMOVAL (ctrl, rc);
997 return map_to_assuan_status (rc);
1001 /* SETATTR <name> <value>
1003 This command is used to store data on a a smartcard. The allowed
1004 names and values are depend on the currently selected smartcard
1005 application. NAME and VALUE must be percent and '+' escaped.
1007 However, the curent implementation assumes that Name is not escaped;
1008 this works as long as noone uses arbitrary escaping.
1010 A PIN will be requested for most NAMEs. See the corresponding
1011 setattr function of the actually used application (app-*.c) for
1012 details. */
1013 static int
1014 cmd_setattr (assuan_context_t ctx, char *orig_line)
1016 ctrl_t ctrl = assuan_get_pointer (ctx);
1017 int rc;
1018 char *keyword;
1019 int keywordlen;
1020 size_t nbytes;
1021 char *line, *linebuf;
1023 if ( IS_LOCKED (ctrl) )
1024 return gpg_error (GPG_ERR_EBUSY);
1026 if ((rc = open_card (ctrl, NULL)))
1027 return rc;
1029 /* We need to use a copy of LINE, because PIN_CB uses the same
1030 context and thus reuses the Assuan provided LINE. */
1031 line = linebuf = xtrystrdup (orig_line);
1032 if (!line)
1033 return ASSUAN_Out_Of_Core;
1035 keyword = line;
1036 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1038 if (*line)
1039 *line++ = 0;
1040 while (spacep (line))
1041 line++;
1042 nbytes = percent_plus_unescape (line);
1044 rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes);
1045 xfree (linebuf);
1047 TEST_CARD_REMOVAL (ctrl, rc);
1048 return map_to_assuan_status (rc);
1051 /* GENKEY [--force] <no>
1053 Generate a key on-card identified by NO, which is application
1054 specific. Return values are application specific. For OpenPGP
1055 cards 2 status lines are returned:
1057 S KEY-FPR <hexstring>
1058 S KEY-CREATED-AT <seconds_since_epoch>
1059 S KEY-DATA [p|n] <hexdata>
1062 --force is required to overwriet an already existing key. The
1063 KEY-CREATED-AT is required for further processing because it is
1064 part of the hashed key material for the fingerprint.
1066 The public part of the key can also later be retrieved using the
1067 READKEY command.
1070 static int
1071 cmd_genkey (assuan_context_t ctx, char *line)
1073 ctrl_t ctrl = assuan_get_pointer (ctx);
1074 int rc;
1075 char *keyno;
1076 int force = has_option (line, "--force");
1078 if ( IS_LOCKED (ctrl) )
1079 return gpg_error (GPG_ERR_EBUSY);
1081 /* Skip over options. */
1082 while ( *line == '-' && line[1] == '-' )
1084 while (*line && !spacep (line))
1085 line++;
1086 while (spacep (line))
1087 line++;
1089 if (!*line)
1090 return set_error (Parameter_Error, "no key number given");
1091 keyno = line;
1092 while (*line && !spacep (line))
1093 line++;
1094 *line = 0;
1096 if ((rc = open_card (ctrl, NULL)))
1097 return rc;
1099 if (!ctrl->app_ctx)
1100 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1102 keyno = xtrystrdup (keyno);
1103 if (!keyno)
1104 return ASSUAN_Out_Of_Core;
1105 rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
1106 xfree (keyno);
1108 TEST_CARD_REMOVAL (ctrl, rc);
1109 return map_to_assuan_status (rc);
1113 /* RANDOM <nbytes>
1115 Get NBYTES of random from the card and send them back as data.
1117 Note, that this function may be even be used on a locked card.
1119 static int
1120 cmd_random (assuan_context_t ctx, char *line)
1122 ctrl_t ctrl = assuan_get_pointer (ctx);
1123 int rc;
1124 size_t nbytes;
1125 unsigned char *buffer;
1127 if (!*line)
1128 return set_error (Parameter_Error, "number of requested bytes missing");
1129 nbytes = strtoul (line, NULL, 0);
1131 if ((rc = open_card (ctrl, NULL)))
1132 return rc;
1134 if (!ctrl->app_ctx)
1135 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1137 buffer = xtrymalloc (nbytes);
1138 if (!buffer)
1139 return ASSUAN_Out_Of_Core;
1141 rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1142 if (!rc)
1144 rc = assuan_send_data (ctx, buffer, nbytes);
1145 xfree (buffer);
1146 return rc; /* that is already an assuan error code */
1148 xfree (buffer);
1150 TEST_CARD_REMOVAL (ctrl, rc);
1151 return map_to_assuan_status (rc);
1155 /* PASSWD [--reset] <chvno>
1157 Change the PIN or reset thye retry counter of the card holder
1158 verfication vector CHVNO. */
1159 static int
1160 cmd_passwd (assuan_context_t ctx, char *line)
1162 ctrl_t ctrl = assuan_get_pointer (ctx);
1163 int rc;
1164 char *chvnostr;
1165 int reset_mode = has_option (line, "--reset");
1167 if ( IS_LOCKED (ctrl) )
1168 return gpg_error (GPG_ERR_EBUSY);
1170 /* Skip over options. */
1171 while (*line == '-' && line[1] == '-')
1173 while (*line && !spacep (line))
1174 line++;
1175 while (spacep (line))
1176 line++;
1178 if (!*line)
1179 return set_error (Parameter_Error, "no CHV number given");
1180 chvnostr = line;
1181 while (*line && !spacep (line))
1182 line++;
1183 *line = 0;
1185 if ((rc = open_card (ctrl, NULL)))
1186 return rc;
1188 if (!ctrl->app_ctx)
1189 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1191 chvnostr = xtrystrdup (chvnostr);
1192 if (!chvnostr)
1193 return ASSUAN_Out_Of_Core;
1194 rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx);
1195 if (rc)
1196 log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1197 xfree (chvnostr);
1199 TEST_CARD_REMOVAL (ctrl, rc);
1200 return map_to_assuan_status (rc);
1204 /* CHECKPIN <hexified_id>
1207 static int
1208 cmd_checkpin (assuan_context_t ctx, char *line)
1210 ctrl_t ctrl = assuan_get_pointer (ctx);
1211 int rc;
1212 char *keyidstr;
1214 if ( IS_LOCKED (ctrl) )
1215 return gpg_error (GPG_ERR_EBUSY);
1217 if ((rc = open_card (ctrl, NULL)))
1218 return rc;
1220 if (!ctrl->app_ctx)
1221 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1223 /* We have to use a copy of the key ID because the function may use
1224 the pin_cb which in turn uses the assuan line buffer and thus
1225 overwriting the original line with the keyid. */
1226 keyidstr = xtrystrdup (line);
1227 if (!keyidstr)
1228 return ASSUAN_Out_Of_Core;
1230 rc = app_check_pin (ctrl->app_ctx,
1231 keyidstr,
1232 pin_cb, ctx);
1233 xfree (keyidstr);
1234 if (rc)
1235 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1237 TEST_CARD_REMOVAL (ctrl, rc);
1238 return map_to_assuan_status (rc);
1242 /* LOCK [--wait]
1244 Grant exclusive card access to this session. Note that there is
1245 no lock counter used and a second lock from the same session will
1246 get ignore. A single unlock (or RESET) unlocks the session.
1247 Return GPG_ERR_EBUSY if another session has locked the reader.
1249 If the option --wait is given the command will wait until a
1250 lock has been released.
1252 static int
1253 cmd_lock (assuan_context_t ctx, char *line)
1255 ctrl_t ctrl = assuan_get_pointer (ctx);
1256 int rc = 0;
1258 retry:
1259 if (locked_session)
1261 if (locked_session != ctrl->server_local)
1262 rc = gpg_error (GPG_ERR_EBUSY);
1264 else
1265 locked_session = ctrl->server_local;
1267 #ifdef USE_GNU_PTH
1268 if (rc && has_option (line, "--wait"))
1270 pth_sleep (1); /* Better implement an event mechanism. However,
1271 for card operations this should be
1272 sufficient. */
1273 goto retry;
1275 #endif /*USE_GNU_PTH*/
1277 if (rc)
1278 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1279 return map_to_assuan_status (rc);
1283 /* UNLOCK
1285 Release exclusive card access.
1287 static int
1288 cmd_unlock (assuan_context_t ctx, char *line)
1290 ctrl_t ctrl = assuan_get_pointer (ctx);
1291 int rc = 0;
1293 if (locked_session)
1295 if (locked_session != ctrl->server_local)
1296 rc = gpg_error (GPG_ERR_EBUSY);
1297 else
1298 locked_session = NULL;
1300 else
1301 rc = gpg_error (GPG_ERR_NOT_LOCKED);
1303 if (rc)
1304 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1305 return map_to_assuan_status (rc);
1312 /* Tell the assuan library about our commands */
1313 static int
1314 register_commands (assuan_context_t ctx)
1316 static struct {
1317 const char *name;
1318 int (*handler)(assuan_context_t, char *line);
1319 } table[] = {
1320 { "SERIALNO", cmd_serialno },
1321 { "LEARN", cmd_learn },
1322 { "READCERT", cmd_readcert },
1323 { "READKEY", cmd_readkey },
1324 { "SETDATA", cmd_setdata },
1325 { "PKSIGN", cmd_pksign },
1326 { "PKAUTH", cmd_pkauth },
1327 { "PKDECRYPT", cmd_pkdecrypt },
1328 { "INPUT", NULL },
1329 { "OUTPUT", NULL },
1330 { "GETATTR", cmd_getattr },
1331 { "SETATTR", cmd_setattr },
1332 { "GENKEY", cmd_genkey },
1333 { "RANDOM", cmd_random },
1334 { "PASSWD", cmd_passwd },
1335 { "CHECKPIN", cmd_checkpin },
1336 { "LOCK", cmd_lock },
1337 { "UNLOCK", cmd_unlock },
1338 { NULL }
1340 int i, rc;
1342 for (i=0; table[i].name; i++)
1344 rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1345 if (rc)
1346 return rc;
1348 assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1350 assuan_register_reset_notify (ctx, reset_notify);
1351 assuan_register_option_handler (ctx, option_handler);
1352 return 0;
1356 /* Startup the server. If LISTEN_FD is given as -1, this is simple
1357 piper server, otherwise it is a regular server */
1358 void
1359 scd_command_handler (int listen_fd)
1361 int rc;
1362 assuan_context_t ctx;
1363 struct server_control_s ctrl;
1365 memset (&ctrl, 0, sizeof ctrl);
1366 scd_init_default_ctrl (&ctrl);
1368 if (listen_fd == -1)
1370 int filedes[2];
1372 filedes[0] = 0;
1373 filedes[1] = 1;
1374 rc = assuan_init_pipe_server (&ctx, filedes);
1376 else
1378 rc = assuan_init_socket_server (&ctx, listen_fd);
1380 if (rc)
1382 log_error ("failed to initialize the server: %s\n",
1383 assuan_strerror(rc));
1384 scd_exit (2);
1386 rc = register_commands (ctx);
1387 if (rc)
1389 log_error ("failed to register commands with Assuan: %s\n",
1390 assuan_strerror(rc));
1391 scd_exit (2);
1393 assuan_set_pointer (ctx, &ctrl);
1395 /* Allocate and initialize the server object. Put it into the list
1396 of active sessions. */
1397 ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
1398 ctrl.server_local->next_session = session_list;
1399 session_list = ctrl.server_local;
1400 ctrl.server_local->ctrl_backlink = &ctrl;
1401 ctrl.server_local->assuan_ctx = ctx;
1403 if (DBG_ASSUAN)
1404 assuan_set_log_stream (ctx, log_get_stream ());
1406 /* We open the reader right at startup so that the ticker is able to
1407 update the status file. */
1408 if (ctrl.reader_slot == -1)
1410 ctrl.reader_slot = get_reader_slot ();
1413 /* Command processing loop. */
1414 for (;;)
1416 rc = assuan_accept (ctx);
1417 if (rc == -1)
1419 break;
1421 else if (rc)
1423 log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
1424 break;
1427 rc = assuan_process (ctx);
1428 if (rc)
1430 log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
1431 continue;
1435 /* Cleanup. */
1436 do_reset (&ctrl, 1);
1438 /* Release the server object. */
1439 if (session_list == ctrl.server_local)
1440 session_list = ctrl.server_local->next_session;
1441 else
1443 struct server_local_s *sl;
1445 for (sl=session_list; sl->next_session; sl = sl->next_session)
1446 if (sl->next_session == ctrl.server_local)
1447 break;
1448 if (!sl->next_session)
1449 BUG ();
1450 sl->next_session = ctrl.server_local->next_session;
1452 xfree (ctrl.server_local);
1454 /* Release the Assuan context. */
1455 assuan_deinit_server (ctx);
1459 /* Send a line with status information via assuan and escape all given
1460 buffers. The variable elements are pairs of (char *, size_t),
1461 terminated with a (NULL, 0). */
1462 void
1463 send_status_info (ctrl_t ctrl, const char *keyword, ...)
1465 va_list arg_ptr;
1466 const unsigned char *value;
1467 size_t valuelen;
1468 char buf[950], *p;
1469 size_t n;
1470 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1472 va_start (arg_ptr, keyword);
1474 p = buf;
1475 n = 0;
1476 while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1478 valuelen = va_arg (arg_ptr, size_t);
1479 if (!valuelen)
1480 continue; /* empty buffer */
1481 if (n)
1483 *p++ = ' ';
1484 n++;
1486 for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1488 if (*value < ' ' || *value == '+')
1490 sprintf (p, "%%%02X", *value);
1491 p += 3;
1493 else if (*value == ' ')
1494 *p++ = '+';
1495 else
1496 *p++ = *value;
1499 *p = 0;
1500 assuan_write_status (ctx, keyword, buf);
1502 va_end (arg_ptr);
1506 /* This function is called by the ticker thread to check for changes
1507 of the reader stati. It updates the reader status files and if
1508 requested by the caller also send a signal to the caller. */
1509 void
1510 scd_update_reader_status_file (void)
1512 static struct {
1513 int any;
1514 unsigned int status;
1515 unsigned int changed;
1516 } last[10];
1517 int slot;
1518 int used;
1519 unsigned int status, changed;
1521 /* Note, that we only try to get the status, because it does not
1522 make sense to wait here for a operation to complete. If we are
1523 busy working with a card, delays in the status file update should
1524 be acceptable. */
1525 for (slot=0; (slot < DIM(last)
1526 &&!apdu_enum_reader (slot, &used)); slot++)
1527 if (used && !apdu_get_status (slot, 0, &status, &changed))
1529 if (!last[slot].any || last[slot].status != status
1530 || last[slot].changed != changed )
1532 char *fname;
1533 char templ[50];
1534 FILE *fp;
1535 struct server_local_s *sl;
1537 log_info ("updating status of slot %d to 0x%04X\n", slot, status);
1539 sprintf (templ, "reader_%d.status", slot);
1540 fname = make_filename (opt.homedir, templ, NULL );
1541 fp = fopen (fname, "w");
1542 if (fp)
1544 fprintf (fp, "%s\n",
1545 (status & 1)? "USABLE":
1546 (status & 4)? "ACTIVE":
1547 (status & 2)? "PRESENT": "NOCARD");
1548 fclose (fp);
1550 xfree (fname);
1552 /* Set the card removed flag for all current sessions. We
1553 will set this on any card change because a reset or
1554 SERIALNO request must be done in any case. */
1555 if (last[slot].any)
1556 update_card_removed (slot, 1);
1558 last[slot].any = 1;
1559 last[slot].status = status;
1560 last[slot].changed = changed;
1563 /* Send a signal to all clients who applied for it. */
1564 for (sl=session_list; sl; sl = sl->next_session)
1565 if (sl->event_signal && sl->assuan_ctx)
1567 pid_t pid = assuan_get_pid (sl->assuan_ctx);
1568 int signo = sl->event_signal;
1570 log_info ("client pid is %d, sending signal %d\n",
1571 pid, signo);
1572 #ifndef HAVE_W32_SYSTEM
1573 if (pid != (pid_t)(-1) && pid && signo > 0)
1574 kill (pid, signo);
1575 #endif