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 (). */
41 #include "ccid-driver.h"
44 #include "server-help.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))
61 #define IS_LOCKED(c) (locked_session && locked_session != (c)->server_local)
64 /* Data used to associate an Assuan context with local server data.
65 This object describes the local properties of one session. */
68 /* We keep a list of all active sessions with the anchor at
69 SESSION_LIST (see below). This field is used for linking. */
70 struct server_local_s *next_session;
72 /* This object is usually assigned to a CTRL object (which is
73 globally visible). While enumerating all sessions we sometimes
74 need to access data of the CTRL object; thus we keep a
78 /* The Assuan context used by this session/server. */
79 assuan_context_t assuan_ctx;
81 #ifdef HAVE_W32_SYSTEM
82 unsigned long event_signal; /* Or 0 if not used. */
84 int event_signal; /* Or 0 if not used. */
87 /* True if the card has been removed and a reset is required to
88 continue operation. */
91 /* If set to true we will be terminate ourself at the end of the
98 /* To keep track of all running sessions, we link all active server
99 contexts and the anchor in this variable. */
100 static struct server_local_s *session_list;
102 /* If a session has been locked we store a link to its server object
104 static struct server_local_s *locked_session;
107 /* Convert the STRING into a newly allocated buffer while translating
108 the hex numbers. Stops at the first invalid character. Blanks and
109 colons are allowed to separate the hex digits. Returns NULL on
110 error or a newly malloced buffer and its length in LENGTH. */
111 static unsigned char *
112 hex_to_buffer (const char *string, size_t *r_length)
114 unsigned char *buffer;
118 buffer = xtrymalloc (strlen (string)+1);
121 for (s=string, n=0; *s; s++)
123 if (spacep (s) || *s == ':')
125 if (hexdigitp (s) && hexdigitp (s+1))
127 buffer[n++] = xtoi_2 (s);
139 /* Reset the card and free the application context. With SEND_RESET
140 set to true actually send a RESET to the reader; this is the normal
141 way of calling the function. */
143 do_reset (ctrl_t ctrl, int send_reset)
145 app_t app = ctrl->app_ctx;
148 app_reset (app, ctrl, IS_LOCKED (ctrl)? 0: send_reset);
150 /* If we hold a lock, unlock now. */
151 if (locked_session && ctrl->server_local == locked_session)
153 locked_session = NULL;
154 log_info ("implicitly unlocking due to RESET\n");
159 reset_notify (assuan_context_t ctx, char *line)
161 ctrl_t ctrl = assuan_get_pointer (ctx);
171 option_handler (assuan_context_t ctx, const char *key, const char *value)
173 ctrl_t ctrl = assuan_get_pointer (ctx);
175 if (!strcmp (key, "event-signal"))
177 /* A value of 0 is allowed to reset the event signal. */
178 #ifdef HAVE_W32_SYSTEM
180 return gpg_error (GPG_ERR_ASS_PARAMETER);
181 ctrl->server_local->event_signal = strtoul (value, NULL, 16);
183 int i = *value? atoi (value) : -1;
185 return gpg_error (GPG_ERR_ASS_PARAMETER);
186 ctrl->server_local->event_signal = i;
194 /* If the card has not yet been opened, do it. */
196 open_card (ctrl_t ctrl)
198 /* If we ever got a card not present error code, return that. Only
199 the SERIALNO command and a reset are able to clear from that
201 if (ctrl->server_local->card_removed)
202 return gpg_error (GPG_ERR_CARD_REMOVED);
204 if ( IS_LOCKED (ctrl) )
205 return gpg_error (GPG_ERR_LOCKED);
210 return select_application (ctrl, NULL, &ctrl->app_ctx, 0, NULL, 0);
213 /* Explicitly open a card for a specific use of APPTYPE or SERIALNO. */
215 open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
218 unsigned char *serialno_bin = NULL;
219 size_t serialno_bin_len = 0;
221 /* If we are already initialized for one specific application we
222 need to check that the client didn't requested a specific
223 application different from the one in use before we continue. */
224 if (apptype && ctrl->app_ctx)
225 return check_application_conflict (apptype, ctrl->app_ctx);
228 serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
230 err = select_application (ctrl, apptype, &ctrl->app_ctx, 1,
231 serialno_bin, serialno_bin_len);
232 xfree (serialno_bin);
238 static const char hlp_serialno[] =
239 "SERIALNO [--demand=<serialno>] [<apptype>]\n"
241 "Return the serial number of the card using a status response. This\n"
242 "function should be used to check for the presence of a card.\n"
244 "If --demand is given, an application on the card with SERIALNO is\n"
245 "selected and an error is returned if no such card available.\n"
247 "If APPTYPE is given, an application of that type is selected and an\n"
248 "error is returned if the application is not supported or available.\n"
249 "The default is to auto-select the application using a hardwired\n"
250 "preference system. Note, that a future extension to this function\n"
251 "may enable specifying a list and order of applications to try.\n"
253 "This function is special in that it can be used to reset the card.\n"
254 "Most other functions will return an error when a card change has\n"
255 "been detected and the use of this function is therefore required.\n"
257 "Background: We want to keep the client clear of handling card\n"
258 "changes between operations; i.e. the client can assume that all\n"
259 "operations are done on the same card unless he calls this function.";
261 cmd_serialno (assuan_context_t ctx, char *line)
263 ctrl_t ctrl = assuan_get_pointer (ctx);
264 struct server_local_s *sl;
269 if ( IS_LOCKED (ctrl) )
270 return gpg_error (GPG_ERR_LOCKED);
272 if ((demand = has_option_name (line, "--demand")))
275 return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
276 line = (char *)++demand;
277 for (; *line && !spacep (line); line++)
285 /* Clear the remove flag so that the open_card is able to reread it. */
286 if (ctrl->server_local->card_removed)
287 ctrl->server_local->card_removed = 0;
289 if ((rc = open_card_with_request (ctrl, *line? line:NULL, demand)))
291 ctrl->server_local->card_removed = 1;
295 /* Success, clear the card_removed flag for all sessions. */
296 for (sl=session_list; sl; sl = sl->next_session)
298 ctrl_t c = sl->ctrl_backlink;
301 c->server_local->card_removed = 0;
304 serial = app_get_serialno (ctrl->app_ctx);
306 return gpg_error (GPG_ERR_INV_VALUE);
308 rc = assuan_write_status (ctx, "SERIALNO", serial);
314 static const char hlp_learn[] =
315 "LEARN [--force] [--keypairinfo]\n"
317 "Learn all useful information of the currently inserted card. When\n"
318 "used without the force options, the command might do an INQUIRE\n"
321 " INQUIRE KNOWNCARDP <hexstring_with_serialNumber>\n"
323 "The client should just send an \"END\" if the processing should go on\n"
324 "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
327 "With the option --keypairinfo only KEYPARIINFO lstatus lines are\n"
330 "The response of this command is a list of status lines formatted as\n"
333 " S APPTYPE <apptype>\n"
335 "This returns the type of the application, currently the strings:\n"
337 " P15 = PKCS-15 structure used\n"
338 " DINSIG = DIN SIG\n"
339 " OPENPGP = OpenPGP card\n"
340 " NKS = NetKey card\n"
342 "are implemented. These strings are aliases for the AID\n"
344 " S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>\n"
346 "If there is no certificate yet stored on the card a single 'X' is\n"
347 "returned as the keygrip. In addition to the keypair info, information\n"
348 "about all certificates stored on the card is also returned:\n"
350 " S CERTINFO <certtype> <hexstring_with_id>\n"
352 "Where CERTTYPE is a number indicating the type of certificate:\n"
354 " 100 := Regular X.509 cert\n"
355 " 101 := Trusted X.509 cert\n"
356 " 102 := Useful X.509 cert\n"
357 " 110 := Root CA cert in a special format (e.g. DINSIG)\n"
358 " 111 := Root CA cert as standard X509 cert.\n"
360 "For certain cards, more information will be returned:\n"
362 " S KEY-FPR <no> <hexstring>\n"
364 "For OpenPGP cards this returns the stored fingerprints of the\n"
365 "keys. This can be used check whether a key is available on the\n"
366 "card. NO may be 1, 2 or 3.\n"
368 " S CA-FPR <no> <hexstring>\n"
370 "Similar to above, these are the fingerprints of keys assumed to be\n"
371 "ultimately trusted.\n"
373 " S DISP-NAME <name_of_card_holder>\n"
375 "The name of the card holder as stored on the card; percent\n"
376 "escaping takes place, spaces are encoded as '+'\n"
378 " S PUBKEY-URL <url>\n"
380 "The URL to be used for locating the entire public key.\n"
382 "Note, that this function may even be used on a locked card.";
384 cmd_learn (assuan_context_t ctx, char *line)
386 ctrl_t ctrl = assuan_get_pointer (ctx);
388 int only_keypairinfo = has_option (line, "--keypairinfo");
390 if ((rc = open_card (ctrl)))
393 /* Unless the force option is used we try a shortcut by identifying
394 the card using a serial number and inquiring the client with
395 that. The client may choose to cancel the operation if he already
396 knows about this card */
397 if (!only_keypairinfo)
401 app_t app = ctrl->app_ctx;
404 return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
406 reader = apdu_get_reader_name (app->slot);
408 return out_of_core ();
409 send_status_direct (ctrl, "READER", reader);
410 /* No need to free the string of READER. */
412 serial = app_get_serialno (ctrl->app_ctx);
414 return gpg_error (GPG_ERR_INV_VALUE);
416 rc = assuan_write_status (ctx, "SERIALNO", serial);
420 return out_of_core ();
423 if (!has_option (line, "--force"))
427 rc = gpgrt_asprintf (&command, "KNOWNCARDP %s", serial);
431 return out_of_core ();
433 rc = assuan_inquire (ctx, command, NULL, NULL, 0);
437 if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
438 log_error ("inquire KNOWNCARDP failed: %s\n",
443 /* Not canceled, so we have to proceeed. */
448 /* Let the application print out its collection of useful status
451 rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
458 static const char hlp_readcert[] =
459 "READCERT <hexified_certid>|<keyid>\n"
461 "Note, that this function may even be used on a locked card.";
463 cmd_readcert (assuan_context_t ctx, char *line)
465 ctrl_t ctrl = assuan_get_pointer (ctx);
470 if ((rc = open_card (ctrl)))
473 line = xstrdup (line); /* Need a copy of the line. */
474 rc = app_readcert (ctrl->app_ctx, ctrl, line, &cert, &ncert);
476 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
481 rc = assuan_send_data (ctx, cert, ncert);
491 static const char hlp_readkey[] =
492 "READKEY [--advanced] <keyid>\n"
494 "Return the public key for the given cert or key ID as a standard\n"
496 "In --advanced mode it returns the S-expression in advanced format.\n"
498 "Note that this function may even be used on a locked card.";
500 cmd_readkey (assuan_context_t ctx, char *line)
502 ctrl_t ctrl = assuan_get_pointer (ctx);
505 unsigned char *cert = NULL;
507 ksba_cert_t kc = NULL;
512 if ((rc = open_card (ctrl)))
515 if (has_option (line, "--advanced"))
518 line = skip_options (line);
520 line = xstrdup (line); /* Need a copy of the line. */
521 /* If the application supports the READKEY function we use that.
522 Otherwise we use the old way by extracting it from the
524 rc = app_readkey (ctrl->app_ctx, ctrl, advanced, line, &pk, &pklen);
526 { /* Yeah, got that key - send it back. */
527 rc = assuan_send_data (ctx, pk, pklen);
534 if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
535 log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
538 rc = app_readcert (ctrl->app_ctx, ctrl, line, &cert, &ncert);
540 log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
547 rc = ksba_cert_new (&kc);
551 rc = ksba_cert_init_from_mem (kc, cert, ncert);
554 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
558 p = ksba_cert_get_public_key (kc);
561 rc = gpg_error (GPG_ERR_NO_PUBKEY);
565 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
566 rc = assuan_send_data (ctx, p, n);
571 ksba_cert_release (kc);
578 static const char hlp_setdata[] =
579 "SETDATA [--append] <hexstring>\n"
581 "The client should use this command to tell us the data he want to sign.\n"
582 "With the option --append, the data is appended to the data set by a\n"
583 "previous SETDATA command.";
585 cmd_setdata (assuan_context_t ctx, char *line)
587 ctrl_t ctrl = assuan_get_pointer (ctx);
593 append = (ctrl->in_data.value && has_option (line, "--append"));
595 line = skip_options (line);
597 if (locked_session && locked_session != ctrl->server_local)
598 return gpg_error (GPG_ERR_LOCKED);
600 /* Parse the hexstring. */
601 for (p=line,n=0; hexdigitp (p); p++, n++)
604 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
606 return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
608 return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
612 if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA)
613 return set_error (GPG_ERR_TOO_LARGE,
614 "limit on total size of data reached");
615 buf = xtrymalloc (ctrl->in_data.valuelen + n);
618 buf = xtrymalloc (n);
620 return out_of_core ();
624 memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen);
625 off = ctrl->in_data.valuelen;
629 for (p=line, i=0; i < n; p += 2, i++)
630 buf[off+i] = xtoi_2 (p);
632 xfree (ctrl->in_data.value);
633 ctrl->in_data.value = buf;
634 ctrl->in_data.valuelen = off+n;
641 pin_cb (void *opaque, const char *info, char **retstr)
643 assuan_context_t ctx = opaque;
646 unsigned char *value;
651 /* We prompt for pinpad entry. To make sure that the popup has
652 been show we use an inquire and not just a status message.
653 We ignore any value returned. */
656 log_debug ("prompting for pinpad entry '%s'\n", info);
657 rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info);
659 return gpg_error (gpg_err_code_from_errno (errno));
660 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
665 log_debug ("dismiss pinpad entry prompt\n");
666 rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT",
667 &value, &valuelen, MAXLEN_PIN);
675 log_debug ("asking for PIN '%s'\n", info);
677 rc = gpgrt_asprintf (&command, "NEEDPIN %s", info);
679 return gpg_error (gpg_err_code_from_errno (errno));
681 /* Fixme: Write an inquire function which returns the result in
682 secure memory and check all further handling of the PIN. */
683 rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN);
688 if (!valuelen || value[valuelen-1])
690 /* We require that the returned value is an UTF-8 string */
692 return gpg_error (GPG_ERR_INV_RESPONSE);
694 *retstr = (char*)value;
699 static const char hlp_pksign[] =
700 "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>\n"
702 "The --hash option is optional; the default is SHA1.";
704 cmd_pksign (assuan_context_t ctx, char *line)
706 ctrl_t ctrl = assuan_get_pointer (ctx);
708 unsigned char *outdata;
713 if (has_option (line, "--hash=rmd160"))
714 hash_algo = GCRY_MD_RMD160;
715 else if (has_option (line, "--hash=sha1"))
716 hash_algo = GCRY_MD_SHA1;
717 else if (has_option (line, "--hash=sha224"))
718 hash_algo = GCRY_MD_SHA224;
719 else if (has_option (line, "--hash=sha256"))
720 hash_algo = GCRY_MD_SHA256;
721 else if (has_option (line, "--hash=sha384"))
722 hash_algo = GCRY_MD_SHA384;
723 else if (has_option (line, "--hash=sha512"))
724 hash_algo = GCRY_MD_SHA512;
725 else if (has_option (line, "--hash=md5"))
726 hash_algo = GCRY_MD_MD5;
727 else if (!strstr (line, "--"))
728 hash_algo = GCRY_MD_SHA1;
730 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
732 line = skip_options (line);
734 if ((rc = open_card (ctrl)))
737 /* We have to use a copy of the key ID because the function may use
738 the pin_cb which in turn uses the assuan line buffer and thus
739 overwriting the original line with the keyid */
740 keyidstr = xtrystrdup (line);
742 return out_of_core ();
744 rc = app_sign (ctrl->app_ctx, ctrl,
747 ctrl->in_data.value, ctrl->in_data.valuelen,
748 &outdata, &outdatalen);
753 log_error ("app_sign failed: %s\n", gpg_strerror (rc));
757 rc = assuan_send_data (ctx, outdata, outdatalen);
760 return rc; /* that is already an assuan error code */
767 static const char hlp_pkauth[] =
768 "PKAUTH <hexified_id>";
770 cmd_pkauth (assuan_context_t ctx, char *line)
772 ctrl_t ctrl = assuan_get_pointer (ctx);
774 unsigned char *outdata;
778 if ((rc = open_card (ctrl)))
782 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
784 /* We have to use a copy of the key ID because the function may use
785 the pin_cb which in turn uses the assuan line buffer and thus
786 overwriting the original line with the keyid */
787 keyidstr = xtrystrdup (line);
789 return out_of_core ();
791 rc = app_auth (ctrl->app_ctx, ctrl, keyidstr, pin_cb, ctx,
792 ctrl->in_data.value, ctrl->in_data.valuelen,
793 &outdata, &outdatalen);
797 log_error ("app_auth failed: %s\n", gpg_strerror (rc));
801 rc = assuan_send_data (ctx, outdata, outdatalen);
804 return rc; /* that is already an assuan error code */
811 static const char hlp_pkdecrypt[] =
812 "PKDECRYPT <hexified_id>";
814 cmd_pkdecrypt (assuan_context_t ctx, char *line)
816 ctrl_t ctrl = assuan_get_pointer (ctx);
818 unsigned char *outdata;
821 unsigned int infoflags;
823 if ((rc = open_card (ctrl)))
826 keyidstr = xtrystrdup (line);
828 return out_of_core ();
829 rc = app_decipher (ctrl->app_ctx, ctrl, keyidstr, pin_cb, ctx,
830 ctrl->in_data.value, ctrl->in_data.valuelen,
831 &outdata, &outdatalen, &infoflags);
836 log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
840 /* If the card driver told us that there is no padding, send a
841 status line. If there is a padding it is assumed that the
842 caller knows what padding is used. It would have been better
843 to always send that information but for backward
844 compatibility we can't do that. */
845 if ((infoflags & APP_DECIPHER_INFO_NOPAD))
846 send_status_direct (ctrl, "PADDING", "0");
847 rc = assuan_send_data (ctx, outdata, outdatalen);
850 return rc; /* that is already an assuan error code */
857 static const char hlp_getattr[] =
860 "This command is used to retrieve data from a smartcard. The\n"
861 "allowed names depend on the currently selected smartcard\n"
862 "application. NAME must be percent and '+' escaped. The value is\n"
863 "returned through status message, see the LEARN command for details.\n"
865 "However, the current implementation assumes that Name is not escaped;\n"
866 "this works as long as no one uses arbitrary escaping. \n"
868 "Note, that this function may even be used on a locked card.";
870 cmd_getattr (assuan_context_t ctx, char *line)
872 ctrl_t ctrl = assuan_get_pointer (ctx);
876 if ((rc = open_card (ctrl)))
880 for (; *line && !spacep (line); line++)
885 /* (We ignore any garbage for now.) */
887 /* FIXME: Applications should not return sensitive data if the card
889 rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
895 static const char hlp_setattr[] =
896 "SETATTR <name> <value> \n"
898 "This command is used to store data on a a smartcard. The allowed\n"
899 "names and values are depend on the currently selected smartcard\n"
900 "application. NAME and VALUE must be percent and '+' escaped.\n"
902 "However, the current implementation assumes that NAME is not\n"
903 "escaped; this works as long as no one uses arbitrary escaping.\n"
905 "A PIN will be requested for most NAMEs. See the corresponding\n"
906 "setattr function of the actually used application (app-*.c) for\n"
909 cmd_setattr (assuan_context_t ctx, char *orig_line)
911 ctrl_t ctrl = assuan_get_pointer (ctx);
916 char *line, *linebuf;
918 if ((rc = open_card (ctrl)))
921 /* We need to use a copy of LINE, because PIN_CB uses the same
922 context and thus reuses the Assuan provided LINE. */
923 line = linebuf = xtrystrdup (orig_line);
925 return out_of_core ();
928 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
932 while (spacep (line))
934 nbytes = percent_plus_unescape_inplace (line, 0);
936 rc = app_setattr (ctrl->app_ctx, ctrl, keyword, pin_cb, ctx,
937 (const unsigned char*)line, nbytes);
944 static const char hlp_writecert[] =
945 "WRITECERT <hexified_certid>\n"
947 "This command is used to store a certifciate on a smartcard. The\n"
948 "allowed certids depend on the currently selected smartcard\n"
949 "application. The actual certifciate is requested using the inquiry\n"
950 "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
952 "In almost all cases a a PIN will be requested. See the related\n"
953 "writecert function of the actually used application (app-*.c) for\n"
956 cmd_writecert (assuan_context_t ctx, char *line)
958 ctrl_t ctrl = assuan_get_pointer (ctx);
961 unsigned char *certdata;
964 line = skip_options (line);
967 return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
969 while (*line && !spacep (line))
973 if ((rc = open_card (ctrl)))
977 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
979 certid = xtrystrdup (certid);
981 return out_of_core ();
983 /* Now get the actual keydata. */
984 rc = assuan_inquire (ctx, "CERTDATA",
985 &certdata, &certdatalen, MAXLEN_CERTDATA);
992 /* Write the certificate to the card. */
993 rc = app_writecert (ctrl->app_ctx, ctrl, certid,
994 pin_cb, ctx, certdata, certdatalen);
1002 static const char hlp_writekey[] =
1003 "WRITEKEY [--force] <keyid> \n"
1005 "This command is used to store a secret key on a a smartcard. The\n"
1006 "allowed keyids depend on the currently selected smartcard\n"
1007 "application. The actual keydata is requested using the inquiry\n"
1008 "\"KEYDATA\" and need to be provided without any protection. With\n"
1009 "--force set an existing key under this KEYID will get overwritten.\n"
1010 "The keydata is expected to be the usual canonical encoded\n"
1013 "A PIN will be requested for most NAMEs. See the corresponding\n"
1014 "writekey function of the actually used application (app-*.c) for\n"
1017 cmd_writekey (assuan_context_t ctx, char *line)
1019 ctrl_t ctrl = assuan_get_pointer (ctx);
1022 int force = has_option (line, "--force");
1023 unsigned char *keydata;
1026 line = skip_options (line);
1029 return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1031 while (*line && !spacep (line))
1035 if ((rc = open_card (ctrl)))
1039 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1041 keyid = xtrystrdup (keyid);
1043 return out_of_core ();
1045 /* Now get the actual keydata. */
1046 assuan_begin_confidential (ctx);
1047 rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1048 assuan_end_confidential (ctx);
1055 /* Write the key to the card. */
1056 rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1057 pin_cb, ctx, keydata, keydatalen);
1065 static const char hlp_genkey[] =
1066 "GENKEY [--force] [--timestamp=<isodate>] <no>\n"
1068 "Generate a key on-card identified by NO, which is application\n"
1069 "specific. Return values are application specific. For OpenPGP\n"
1070 "cards 3 status lines are returned:\n"
1072 " S KEY-FPR <hexstring>\n"
1073 " S KEY-CREATED-AT <seconds_since_epoch>\n"
1074 " S KEY-DATA [-|p|n] <hexdata>\n"
1076 " 'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
1077 " indicate that HEXDATA is the first chunk of a parameter given\n"
1078 " by the next KEY-DATA.\n"
1080 "--force is required to overwrite an already existing key. The\n"
1081 "KEY-CREATED-AT is required for further processing because it is\n"
1082 "part of the hashed key material for the fingerprint.\n"
1084 "If --timestamp is given an OpenPGP key will be created using this\n"
1085 "value. The value needs to be in ISO Format; e.g.\n"
1086 "\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
1088 "The public part of the key can also later be retrieved using the\n"
1091 cmd_genkey (assuan_context_t ctx, char *line)
1093 ctrl_t ctrl = assuan_get_pointer (ctx);
1100 force = has_option (line, "--force");
1102 if ((s=has_option_name (line, "--timestamp")))
1105 return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1106 timestamp = isotime2epoch (s+1);
1108 return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1114 line = skip_options (line);
1116 return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1118 while (*line && !spacep (line))
1122 if ((rc = open_card (ctrl)))
1126 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1128 keyno = xtrystrdup (keyno);
1130 return out_of_core ();
1131 rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1132 timestamp, pin_cb, ctx);
1139 static const char hlp_random[] =
1142 "Get NBYTES of random from the card and send them back as data.\n"
1143 "This usually involves EEPROM write on the card and thus excessive\n"
1144 "use of this command may destroy the card.\n"
1146 "Note, that this function may be even be used on a locked card.";
1148 cmd_random (assuan_context_t ctx, char *line)
1150 ctrl_t ctrl = assuan_get_pointer (ctx);
1153 unsigned char *buffer;
1156 return set_error (GPG_ERR_ASS_PARAMETER,
1157 "number of requested bytes missing");
1158 nbytes = strtoul (line, NULL, 0);
1160 if ((rc = open_card (ctrl)))
1164 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1166 buffer = xtrymalloc (nbytes);
1168 return out_of_core ();
1170 rc = app_get_challenge (ctrl->app_ctx, ctrl, nbytes, buffer);
1173 rc = assuan_send_data (ctx, buffer, nbytes);
1175 return rc; /* that is already an assuan error code */
1184 static const char hlp_passwd[] =
1185 "PASSWD [--reset] [--nullpin] <chvno>\n"
1187 "Change the PIN or, if --reset is given, reset the retry counter of\n"
1188 "the card holder verification vector CHVNO. The option --nullpin is\n"
1189 "used for TCOS cards to set the initial PIN. The format of CHVNO\n"
1190 "depends on the card application.";
1192 cmd_passwd (assuan_context_t ctx, char *line)
1194 ctrl_t ctrl = assuan_get_pointer (ctx);
1197 unsigned int flags = 0;
1199 if (has_option (line, "--reset"))
1200 flags |= APP_CHANGE_FLAG_RESET;
1201 if (has_option (line, "--nullpin"))
1202 flags |= APP_CHANGE_FLAG_NULLPIN;
1204 line = skip_options (line);
1207 return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1209 while (*line && !spacep (line))
1213 if ((rc = open_card (ctrl)))
1217 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1219 chvnostr = xtrystrdup (chvnostr);
1221 return out_of_core ();
1222 rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1224 log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1231 static const char hlp_checkpin[] =
1232 "CHECKPIN <idstr>\n"
1234 "Perform a VERIFY operation without doing anything else. This may\n"
1235 "be used to initialize a the PIN cache earlier to long lasting\n"
1236 "operations. Its use is highly application dependent.\n"
1240 " Perform a simple verify operation for CHV1 and CHV2, so that\n"
1241 " further operations won't ask for CHV2 and it is possible to do a\n"
1242 " cheap check on the PIN: If there is something wrong with the PIN\n"
1243 " entry system, only the regular CHV will get blocked and not the\n"
1244 " dangerous CHV3. IDSTR is the usual card's serial number in hex\n"
1245 " notation; an optional fingerprint part will get ignored. There\n"
1246 " is however a special mode if the IDSTR is sffixed with the\n"
1247 " literal string \"[CHV3]\": In this case the Admin PIN is checked\n"
1248 " if and only if the retry counter is still at 3.\n"
1252 " Any of the valid PIN Ids may be used. These are the strings:\n"
1254 " PW1.CH - Global password 1\n"
1255 " PW2.CH - Global password 2\n"
1256 " PW1.CH.SIG - SigG password 1\n"
1257 " PW2.CH.SIG - SigG password 2\n"
1259 " For a definitive list, see the implementation in app-nks.c.\n"
1260 " Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
1261 " 3.0 they are technically alternative PINs used to mutally\n"
1262 " unblock each other.";
1264 cmd_checkpin (assuan_context_t ctx, char *line)
1266 ctrl_t ctrl = assuan_get_pointer (ctx);
1270 if ((rc = open_card (ctrl)))
1274 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1276 /* We have to use a copy of the key ID because the function may use
1277 the pin_cb which in turn uses the assuan line buffer and thus
1278 overwriting the original line with the keyid. */
1279 idstr = xtrystrdup (line);
1281 return out_of_core ();
1283 rc = app_check_pin (ctrl->app_ctx, ctrl, idstr, pin_cb, ctx);
1286 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1292 static const char hlp_lock[] =
1295 "Grant exclusive card access to this session. Note that there is\n"
1296 "no lock counter used and a second lock from the same session will\n"
1297 "be ignored. A single unlock (or RESET) unlocks the session.\n"
1298 "Return GPG_ERR_LOCKED if another session has locked the reader.\n"
1300 "If the option --wait is given the command will wait until a\n"
1301 "lock has been released.";
1303 cmd_lock (assuan_context_t ctx, char *line)
1305 ctrl_t ctrl = assuan_get_pointer (ctx);
1311 if (locked_session != ctrl->server_local)
1312 rc = gpg_error (GPG_ERR_LOCKED);
1315 locked_session = ctrl->server_local;
1318 if (rc && has_option (line, "--wait"))
1321 npth_sleep (1); /* Better implement an event mechanism. However,
1322 for card operations this should be
1324 /* FIXME: Need to check that the connection is still alive.
1325 This can be done by issuing status messages. */
1331 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1336 static const char hlp_unlock[] =
1339 "Release exclusive card access.";
1341 cmd_unlock (assuan_context_t ctx, char *line)
1343 ctrl_t ctrl = assuan_get_pointer (ctx);
1350 if (locked_session != ctrl->server_local)
1351 rc = gpg_error (GPG_ERR_LOCKED);
1353 locked_session = NULL;
1356 rc = gpg_error (GPG_ERR_NOT_LOCKED);
1359 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1364 static const char hlp_getinfo[] =
1367 "Multi purpose command to return certain information. \n"
1368 "Supported values of WHAT are:\n"
1370 "version - Return the version of the program.\n"
1371 "pid - Return the process id of the server.\n"
1373 "socket_name - Return the name of the socket.\n"
1375 "status - Return the status of the current reader (in the future, may\n"
1376 "also return the status of all readers). The status is a list of\n"
1377 "one-character flags. The following flags are currently defined:\n"
1378 " 'u' Usable card present. This is the normal state during operation.\n"
1379 " 'r' Card removed. A reset is necessary.\n"
1380 "These flags are exclusive.\n"
1382 "reader_list - Return a list of detected card readers. Does\n"
1383 " currently only work with the internal CCID driver.\n"
1385 "deny_admin - Returns OK if admin commands are not allowed or\n"
1386 " GPG_ERR_GENERAL if admin commands are allowed.\n"
1388 "app_list - Return a list of supported applications. One\n"
1389 " application per line, fields delimited by colons,\n"
1390 " first field is the name.\n"
1392 "card_list - Return a list of serial numbers of active cards,\n"
1393 " using a status response.";
1395 cmd_getinfo (assuan_context_t ctx, char *line)
1399 if (!strcmp (line, "version"))
1401 const char *s = VERSION;
1402 rc = assuan_send_data (ctx, s, strlen (s));
1404 else if (!strcmp (line, "pid"))
1408 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1409 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1411 else if (!strcmp (line, "socket_name"))
1413 const char *s = scd_get_socket_name ();
1416 rc = assuan_send_data (ctx, s, strlen (s));
1418 rc = gpg_error (GPG_ERR_NO_DATA);
1420 else if (!strcmp (line, "status"))
1422 ctrl_t ctrl = assuan_get_pointer (ctx);
1425 if (open_card (ctrl))
1430 rc = assuan_send_data (ctx, &flag, 1);
1432 else if (!strcmp (line, "reader_list"))
1435 char *s = ccid_get_reader_list ();
1441 rc = assuan_send_data (ctx, s, strlen (s));
1443 rc = gpg_error (GPG_ERR_NO_DATA);
1446 else if (!strcmp (line, "deny_admin"))
1447 rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1448 else if (!strcmp (line, "app_list"))
1450 char *s = get_supported_applications ();
1452 rc = assuan_send_data (ctx, s, strlen (s));
1457 else if (!strcmp (line, "card_list"))
1459 ctrl_t ctrl = assuan_get_pointer (ctx);
1461 app_send_card_list (ctrl);
1464 rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1469 static const char hlp_restart[] =
1472 "Restart the current connection; this is a kind of warm reset. It\n"
1473 "deletes the context used by this connection but does not send a\n"
1474 "RESET to the card. Thus the card itself won't get reset. \n"
1476 "This is used by gpg-agent to reuse a primary pipe connection and\n"
1477 "may be used by clients to backup from a conflict in the serial\n"
1478 "command; i.e. to select another application.";
1480 cmd_restart (assuan_context_t ctx, char *line)
1482 ctrl_t ctrl = assuan_get_pointer (ctx);
1483 app_t app = ctrl->app_ctx;
1489 ctrl->app_ctx = NULL;
1490 release_application (app);
1492 if (locked_session && ctrl->server_local == locked_session)
1494 locked_session = NULL;
1495 log_info ("implicitly unlocking due to RESTART\n");
1501 static const char hlp_disconnect[] =
1504 "Disconnect the card if the backend supports a disconnect operation.";
1506 cmd_disconnect (assuan_context_t ctx, char *line)
1508 ctrl_t ctrl = assuan_get_pointer (ctx);
1513 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1515 apdu_disconnect (ctrl->app_ctx->slot);
1521 static const char hlp_apdu[] =
1522 "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n"
1524 "Send an APDU to the current reader. This command bypasses the high\n"
1525 "level functions and sends the data directly to the card. HEXSTRING\n"
1526 "is expected to be a proper APDU. If HEXSTRING is not given no\n"
1527 "commands are set to the card but the command will implictly check\n"
1528 "whether the card is ready for use. \n"
1530 "Using the option \"--atr\" returns the ATR of the card as a status\n"
1531 "message before any data like this:\n"
1532 " S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1\n"
1534 "Using the option --more handles the card status word MORE_DATA\n"
1535 "(61xx) and concatenates all responses to one block.\n"
1537 "Using the option \"--exlen\" the returned APDU may use extended\n"
1538 "length up to N bytes. If N is not given a default value is used\n"
1539 "(currently 4096).";
1541 cmd_apdu (assuan_context_t ctx, char *line)
1543 ctrl_t ctrl = assuan_get_pointer (ctx);
1546 unsigned char *apdu;
1553 if (has_option (line, "--dump-atr"))
1556 with_atr = has_option (line, "--atr");
1557 handle_more = has_option (line, "--more");
1559 if ((s=has_option_name (line, "--exlen")))
1562 exlen = strtoul (s+1, NULL, 0);
1569 line = skip_options (line);
1571 if ((rc = open_card (ctrl)))
1574 app = ctrl->app_ctx;
1576 return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
1584 atr = apdu_get_atr (app->slot, &atrlen);
1585 if (!atr || atrlen > sizeof hexbuf - 2 )
1587 rc = gpg_error (GPG_ERR_INV_CARD);
1592 char *string, *p, *pend;
1594 string = atr_dump (atr, atrlen);
1597 for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1)
1599 rc = assuan_send_data (ctx, p, pend - p + 1);
1601 rc = assuan_send_data (ctx, NULL, 0);
1604 rc = assuan_send_data (ctx, p, strlen (p));
1612 bin2hex (atr, atrlen, hexbuf);
1613 send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1618 apdu = hex_to_buffer (line, &apdulen);
1621 rc = gpg_error_from_syserror ();
1626 unsigned char *result = NULL;
1629 rc = apdu_send_direct (app->slot, exlen,
1630 apdu, apdulen, handle_more,
1631 &result, &resultlen);
1633 log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1636 rc = assuan_send_data (ctx, result, resultlen);
1647 static const char hlp_killscd[] =
1652 cmd_killscd (assuan_context_t ctx, char *line)
1654 ctrl_t ctrl = assuan_get_pointer (ctx);
1658 ctrl->server_local->stopme = 1;
1659 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
1665 /* Tell the assuan library about our commands */
1667 register_commands (assuan_context_t ctx)
1671 assuan_handler_t handler;
1672 const char * const help;
1674 { "SERIALNO", cmd_serialno, hlp_serialno },
1675 { "LEARN", cmd_learn, hlp_learn },
1676 { "READCERT", cmd_readcert, hlp_readcert },
1677 { "READKEY", cmd_readkey, hlp_readkey },
1678 { "SETDATA", cmd_setdata, hlp_setdata },
1679 { "PKSIGN", cmd_pksign, hlp_pksign },
1680 { "PKAUTH", cmd_pkauth, hlp_pkauth },
1681 { "PKDECRYPT", cmd_pkdecrypt,hlp_pkdecrypt },
1684 { "GETATTR", cmd_getattr, hlp_getattr },
1685 { "SETATTR", cmd_setattr, hlp_setattr },
1686 { "WRITECERT", cmd_writecert,hlp_writecert },
1687 { "WRITEKEY", cmd_writekey, hlp_writekey },
1688 { "GENKEY", cmd_genkey, hlp_genkey },
1689 { "RANDOM", cmd_random, hlp_random },
1690 { "PASSWD", cmd_passwd, hlp_passwd },
1691 { "CHECKPIN", cmd_checkpin, hlp_checkpin },
1692 { "LOCK", cmd_lock, hlp_lock },
1693 { "UNLOCK", cmd_unlock, hlp_unlock },
1694 { "GETINFO", cmd_getinfo, hlp_getinfo },
1695 { "RESTART", cmd_restart, hlp_restart },
1696 { "DISCONNECT", cmd_disconnect,hlp_disconnect },
1697 { "APDU", cmd_apdu, hlp_apdu },
1698 { "KILLSCD", cmd_killscd, hlp_killscd },
1703 for (i=0; table[i].name; i++)
1705 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1710 assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1712 assuan_register_reset_notify (ctx, reset_notify);
1713 assuan_register_option_handler (ctx, option_handler);
1718 /* Startup the server. If FD is given as -1 this is simple pipe
1719 server, otherwise it is a regular server. Returns true if there
1720 are no more active asessions. */
1722 scd_command_handler (ctrl_t ctrl, int fd)
1725 assuan_context_t ctx = NULL;
1728 rc = assuan_new (&ctx);
1731 log_error ("failed to allocate assuan context: %s\n",
1738 assuan_fd_t filedes[2];
1740 filedes[0] = assuan_fdopen (0);
1741 filedes[1] = assuan_fdopen (1);
1742 rc = assuan_init_pipe_server (ctx, filedes);
1746 rc = assuan_init_socket_server (ctx, INT2FD(fd),
1747 ASSUAN_SOCKET_SERVER_ACCEPTED);
1751 log_error ("failed to initialize the server: %s\n",
1755 rc = register_commands (ctx);
1758 log_error ("failed to register commands with Assuan: %s\n",
1762 assuan_set_pointer (ctx, ctrl);
1764 /* Allocate and initialize the server object. Put it into the list
1765 of active sessions. */
1766 ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1767 ctrl->server_local->next_session = session_list;
1768 session_list = ctrl->server_local;
1769 ctrl->server_local->ctrl_backlink = ctrl;
1770 ctrl->server_local->assuan_ctx = ctx;
1772 /* Command processing loop. */
1775 rc = assuan_accept (ctx);
1782 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1786 rc = assuan_process (ctx);
1789 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1794 /* Cleanup. We don't send an explicit reset to the card. */
1797 /* Release the server object. */
1798 if (session_list == ctrl->server_local)
1799 session_list = ctrl->server_local->next_session;
1802 struct server_local_s *sl;
1804 for (sl=session_list; sl->next_session; sl = sl->next_session)
1805 if (sl->next_session == ctrl->server_local)
1807 if (!sl->next_session)
1809 sl->next_session = ctrl->server_local->next_session;
1811 stopme = ctrl->server_local->stopme;
1812 xfree (ctrl->server_local);
1813 ctrl->server_local = NULL;
1815 /* Release the Assuan context. */
1816 assuan_release (ctx);
1821 /* If there are no more sessions return true. */
1822 return !session_list;
1826 /* Send a line with status information via assuan and escape all given
1827 buffers. The variable elements are pairs of (char *, size_t),
1828 terminated with a (NULL, 0). */
1830 send_status_info (ctrl_t ctrl, const char *keyword, ...)
1833 const unsigned char *value;
1837 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1839 va_start (arg_ptr, keyword);
1843 while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1845 valuelen = va_arg (arg_ptr, size_t);
1847 continue; /* empty buffer */
1853 for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1855 if (*value == '+' || *value == '\"' || *value == '%'
1858 sprintf (p, "%%%02X", *value);
1861 else if (*value == ' ')
1868 assuan_write_status (ctx, keyword, buf);
1874 /* Send a ready formatted status line via assuan. */
1876 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
1878 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1880 if (strchr (args, '\n'))
1881 log_error ("error: LF detected in status line - not sending\n");
1883 assuan_write_status (ctx, keyword, args);
1887 /* Helper to send the clients a status change notification. */
1889 send_client_notifications (app_t app, int removal)
1893 #ifdef HAVE_W32_SYSTEM
1901 struct server_local_s *sl;
1903 for (sl=session_list; sl; sl = sl->next_session)
1904 if (sl->ctrl_backlink && sl->ctrl_backlink->app_ctx == app)
1907 #ifdef HAVE_W32_SYSTEM
1915 sl->ctrl_backlink->app_ctx = NULL;
1916 sl->card_removed = 1;
1917 release_application (app);
1920 if (!sl->event_signal || !sl->assuan_ctx)
1923 pid = assuan_get_pid (sl->assuan_ctx);
1925 #ifdef HAVE_W32_SYSTEM
1926 handle = (void *)sl->event_signal;
1927 for (kidx=0; kidx < killidx; kidx++)
1928 if (killed[kidx].pid == pid
1929 && killed[kidx].handle == handle)
1932 log_info ("event %lx (%p) already triggered for client %d\n",
1933 sl->event_signal, handle, (int)pid);
1936 log_info ("triggering event %lx (%p) for client %d\n",
1937 sl->event_signal, handle, (int)pid);
1938 if (!SetEvent (handle))
1939 log_error ("SetEvent(%lx) failed: %s\n",
1940 sl->event_signal, w32_strerror (-1));
1941 if (killidx < DIM (killed))
1943 killed[killidx].pid = pid;
1944 killed[killidx].handle = handle;
1948 #else /*!HAVE_W32_SYSTEM*/
1949 signo = sl->event_signal;
1951 if (pid != (pid_t)(-1) && pid && signo > 0)
1953 for (kidx=0; kidx < killidx; kidx++)
1954 if (killed[kidx].pid == pid
1955 && killed[kidx].signo == signo)
1958 log_info ("signal %d already sent to client %d\n",
1962 log_info ("sending signal %d to client %d\n",
1965 if (killidx < DIM (killed))
1967 killed[killidx].pid = pid;
1968 killed[killidx].signo = signo;
1973 #endif /*!HAVE_W32_SYSTEM*/