1 /* command.c - SCdaemon command handler
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3 * 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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/>.
36 #include "app-common.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
42 #include "ccid-driver.h"
45 #include "server-help.h"
47 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
48 #define MAXLEN_PIN 100
50 /* Maximum allowed size of key data as used in inquiries. */
51 #define MAXLEN_KEYDATA 4096
53 /* Maximum allowed total data size for SETDATA. */
54 #define MAXLEN_SETDATA 4096
56 /* Maximum allowed size of certificate data as used in inquiries. */
57 #define MAXLEN_CERTDATA 16384
60 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
63 /* Macro to flag a removed card. ENODEV is also tested to catch the
64 case of a removed reader. */
65 #define TEST_CARD_REMOVAL(c,r) \
68 if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
69 || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \
70 || gpg_err_code (_r) == GPG_ERR_CARD_RESET \
71 || gpg_err_code (_r) == GPG_ERR_ENODEV ) \
72 update_card_removed ((c)->server_local->vreader_idx, 1); \
75 #define IS_LOCKED(c) \
77 && locked_session != (c)->server_local \
78 && (c)->server_local->vreader_idx != -1 \
79 && locked_session->ctrl_backlink \
80 && ((c)->server_local->vreader_idx \
81 == locked_session->ctrl_backlink->server_local->vreader_idx))
84 /* This structure is used to keep track of user readers. To
85 eventually accommodate this structure for RFID cards, where more
86 than one card is used per reader, we name it virtual reader. */
89 int valid; /* True if the other objects are valid. */
90 int slot; /* APDU slot number of the reader or -1 if not open. */
92 int reset_failed; /* A reset failed. */
94 int any; /* Flag indicating whether any status check has been
95 done. This is set once to indicate that the status
96 tracking for the slot has been initialized. */
97 unsigned int status; /* Last status of the reader. */
98 unsigned int changed; /* Last change counter of the reader. */
102 /* Data used to associate an Assuan context with local server data.
103 This object describes the local properties of one session. */
104 struct server_local_s
106 /* We keep a list of all active sessions with the anchor at
107 SESSION_LIST (see below). This field is used for linking. */
108 struct server_local_s *next_session;
110 /* This object is usually assigned to a CTRL object (which is
111 globally visible). While enumerating all sessions we sometimes
112 need to access data of the CTRL object; thus we keep a
114 ctrl_t ctrl_backlink;
116 /* The Assuan context used by this session/server. */
117 assuan_context_t assuan_ctx;
119 #ifdef HAVE_W32_SYSTEM
120 unsigned long event_signal; /* Or 0 if not used. */
122 int event_signal; /* Or 0 if not used. */
125 /* Index into the vreader table (command.c) or -1 if not open. */
128 /* True if the card has been removed and a reset is required to
129 continue operation. */
132 /* A disconnect command has been sent. */
133 int disconnect_allowed;
135 /* If set to true we will be terminate ourself at the end of the
142 /* The table with information on all used virtual readers. */
143 static struct vreader_s vreader_table[10];
146 /* To keep track of all running sessions, we link all active server
147 contexts and the anchor in this variable. */
148 static struct server_local_s *session_list;
150 /* If a session has been locked we store a link to its server object
152 static struct server_local_s *locked_session;
154 /* While doing a reset we need to make sure that the ticker does not
155 call scd_update_reader_status_file while we are using it. */
156 static npth_mutex_t status_file_update_lock;
159 /*-- Local prototypes --*/
160 static void update_reader_status_file (int set_card_removed_flag);
165 /* This function must be called once to initialize this module. This
166 has to be done before a second thread is spawned. We can't do the
167 static initialization because Pth emulation code might not be able
168 to do a static init; in particular, it is not possible for W32. */
170 initialize_module_command (void)
172 static int initialized;
177 err = npth_mutex_init (&status_file_update_lock, NULL);
184 /* Helper to return the slot number for a given virtual reader index
185 VRDR. In case on an error -1 is returned. */
187 vreader_slot (int vrdr)
189 if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table)))
191 if (!vreader_table [vrdr].valid)
193 return vreader_table[vrdr].slot;
197 /* Update the CARD_REMOVED element of all sessions using the virtual
198 reader given by VRDR to VALUE. */
200 update_card_removed (int vrdr, int value)
202 struct server_local_s *sl;
207 for (sl=session_list; sl; sl = sl->next_session)
209 ctrl_t ctrl = sl->ctrl_backlink;
211 if (ctrl && ctrl->server_local->vreader_idx == vrdr)
213 sl->card_removed = value;
216 struct app_ctx_s *app = ctrl->app_ctx;
217 ctrl->app_ctx = NULL;
218 release_application (app);
223 /* Let the card application layer know about the removal. */
226 int slot = vreader_slot (vrdr);
228 log_debug ("Removal of a card: %d\n", vrdr);
229 apdu_close_reader (slot);
230 application_notify_card_reset (slot);
231 vreader_table[vrdr].slot = -1;
236 /* Convert the STRING into a newly allocated buffer while translating
237 the hex numbers. Stops at the first invalid character. Blanks and
238 colons are allowed to separate the hex digits. Returns NULL on
239 error or a newly malloced buffer and its length in LENGTH. */
240 static unsigned char *
241 hex_to_buffer (const char *string, size_t *r_length)
243 unsigned char *buffer;
247 buffer = xtrymalloc (strlen (string)+1);
250 for (s=string, n=0; *s; s++)
252 if (spacep (s) || *s == ':')
254 if (hexdigitp (s) && hexdigitp (s+1))
256 buffer[n++] = xtoi_2 (s);
268 /* Reset the card and free the application context. With SEND_RESET
269 set to true actually send a RESET to the reader; this is the normal
270 way of calling the function. */
272 do_reset (ctrl_t ctrl, int send_reset)
274 int vrdr = ctrl->server_local->vreader_idx;
277 struct app_ctx_s *app = ctrl->app_ctx;
279 if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
282 /* If there is an active application, release it. */
285 ctrl->app_ctx = NULL;
286 release_application (app);
289 /* Release the same application which is used by other sessions. */
292 struct server_local_s *sl;
294 for (sl=session_list; sl; sl = sl->next_session)
296 ctrl_t c = sl->ctrl_backlink;
298 if (c && c != ctrl && c->server_local->vreader_idx == vrdr)
300 struct app_ctx_s *app0 = c->app_ctx;
304 release_application (app0);
310 /* If we want a real reset for the card, send the reset APDU and
311 tell the application layer about it. */
312 slot = vreader_slot (vrdr);
313 if (slot != -1 && send_reset && !IS_LOCKED (ctrl) )
315 application_notify_card_reset (slot);
316 switch (apdu_reset (slot))
320 case SW_HOST_NO_CARD:
321 case SW_HOST_CARD_INACTIVE:
324 apdu_close_reader (slot);
325 vreader_table[vrdr].slot = -1;
330 /* If we hold a lock, unlock now. */
331 if (locked_session && ctrl->server_local == locked_session)
333 locked_session = NULL;
334 log_info ("implicitly unlocking due to RESET\n");
337 /* Reset the card removed flag for the current reader. We need to
338 take the lock here so that the ticker thread won't concurrently
339 try to update the file. Calling update_reader_status_file is
340 required to get hold of the new status of the card in the vreader
342 err = npth_mutex_lock (&status_file_update_lock);
345 log_error ("failed to acquire status_file_update lock\n");
346 ctrl->server_local->vreader_idx = -1;
349 update_reader_status_file (0); /* Update slot status table. */
350 update_card_removed (vrdr, 0); /* Clear card_removed flag. */
351 err = npth_mutex_unlock (&status_file_update_lock);
353 log_error ("failed to release status_file_update lock: %s\n",
356 /* Do this last, so that the update_card_removed above does its job. */
357 ctrl->server_local->vreader_idx = -1;
362 reset_notify (assuan_context_t ctx, char *line)
364 ctrl_t ctrl = assuan_get_pointer (ctx);
374 option_handler (assuan_context_t ctx, const char *key, const char *value)
376 ctrl_t ctrl = assuan_get_pointer (ctx);
378 if (!strcmp (key, "event-signal"))
380 /* A value of 0 is allowed to reset the event signal. */
381 #ifdef HAVE_W32_SYSTEM
383 return gpg_error (GPG_ERR_ASS_PARAMETER);
384 ctrl->server_local->event_signal = strtoul (value, NULL, 16);
386 int i = *value? atoi (value) : -1;
388 return gpg_error (GPG_ERR_ASS_PARAMETER);
389 ctrl->server_local->event_signal = i;
397 /* Return the index of the current reader or open the reader if no
398 other sessions are using that reader. If it is not possible to
399 open the reader -1 is returned. Note, that we currently support
400 only one reader but most of the code (except for this function)
401 should be able to cope with several readers. */
403 get_current_reader (void)
405 struct vreader_s *vr;
407 /* We only support one reader for now. */
408 vr = &vreader_table[0];
410 /* Initialize the vreader item if not yet done. */
417 /* Try to open the reader. */
420 vr->slot = apdu_open_reader (opt.reader_port);
422 /* If we still don't have a slot, we have no readers.
423 Invalidate for now until a reader is attached. */
430 /* Return the vreader index or -1. */
431 return vr->valid ? 0 : -1;
435 /* If the card has not yet been opened, do it. */
437 open_card (ctrl_t ctrl, const char *apptype)
442 /* If we ever got a card not present error code, return that. Only
443 the SERIALNO command and a reset are able to clear from that
445 if (ctrl->server_local->card_removed)
446 return gpg_error (GPG_ERR_CARD_REMOVED);
448 if ( IS_LOCKED (ctrl) )
449 return gpg_error (GPG_ERR_LOCKED);
451 /* If we are already initialized for one specific application we
452 need to check that the client didn't requested a specific
453 application different from the one in use before we continue. */
456 return check_application_conflict
457 (ctrl, vreader_slot (ctrl->server_local->vreader_idx), apptype);
460 /* Setup the vreader and select the application. */
461 if (ctrl->server_local->vreader_idx != -1)
462 vrdr = ctrl->server_local->vreader_idx;
464 vrdr = get_current_reader ();
465 ctrl->server_local->vreader_idx = vrdr;
467 err = gpg_error (GPG_ERR_CARD);
470 /* Fixme: We should move the apdu_connect call to
471 select_application. */
473 int slot = vreader_slot (vrdr);
475 ctrl->server_local->disconnect_allowed = 0;
476 sw = apdu_connect (slot);
477 if (sw && sw != SW_HOST_ALREADY_CONNECTED)
479 if (sw == SW_HOST_NO_CARD)
480 err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
481 else if (sw == SW_HOST_CARD_INACTIVE)
482 err = gpg_error (GPG_ERR_CARD_RESET);
484 err = gpg_error (GPG_ERR_ENODEV);
487 err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
490 TEST_CARD_REMOVAL (ctrl, err);
495 static const char hlp_serialno[] =
496 "SERIALNO [<apptype>]\n"
498 "Return the serial number of the card using a status response. This\n"
499 "function should be used to check for the presence of a card.\n"
501 "If APPTYPE is given, an application of that type is selected and an\n"
502 "error is returned if the application is not supported or available.\n"
503 "The default is to auto-select the application using a hardwired\n"
504 "preference system. Note, that a future extension to this function\n"
505 "may enable specifying a list and order of applications to try.\n"
507 "This function is special in that it can be used to reset the card.\n"
508 "Most other functions will return an error when a card change has\n"
509 "been detected and the use of this function is therefore required.\n"
511 "Background: We want to keep the client clear of handling card\n"
512 "changes between operations; i.e. the client can assume that all\n"
513 "operations are done on the same card unless he calls this function.";
515 cmd_serialno (assuan_context_t ctx, char *line)
517 ctrl_t ctrl = assuan_get_pointer (ctx);
523 /* Clear the remove flag so that the open_card is able to reread it. */
525 if (ctrl->server_local->card_removed)
527 if ( IS_LOCKED (ctrl) )
528 return gpg_error (GPG_ERR_LOCKED);
532 if ((rc = open_card (ctrl, *line? line:NULL)))
534 /* In case of an inactive card, retry once. */
535 if (gpg_err_code (rc) == GPG_ERR_CARD_RESET && retries++ < 1)
540 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
544 rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
545 serial, (unsigned long)stamp);
551 static const char hlp_learn[] =
552 "LEARN [--force] [--keypairinfo]\n"
554 "Learn all useful information of the currently inserted card. When\n"
555 "used without the force options, the command might do an INQUIRE\n"
558 " INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>\n"
560 "The client should just send an \"END\" if the processing should go on\n"
561 "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
564 "With the option --keypairinfo only KEYPARIINFO lstatus lines are\n"
567 "The response of this command is a list of status lines formatted as\n"
570 " S APPTYPE <apptype>\n"
572 "This returns the type of the application, currently the strings:\n"
574 " P15 = PKCS-15 structure used\n"
575 " DINSIG = DIN SIG\n"
576 " OPENPGP = OpenPGP card\n"
577 " NKS = NetKey card\n"
579 "are implemented. These strings are aliases for the AID\n"
581 " S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>\n"
583 "If there is no certificate yet stored on the card a single 'X' is\n"
584 "returned as the keygrip. In addition to the keypair info, information\n"
585 "about all certificates stored on the card is also returned:\n"
587 " S CERTINFO <certtype> <hexstring_with_id>\n"
589 "Where CERTTYPE is a number indicating the type of certificate:\n"
591 " 100 := Regular X.509 cert\n"
592 " 101 := Trusted X.509 cert\n"
593 " 102 := Useful X.509 cert\n"
594 " 110 := Root CA cert in a special format (e.g. DINSIG)\n"
595 " 111 := Root CA cert as standard X509 cert.\n"
597 "For certain cards, more information will be returned:\n"
599 " S KEY-FPR <no> <hexstring>\n"
601 "For OpenPGP cards this returns the stored fingerprints of the\n"
602 "keys. This can be used check whether a key is available on the\n"
603 "card. NO may be 1, 2 or 3.\n"
605 " S CA-FPR <no> <hexstring>\n"
607 "Similar to above, these are the fingerprints of keys assumed to be\n"
608 "ultimately trusted.\n"
610 " S DISP-NAME <name_of_card_holder>\n"
612 "The name of the card holder as stored on the card; percent\n"
613 "escaping takes place, spaces are encoded as '+'\n"
615 " S PUBKEY-URL <url>\n"
617 "The URL to be used for locating the entire public key.\n"
619 "Note, that this function may even be used on a locked card.";
621 cmd_learn (assuan_context_t ctx, char *line)
623 ctrl_t ctrl = assuan_get_pointer (ctx);
625 int only_keypairinfo = has_option (line, "--keypairinfo");
627 if ((rc = open_card (ctrl, NULL)))
630 /* Unless the force option is used we try a shortcut by identifying
631 the card using a serial number and inquiring the client with
632 that. The client may choose to cancel the operation if he already
633 knows about this card */
634 if (!only_keypairinfo)
641 slot = vreader_slot (ctrl->server_local->vreader_idx);
642 reader = apdu_get_reader_name (slot);
644 return out_of_core ();
645 send_status_direct (ctrl, "READER", reader);
646 /* No need to free the string of READER. */
648 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
652 rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
653 serial, (unsigned long)stamp);
657 return out_of_core ();
660 if (!has_option (line, "--force"))
664 rc = gpgrt_asprintf (&command, "KNOWNCARDP %s %lu",
665 serial, (unsigned long)stamp);
669 return out_of_core ();
671 rc = assuan_inquire (ctx, command, NULL, NULL, 0);
675 if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
676 log_error ("inquire KNOWNCARDP failed: %s\n",
681 /* Not canceled, so we have to proceeed. */
686 /* Let the application print out its collection of useful status
689 rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
691 TEST_CARD_REMOVAL (ctrl, rc);
697 static const char hlp_readcert[] =
698 "READCERT <hexified_certid>|<keyid>\n"
700 "Note, that this function may even be used on a locked card.";
702 cmd_readcert (assuan_context_t ctx, char *line)
704 ctrl_t ctrl = assuan_get_pointer (ctx);
709 if ((rc = open_card (ctrl, NULL)))
712 line = xstrdup (line); /* Need a copy of the line. */
713 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
715 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
720 rc = assuan_send_data (ctx, cert, ncert);
726 TEST_CARD_REMOVAL (ctrl, rc);
731 static const char hlp_readkey[] =
732 "READKEY [--advanced] <keyid>\n"
734 "Return the public key for the given cert or key ID as a standard\n"
736 "In --advanced mode it returns the S-expression in advanced format.\n"
738 "Note that this function may even be used on a locked card.";
740 cmd_readkey (assuan_context_t ctx, char *line)
742 ctrl_t ctrl = assuan_get_pointer (ctx);
745 unsigned char *cert = NULL;
747 ksba_cert_t kc = NULL;
752 if ((rc = open_card (ctrl, NULL)))
755 if (has_option (line, "--advanced"))
758 line = skip_options (line);
760 line = xstrdup (line); /* Need a copy of the line. */
761 /* If the application supports the READKEY function we use that.
762 Otherwise we use the old way by extracting it from the
764 rc = app_readkey (ctrl->app_ctx, advanced, line, &pk, &pklen);
766 { /* Yeah, got that key - send it back. */
767 rc = assuan_send_data (ctx, pk, pklen);
774 if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
775 log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
778 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
780 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
787 rc = ksba_cert_new (&kc);
791 rc = ksba_cert_init_from_mem (kc, cert, ncert);
794 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
798 p = ksba_cert_get_public_key (kc);
801 rc = gpg_error (GPG_ERR_NO_PUBKEY);
805 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
806 rc = assuan_send_data (ctx, p, n);
811 ksba_cert_release (kc);
813 TEST_CARD_REMOVAL (ctrl, rc);
819 static const char hlp_setdata[] =
820 "SETDATA [--append] <hexstring>\n"
822 "The client should use this command to tell us the data he want to sign.\n"
823 "With the option --append, the data is appended to the data set by a\n"
824 "previous SETDATA command.";
826 cmd_setdata (assuan_context_t ctx, char *line)
828 ctrl_t ctrl = assuan_get_pointer (ctx);
834 append = (ctrl->in_data.value && has_option (line, "--append"));
836 line = skip_options (line);
838 if (locked_session && locked_session != ctrl->server_local)
839 return gpg_error (GPG_ERR_LOCKED);
841 /* Parse the hexstring. */
842 for (p=line,n=0; hexdigitp (p); p++, n++)
845 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
847 return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
849 return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
853 if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
854 return set_error (GPG_ERR_TOO_LARGE,
855 "limit on total size of data reached");
856 buf = xtrymalloc (ctrl->in_data.valuelen + n);
859 buf = xtrymalloc (n);
861 return out_of_core ();
865 memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
866 off = ctrl->in_data.valuelen;
870 for (p=line, i=0; i < n; p += 2, i++)
871 buf[off+i] = xtoi_2 (p);
873 xfree (ctrl->in_data.value);
874 ctrl->in_data.value = buf;
875 ctrl->in_data.valuelen = off+n;
882 pin_cb (void *opaque, const char *info, char **retstr)
884 assuan_context_t ctx = opaque;
887 unsigned char *value;
892 /* We prompt for pinpad entry. To make sure that the popup has
893 been show we use an inquire and not just a status message.
894 We ignore any value returned. */
897 log_debug ("prompting for pinpad entry '%s'\n", info);
898 rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
900 return gpg_error (gpg_err_code_from_errno (errno));
901 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
906 log_debug ("dismiss pinpad entry prompt\n");
907 rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT",
908 &value, &valuelen, MAXLEN_PIN);
916 log_debug ("asking for PIN '%s'\n", info);
918 rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
920 return gpg_error (gpg_err_code_from_errno (errno));
922 /* Fixme: Write an inquire function which returns the result in
923 secure memory and check all further handling of the PIN. */
924 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
929 if (!valuelen || value[valuelen-1])
931 /* We require that the returned value is an UTF-8 string */
933 return gpg_error (GPG_ERR_INV_RESPONSE);
935 *retstr = (char*)value;
940 static const char hlp_pksign[] =
941 "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>\n"
943 "The --hash option is optional; the default is SHA1.";
945 cmd_pksign (assuan_context_t ctx, char *line)
947 ctrl_t ctrl = assuan_get_pointer (ctx);
949 unsigned char *outdata;
954 if (has_option (line, "--hash=rmd160"))
955 hash_algo = GCRY_MD_RMD160;
956 else if (has_option (line, "--hash=sha1"))
957 hash_algo = GCRY_MD_SHA1;
958 else if (has_option (line, "--hash=sha224"))
959 hash_algo = GCRY_MD_SHA224;
960 else if (has_option (line, "--hash=sha256"))
961 hash_algo = GCRY_MD_SHA256;
962 else if (has_option (line, "--hash=sha384"))
963 hash_algo = GCRY_MD_SHA384;
964 else if (has_option (line, "--hash=sha512"))
965 hash_algo = GCRY_MD_SHA512;
966 else if (has_option (line, "--hash=md5"))
967 hash_algo = GCRY_MD_MD5;
968 else if (!strstr (line, "--"))
969 hash_algo = GCRY_MD_SHA1;
971 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
973 line = skip_options (line);
975 if ( IS_LOCKED (ctrl) )
976 return gpg_error (GPG_ERR_LOCKED);
978 if ((rc = open_card (ctrl, NULL)))
981 /* We have to use a copy of the key ID because the function may use
982 the pin_cb which in turn uses the assuan line buffer and thus
983 overwriting the original line with the keyid */
984 keyidstr = xtrystrdup (line);
986 return out_of_core ();
988 rc = app_sign (ctrl->app_ctx,
991 ctrl->in_data.value, ctrl->in_data.valuelen,
992 &outdata, &outdatalen);
997 log_error ("app_sign failed: %s\n", gpg_strerror (rc));
1001 rc = assuan_send_data (ctx, outdata, outdatalen);
1004 return rc; /* that is already an assuan error code */
1007 TEST_CARD_REMOVAL (ctrl, rc);
1012 static const char hlp_pkauth[] =
1013 "PKAUTH <hexified_id>";
1015 cmd_pkauth (assuan_context_t ctx, char *line)
1017 ctrl_t ctrl = assuan_get_pointer (ctx);
1019 unsigned char *outdata;
1023 if ( IS_LOCKED (ctrl) )
1024 return gpg_error (GPG_ERR_LOCKED);
1026 if ((rc = open_card (ctrl, NULL)))
1030 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1032 /* We have to use a copy of the key ID because the function may use
1033 the pin_cb which in turn uses the assuan line buffer and thus
1034 overwriting the original line with the keyid */
1035 keyidstr = xtrystrdup (line);
1037 return out_of_core ();
1039 rc = app_auth (ctrl->app_ctx,
1042 ctrl->in_data.value, ctrl->in_data.valuelen,
1043 &outdata, &outdatalen);
1047 log_error ("app_auth failed: %s\n", gpg_strerror (rc));
1051 rc = assuan_send_data (ctx, outdata, outdatalen);
1054 return rc; /* that is already an assuan error code */
1057 TEST_CARD_REMOVAL (ctrl, rc);
1062 static const char hlp_pkdecrypt[] =
1063 "PKDECRYPT <hexified_id>";
1065 cmd_pkdecrypt (assuan_context_t ctx, char *line)
1067 ctrl_t ctrl = assuan_get_pointer (ctx);
1069 unsigned char *outdata;
1072 unsigned int infoflags;
1074 if ( IS_LOCKED (ctrl) )
1075 return gpg_error (GPG_ERR_LOCKED);
1077 if ((rc = open_card (ctrl, NULL)))
1080 keyidstr = xtrystrdup (line);
1082 return out_of_core ();
1083 rc = app_decipher (ctrl->app_ctx,
1086 ctrl->in_data.value, ctrl->in_data.valuelen,
1087 &outdata, &outdatalen, &infoflags);
1092 log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
1096 /* If the card driver told us that there is no padding, send a
1097 status line. If there is a padding it is assumed that the
1098 caller knows what padding is used. It would have been better
1099 to always send that information but for backward
1100 compatibility we can't do that. */
1101 if ((infoflags & APP_DECIPHER_INFO_NOPAD))
1102 send_status_direct (ctrl, "PADDING", "0");
1103 rc = assuan_send_data (ctx, outdata, outdatalen);
1106 return rc; /* that is already an assuan error code */
1109 TEST_CARD_REMOVAL (ctrl, rc);
1114 static const char hlp_getattr[] =
1117 "This command is used to retrieve data from a smartcard. The\n"
1118 "allowed names depend on the currently selected smartcard\n"
1119 "application. NAME must be percent and '+' escaped. The value is\n"
1120 "returned through status message, see the LEARN command for details.\n"
1122 "However, the current implementation assumes that Name is not escaped;\n"
1123 "this works as long as no one uses arbitrary escaping. \n"
1125 "Note, that this function may even be used on a locked card.";
1127 cmd_getattr (assuan_context_t ctx, char *line)
1129 ctrl_t ctrl = assuan_get_pointer (ctx);
1131 const char *keyword;
1133 if ((rc = open_card (ctrl, NULL)))
1137 for (; *line && !spacep (line); line++)
1142 /* (We ignore any garbage for now.) */
1144 /* FIXME: Applications should not return sensitive data if the card
1146 rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
1148 TEST_CARD_REMOVAL (ctrl, rc);
1153 static const char hlp_setattr[] =
1154 "SETATTR <name> <value> \n"
1156 "This command is used to store data on a a smartcard. The allowed\n"
1157 "names and values are depend on the currently selected smartcard\n"
1158 "application. NAME and VALUE must be percent and '+' escaped.\n"
1160 "However, the current implementation assumes that NAME is not\n"
1161 "escaped; this works as long as no one uses arbitrary escaping.\n"
1163 "A PIN will be requested for most NAMEs. See the corresponding\n"
1164 "setattr function of the actually used application (app-*.c) for\n"
1167 cmd_setattr (assuan_context_t ctx, char *orig_line)
1169 ctrl_t ctrl = assuan_get_pointer (ctx);
1174 char *line, *linebuf;
1176 if ( IS_LOCKED (ctrl) )
1177 return gpg_error (GPG_ERR_LOCKED);
1179 if ((rc = open_card (ctrl, NULL)))
1182 /* We need to use a copy of LINE, because PIN_CB uses the same
1183 context and thus reuses the Assuan provided LINE. */
1184 line = linebuf = xtrystrdup (orig_line);
1186 return out_of_core ();
1189 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1193 while (spacep (line))
1195 nbytes = percent_plus_unescape_inplace (line, 0);
1197 rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx,
1198 (const unsigned char*)line, nbytes);
1201 TEST_CARD_REMOVAL (ctrl, rc);
1206 static const char hlp_writecert[] =
1207 "WRITECERT <hexified_certid>\n"
1209 "This command is used to store a certifciate on a smartcard. The\n"
1210 "allowed certids depend on the currently selected smartcard\n"
1211 "application. The actual certifciate is requested using the inquiry\n"
1212 "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
1214 "In almost all cases a a PIN will be requested. See the related\n"
1215 "writecert function of the actually used application (app-*.c) for\n"
1218 cmd_writecert (assuan_context_t ctx, char *line)
1220 ctrl_t ctrl = assuan_get_pointer (ctx);
1223 unsigned char *certdata;
1226 if ( IS_LOCKED (ctrl) )
1227 return gpg_error (GPG_ERR_LOCKED);
1229 line = skip_options (line);
1232 return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1234 while (*line && !spacep (line))
1238 if ((rc = open_card (ctrl, NULL)))
1242 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1244 certid = xtrystrdup (certid);
1246 return out_of_core ();
1248 /* Now get the actual keydata. */
1249 rc = assuan_inquire (ctx, "CERTDATA",
1250 &certdata, &certdatalen, MAXLEN_CERTDATA);
1257 /* Write the certificate to the card. */
1258 rc = app_writecert (ctrl->app_ctx, ctrl, certid,
1259 pin_cb, ctx, certdata, certdatalen);
1263 TEST_CARD_REMOVAL (ctrl, rc);
1268 static const char hlp_writekey[] =
1269 "WRITEKEY [--force] <keyid> \n"
1271 "This command is used to store a secret key on a a smartcard. The\n"
1272 "allowed keyids depend on the currently selected smartcard\n"
1273 "application. The actual keydata is requested using the inquiry\n"
1274 "\"KEYDATA\" and need to be provided without any protection. With\n"
1275 "--force set an existing key under this KEYID will get overwritten.\n"
1276 "The keydata is expected to be the usual canonical encoded\n"
1279 "A PIN will be requested for most NAMEs. See the corresponding\n"
1280 "writekey function of the actually used application (app-*.c) for\n"
1283 cmd_writekey (assuan_context_t ctx, char *line)
1285 ctrl_t ctrl = assuan_get_pointer (ctx);
1288 int force = has_option (line, "--force");
1289 unsigned char *keydata;
1292 if ( IS_LOCKED (ctrl) )
1293 return gpg_error (GPG_ERR_LOCKED);
1295 line = skip_options (line);
1298 return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1300 while (*line && !spacep (line))
1304 if ((rc = open_card (ctrl, NULL)))
1308 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1310 keyid = xtrystrdup (keyid);
1312 return out_of_core ();
1314 /* Now get the actual keydata. */
1315 assuan_begin_confidential (ctx);
1316 rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1317 assuan_end_confidential (ctx);
1324 /* Write the key to the card. */
1325 rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1326 pin_cb, ctx, keydata, keydatalen);
1330 TEST_CARD_REMOVAL (ctrl, rc);
1335 static const char hlp_genkey[] =
1336 "GENKEY [--force] [--timestamp=<isodate>] <no>\n"
1338 "Generate a key on-card identified by NO, which is application\n"
1339 "specific. Return values are application specific. For OpenPGP\n"
1340 "cards 3 status lines are returned:\n"
1342 " S KEY-FPR <hexstring>\n"
1343 " S KEY-CREATED-AT <seconds_since_epoch>\n"
1344 " S KEY-DATA [-|p|n] <hexdata>\n"
1346 " 'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
1347 " indicate that HEXDATA is the first chunk of a parameter given\n"
1348 " by the next KEY-DATA.\n"
1350 "--force is required to overwrite an already existing key. The\n"
1351 "KEY-CREATED-AT is required for further processing because it is\n"
1352 "part of the hashed key material for the fingerprint.\n"
1354 "If --timestamp is given an OpenPGP key will be created using this\n"
1355 "value. The value needs to be in ISO Format; e.g.\n"
1356 "\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
1358 "The public part of the key can also later be retrieved using the\n"
1361 cmd_genkey (assuan_context_t ctx, char *line)
1363 ctrl_t ctrl = assuan_get_pointer (ctx);
1370 if ( IS_LOCKED (ctrl) )
1371 return gpg_error (GPG_ERR_LOCKED);
1373 force = has_option (line, "--force");
1375 if ((s=has_option_name (line, "--timestamp")))
1378 return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1379 timestamp = isotime2epoch (s+1);
1381 return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1387 line = skip_options (line);
1389 return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1391 while (*line && !spacep (line))
1395 if ((rc = open_card (ctrl, NULL)))
1399 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1401 keyno = xtrystrdup (keyno);
1403 return out_of_core ();
1404 rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1405 timestamp, pin_cb, ctx);
1408 TEST_CARD_REMOVAL (ctrl, rc);
1413 static const char hlp_random[] =
1416 "Get NBYTES of random from the card and send them back as data.\n"
1417 "This usually involves EEPROM write on the card and thus excessive\n"
1418 "use of this command may destroy the card.\n"
1420 "Note, that this function may be even be used on a locked card.";
1422 cmd_random (assuan_context_t ctx, char *line)
1424 ctrl_t ctrl = assuan_get_pointer (ctx);
1427 unsigned char *buffer;
1430 return set_error (GPG_ERR_ASS_PARAMETER,
1431 "number of requested bytes missing");
1432 nbytes = strtoul (line, NULL, 0);
1434 if ((rc = open_card (ctrl, NULL)))
1438 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1440 buffer = xtrymalloc (nbytes);
1442 return out_of_core ();
1444 rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1447 rc = assuan_send_data (ctx, buffer, nbytes);
1449 return rc; /* that is already an assuan error code */
1453 TEST_CARD_REMOVAL (ctrl, rc);
1459 static const char hlp_passwd[] =
1460 "PASSWD [--reset] [--nullpin] <chvno>\n"
1462 "Change the PIN or, if --reset is given, reset the retry counter of\n"
1463 "the card holder verification vector CHVNO. The option --nullpin is\n"
1464 "used for TCOS cards to set the initial PIN. The format of CHVNO\n"
1465 "depends on the card application.";
1467 cmd_passwd (assuan_context_t ctx, char *line)
1469 ctrl_t ctrl = assuan_get_pointer (ctx);
1472 unsigned int flags = 0;
1474 if (has_option (line, "--reset"))
1475 flags |= APP_CHANGE_FLAG_RESET;
1476 if (has_option (line, "--nullpin"))
1477 flags |= APP_CHANGE_FLAG_NULLPIN;
1479 if ( IS_LOCKED (ctrl) )
1480 return gpg_error (GPG_ERR_LOCKED);
1482 line = skip_options (line);
1485 return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1487 while (*line && !spacep (line))
1491 if ((rc = open_card (ctrl, NULL)))
1495 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1497 chvnostr = xtrystrdup (chvnostr);
1499 return out_of_core ();
1500 rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1502 log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1505 TEST_CARD_REMOVAL (ctrl, rc);
1510 static const char hlp_checkpin[] =
1511 "CHECKPIN <idstr>\n"
1513 "Perform a VERIFY operation without doing anything else. This may\n"
1514 "be used to initialize a the PIN cache earlier to long lasting\n"
1515 "operations. Its use is highly application dependent.\n"
1519 " Perform a simple verify operation for CHV1 and CHV2, so that\n"
1520 " further operations won't ask for CHV2 and it is possible to do a\n"
1521 " cheap check on the PIN: If there is something wrong with the PIN\n"
1522 " entry system, only the regular CHV will get blocked and not the\n"
1523 " dangerous CHV3. IDSTR is the usual card's serial number in hex\n"
1524 " notation; an optional fingerprint part will get ignored. There\n"
1525 " is however a special mode if the IDSTR is sffixed with the\n"
1526 " literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1527 " if and only if the retry counter is still at 3.\n"
1531 " Any of the valid PIN Ids may be used. These are the strings:\n"
1533 " PW1.CH - Global password 1\n"
1534 " PW2.CH - Global password 2\n"
1535 " PW1.CH.SIG - SigG password 1\n"
1536 " PW2.CH.SIG - SigG password 2\n"
1538 " For a definitive list, see the implementation in app-nks.c.\n"
1539 " Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1540 " 3.0 they are technically alternative PINs used to mutally\n"
1541 " unblock each other.";
1543 cmd_checkpin (assuan_context_t ctx, char *line)
1545 ctrl_t ctrl = assuan_get_pointer (ctx);
1549 if ( IS_LOCKED (ctrl) )
1550 return gpg_error (GPG_ERR_LOCKED);
1552 if ((rc = open_card (ctrl, NULL)))
1556 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1558 /* We have to use a copy of the key ID because the function may use
1559 the pin_cb which in turn uses the assuan line buffer and thus
1560 overwriting the original line with the keyid. */
1561 idstr = xtrystrdup (line);
1563 return out_of_core ();
1565 rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx);
1568 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1570 TEST_CARD_REMOVAL (ctrl, rc);
1575 static const char hlp_lock[] =
1578 "Grant exclusive card access to this session. Note that there is\n"
1579 "no lock counter used and a second lock from the same session will\n"
1580 "be ignored. A single unlock (or RESET) unlocks the session.\n"
1581 "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1583 "If the option --wait is given the command will wait until a\n"
1584 "lock has been released.";
1586 cmd_lock (assuan_context_t ctx, char *line)
1588 ctrl_t ctrl = assuan_get_pointer (ctx);
1594 if (locked_session != ctrl->server_local)
1595 rc = gpg_error (GPG_ERR_LOCKED);
1598 locked_session = ctrl->server_local;
1601 if (rc && has_option (line, "--wait"))
1604 npth_sleep (1); /* Better implement an event mechanism. However,
1605 for card operations this should be
1607 /* FIXME: Need to check that the connection is still alive.
1608 This can be done by issuing status messages. */
1614 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1619 static const char hlp_unlock[] =
1622 "Release exclusive card access.";
1624 cmd_unlock (assuan_context_t ctx, char *line)
1626 ctrl_t ctrl = assuan_get_pointer (ctx);
1633 if (locked_session != ctrl->server_local)
1634 rc = gpg_error (GPG_ERR_LOCKED);
1636 locked_session = NULL;
1639 rc = gpg_error (GPG_ERR_NOT_LOCKED);
1642 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1647 static const char hlp_getinfo[] =
1650 "Multi purpose command to return certain information. \n"
1651 "Supported values of WHAT are:\n"
1653 "version - Return the version of the program.\n"
1654 "pid - Return the process id of the server.\n"
1656 "socket_name - Return the name of the socket.\n"
1658 "status - Return the status of the current reader (in the future, may\n"
1659 "also return the status of all readers). The status is a list of\n"
1660 "one-character flags. The following flags are currently defined:\n"
1661 " 'u' Usable card present. This is the normal state during operation.\n"
1662 " 'r' Card removed. A reset is necessary.\n"
1663 "These flags are exclusive.\n"
1665 "reader_list - Return a list of detected card readers. Does\n"
1666 " currently only work with the internal CCID driver.\n"
1668 "deny_admin - Returns OK if admin commands are not allowed or\n"
1669 " GPG_ERR_GENERAL if admin commands are allowed.\n"
1671 "app_list - Return a list of supported applications. One\n"
1672 " application per line, fields delimited by colons,\n"
1673 " first field is the name.";
1675 cmd_getinfo (assuan_context_t ctx, char *line)
1679 if (!strcmp (line, "version"))
1681 const char *s = VERSION;
1682 rc = assuan_send_data (ctx, s, strlen (s));
1684 else if (!strcmp (line, "pid"))
1688 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1689 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1691 else if (!strcmp (line, "socket_name"))
1693 const char *s = scd_get_socket_name ();
1696 rc = assuan_send_data (ctx, s, strlen (s));
1698 rc = gpg_error (GPG_ERR_NO_DATA);
1700 else if (!strcmp (line, "status"))
1702 ctrl_t ctrl = assuan_get_pointer (ctx);
1703 int vrdr = ctrl->server_local->vreader_idx;
1706 if (!ctrl->server_local->card_removed && vrdr != -1)
1708 struct vreader_s *vr;
1710 if (!(vrdr >= 0 && vrdr < DIM(vreader_table)))
1713 vr = &vreader_table[vrdr];
1714 if (vr->valid && vr->any && (vr->status & 1))
1717 rc = assuan_send_data (ctx, &flag, 1);
1719 else if (!strcmp (line, "reader_list"))
1722 char *s = ccid_get_reader_list ();
1728 rc = assuan_send_data (ctx, s, strlen (s));
1730 rc = gpg_error (GPG_ERR_NO_DATA);
1733 else if (!strcmp (line, "deny_admin"))
1734 rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1735 else if (!strcmp (line, "app_list"))
1737 char *s = get_supported_applications ();
1739 rc = assuan_send_data (ctx, s, strlen (s));
1745 rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1750 static const char hlp_restart[] =
1753 "Restart the current connection; this is a kind of warm reset. It\n"
1754 "deletes the context used by this connection but does not send a\n"
1755 "RESET to the card. Thus the card itself won't get reset. \n"
1757 "This is used by gpg-agent to reuse a primary pipe connection and\n"
1758 "may be used by clients to backup from a conflict in the serial\n"
1759 "command; i.e. to select another application.";
1761 cmd_restart (assuan_context_t ctx, char *line)
1763 ctrl_t ctrl = assuan_get_pointer (ctx);
1764 struct app_ctx_s *app = ctrl->app_ctx;
1770 ctrl->app_ctx = NULL;
1771 release_application (app);
1773 if (locked_session && ctrl->server_local == locked_session)
1775 locked_session = NULL;
1776 log_info ("implicitly unlocking due to RESTART\n");
1782 static const char hlp_disconnect[] =
1785 "Disconnect the card if it is not any longer used by other\n"
1786 "connections and the backend supports a disconnect operation.";
1788 cmd_disconnect (assuan_context_t ctx, char *line)
1790 ctrl_t ctrl = assuan_get_pointer (ctx);
1794 ctrl->server_local->disconnect_allowed = 1;
1800 static const char hlp_apdu[] =
1801 "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1803 "Send an APDU to the current reader. This command bypasses the high\n"
1804 "level functions and sends the data directly to the card. HEXSTRING\n"
1805 "is expected to be a proper APDU. If HEXSTRING is not given no\n"
1806 "commands are set to the card but the command will implictly check\n"
1807 "whether the card is ready for use. \n"
1809 "Using the option \"--atr\" returns the ATR of the card as a status\n"
1810 "message before any data like this:\n"
1811 " S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1813 "Using the option --more handles the card status word MORE_DATA\n"
1814 "(61xx) and concatenates all responses to one block.\n"
1816 "Using the option \"--exlen\" the returned APDU may use extended\n"
1817 "length up to N bytes. If N is not given a default value is used\n"
1818 "(currently 4096).";
1820 cmd_apdu (assuan_context_t ctx, char *line)
1822 ctrl_t ctrl = assuan_get_pointer (ctx);
1824 unsigned char *apdu;
1832 if (has_option (line, "--dump-atr"))
1835 with_atr = has_option (line, "--atr");
1836 handle_more = has_option (line, "--more");
1838 if ((s=has_option_name (line, "--exlen")))
1841 exlen = strtoul (s+1, NULL, 0);
1848 line = skip_options (line);
1850 if ( IS_LOCKED (ctrl) )
1851 return gpg_error (GPG_ERR_LOCKED);
1853 if ((rc = open_card (ctrl, NULL)))
1856 slot = vreader_slot (ctrl->server_local->vreader_idx);
1864 atr = apdu_get_atr (slot, &atrlen);
1865 if (!atr || atrlen > sizeof hexbuf - 2 )
1867 rc = gpg_error (GPG_ERR_INV_CARD);
1872 char *string, *p, *pend;
1874 string = atr_dump (atr, atrlen);
1877 for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1879 rc = assuan_send_data (ctx, p, pend - p + 1);
1881 rc = assuan_send_data (ctx, NULL, 0);
1884 rc = assuan_send_data (ctx, p, strlen (p));
1892 bin2hex (atr, atrlen, hexbuf);
1893 send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1898 apdu = hex_to_buffer (line, &apdulen);
1901 rc = gpg_error_from_syserror ();
1906 unsigned char *result = NULL;
1909 rc = apdu_send_direct (slot, exlen,
1910 apdu, apdulen, handle_more,
1911 &result, &resultlen);
1913 log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1916 rc = assuan_send_data (ctx, result, resultlen);
1923 TEST_CARD_REMOVAL (ctrl, rc);
1928 static const char hlp_killscd[] =
1933 cmd_killscd (assuan_context_t ctx, char *line)
1935 ctrl_t ctrl = assuan_get_pointer (ctx);
1939 ctrl->server_local->stopme = 1;
1940 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1946 /* Tell the assuan library about our commands */
1948 register_commands (assuan_context_t ctx)
1952 assuan_handler_t handler;
1953 const char * const help;
1955 { "SERIALNO", cmd_serialno, hlp_serialno },
1956 { "LEARN", cmd_learn, hlp_learn },
1957 { "READCERT", cmd_readcert, hlp_readcert },
1958 { "READKEY", cmd_readkey, hlp_readkey },
1959 { "SETDATA", cmd_setdata, hlp_setdata },
1960 { "PKSIGN", cmd_pksign, hlp_pksign },
1961 { "PKAUTH", cmd_pkauth, hlp_pkauth },
1962 { "PKDECRYPT", cmd_pkdecrypt,hlp_pkdecrypt },
1965 { "GETATTR", cmd_getattr, hlp_getattr },
1966 { "SETATTR", cmd_setattr, hlp_setattr },
1967 { "WRITECERT", cmd_writecert,hlp_writecert },
1968 { "WRITEKEY", cmd_writekey, hlp_writekey },
1969 { "GENKEY", cmd_genkey, hlp_genkey },
1970 { "RANDOM", cmd_random, hlp_random },
1971 { "PASSWD", cmd_passwd, hlp_passwd },
1972 { "CHECKPIN", cmd_checkpin, hlp_checkpin },
1973 { "LOCK", cmd_lock, hlp_lock },
1974 { "UNLOCK", cmd_unlock, hlp_unlock },
1975 { "GETINFO", cmd_getinfo, hlp_getinfo },
1976 { "RESTART", cmd_restart, hlp_restart },
1977 { "DISCONNECT", cmd_disconnect,hlp_disconnect },
1978 { "APDU", cmd_apdu, hlp_apdu },
1979 { "KILLSCD", cmd_killscd, hlp_killscd },
1984 for (i=0; table[i].name; i++)
1986 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1991 assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1993 assuan_register_reset_notify (ctx, reset_notify);
1994 assuan_register_option_handler (ctx, option_handler);
1999 /* Startup the server. If FD is given as -1 this is simple pipe
2000 server, otherwise it is a regular server. Returns true if there
2001 are no more active asessions. */
2003 scd_command_handler (ctrl_t ctrl, int fd)
2006 assuan_context_t ctx = NULL;
2009 rc = assuan_new (&ctx);
2012 log_error ("failed to allocate assuan context: %s\n",
2019 assuan_fd_t filedes[2];
2021 filedes[0] = assuan_fdopen (0);
2022 filedes[1] = assuan_fdopen (1);
2023 rc = assuan_init_pipe_server (ctx, filedes);
2027 rc = assuan_init_socket_server (ctx, INT2FD(fd),
2028 ASSUAN_SOCKET_SERVER_ACCEPTED);
2032 log_error ("failed to initialize the server: %s\n",
2036 rc = register_commands (ctx);
2039 log_error ("failed to register commands with Assuan: %s\n",
2043 assuan_set_pointer (ctx, ctrl);
2045 /* Allocate and initialize the server object. Put it into the list
2046 of active sessions. */
2047 ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2048 ctrl->server_local->next_session = session_list;
2049 session_list = ctrl->server_local;
2050 ctrl->server_local->ctrl_backlink = ctrl;
2051 ctrl->server_local->assuan_ctx = ctx;
2053 /* We open the reader right at startup so that the ticker is able to
2054 update the status file. */
2055 ctrl->server_local->vreader_idx = get_current_reader ();
2057 /* Command processing loop. */
2060 rc = assuan_accept (ctx);
2067 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2071 rc = assuan_process (ctx);
2074 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2079 /* Cleanup. We don't send an explicit reset to the card. */
2082 /* Release the server object. */
2083 if (session_list == ctrl->server_local)
2084 session_list = ctrl->server_local->next_session;
2087 struct server_local_s *sl;
2089 for (sl=session_list; sl->next_session; sl = sl->next_session)
2090 if (sl->next_session == ctrl->server_local)
2092 if (!sl->next_session)
2094 sl->next_session = ctrl->server_local->next_session;
2096 stopme = ctrl->server_local->stopme;
2097 xfree (ctrl->server_local);
2098 ctrl->server_local = NULL;
2100 /* Release the Assuan context. */
2101 assuan_release (ctx);
2106 /* If there are no more sessions return true. */
2107 return !session_list;
2111 /* Send a line with status information via assuan and escape all given
2112 buffers. The variable elements are pairs of (char *, size_t),
2113 terminated with a (NULL, 0). */
2115 send_status_info (ctrl_t ctrl, const char *keyword, ...)
2118 const unsigned char *value;
2122 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2124 va_start (arg_ptr, keyword);
2128 while ( (value = va_arg (arg_ptr, const unsigned char *)) )
2130 valuelen = va_arg (arg_ptr, size_t);
2132 continue; /* empty buffer */
2138 for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2140 if (*value == '+' || *value == '\"' || *value == '%'
2143 sprintf (p, "%%%02X", *value);
2146 else if (*value == ' ')
2153 assuan_write_status (ctx, keyword, buf);
2159 /* Send a ready formatted status line via assuan. */
2161 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2163 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2165 if (strchr (args, '\n'))
2166 log_error ("error: LF detected in status line - not sending\n");
2168 assuan_write_status (ctx, keyword, args);
2172 /* Helper to send the clients a status change notification. */
2174 send_client_notifications (void)
2178 #ifdef HAVE_W32_SYSTEM
2186 struct server_local_s *sl;
2188 for (sl=session_list; sl; sl = sl->next_session)
2190 if (sl->event_signal && sl->assuan_ctx)
2192 pid_t pid = assuan_get_pid (sl->assuan_ctx);
2193 #ifdef HAVE_W32_SYSTEM
2194 HANDLE handle = (void *)sl->event_signal;
2196 for (kidx=0; kidx < killidx; kidx++)
2197 if (killed[kidx].pid == pid
2198 && killed[kidx].handle == handle)
2201 log_info ("event %lx (%p) already triggered for client %d\n",
2202 sl->event_signal, handle, (int)pid);
2205 log_info ("triggering event %lx (%p) for client %d\n",
2206 sl->event_signal, handle, (int)pid);
2207 if (!SetEvent (handle))
2208 log_error ("SetEvent(%lx) failed: %s\n",
2209 sl->event_signal, w32_strerror (-1));
2210 if (killidx < DIM (killed))
2212 killed[killidx].pid = pid;
2213 killed[killidx].handle = handle;
2217 #else /*!HAVE_W32_SYSTEM*/
2218 int signo = sl->event_signal;
2220 if (pid != (pid_t)(-1) && pid && signo > 0)
2222 for (kidx=0; kidx < killidx; kidx++)
2223 if (killed[kidx].pid == pid
2224 && killed[kidx].signo == signo)
2227 log_info ("signal %d already sent to client %d\n",
2231 log_info ("sending signal %d to client %d\n",
2234 if (killidx < DIM (killed))
2236 killed[killidx].pid = pid;
2237 killed[killidx].signo = signo;
2242 #endif /*!HAVE_W32_SYSTEM*/
2249 /* This is the core of scd_update_reader_status_file but the caller
2250 needs to take care of the locking. */
2252 update_reader_status_file (int set_card_removed_flag)
2255 unsigned int status, changed;
2257 /* Note, that we only try to get the status, because it does not
2258 make sense to wait here for a operation to complete. If we are
2259 busy working with a card, delays in the status file update should
2261 for (idx=0; idx < DIM(vreader_table); idx++)
2263 struct vreader_s *vr = vreader_table + idx;
2264 struct server_local_s *sl;
2267 if (!vr->valid || vr->slot == -1)
2268 continue; /* Not valid or reader not yet open. */
2270 sw_apdu = apdu_get_status (vr->slot, 0, &status, &changed);
2271 if (sw_apdu == SW_HOST_NO_READER)
2273 /* Most likely the _reader_ has been unplugged. */
2274 apdu_close_reader (vr->slot);
2276 changed = vr->changed;
2280 /* Get status failed. Ignore that. */
2284 if (!vr->any || vr->status != status || vr->changed != changed )
2290 log_info ("updating reader %d (%d) status: 0x%04X->0x%04X (%u->%u)\n",
2291 idx, vr->slot, vr->status, status, vr->changed, changed);
2292 vr->status = status;
2293 vr->changed = changed;
2295 /* FIXME: Should this be IDX instead of vr->slot? This
2296 depends on how client sessions will associate the reader
2297 status with their session. */
2298 snprintf (templ, sizeof templ, "reader_%d.status", vr->slot);
2299 fname = make_filename (gnupg_homedir (), templ, NULL );
2300 fp = fopen (fname, "w");
2303 fprintf (fp, "%s\n",
2304 (status & 1)? "USABLE":
2305 (status & 4)? "ACTIVE":
2306 (status & 2)? "PRESENT": "NOCARD");
2311 /* If a status script is executable, run it. */
2313 const char *args[9], *envs[2];
2314 char numbuf1[30], numbuf2[30], numbuf3[30];
2315 char *homestr, *envstr;
2318 homestr = make_filename (gnupg_homedir (), NULL);
2319 if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
2320 log_error ("out of core while building environment\n");
2326 sprintf (numbuf1, "%d", vr->slot);
2327 sprintf (numbuf2, "0x%04X", vr->status);
2328 sprintf (numbuf3, "0x%04X", status);
2329 args[0] = "--reader-port";
2331 args[2] = "--old-code";
2333 args[4] = "--new-code";
2335 args[6] = "--status";
2336 args[7] = ((status & 1)? "USABLE":
2337 (status & 4)? "ACTIVE":
2338 (status & 2)? "PRESENT": "NOCARD");
2341 fname = make_filename (gnupg_homedir (), "scd-event", NULL);
2342 err = gnupg_spawn_process_detached (fname, args, envs);
2343 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
2344 log_error ("failed to run event handler '%s': %s\n",
2345 fname, gpg_strerror (err));
2352 /* Set the card removed flag for all current sessions. */
2353 if (vr->any && vr->status == 0 && set_card_removed_flag)
2354 update_card_removed (idx, 1);
2358 /* Send a signal to all clients who applied for it. */
2359 send_client_notifications ();
2362 /* Check whether a disconnect is pending. */
2363 if (opt.card_timeout)
2365 for (sl=session_list; sl; sl = sl->next_session)
2366 if (!sl->disconnect_allowed)
2368 if (session_list && !sl)
2370 /* FIXME: Use a real timeout. */
2371 /* At least one connection and all allow a disconnect. */
2372 log_info ("disconnecting card in reader %d (%d)\n",
2374 apdu_disconnect (vr->slot);
2381 /* This function is called by the ticker thread to check for changes
2382 of the reader stati. It updates the reader status files and if
2383 requested by the caller also send a signal to the caller. */
2385 scd_update_reader_status_file (void)
2388 err = npth_mutex_lock (&status_file_update_lock);
2390 return; /* locked - give up. */
2391 update_reader_status_file (1);
2392 err = npth_mutex_unlock (&status_file_update_lock);
2394 log_error ("failed to release status_file_update lock: %s\n",