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 <http://www.gnu.org/licenses/>.
36 #include "app-common.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
42 #include "ccid-driver.h"
46 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
47 #define MAXLEN_PIN 100
49 /* Maximum allowed size of key data as used in inquiries. */
50 #define MAXLEN_KEYDATA 4096
52 /* Maximum allowed total data size for SETDATA. */
53 #define MAXLEN_SETDATA 4096
55 /* Maximum allowed size of certificate data as used in inquiries. */
56 #define MAXLEN_CERTDATA 16384
59 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
62 /* Macro to flag a removed card. ENODEV is also tested to catch the
63 case of a removed reader. */
64 #define TEST_CARD_REMOVAL(c,r) \
67 if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
68 || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \
69 || gpg_err_code (_r) == GPG_ERR_CARD_RESET \
70 || gpg_err_code (_r) == GPG_ERR_ENODEV ) \
71 update_card_removed ((c)->server_local->vreader_idx, 1); \
74 #define IS_LOCKED(c) \
76 && locked_session != (c)->server_local \
77 && (c)->server_local->vreader_idx != -1 \
78 && locked_session->ctrl_backlink \
79 && ((c)->server_local->vreader_idx \
80 == locked_session->ctrl_backlink->server_local->vreader_idx))
83 /* This structure is used to keep track of user readers. To
84 eventually accommodate this structure for RFID cards, where more
85 than one card is used per reader, we name it virtual reader. */
88 int valid; /* True if the other objects are valid. */
89 int slot; /* APDU slot number of the reader or -1 if not open. */
91 int reset_failed; /* A reset failed. */
93 int any; /* Flag indicating whether any status check has been
94 done. This is set once to indicate that the status
95 tracking for the slot has been initialized. */
96 unsigned int status; /* Last status of the reader. */
97 unsigned int changed; /* Last change counter of the reader. */
101 /* Data used to associate an Assuan context with local server data.
102 This object describes the local properties of one session. */
103 struct server_local_s
105 /* We keep a list of all active sessions with the anchor at
106 SESSION_LIST (see below). This field is used for linking. */
107 struct server_local_s *next_session;
109 /* This object is usually assigned to a CTRL object (which is
110 globally visible). While enumerating all sessions we sometimes
111 need to access data of the CTRL object; thus we keep a
113 ctrl_t ctrl_backlink;
115 /* The Assuan context used by this session/server. */
116 assuan_context_t assuan_ctx;
118 #ifdef HAVE_W32_SYSTEM
119 unsigned long event_signal; /* Or 0 if not used. */
121 int event_signal; /* Or 0 if not used. */
124 /* Index into the vreader table (command.c) or -1 if not open. */
127 /* True if the card has been removed and a reset is required to
128 continue operation. */
131 /* Flag indicating that the application context needs to be released
132 at the next opportunity. */
133 int app_ctx_marked_for_release;
135 /* A disconnect command has been sent. */
136 int disconnect_allowed;
138 /* If set to true we will be terminate ourself at the end of the
145 /* The table with information on all used virtual readers. */
146 static struct vreader_s vreader_table[10];
149 /* To keep track of all running sessions, we link all active server
150 contexts and the anchor in this variable. */
151 static struct server_local_s *session_list;
153 /* If a session has been locked we store a link to its server object
155 static struct server_local_s *locked_session;
157 /* While doing a reset we need to make sure that the ticker does not
158 call scd_update_reader_status_file while we are using it. */
159 static npth_mutex_t status_file_update_lock;
162 /*-- Local prototypes --*/
163 static void update_reader_status_file (int set_card_removed_flag);
168 /* This function must be called once to initialize this module. This
169 has to be done before a second thread is spawned. We can't do the
170 static initialization because Pth emulation code might not be able
171 to do a static init; in particular, it is not possible for W32. */
173 initialize_module_command (void)
175 static int initialized;
180 err = npth_mutex_init (&status_file_update_lock, NULL);
187 /* Helper to return the slot number for a given virtual reader index
188 VRDR. In case on an error -1 is returned. */
190 vreader_slot (int vrdr)
192 if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table)))
194 if (!vreader_table [vrdr].valid)
196 return vreader_table[vrdr].slot;
200 /* Update the CARD_REMOVED element of all sessions using the virtual
201 reader given by VRDR to VALUE. */
203 update_card_removed (int vrdr, int value)
205 struct server_local_s *sl;
210 for (sl=session_list; sl; sl = sl->next_session)
211 if (sl->ctrl_backlink
212 && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
214 sl->card_removed = value;
216 /* Let the card application layer know about the removal. */
218 application_notify_card_reset (vreader_slot (vrdr));
222 /* Check whether the option NAME appears in LINE. Returns 1 or 0. */
224 has_option (const char *line, const char *name)
227 int n = strlen (name);
229 s = strstr (line, name);
230 return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
233 /* Same as has_option but does only test for the name of the option
234 and ignores an argument, i.e. with NAME being "--hash" it would
235 return a pointer for "--hash" as well as for "--hash=foo". If
236 there is no such option NULL is returned. The pointer returned
237 points right behind the option name, this may be an equal sign, Nul
240 has_option_name (const char *line, const char *name)
243 int n = strlen (name);
245 s = strstr (line, name);
246 return (s && (s == line || spacep (s-1))
247 && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL;
251 /* Skip over options. It is assumed that leading spaces have been
252 removed (this is the case for lines passed to a handler from
253 assuan). Blanks after the options are also removed. */
255 skip_options (char *line)
257 while ( *line == '-' && line[1] == '-' )
259 while (*line && !spacep (line))
261 while (spacep (line))
269 /* Convert the STRING into a newly allocated buffer while translating
270 the hex numbers. Stops at the first invalid character. Blanks and
271 colons are allowed to separate the hex digits. Returns NULL on
272 error or a newly malloced buffer and its length in LENGTH. */
273 static unsigned char *
274 hex_to_buffer (const char *string, size_t *r_length)
276 unsigned char *buffer;
280 buffer = xtrymalloc (strlen (string)+1);
283 for (s=string, n=0; *s; s++)
285 if (spacep (s) || *s == ':')
287 if (hexdigitp (s) && hexdigitp (s+1))
289 buffer[n++] = xtoi_2 (s);
301 /* Reset the card and free the application context. With SEND_RESET
302 set to true actually send a RESET to the reader; this is the normal
303 way of calling the function. */
305 do_reset (ctrl_t ctrl, int send_reset)
307 int vrdr = ctrl->server_local->vreader_idx;
311 if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
314 /* If there is an active application, release it. Tell all other
315 sessions using the same application to release the
319 release_application (ctrl->app_ctx);
320 ctrl->app_ctx = NULL;
323 struct server_local_s *sl;
325 for (sl=session_list; sl; sl = sl->next_session)
326 if (sl->ctrl_backlink
327 && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
329 sl->app_ctx_marked_for_release = 1;
334 /* If we want a real reset for the card, send the reset APDU and
335 tell the application layer about it. */
336 slot = vreader_slot (vrdr);
337 if (slot != -1 && send_reset && !IS_LOCKED (ctrl) )
339 application_notify_card_reset (slot);
340 switch (apdu_reset (slot))
344 case SW_HOST_NO_CARD:
345 case SW_HOST_CARD_INACTIVE:
348 apdu_close_reader (slot);
349 vreader_table[vrdr].slot = slot = -1;
354 /* If we hold a lock, unlock now. */
355 if (locked_session && ctrl->server_local == locked_session)
357 locked_session = NULL;
358 log_info ("implicitly unlocking due to RESET\n");
361 /* Reset the card removed flag for the current reader. We need to
362 take the lock here so that the ticker thread won't concurrently
363 try to update the file. Calling update_reader_status_file is
364 required to get hold of the new status of the card in the vreader
366 err = npth_mutex_lock (&status_file_update_lock);
369 log_error ("failed to acquire status_file_update lock\n");
370 ctrl->server_local->vreader_idx = -1;
373 update_reader_status_file (0); /* Update slot status table. */
374 update_card_removed (vrdr, 0); /* Clear card_removed flag. */
375 err = npth_mutex_unlock (&status_file_update_lock);
377 log_error ("failed to release status_file_update lock: %s\n",
380 /* Do this last, so that the update_card_removed above does its job. */
381 ctrl->server_local->vreader_idx = -1;
386 reset_notify (assuan_context_t ctx, char *line)
388 ctrl_t ctrl = assuan_get_pointer (ctx);
398 option_handler (assuan_context_t ctx, const char *key, const char *value)
400 ctrl_t ctrl = assuan_get_pointer (ctx);
402 if (!strcmp (key, "event-signal"))
404 /* A value of 0 is allowed to reset the event signal. */
405 #ifdef HAVE_W32_SYSTEM
407 return gpg_error (GPG_ERR_ASS_PARAMETER);
408 ctrl->server_local->event_signal = strtoul (value, NULL, 16);
410 int i = *value? atoi (value) : -1;
412 return gpg_error (GPG_ERR_ASS_PARAMETER);
413 ctrl->server_local->event_signal = i;
421 /* Return the index of the current reader or open the reader if no
422 other sessions are using that reader. If it is not possible to
423 open the reader -1 is returned. Note, that we currently support
424 only one reader but most of the code (except for this function)
425 should be able to cope with several readers. */
427 get_current_reader (void)
429 struct vreader_s *vr;
431 /* We only support one reader for now. */
432 vr = &vreader_table[0];
434 /* Initialize the vreader item if not yet done. */
441 /* Try to open the reader. */
444 vr->slot = apdu_open_reader (opt.reader_port);
446 /* If we still don't have a slot, we have no readers.
447 Invalidate for now until a reader is attached. */
454 /* Return the vreader index or -1. */
455 return vr->valid ? 0 : -1;
459 /* If the card has not yet been opened, do it. */
461 open_card (ctrl_t ctrl, const char *apptype)
466 /* If we ever got a card not present error code, return that. Only
467 the SERIALNO command and a reset are able to clear from that
469 if (ctrl->server_local->card_removed)
470 return gpg_error (GPG_ERR_CARD_REMOVED);
472 if ( IS_LOCKED (ctrl) )
473 return gpg_error (GPG_ERR_LOCKED);
475 /* If the application has been marked for release do it now. We
476 can't do it immediately in do_reset because the application may
478 if (ctrl->server_local->app_ctx_marked_for_release)
480 ctrl->server_local->app_ctx_marked_for_release = 0;
481 release_application (ctrl->app_ctx);
482 ctrl->app_ctx = NULL;
485 /* If we are already initialized for one specific application we
486 need to check that the client didn't requested a specific
487 application different from the one in use before we continue. */
490 return check_application_conflict
491 (ctrl, vreader_slot (ctrl->server_local->vreader_idx), apptype);
494 /* Setup the vreader and select the application. */
495 if (ctrl->server_local->vreader_idx != -1)
496 vrdr = ctrl->server_local->vreader_idx;
498 vrdr = get_current_reader ();
499 ctrl->server_local->vreader_idx = vrdr;
501 err = gpg_error (GPG_ERR_CARD);
504 /* Fixme: We should move the apdu_connect call to
505 select_application. */
507 int slot = vreader_slot (vrdr);
509 ctrl->server_local->disconnect_allowed = 0;
510 sw = apdu_connect (slot);
511 if (sw && sw != SW_HOST_ALREADY_CONNECTED)
513 if (sw == SW_HOST_NO_CARD)
514 err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
515 else if (sw == SW_HOST_CARD_INACTIVE)
516 err = gpg_error (GPG_ERR_CARD_RESET);
518 err = gpg_error (GPG_ERR_CARD);
521 err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
524 TEST_CARD_REMOVAL (ctrl, err);
529 static const char hlp_serialno[] =
530 "SERIALNO [<apptype>]\n"
532 "Return the serial number of the card using a status response. This\n"
533 "function should be used to check for the presence of a card.\n"
535 "If APPTYPE is given, an application of that type is selected and an\n"
536 "error is returned if the application is not supported or available.\n"
537 "The default is to auto-select the application using a hardwired\n"
538 "preference system. Note, that a future extension to this function\n"
539 "may allow to specify a list and order of applications to try.\n"
541 "This function is special in that it can be used to reset the card.\n"
542 "Most other functions will return an error when a card change has\n"
543 "been detected and the use of this function is therefore required.\n"
545 "Background: We want to keep the client clear of handling card\n"
546 "changes between operations; i.e. the client can assume that all\n"
547 "operations are done on the same card unless he calls this function.";
549 cmd_serialno (assuan_context_t ctx, char *line)
551 ctrl_t ctrl = assuan_get_pointer (ctx);
557 /* Clear the remove flag so that the open_card is able to reread it. */
559 if (ctrl->server_local->card_removed)
561 if ( IS_LOCKED (ctrl) )
562 return gpg_error (GPG_ERR_LOCKED);
566 if ((rc = open_card (ctrl, *line? line:NULL)))
568 /* In case of an inactive card, retry once. */
569 if (gpg_err_code (rc) == GPG_ERR_CARD_RESET && retries++ < 1)
574 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
578 rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
579 serial, (unsigned long)stamp);
585 static const char hlp_learn[] =
586 "LEARN [--force] [--keypairinfo]\n"
588 "Learn all useful information of the currently inserted card. When\n"
589 "used without the force options, the command might do an INQUIRE\n"
592 " INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>\n"
594 "The client should just send an \"END\" if the processing should go on\n"
595 "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
598 "With the option --keypairinfo only KEYPARIINFO lstatus lines are\n"
601 "The response of this command is a list of status lines formatted as\n"
604 " S APPTYPE <apptype>\n"
606 "This returns the type of the application, currently the strings:\n"
608 " P15 = PKCS-15 structure used\n"
609 " DINSIG = DIN SIG\n"
610 " OPENPGP = OpenPGP card\n"
611 " NKS = NetKey card\n"
613 "are implemented. These strings are aliases for the AID\n"
615 " S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>\n"
617 "If there is no certificate yet stored on the card a single 'X' is\n"
618 "returned as the keygrip. In addition to the keypair info, information\n"
619 "about all certificates stored on the card is also returned:\n"
621 " S CERTINFO <certtype> <hexstring_with_id>\n"
623 "Where CERTTYPE is a number indicating the type of certificate:\n"
625 " 100 := Regular X.509 cert\n"
626 " 101 := Trusted X.509 cert\n"
627 " 102 := Useful X.509 cert\n"
628 " 110 := Root CA cert in a special format (e.g. DINSIG)\n"
629 " 111 := Root CA cert as standard X509 cert.\n"
631 "For certain cards, more information will be returned:\n"
633 " S KEY-FPR <no> <hexstring>\n"
635 "For OpenPGP cards this returns the stored fingerprints of the\n"
636 "keys. This can be used check whether a key is available on the\n"
637 "card. NO may be 1, 2 or 3.\n"
639 " S CA-FPR <no> <hexstring>\n"
641 "Similar to above, these are the fingerprints of keys assumed to be\n"
642 "ultimately trusted.\n"
644 " S DISP-NAME <name_of_card_holder>\n"
646 "The name of the card holder as stored on the card; percent\n"
647 "escaping takes place, spaces are encoded as '+'\n"
649 " S PUBKEY-URL <url>\n"
651 "The URL to be used for locating the entire public key.\n"
653 "Note, that this function may even be used on a locked card.";
655 cmd_learn (assuan_context_t ctx, char *line)
657 ctrl_t ctrl = assuan_get_pointer (ctx);
659 int only_keypairinfo = has_option (line, "--keypairinfo");
661 if ((rc = open_card (ctrl, NULL)))
664 /* Unless the force option is used we try a shortcut by identifying
665 the card using a serial number and inquiring the client with
666 that. The client may choose to cancel the operation if he already
667 knows about this card */
668 if (!only_keypairinfo)
675 slot = vreader_slot (ctrl->server_local->vreader_idx);
676 reader = apdu_get_reader_name (slot);
678 return out_of_core ();
679 send_status_direct (ctrl, "READER", reader);
680 /* No need to free the string of READER. */
682 rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
686 rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
687 serial, (unsigned long)stamp);
691 return out_of_core ();
694 if (!has_option (line, "--force"))
698 rc = gpgrt_asprintf (&command, "KNOWNCARDP %s %lu",
699 serial, (unsigned long)stamp);
703 return out_of_core ();
705 rc = assuan_inquire (ctx, command, NULL, NULL, 0);
709 if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
710 log_error ("inquire KNOWNCARDP failed: %s\n",
715 /* Not canceled, so we have to proceeed. */
720 /* Let the application print out its collection of useful status
723 rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
725 TEST_CARD_REMOVAL (ctrl, rc);
731 static const char hlp_readcert[] =
732 "READCERT <hexified_certid>|<keyid>\n"
734 "Note, that this function may even be used on a locked card.";
736 cmd_readcert (assuan_context_t ctx, char *line)
738 ctrl_t ctrl = assuan_get_pointer (ctx);
743 if ((rc = open_card (ctrl, NULL)))
746 line = xstrdup (line); /* Need a copy of the line. */
747 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
749 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
754 rc = assuan_send_data (ctx, cert, ncert);
760 TEST_CARD_REMOVAL (ctrl, rc);
765 static const char hlp_readkey[] =
768 "Return the public key for the given cert or key ID as a standard\n"
771 "Note, that this function may even be used on a locked card.";
773 cmd_readkey (assuan_context_t ctx, char *line)
775 ctrl_t ctrl = assuan_get_pointer (ctx);
777 unsigned char *cert = NULL;
779 ksba_cert_t kc = NULL;
784 if ((rc = open_card (ctrl, NULL)))
787 line = xstrdup (line); /* Need a copy of the line. */
788 /* If the application supports the READKEY function we use that.
789 Otherwise we use the old way by extracting it from the
791 rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
793 { /* Yeah, got that key - send it back. */
794 rc = assuan_send_data (ctx, pk, pklen);
801 if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
802 log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
805 rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
807 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
814 rc = ksba_cert_new (&kc);
818 rc = ksba_cert_init_from_mem (kc, cert, ncert);
821 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
825 p = ksba_cert_get_public_key (kc);
828 rc = gpg_error (GPG_ERR_NO_PUBKEY);
832 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
833 rc = assuan_send_data (ctx, p, n);
838 ksba_cert_release (kc);
840 TEST_CARD_REMOVAL (ctrl, rc);
846 static const char hlp_setdata[] =
847 "SETDATA [--append] <hexstring>\n"
849 "The client should use this command to tell us the data he want to sign.\n"
850 "With the option --append, the data is appended to the data set by a\n"
851 "previous SETDATA command.";
853 cmd_setdata (assuan_context_t ctx, char *line)
855 ctrl_t ctrl = assuan_get_pointer (ctx);
861 append = (ctrl->in_data.value && has_option (line, "--append"));
863 line = skip_options (line);
865 if (locked_session && locked_session != ctrl->server_local)
866 return gpg_error (GPG_ERR_LOCKED);
868 /* Parse the hexstring. */
869 for (p=line,n=0; hexdigitp (p); p++, n++)
872 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
874 return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
876 return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
880 if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
881 return set_error (GPG_ERR_TOO_LARGE,
882 "limit on total size of data reached");
883 buf = xtrymalloc (ctrl->in_data.valuelen + n);
886 buf = xtrymalloc (n);
888 return out_of_core ();
892 memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
893 off = ctrl->in_data.valuelen;
897 for (p=line, i=0; i < n; p += 2, i++)
898 buf[off+i] = xtoi_2 (p);
900 xfree (ctrl->in_data.value);
901 ctrl->in_data.value = buf;
902 ctrl->in_data.valuelen = off+n;
909 pin_cb (void *opaque, const char *info, char **retstr)
911 assuan_context_t ctx = opaque;
914 unsigned char *value;
919 /* We prompt for pinpad entry. To make sure that the popup has
920 been show we use an inquire and not just a status message.
921 We ignore any value returned. */
924 log_debug ("prompting for pinpad entry '%s'\n", info);
925 rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
927 return gpg_error (gpg_err_code_from_errno (errno));
928 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
933 log_debug ("dismiss pinpad entry prompt\n");
934 rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT",
935 &value, &valuelen, MAXLEN_PIN);
943 log_debug ("asking for PIN '%s'\n", info);
945 rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
947 return gpg_error (gpg_err_code_from_errno (errno));
949 /* Fixme: Write an inquire function which returns the result in
950 secure memory and check all further handling of the PIN. */
951 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
956 if (!valuelen || value[valuelen-1])
958 /* We require that the returned value is an UTF-8 string */
960 return gpg_error (GPG_ERR_INV_RESPONSE);
962 *retstr = (char*)value;
967 static const char hlp_pksign[] =
968 "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>\n"
970 "The --hash option is optional; the default is SHA1.";
972 cmd_pksign (assuan_context_t ctx, char *line)
974 ctrl_t ctrl = assuan_get_pointer (ctx);
976 unsigned char *outdata;
981 if (has_option (line, "--hash=rmd160"))
982 hash_algo = GCRY_MD_RMD160;
983 else if (has_option (line, "--hash=sha1"))
984 hash_algo = GCRY_MD_SHA1;
985 else if (has_option (line, "--hash=sha224"))
986 hash_algo = GCRY_MD_SHA224;
987 else if (has_option (line, "--hash=sha256"))
988 hash_algo = GCRY_MD_SHA256;
989 else if (has_option (line, "--hash=sha384"))
990 hash_algo = GCRY_MD_SHA384;
991 else if (has_option (line, "--hash=sha512"))
992 hash_algo = GCRY_MD_SHA512;
993 else if (has_option (line, "--hash=md5"))
994 hash_algo = GCRY_MD_MD5;
995 else if (!strstr (line, "--"))
996 hash_algo = GCRY_MD_SHA1;
998 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
1000 line = skip_options (line);
1002 if ( IS_LOCKED (ctrl) )
1003 return gpg_error (GPG_ERR_LOCKED);
1005 if ((rc = open_card (ctrl, NULL)))
1008 /* We have to use a copy of the key ID because the function may use
1009 the pin_cb which in turn uses the assuan line buffer and thus
1010 overwriting the original line with the keyid */
1011 keyidstr = xtrystrdup (line);
1013 return out_of_core ();
1015 rc = app_sign (ctrl->app_ctx,
1016 keyidstr, hash_algo,
1018 ctrl->in_data.value, ctrl->in_data.valuelen,
1019 &outdata, &outdatalen);
1024 log_error ("app_sign failed: %s\n", gpg_strerror (rc));
1028 rc = assuan_send_data (ctx, outdata, outdatalen);
1031 return rc; /* that is already an assuan error code */
1034 TEST_CARD_REMOVAL (ctrl, rc);
1039 static const char hlp_pkauth[] =
1040 "PKAUTH <hexified_id>";
1042 cmd_pkauth (assuan_context_t ctx, char *line)
1044 ctrl_t ctrl = assuan_get_pointer (ctx);
1046 unsigned char *outdata;
1050 if ( IS_LOCKED (ctrl) )
1051 return gpg_error (GPG_ERR_LOCKED);
1053 if ((rc = open_card (ctrl, NULL)))
1057 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1059 /* We have to use a copy of the key ID because the function may use
1060 the pin_cb which in turn uses the assuan line buffer and thus
1061 overwriting the original line with the keyid */
1062 keyidstr = xtrystrdup (line);
1064 return out_of_core ();
1066 rc = app_auth (ctrl->app_ctx,
1069 ctrl->in_data.value, ctrl->in_data.valuelen,
1070 &outdata, &outdatalen);
1074 log_error ("app_auth failed: %s\n", gpg_strerror (rc));
1078 rc = assuan_send_data (ctx, outdata, outdatalen);
1081 return rc; /* that is already an assuan error code */
1084 TEST_CARD_REMOVAL (ctrl, rc);
1089 static const char hlp_pkdecrypt[] =
1090 "PKDECRYPT <hexified_id>";
1092 cmd_pkdecrypt (assuan_context_t ctx, char *line)
1094 ctrl_t ctrl = assuan_get_pointer (ctx);
1096 unsigned char *outdata;
1099 unsigned int infoflags;
1101 if ( IS_LOCKED (ctrl) )
1102 return gpg_error (GPG_ERR_LOCKED);
1104 if ((rc = open_card (ctrl, NULL)))
1107 keyidstr = xtrystrdup (line);
1109 return out_of_core ();
1110 rc = app_decipher (ctrl->app_ctx,
1113 ctrl->in_data.value, ctrl->in_data.valuelen,
1114 &outdata, &outdatalen, &infoflags);
1119 log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
1123 /* If the card driver told us that there is no padding, send a
1124 status line. If there is a padding it is assumed that the
1125 caller knows what padding is used. It would have been better
1126 to always send that information but for backward
1127 compatibility we can't do that. */
1128 if ((infoflags & APP_DECIPHER_INFO_NOPAD))
1129 send_status_direct (ctrl, "PADDING", "0");
1130 rc = assuan_send_data (ctx, outdata, outdatalen);
1133 return rc; /* that is already an assuan error code */
1136 TEST_CARD_REMOVAL (ctrl, rc);
1141 static const char hlp_getattr[] =
1144 "This command is used to retrieve data from a smartcard. The\n"
1145 "allowed names depend on the currently selected smartcard\n"
1146 "application. NAME must be percent and '+' escaped. The value is\n"
1147 "returned through status message, see the LEARN command for details.\n"
1149 "However, the current implementation assumes that Name is not escaped;\n"
1150 "this works as long as no one uses arbitrary escaping. \n"
1152 "Note, that this function may even be used on a locked card.";
1154 cmd_getattr (assuan_context_t ctx, char *line)
1156 ctrl_t ctrl = assuan_get_pointer (ctx);
1158 const char *keyword;
1160 if ((rc = open_card (ctrl, NULL)))
1164 for (; *line && !spacep (line); line++)
1169 /* (We ignore any garbage for now.) */
1171 /* FIXME: Applications should not return sensitive data if the card
1173 rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
1175 TEST_CARD_REMOVAL (ctrl, rc);
1180 static const char hlp_setattr[] =
1181 "SETATTR <name> <value> \n"
1183 "This command is used to store data on a a smartcard. The allowed\n"
1184 "names and values are depend on the currently selected smartcard\n"
1185 "application. NAME and VALUE must be percent and '+' escaped.\n"
1187 "However, the current implementation assumes that NAME is not\n"
1188 "escaped; this works as long as no one uses arbitrary escaping.\n"
1190 "A PIN will be requested for most NAMEs. See the corresponding\n"
1191 "setattr function of the actually used application (app-*.c) for\n"
1194 cmd_setattr (assuan_context_t ctx, char *orig_line)
1196 ctrl_t ctrl = assuan_get_pointer (ctx);
1201 char *line, *linebuf;
1203 if ( IS_LOCKED (ctrl) )
1204 return gpg_error (GPG_ERR_LOCKED);
1206 if ((rc = open_card (ctrl, NULL)))
1209 /* We need to use a copy of LINE, because PIN_CB uses the same
1210 context and thus reuses the Assuan provided LINE. */
1211 line = linebuf = xtrystrdup (orig_line);
1213 return out_of_core ();
1216 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1220 while (spacep (line))
1222 nbytes = percent_plus_unescape_inplace (line, 0);
1224 rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx,
1225 (const unsigned char*)line, nbytes);
1228 TEST_CARD_REMOVAL (ctrl, rc);
1233 static const char hlp_writecert[] =
1234 "WRITECERT <hexified_certid>\n"
1236 "This command is used to store a certifciate on a smartcard. The\n"
1237 "allowed certids depend on the currently selected smartcard\n"
1238 "application. The actual certifciate is requested using the inquiry\n"
1239 "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
1241 "In almost all cases a a PIN will be requested. See the related\n"
1242 "writecert function of the actually used application (app-*.c) for\n"
1245 cmd_writecert (assuan_context_t ctx, char *line)
1247 ctrl_t ctrl = assuan_get_pointer (ctx);
1250 unsigned char *certdata;
1253 if ( IS_LOCKED (ctrl) )
1254 return gpg_error (GPG_ERR_LOCKED);
1256 line = skip_options (line);
1259 return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1261 while (*line && !spacep (line))
1265 if ((rc = open_card (ctrl, NULL)))
1269 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1271 certid = xtrystrdup (certid);
1273 return out_of_core ();
1275 /* Now get the actual keydata. */
1276 rc = assuan_inquire (ctx, "CERTDATA",
1277 &certdata, &certdatalen, MAXLEN_CERTDATA);
1284 /* Write the certificate to the card. */
1285 rc = app_writecert (ctrl->app_ctx, ctrl, certid,
1286 pin_cb, ctx, certdata, certdatalen);
1290 TEST_CARD_REMOVAL (ctrl, rc);
1295 static const char hlp_writekey[] =
1296 "WRITEKEY [--force] <keyid> \n"
1298 "This command is used to store a secret key on a a smartcard. The\n"
1299 "allowed keyids depend on the currently selected smartcard\n"
1300 "application. The actual keydata is requested using the inquiry\n"
1301 "\"KEYDATA\" and need to be provided without any protection. With\n"
1302 "--force set an existing key under this KEYID will get overwritten.\n"
1303 "The keydata is expected to be the usual canonical encoded\n"
1306 "A PIN will be requested for most NAMEs. See the corresponding\n"
1307 "writekey function of the actually used application (app-*.c) for\n"
1310 cmd_writekey (assuan_context_t ctx, char *line)
1312 ctrl_t ctrl = assuan_get_pointer (ctx);
1315 int force = has_option (line, "--force");
1316 unsigned char *keydata;
1319 if ( IS_LOCKED (ctrl) )
1320 return gpg_error (GPG_ERR_LOCKED);
1322 line = skip_options (line);
1325 return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1327 while (*line && !spacep (line))
1331 if ((rc = open_card (ctrl, NULL)))
1335 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1337 keyid = xtrystrdup (keyid);
1339 return out_of_core ();
1341 /* Now get the actual keydata. */
1342 assuan_begin_confidential (ctx);
1343 rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1344 assuan_end_confidential (ctx);
1351 /* Write the key to the card. */
1352 rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1353 pin_cb, ctx, keydata, keydatalen);
1357 TEST_CARD_REMOVAL (ctrl, rc);
1362 static const char hlp_genkey[] =
1363 "GENKEY [--force] [--timestamp=<isodate>] <no>\n"
1365 "Generate a key on-card identified by NO, which is application\n"
1366 "specific. Return values are application specific. For OpenPGP\n"
1367 "cards 3 status lines are returned:\n"
1369 " S KEY-FPR <hexstring>\n"
1370 " S KEY-CREATED-AT <seconds_since_epoch>\n"
1371 " S KEY-DATA [-|p|n] <hexdata>\n"
1373 " 'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
1374 " indicate that HEXDATA is the first chunk of a parameter given\n"
1375 " by the next KEY-DATA.\n"
1377 "--force is required to overwrite an already existing key. The\n"
1378 "KEY-CREATED-AT is required for further processing because it is\n"
1379 "part of the hashed key material for the fingerprint.\n"
1381 "If --timestamp is given an OpenPGP key will be created using this\n"
1382 "value. The value needs to be in ISO Format; e.g.\n"
1383 "\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
1385 "The public part of the key can also later be retrieved using the\n"
1388 cmd_genkey (assuan_context_t ctx, char *line)
1390 ctrl_t ctrl = assuan_get_pointer (ctx);
1397 if ( IS_LOCKED (ctrl) )
1398 return gpg_error (GPG_ERR_LOCKED);
1400 force = has_option (line, "--force");
1402 if ((s=has_option_name (line, "--timestamp")))
1405 return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1406 timestamp = isotime2epoch (s+1);
1408 return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1414 line = skip_options (line);
1416 return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1418 while (*line && !spacep (line))
1422 if ((rc = open_card (ctrl, NULL)))
1426 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1428 keyno = xtrystrdup (keyno);
1430 return out_of_core ();
1431 rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1432 timestamp, pin_cb, ctx);
1435 TEST_CARD_REMOVAL (ctrl, rc);
1440 static const char hlp_random[] =
1443 "Get NBYTES of random from the card and send them back as data.\n"
1444 "This usually involves EEPROM write on the card and thus excessive\n"
1445 "use of this command may destroy the card.\n"
1447 "Note, that this function may be even be used on a locked card.";
1449 cmd_random (assuan_context_t ctx, char *line)
1451 ctrl_t ctrl = assuan_get_pointer (ctx);
1454 unsigned char *buffer;
1457 return set_error (GPG_ERR_ASS_PARAMETER,
1458 "number of requested bytes missing");
1459 nbytes = strtoul (line, NULL, 0);
1461 if ((rc = open_card (ctrl, NULL)))
1465 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1467 buffer = xtrymalloc (nbytes);
1469 return out_of_core ();
1471 rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1474 rc = assuan_send_data (ctx, buffer, nbytes);
1476 return rc; /* that is already an assuan error code */
1480 TEST_CARD_REMOVAL (ctrl, rc);
1486 static const char hlp_passwd[] =
1487 "PASSWD [--reset] [--nullpin] <chvno>\n"
1489 "Change the PIN or, if --reset is given, reset the retry counter of\n"
1490 "the card holder verification vector CHVNO. The option --nullpin is\n"
1491 "used for TCOS cards to set the initial PIN. The format of CHVNO\n"
1492 "depends on the card application.";
1494 cmd_passwd (assuan_context_t ctx, char *line)
1496 ctrl_t ctrl = assuan_get_pointer (ctx);
1499 unsigned int flags = 0;
1501 if (has_option (line, "--reset"))
1502 flags |= APP_CHANGE_FLAG_RESET;
1503 if (has_option (line, "--nullpin"))
1504 flags |= APP_CHANGE_FLAG_NULLPIN;
1506 if ( IS_LOCKED (ctrl) )
1507 return gpg_error (GPG_ERR_LOCKED);
1509 line = skip_options (line);
1512 return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1514 while (*line && !spacep (line))
1518 if ((rc = open_card (ctrl, NULL)))
1522 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1524 chvnostr = xtrystrdup (chvnostr);
1526 return out_of_core ();
1527 rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1529 log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1532 TEST_CARD_REMOVAL (ctrl, rc);
1537 static const char hlp_checkpin[] =
1538 "CHECKPIN <idstr>\n"
1540 "Perform a VERIFY operation without doing anything else. This may\n"
1541 "be used to initialize a the PIN cache earlier to long lasting\n"
1542 "operations. Its use is highly application dependent.\n"
1546 " Perform a simple verify operation for CHV1 and CHV2, so that\n"
1547 " further operations won't ask for CHV2 and it is possible to do a\n"
1548 " cheap check on the PIN: If there is something wrong with the PIN\n"
1549 " entry system, only the regular CHV will get blocked and not the\n"
1550 " dangerous CHV3. IDSTR is the usual card's serial number in hex\n"
1551 " notation; an optional fingerprint part will get ignored. There\n"
1552 " is however a special mode if the IDSTR is sffixed with the\n"
1553 " literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1554 " if and only if the retry counter is still at 3.\n"
1558 " Any of the valid PIN Ids may be used. These are the strings:\n"
1560 " PW1.CH - Global password 1\n"
1561 " PW2.CH - Global password 2\n"
1562 " PW1.CH.SIG - SigG password 1\n"
1563 " PW2.CH.SIG - SigG password 2\n"
1565 " For a definitive list, see the implementation in app-nks.c.\n"
1566 " Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1567 " 3.0 they are technically alternative PINs used to mutally\n"
1568 " unblock each other.";
1570 cmd_checkpin (assuan_context_t ctx, char *line)
1572 ctrl_t ctrl = assuan_get_pointer (ctx);
1576 if ( IS_LOCKED (ctrl) )
1577 return gpg_error (GPG_ERR_LOCKED);
1579 if ((rc = open_card (ctrl, NULL)))
1583 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1585 /* We have to use a copy of the key ID because the function may use
1586 the pin_cb which in turn uses the assuan line buffer and thus
1587 overwriting the original line with the keyid. */
1588 idstr = xtrystrdup (line);
1590 return out_of_core ();
1592 rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx);
1595 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1597 TEST_CARD_REMOVAL (ctrl, rc);
1602 static const char hlp_lock[] =
1605 "Grant exclusive card access to this session. Note that there is\n"
1606 "no lock counter used and a second lock from the same session will\n"
1607 "be ignored. A single unlock (or RESET) unlocks the session.\n"
1608 "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1610 "If the option --wait is given the command will wait until a\n"
1611 "lock has been released.";
1613 cmd_lock (assuan_context_t ctx, char *line)
1615 ctrl_t ctrl = assuan_get_pointer (ctx);
1621 if (locked_session != ctrl->server_local)
1622 rc = gpg_error (GPG_ERR_LOCKED);
1625 locked_session = ctrl->server_local;
1628 if (rc && has_option (line, "--wait"))
1631 npth_sleep (1); /* Better implement an event mechanism. However,
1632 for card operations this should be
1634 /* FIXME: Need to check that the connection is still alive.
1635 This can be done by issuing status messages. */
1641 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1646 static const char hlp_unlock[] =
1649 "Release exclusive card access.";
1651 cmd_unlock (assuan_context_t ctx, char *line)
1653 ctrl_t ctrl = assuan_get_pointer (ctx);
1660 if (locked_session != ctrl->server_local)
1661 rc = gpg_error (GPG_ERR_LOCKED);
1663 locked_session = NULL;
1666 rc = gpg_error (GPG_ERR_NOT_LOCKED);
1669 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1674 static const char hlp_getinfo[] =
1677 "Multi purpose command to return certain information. \n"
1678 "Supported values of WHAT are:\n"
1680 "version - Return the version of the program.\n"
1681 "pid - Return the process id of the server.\n"
1683 "socket_name - Return the name of the socket.\n"
1685 "status - Return the status of the current reader (in the future, may\n"
1686 "also return the status of all readers). The status is a list of\n"
1687 "one-character flags. The following flags are currently defined:\n"
1688 " 'u' Usable card present. This is the normal state during operation.\n"
1689 " 'r' Card removed. A reset is necessary.\n"
1690 "These flags are exclusive.\n"
1692 "reader_list - Return a list of detected card readers. Does\n"
1693 " currently only work with the internal CCID driver.\n"
1695 "deny_admin - Returns OK if admin commands are not allowed or\n"
1696 " GPG_ERR_GENERAL if admin commands are allowed.\n"
1698 "app_list - Return a list of supported applications. One\n"
1699 " application per line, fields delimited by colons,\n"
1700 " first field is the name.";
1702 cmd_getinfo (assuan_context_t ctx, char *line)
1706 if (!strcmp (line, "version"))
1708 const char *s = VERSION;
1709 rc = assuan_send_data (ctx, s, strlen (s));
1711 else if (!strcmp (line, "pid"))
1715 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1716 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1718 else if (!strcmp (line, "socket_name"))
1720 const char *s = scd_get_socket_name ();
1723 rc = assuan_send_data (ctx, s, strlen (s));
1725 rc = gpg_error (GPG_ERR_NO_DATA);
1727 else if (!strcmp (line, "status"))
1729 ctrl_t ctrl = assuan_get_pointer (ctx);
1730 int vrdr = ctrl->server_local->vreader_idx;
1733 if (!ctrl->server_local->card_removed && vrdr != -1)
1735 struct vreader_s *vr;
1737 if (!(vrdr >= 0 && vrdr < DIM(vreader_table)))
1740 vr = &vreader_table[vrdr];
1741 if (vr->valid && vr->any && (vr->status & 1))
1744 rc = assuan_send_data (ctx, &flag, 1);
1746 else if (!strcmp (line, "reader_list"))
1749 char *s = ccid_get_reader_list ();
1755 rc = assuan_send_data (ctx, s, strlen (s));
1757 rc = gpg_error (GPG_ERR_NO_DATA);
1760 else if (!strcmp (line, "deny_admin"))
1761 rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1762 else if (!strcmp (line, "app_list"))
1764 char *s = get_supported_applications ();
1766 rc = assuan_send_data (ctx, s, strlen (s));
1772 rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1777 static const char hlp_restart[] =
1780 "Restart the current connection; this is a kind of warm reset. It\n"
1781 "deletes the context used by this connection but does not send a\n"
1782 "RESET to the card. Thus the card itself won't get reset. \n"
1784 "This is used by gpg-agent to reuse a primary pipe connection and\n"
1785 "may be used by clients to backup from a conflict in the serial\n"
1786 "command; i.e. to select another application.";
1788 cmd_restart (assuan_context_t ctx, char *line)
1790 ctrl_t ctrl = assuan_get_pointer (ctx);
1796 release_application (ctrl->app_ctx);
1797 ctrl->app_ctx = NULL;
1799 if (locked_session && ctrl->server_local == locked_session)
1801 locked_session = NULL;
1802 log_info ("implicitly unlocking due to RESTART\n");
1808 static const char hlp_disconnect[] =
1811 "Disconnect the card if it is not any longer used by other\n"
1812 "connections and the backend supports a disconnect operation.";
1814 cmd_disconnect (assuan_context_t ctx, char *line)
1816 ctrl_t ctrl = assuan_get_pointer (ctx);
1820 ctrl->server_local->disconnect_allowed = 1;
1826 static const char hlp_apdu[] =
1827 "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1829 "Send an APDU to the current reader. This command bypasses the high\n"
1830 "level functions and sends the data directly to the card. HEXSTRING\n"
1831 "is expected to be a proper APDU. If HEXSTRING is not given no\n"
1832 "commands are set to the card but the command will implictly check\n"
1833 "whether the card is ready for use. \n"
1835 "Using the option \"--atr\" returns the ATR of the card as a status\n"
1836 "message before any data like this:\n"
1837 " S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1839 "Using the option --more handles the card status word MORE_DATA\n"
1840 "(61xx) and concatenates all responses to one block.\n"
1842 "Using the option \"--exlen\" the returned APDU may use extended\n"
1843 "length up to N bytes. If N is not given a default value is used\n"
1844 "(currently 4096).";
1846 cmd_apdu (assuan_context_t ctx, char *line)
1848 ctrl_t ctrl = assuan_get_pointer (ctx);
1850 unsigned char *apdu;
1858 if (has_option (line, "--dump-atr"))
1861 with_atr = has_option (line, "--atr");
1862 handle_more = has_option (line, "--more");
1864 if ((s=has_option_name (line, "--exlen")))
1867 exlen = strtoul (s+1, NULL, 0);
1874 line = skip_options (line);
1876 if ( IS_LOCKED (ctrl) )
1877 return gpg_error (GPG_ERR_LOCKED);
1879 if ((rc = open_card (ctrl, NULL)))
1882 slot = vreader_slot (ctrl->server_local->vreader_idx);
1890 atr = apdu_get_atr (slot, &atrlen);
1891 if (!atr || atrlen > sizeof hexbuf - 2 )
1893 rc = gpg_error (GPG_ERR_INV_CARD);
1898 char *string, *p, *pend;
1900 string = atr_dump (atr, atrlen);
1903 for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1905 rc = assuan_send_data (ctx, p, pend - p + 1);
1907 rc = assuan_send_data (ctx, NULL, 0);
1910 rc = assuan_send_data (ctx, p, strlen (p));
1918 bin2hex (atr, atrlen, hexbuf);
1919 send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1924 apdu = hex_to_buffer (line, &apdulen);
1927 rc = gpg_error_from_syserror ();
1932 unsigned char *result = NULL;
1935 rc = apdu_send_direct (slot, exlen,
1936 apdu, apdulen, handle_more,
1937 &result, &resultlen);
1939 log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1942 rc = assuan_send_data (ctx, result, resultlen);
1949 TEST_CARD_REMOVAL (ctrl, rc);
1954 static const char hlp_killscd[] =
1959 cmd_killscd (assuan_context_t ctx, char *line)
1961 ctrl_t ctrl = assuan_get_pointer (ctx);
1965 ctrl->server_local->stopme = 1;
1966 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1972 /* Tell the assuan library about our commands */
1974 register_commands (assuan_context_t ctx)
1978 assuan_handler_t handler;
1979 const char * const help;
1981 { "SERIALNO", cmd_serialno, hlp_serialno },
1982 { "LEARN", cmd_learn, hlp_learn },
1983 { "READCERT", cmd_readcert, hlp_readcert },
1984 { "READKEY", cmd_readkey, hlp_readkey },
1985 { "SETDATA", cmd_setdata, hlp_setdata },
1986 { "PKSIGN", cmd_pksign, hlp_pksign },
1987 { "PKAUTH", cmd_pkauth, hlp_pkauth },
1988 { "PKDECRYPT", cmd_pkdecrypt,hlp_pkdecrypt },
1991 { "GETATTR", cmd_getattr, hlp_getattr },
1992 { "SETATTR", cmd_setattr, hlp_setattr },
1993 { "WRITECERT", cmd_writecert,hlp_writecert },
1994 { "WRITEKEY", cmd_writekey, hlp_writekey },
1995 { "GENKEY", cmd_genkey, hlp_genkey },
1996 { "RANDOM", cmd_random, hlp_random },
1997 { "PASSWD", cmd_passwd, hlp_passwd },
1998 { "CHECKPIN", cmd_checkpin, hlp_checkpin },
1999 { "LOCK", cmd_lock, hlp_lock },
2000 { "UNLOCK", cmd_unlock, hlp_unlock },
2001 { "GETINFO", cmd_getinfo, hlp_getinfo },
2002 { "RESTART", cmd_restart, hlp_restart },
2003 { "DISCONNECT", cmd_disconnect,hlp_disconnect },
2004 { "APDU", cmd_apdu, hlp_apdu },
2005 { "KILLSCD", cmd_killscd, hlp_killscd },
2010 for (i=0; table[i].name; i++)
2012 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2017 assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
2019 assuan_register_reset_notify (ctx, reset_notify);
2020 assuan_register_option_handler (ctx, option_handler);
2025 /* Startup the server. If FD is given as -1 this is simple pipe
2026 server, otherwise it is a regular server. Returns true if there
2027 are no more active asessions. */
2029 scd_command_handler (ctrl_t ctrl, int fd)
2032 assuan_context_t ctx = NULL;
2035 rc = assuan_new (&ctx);
2038 log_error ("failed to allocate assuan context: %s\n",
2045 assuan_fd_t filedes[2];
2047 filedes[0] = assuan_fdopen (0);
2048 filedes[1] = assuan_fdopen (1);
2049 rc = assuan_init_pipe_server (ctx, filedes);
2053 rc = assuan_init_socket_server (ctx, INT2FD(fd),
2054 ASSUAN_SOCKET_SERVER_ACCEPTED);
2058 log_error ("failed to initialize the server: %s\n",
2062 rc = register_commands (ctx);
2065 log_error ("failed to register commands with Assuan: %s\n",
2069 assuan_set_pointer (ctx, ctrl);
2071 /* Allocate and initialize the server object. Put it into the list
2072 of active sessions. */
2073 ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2074 ctrl->server_local->next_session = session_list;
2075 session_list = ctrl->server_local;
2076 ctrl->server_local->ctrl_backlink = ctrl;
2077 ctrl->server_local->assuan_ctx = ctx;
2078 ctrl->server_local->vreader_idx = -1;
2080 /* We open the reader right at startup so that the ticker is able to
2081 update the status file. */
2082 if (ctrl->server_local->vreader_idx == -1)
2084 ctrl->server_local->vreader_idx = get_current_reader ();
2087 /* Command processing loop. */
2090 rc = assuan_accept (ctx);
2097 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2101 rc = assuan_process (ctx);
2104 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2109 /* Cleanup. We don't send an explicit reset to the card. */
2112 /* Release the server object. */
2113 if (session_list == ctrl->server_local)
2114 session_list = ctrl->server_local->next_session;
2117 struct server_local_s *sl;
2119 for (sl=session_list; sl->next_session; sl = sl->next_session)
2120 if (sl->next_session == ctrl->server_local)
2122 if (!sl->next_session)
2124 sl->next_session = ctrl->server_local->next_session;
2126 stopme = ctrl->server_local->stopme;
2127 xfree (ctrl->server_local);
2128 ctrl->server_local = NULL;
2130 /* Release the Assuan context. */
2131 assuan_release (ctx);
2136 /* If there are no more sessions return true. */
2137 return !session_list;
2141 /* Send a line with status information via assuan and escape all given
2142 buffers. The variable elements are pairs of (char *, size_t),
2143 terminated with a (NULL, 0). */
2145 send_status_info (ctrl_t ctrl, const char *keyword, ...)
2148 const unsigned char *value;
2152 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2154 va_start (arg_ptr, keyword);
2158 while ( (value = va_arg (arg_ptr, const unsigned char *)) )
2160 valuelen = va_arg (arg_ptr, size_t);
2162 continue; /* empty buffer */
2168 for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2170 if (*value < ' ' || *value == '+')
2172 sprintf (p, "%%%02X", *value);
2175 else if (*value == ' ')
2182 assuan_write_status (ctx, keyword, buf);
2188 /* Send a ready formatted status line via assuan. */
2190 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2192 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2194 if (strchr (args, '\n'))
2195 log_error ("error: LF detected in status line - not sending\n");
2197 assuan_write_status (ctx, keyword, args);
2201 /* Helper to send the clients a status change notification. */
2203 send_client_notifications (void)
2207 #ifdef HAVE_W32_SYSTEM
2215 struct server_local_s *sl;
2217 for (sl=session_list; sl; sl = sl->next_session)
2219 if (sl->event_signal && sl->assuan_ctx)
2221 pid_t pid = assuan_get_pid (sl->assuan_ctx);
2222 #ifdef HAVE_W32_SYSTEM
2223 HANDLE handle = (void *)sl->event_signal;
2225 for (kidx=0; kidx < killidx; kidx++)
2226 if (killed[kidx].pid == pid
2227 && killed[kidx].handle == handle)
2230 log_info ("event %lx (%p) already triggered for client %d\n",
2231 sl->event_signal, handle, (int)pid);
2234 log_info ("triggering event %lx (%p) for client %d\n",
2235 sl->event_signal, handle, (int)pid);
2236 if (!SetEvent (handle))
2237 log_error ("SetEvent(%lx) failed: %s\n",
2238 sl->event_signal, w32_strerror (-1));
2239 if (killidx < DIM (killed))
2241 killed[killidx].pid = pid;
2242 killed[killidx].handle = handle;
2246 #else /*!HAVE_W32_SYSTEM*/
2247 int signo = sl->event_signal;
2249 if (pid != (pid_t)(-1) && pid && signo > 0)
2251 for (kidx=0; kidx < killidx; kidx++)
2252 if (killed[kidx].pid == pid
2253 && killed[kidx].signo == signo)
2256 log_info ("signal %d already sent to client %d\n",
2260 log_info ("sending signal %d to client %d\n",
2263 if (killidx < DIM (killed))
2265 killed[killidx].pid = pid;
2266 killed[killidx].signo = signo;
2271 #endif /*!HAVE_W32_SYSTEM*/
2278 /* This is the core of scd_update_reader_status_file but the caller
2279 needs to take care of the locking. */
2281 update_reader_status_file (int set_card_removed_flag)
2284 unsigned int status, changed;
2286 /* Note, that we only try to get the status, because it does not
2287 make sense to wait here for a operation to complete. If we are
2288 busy working with a card, delays in the status file update should
2290 for (idx=0; idx < DIM(vreader_table); idx++)
2292 struct vreader_s *vr = vreader_table + idx;
2293 struct server_local_s *sl;
2296 if (!vr->valid || vr->slot == -1)
2297 continue; /* Not valid or reader not yet open. */
2299 sw_apdu = apdu_get_status (vr->slot, 0, &status, &changed);
2300 if (sw_apdu == SW_HOST_NO_READER)
2302 /* Most likely the _reader_ has been unplugged. */
2303 application_notify_card_reset (vr->slot);
2304 apdu_close_reader (vr->slot);
2307 changed = vr->changed;
2311 /* Get status failed. Ignore that. */
2315 if (!vr->any || vr->status != status || vr->changed != changed )
2321 log_info ("updating reader %d (%d) status: 0x%04X->0x%04X (%u->%u)\n",
2322 idx, vr->slot, vr->status, status, vr->changed, changed);
2323 vr->status = status;
2324 vr->changed = changed;
2326 /* FIXME: Should this be IDX instead of vr->slot? This
2327 depends on how client sessions will associate the reader
2328 status with their session. */
2329 snprintf (templ, sizeof templ, "reader_%d.status", vr->slot);
2330 fname = make_filename (opt.homedir, templ, NULL );
2331 fp = fopen (fname, "w");
2334 fprintf (fp, "%s\n",
2335 (status & 1)? "USABLE":
2336 (status & 4)? "ACTIVE":
2337 (status & 2)? "PRESENT": "NOCARD");
2342 /* If a status script is executable, run it. */
2344 const char *args[9], *envs[2];
2345 char numbuf1[30], numbuf2[30], numbuf3[30];
2346 char *homestr, *envstr;
2349 homestr = make_filename (opt.homedir, NULL);
2350 if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
2351 log_error ("out of core while building environment\n");
2357 sprintf (numbuf1, "%d", vr->slot);
2358 sprintf (numbuf2, "0x%04X", vr->status);
2359 sprintf (numbuf3, "0x%04X", status);
2360 args[0] = "--reader-port";
2362 args[2] = "--old-code";
2364 args[4] = "--new-code";
2366 args[6] = "--status";
2367 args[7] = ((status & 1)? "USABLE":
2368 (status & 4)? "ACTIVE":
2369 (status & 2)? "PRESENT": "NOCARD");
2372 fname = make_filename (opt.homedir, "scd-event", NULL);
2373 err = gnupg_spawn_process_detached (fname, args, envs);
2374 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
2375 log_error ("failed to run event handler '%s': %s\n",
2376 fname, gpg_strerror (err));
2383 /* Set the card removed flag for all current sessions. */
2384 if (vr->any && vr->status == 0 && set_card_removed_flag)
2385 update_card_removed (idx, 1);
2389 /* Send a signal to all clients who applied for it. */
2390 send_client_notifications ();
2393 /* Check whether a disconnect is pending. */
2394 if (opt.card_timeout)
2396 for (sl=session_list; sl; sl = sl->next_session)
2397 if (!sl->disconnect_allowed)
2399 if (session_list && !sl)
2401 /* FIXME: Use a real timeout. */
2402 /* At least one connection and all allow a disconnect. */
2403 log_info ("disconnecting card in reader %d (%d)\n",
2405 apdu_disconnect (vr->slot);
2412 /* This function is called by the ticker thread to check for changes
2413 of the reader stati. It updates the reader status files and if
2414 requested by the caller also send a signal to the caller. */
2416 scd_update_reader_status_file (void)
2419 err = npth_mutex_lock (&status_file_update_lock);
2421 return; /* locked - give up. */
2422 update_reader_status_file (1);
2423 err = npth_mutex_unlock (&status_file_update_lock);
2425 log_error ("failed to release status_file_update lock: %s\n",