1 /* command.c - SCdaemon command handler
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
38 #include "app-common.h"
39 #include "apdu.h" /* Required for apdu_*_reader (). */
42 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
43 #define MAXLEN_PIN 100
45 /* Maximum allowed size of key data as used in inquiries. */
46 #define MAXLEN_KEYDATA 4096
49 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
52 /* Macro to flag a removed card. */
53 #define TEST_CARD_REMOVAL(c,r) \
56 if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
57 || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED) \
58 update_card_removed ((c)->reader_slot, 1); \
61 #define IS_LOCKED(c) \
62 (locked_session && locked_session != (c)->server_local \
63 && (c)->reader_slot != -1 && locked_session->ctrl_backlink \
64 && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
67 /* This structure is used to keep track of open readers (slots). */
70 int valid
; /* True if the other objects are valid. */
71 int slot
; /* Slot number of the reader or -1 if not open. */
73 int reset_failed
; /* A reset failed. */
75 int any
; /* Flag indicating whether any status check has been
76 done. This is set once to indicate that the status
77 tracking for the slot has been initialized. */
78 unsigned int status
; /* Last status of the slot. */
79 unsigned int changed
; /* Last change counter of teh slot. */
83 /* Data used to associate an Assuan context with local server data.
84 This object describes the local properties of one session. */
87 /* We keep a list of all active sessions with the anchor at
88 SESSION_LIST (see below). This field is used for linking. */
89 struct server_local_s
*next_session
;
91 /* This object is usually assigned to a CTRL object (which is
92 globally visible). While enumerating all sessions we sometimes
93 need to access data of the CTRL object; thus we keep a
97 /* The Assuan context used by this session/server. */
98 assuan_context_t assuan_ctx
;
100 int event_signal
; /* Or 0 if not used. */
102 /* True if the card has been removed and a reset is required to
103 continue operation. */
108 /* The table with information on all used slots. FIXME: This is a
109 different slot number than the one used by the APDU layer, and
110 should be renamed. */
111 static struct slot_status_s slot_table
[10];
114 /* To keep track of all running sessions, we link all active server
115 contexts and the anchor in this variable. */
116 static struct server_local_s
*session_list
;
118 /* If a session has been locked we store a link to its server object
120 static struct server_local_s
*locked_session
;
122 /* While doing a reset we need to make sure that the ticker does not
123 call scd_update_reader_status_file while we are using it. */
124 static pth_mutex_t status_file_update_lock
= PTH_MUTEX_INIT
;
127 /*-- Local prototypes --*/
128 static void update_reader_status_file (void);
132 /* Update the CARD_REMOVED element of all sessions using the reader
133 given by SLOT to VALUE */
135 update_card_removed (int slot
, int value
)
137 struct server_local_s
*sl
;
139 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
140 if (sl
->ctrl_backlink
141 && sl
->ctrl_backlink
->reader_slot
== slot
)
143 sl
->card_removed
= value
;
146 application_notify_card_removed (slot
);
151 /* Check whether the option NAME appears in LINE */
153 has_option (const char *line
, const char *name
)
156 int n
= strlen (name
);
158 s
= strstr (line
, name
);
159 return (s
&& (s
== line
|| spacep (s
-1)) && (!s
[n
] || spacep (s
+n
)));
163 /* Convert the STRING into a newly allocated buffer while translating
164 the hex numbers. Stops at the first invalid character. Blanks and
165 colons are allowed to separate the hex digits. Returns NULL on
166 error or a newly malloced buffer and its length in LENGTH. */
167 static unsigned char *
168 hex_to_buffer (const char *string
, size_t *r_length
)
170 unsigned char *buffer
;
174 buffer
= xtrymalloc (strlen (string
)+1);
177 for (s
=string
, n
=0; *s
; s
++)
179 if (spacep (s
) || *s
== ':')
181 if (hexdigitp (s
) && hexdigitp (s
+1))
183 buffer
[n
++] = xtoi_2 (s
);
195 /* Reset the card and free the application context. With SEND_RESET
196 set to true actually send a RESET to the reader. */
198 do_reset (ctrl_t ctrl
, int send_reset
)
200 int slot
= ctrl
->reader_slot
;
202 if (!(slot
== -1 || (slot
>= 0 && slot
< DIM(slot_table
))))
207 release_application (ctrl
->app_ctx
);
208 ctrl
->app_ctx
= NULL
;
211 if (slot
!= -1 && send_reset
&& !IS_LOCKED (ctrl
) )
213 if (apdu_reset (slot
))
215 slot_table
[slot
].reset_failed
= 1;
219 /* If we hold a lock, unlock now. */
220 if (locked_session
&& ctrl
->server_local
== locked_session
)
222 locked_session
= NULL
;
223 log_info ("implicitly unlocking due to RESET\n");
226 /* Reset card removed flag for the current reader. We need to take
227 the lock here so that the ticker thread won't concurrently try to
228 update the file. Note that the update function will set the card
229 removed flag and we will later reset it - not a particualar nice
230 way of implementing it but it works. */
231 if (!pth_mutex_acquire (&status_file_update_lock
, 0, NULL
))
233 log_error ("failed to acquire status_fle_update lock\n");
234 ctrl
->reader_slot
= -1;
237 update_reader_status_file ();
238 update_card_removed (slot
, 0);
239 if (!pth_mutex_release (&status_file_update_lock
))
240 log_error ("failed to release status_file_update lock\n");
242 /* Do this last, so that update_card_removed does its job. */
243 ctrl
->reader_slot
= -1;
248 reset_notify (assuan_context_t ctx
)
250 ctrl_t ctrl
= assuan_get_pointer (ctx
);
257 option_handler (assuan_context_t ctx
, const char *key
, const char *value
)
259 ctrl_t ctrl
= assuan_get_pointer (ctx
);
261 if (!strcmp (key
, "event-signal"))
263 /* A value of 0 is allowed to reset the event signal. */
264 int i
= *value
? atoi (value
) : -1;
266 return gpg_error (GPG_ERR_ASS_PARAMETER
);
267 ctrl
->server_local
->event_signal
= i
;
274 /* Return the slot of the current reader or open the reader if no
275 other sessions are using a reader. Note, that we currently support
276 only one reader but most of the code (except for this function)
277 should be able to cope with several readers. */
279 get_reader_slot (void)
281 struct slot_status_s
*ss
;
283 ss
= &slot_table
[0]; /* One reader for now. */
285 /* Initialize the item if needed. */
292 /* Try to open the reader. */
294 ss
->slot
= apdu_open_reader (opt
.reader_port
);
296 /* Return the slot_table index. */
300 /* If the card has not yet been opened, do it. Note that this
301 function returns an Assuan error, so don't map the error a second
303 static assuan_error_t
304 open_card (ctrl_t ctrl
, const char *apptype
)
309 /* If we ever got a card not present error code, return that. Only
310 the SERIALNO command and a reset are able to clear from that
312 if (ctrl
->server_local
->card_removed
)
313 return gpg_error (GPG_ERR_CARD_REMOVED
);
315 if ( IS_LOCKED (ctrl
) )
316 return gpg_error (GPG_ERR_LOCKED
);
320 /* Already initialized for one specific application. Need to
321 check that the client didn't requested a specific application
322 different from the one in use. */
323 return check_application_conflict (ctrl
, apptype
);
326 if (ctrl
->reader_slot
!= -1)
327 slot
= ctrl
->reader_slot
;
329 slot
= get_reader_slot ();
330 ctrl
->reader_slot
= slot
;
332 err
= gpg_error (GPG_ERR_CARD
);
334 err
= select_application (ctrl
, slot
, apptype
, &ctrl
->app_ctx
);
336 TEST_CARD_REMOVAL (ctrl
, err
);
341 /* Do the percent and plus/space unescaping in place and return the
342 length of the valid buffer. */
344 percent_plus_unescape (unsigned char *string
)
346 unsigned char *p
= string
;
351 if (*string
== '%' && string
[1] && string
[2])
354 *p
++ = xtoi_2 (string
);
358 else if (*string
== '+')
376 /* SERIALNO [APPTYPE]
378 Return the serial number of the card using a status reponse. This
379 functon should be used to check for the presence of a card.
381 If APPTYPE is given, an application of that type is selected and an
382 error is returned if the application is not supported or available.
383 The default is to auto-select the application using a hardwired
384 preference system. Note, that a future extension to this function
385 may allow to specify a list and order of applications to try.
387 This function is special in that it can be used to reset the card.
388 Most other functions will return an error when a card change has
389 been detected and the use of this function is therefore required.
391 Background: We want to keep the client clear of handling card
392 changes between operations; i.e. the client can assume that all
393 operations are done on the same card unless he calls this function.
396 cmd_serialno (assuan_context_t ctx
, char *line
)
398 ctrl_t ctrl
= assuan_get_pointer (ctx
);
400 char *serial_and_stamp
;
404 /* Clear the remove flag so that the open_card is able to reread it. */
405 if (ctrl
->server_local
->card_removed
)
407 if ( IS_LOCKED (ctrl
) )
408 return gpg_error (GPG_ERR_LOCKED
);
412 if ((rc
= open_card (ctrl
, *line
? line
:NULL
)))
415 rc
= app_get_serial_and_stamp (ctrl
->app_ctx
, &serial
, &stamp
);
419 rc
= asprintf (&serial_and_stamp
, "%s %lu", serial
, (unsigned long)stamp
);
422 return out_of_core ();
424 assuan_write_status (ctx
, "SERIALNO", serial_and_stamp
);
425 free (serial_and_stamp
);
434 Learn all useful information of the currently inserted card. When
435 used without the force options, the command might do an INQUIRE
438 INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
440 The client should just send an "END" if the processing should go on
441 or a "CANCEL" to force the function to terminate with a Cancel
442 error message. The response of this command is a list of status
443 lines formatted as this:
447 This returns the type of the application, currently the strings:
449 P15 = PKCS-15 structure used
451 OPENPGP = OpenPGP card
453 are implemented. These strings are aliases for the AID
455 S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
457 If there is no certificate yet stored on the card a single "X" is
458 returned as the keygrip. In addition to the keypair info, information
459 about all certificates stored on the card is also returned:
461 S CERTINFO <certtype> <hexstring_with_id>
463 Where CERTTYPE is a number indicating the type of certificate:
465 100 := Regular X.509 cert
466 101 := Trusted X.509 cert
467 102 := Useful X.509 cert
468 110 := Root CA cert (DINSIG)
470 For certain cards, more information will be returned:
472 S KEY-FPR <no> <hexstring>
474 For OpenPGP cards this returns the stored fingerprints of the
475 keys. This can be used check whether a key is available on the
476 card. NO may be 1, 2 or 3.
478 S CA-FPR <no> <hexstring>
480 Similar to above, these are the fingerprints of keys assumed to be
483 S DISP-NAME <name_of_card_holder>
485 The name of the card holder as stored on the card; percent
486 escaping takes place, spaces are encoded as '+'
490 The URL to be used for locating the entire public key.
492 Note, that this function may be even be used on a locked card.
495 cmd_learn (assuan_context_t ctx
, char *line
)
497 ctrl_t ctrl
= assuan_get_pointer (ctx
);
500 if ((rc
= open_card (ctrl
, NULL
)))
503 /* Unless the force option is used we try a shortcut by identifying
504 the card using a serial number and inquiring the client with
505 that. The client may choose to cancel the operation if he already
506 knows about this card */
508 char *serial_and_stamp
;
512 rc
= app_get_serial_and_stamp (ctrl
->app_ctx
, &serial
, &stamp
);
515 rc
= asprintf (&serial_and_stamp
, "%s %lu", serial
, (unsigned long)stamp
);
518 return out_of_core ();
520 assuan_write_status (ctx
, "SERIALNO", serial_and_stamp
);
522 if (!has_option (line
, "--force"))
526 rc
= asprintf (&command
, "KNOWNCARDP %s", serial_and_stamp
);
529 free (serial_and_stamp
);
530 return out_of_core ();
533 rc
= assuan_inquire (ctx
, command
, NULL
, NULL
, 0);
534 free (command
); /* (must use standard free here) */
537 if (gpg_err_code (rc
) != GPG_ERR_ASS_CANCELED
)
538 log_error ("inquire KNOWNCARDP failed: %s\n",
540 free (serial_and_stamp
);
543 /* not canceled, so we have to proceeed */
545 free (serial_and_stamp
);
548 /* Let the application print out its collection of useful status
551 rc
= app_write_learn_status (ctrl
->app_ctx
, ctrl
);
553 TEST_CARD_REMOVAL (ctrl
, rc
);
559 /* READCERT <hexified_certid>
561 Note, that this function may even be used on a locked card.
564 cmd_readcert (assuan_context_t ctx
, char *line
)
566 ctrl_t ctrl
= assuan_get_pointer (ctx
);
571 if ((rc
= open_card (ctrl
, NULL
)))
574 line
= xstrdup (line
); /* Need a copy of the line. */
575 rc
= app_readcert (ctrl
->app_ctx
, line
, &cert
, &ncert
);
577 log_error ("app_readcert failed: %s\n", gpg_strerror (rc
));
582 rc
= assuan_send_data (ctx
, cert
, ncert
);
588 TEST_CARD_REMOVAL (ctrl
, rc
);
595 Return the public key for the given cert or key ID as an standard
598 Note, that this function may even be used on a locked card.
601 cmd_readkey (assuan_context_t ctx
, char *line
)
603 ctrl_t ctrl
= assuan_get_pointer (ctx
);
605 unsigned char *cert
= NULL
;
607 ksba_cert_t kc
= NULL
;
612 if ((rc
= open_card (ctrl
, NULL
)))
615 line
= xstrdup (line
); /* Need a copy of the line. */
616 /* If the application supports the READKEY function we use that.
617 Otherwise we use the old way by extracting it from the
619 rc
= app_readkey (ctrl
->app_ctx
, line
, &pk
, &pklen
);
621 { /* Yeah, got that key - send it back. */
622 rc
= assuan_send_data (ctx
, pk
, pklen
);
629 if (gpg_err_code (rc
) != GPG_ERR_UNSUPPORTED_OPERATION
)
630 log_error ("app_readkey failed: %s\n", gpg_strerror (rc
));
633 rc
= app_readcert (ctrl
->app_ctx
, line
, &cert
, &ncert
);
635 log_error ("app_readcert failed: %s\n", gpg_strerror (rc
));
642 rc
= ksba_cert_new (&kc
);
648 rc
= ksba_cert_init_from_mem (kc
, cert
, ncert
);
651 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc
));
655 p
= ksba_cert_get_public_key (kc
);
658 rc
= gpg_error (GPG_ERR_NO_PUBKEY
);
662 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
663 rc
= assuan_send_data (ctx
, p
, n
);
668 ksba_cert_release (kc
);
670 TEST_CARD_REMOVAL (ctrl
, rc
);
677 /* SETDATA <hexstring>
679 The client should use this command to tell us the data he want to
682 cmd_setdata (assuan_context_t ctx
, char *line
)
684 ctrl_t ctrl
= assuan_get_pointer (ctx
);
689 if (locked_session
&& locked_session
!= ctrl
->server_local
)
690 return gpg_error (GPG_ERR_LOCKED
);
692 /* Parse the hexstring. */
693 for (p
=line
,n
=0; hexdigitp (p
); p
++, n
++)
696 return set_error (GPG_ERR_ASS_PARAMETER
, "invalid hexstring");
698 return set_error (GPG_ERR_ASS_PARAMETER
, "no data given");
700 return set_error (GPG_ERR_ASS_PARAMETER
, "odd number of digits");
702 buf
= xtrymalloc (n
);
704 return out_of_core ();
706 ctrl
->in_data
.value
= buf
;
707 ctrl
->in_data
.valuelen
= n
;
708 for (p
=line
, n
=0; n
< ctrl
->in_data
.valuelen
; p
+= 2, n
++)
716 pin_cb (void *opaque
, const char *info
, char **retstr
)
718 assuan_context_t ctx
= opaque
;
721 unsigned char *value
;
725 log_debug ("asking for PIN '%s'\n", info
);
727 rc
= asprintf (&command
, "NEEDPIN %s", info
);
729 return gpg_error (gpg_err_code_from_errno (errno
));
731 /* Fixme: Write an inquire function which returns the result in
732 secure memory and check all further handling of the PIN. */
733 rc
= assuan_inquire (ctx
, command
, &value
, &valuelen
, MAXLEN_PIN
);
738 if (!valuelen
|| value
[valuelen
-1])
740 /* We require that the returned value is an UTF-8 string */
742 return gpg_error (GPG_ERR_INV_RESPONSE
);
744 *retstr
= (char*)value
;
749 /* PKSIGN [--hash=[rmd160|sha1|md5]] <hexified_id>
751 The --hash option is optional; the default is SHA1.
755 cmd_pksign (assuan_context_t ctx
, char *line
)
757 ctrl_t ctrl
= assuan_get_pointer (ctx
);
759 unsigned char *outdata
;
764 if (has_option (line
, "--hash=rmd160"))
765 hash_algo
= GCRY_MD_RMD160
;
766 else if (has_option (line
, "--hash=sha1"))
767 hash_algo
= GCRY_MD_SHA1
;
768 else if (has_option (line
, "--hash=md5"))
769 hash_algo
= GCRY_MD_MD5
;
770 else if (!strstr (line
, "--"))
771 hash_algo
= GCRY_MD_SHA1
;
773 return set_error (GPG_ERR_ASS_PARAMETER
, "invalid hash algorithm");
774 /* Skip over options. */
775 while ( *line
== '-' && line
[1] == '-' )
777 while (*line
&& !spacep (line
))
779 while (spacep (line
))
783 if ( IS_LOCKED (ctrl
) )
784 return gpg_error (GPG_ERR_LOCKED
);
786 if ((rc
= open_card (ctrl
, NULL
)))
789 /* We have to use a copy of the key ID because the function may use
790 the pin_cb which in turn uses the assuan line buffer and thus
791 overwriting the original line with the keyid */
792 keyidstr
= xtrystrdup (line
);
794 return out_of_core ();
796 rc
= app_sign (ctrl
->app_ctx
,
799 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
800 &outdata
, &outdatalen
);
805 log_error ("card_sign failed: %s\n", gpg_strerror (rc
));
809 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
812 return rc
; /* that is already an assuan error code */
815 TEST_CARD_REMOVAL (ctrl
, rc
);
819 /* PKAUTH <hexified_id>
823 cmd_pkauth (assuan_context_t ctx
, char *line
)
825 ctrl_t ctrl
= assuan_get_pointer (ctx
);
827 unsigned char *outdata
;
831 if ( IS_LOCKED (ctrl
) )
832 return gpg_error (GPG_ERR_LOCKED
);
834 if ((rc
= open_card (ctrl
, NULL
)))
838 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
840 /* We have to use a copy of the key ID because the function may use
841 the pin_cb which in turn uses the assuan line buffer and thus
842 overwriting the original line with the keyid */
843 keyidstr
= xtrystrdup (line
);
845 return out_of_core ();
847 rc
= app_auth (ctrl
->app_ctx
,
850 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
851 &outdata
, &outdatalen
);
855 log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc
));
859 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
862 return rc
; /* that is already an assuan error code */
865 TEST_CARD_REMOVAL (ctrl
, rc
);
869 /* PKDECRYPT <hexified_id>
873 cmd_pkdecrypt (assuan_context_t ctx
, char *line
)
875 ctrl_t ctrl
= assuan_get_pointer (ctx
);
877 unsigned char *outdata
;
881 if ( IS_LOCKED (ctrl
) )
882 return gpg_error (GPG_ERR_LOCKED
);
884 if ((rc
= open_card (ctrl
, NULL
)))
887 keyidstr
= xtrystrdup (line
);
889 return out_of_core ();
890 rc
= app_decipher (ctrl
->app_ctx
,
893 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
894 &outdata
, &outdatalen
);
899 log_error ("card_create_signature failed: %s\n", gpg_strerror (rc
));
903 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
906 return rc
; /* that is already an assuan error code */
909 TEST_CARD_REMOVAL (ctrl
, rc
);
916 This command is used to retrieve data from a smartcard. The
917 allowed names depend on the currently selected smartcard
918 application. NAME must be percent and '+' escaped. The value is
919 returned through status message, see the LEARN command for details.
921 However, the current implementation assumes that Name is not escaped;
922 this works as long as noone uses arbitrary escaping.
924 Note, that this function may even be used on a locked card.
927 cmd_getattr (assuan_context_t ctx
, char *line
)
929 ctrl_t ctrl
= assuan_get_pointer (ctx
);
933 if ((rc
= open_card (ctrl
, NULL
)))
937 for (; *line
&& !spacep (line
); line
++)
942 /* (We ignore any garbage for now.) */
944 /* FIXME: Applications should not return sensitive data if the card
946 rc
= app_getattr (ctrl
->app_ctx
, ctrl
, keyword
);
948 TEST_CARD_REMOVAL (ctrl
, rc
);
953 /* SETATTR <name> <value>
955 This command is used to store data on a a smartcard. The allowed
956 names and values are depend on the currently selected smartcard
957 application. NAME and VALUE must be percent and '+' escaped.
959 However, the curent implementation assumes that Name is not escaped;
960 this works as long as noone uses arbitrary escaping.
962 A PIN will be requested for most NAMEs. See the corresponding
963 setattr function of the actually used application (app-*.c) for
966 cmd_setattr (assuan_context_t ctx
, char *orig_line
)
968 ctrl_t ctrl
= assuan_get_pointer (ctx
);
973 char *line
, *linebuf
;
975 if ( IS_LOCKED (ctrl
) )
976 return gpg_error (GPG_ERR_LOCKED
);
978 if ((rc
= open_card (ctrl
, NULL
)))
981 /* We need to use a copy of LINE, because PIN_CB uses the same
982 context and thus reuses the Assuan provided LINE. */
983 line
= linebuf
= xtrystrdup (orig_line
);
985 return out_of_core ();
988 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
992 while (spacep (line
))
994 nbytes
= percent_plus_unescape ((unsigned char*)line
);
996 rc
= app_setattr (ctrl
->app_ctx
, keyword
, pin_cb
, ctx
,
997 (const unsigned char*)line
, nbytes
);
1000 TEST_CARD_REMOVAL (ctrl
, rc
);
1006 /* WRITEKEY [--force] <keyid>
1008 This command is used to store a secret key on a a smartcard. The
1009 allowed keyids depend on the currently selected smartcard
1010 application. The actual keydata is requested using the inquiry
1011 "KETDATA" and need to be provided without any protection. With
1012 --force set an existing key under this KEYID will get overwritten.
1013 The keydata is expected to be the usual canonical encoded
1016 A PIN will be requested for most NAMEs. See the corresponding
1017 writekey function of the actually used application (app-*.c) for
1020 cmd_writekey (assuan_context_t ctx
, char *line
)
1022 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1025 int force
= has_option (line
, "--force");
1026 unsigned char *keydata
;
1029 if ( IS_LOCKED (ctrl
) )
1030 return gpg_error (GPG_ERR_LOCKED
);
1032 /* Skip over options. */
1033 while ( *line
== '-' && line
[1] == '-' )
1035 while (*line
&& !spacep (line
))
1037 while (spacep (line
))
1041 return set_error (GPG_ERR_ASS_PARAMETER
, "no keyid given");
1043 while (*line
&& !spacep (line
))
1047 if ((rc
= open_card (ctrl
, NULL
)))
1051 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1053 keyid
= xtrystrdup (keyid
);
1055 return out_of_core ();
1057 /* Now get the actual keydata. */
1058 rc
= assuan_inquire (ctx
, "KEYDATA", &keydata
, &keydatalen
, MAXLEN_KEYDATA
);
1065 /* Write the key to the card. */
1066 rc
= app_writekey (ctrl
->app_ctx
, ctrl
, keyid
, force
? 1:0,
1067 pin_cb
, ctx
, keydata
, keydatalen
);
1071 TEST_CARD_REMOVAL (ctrl
, rc
);
1077 /* GENKEY [--force] <no>
1079 Generate a key on-card identified by NO, which is application
1080 specific. Return values are application specific. For OpenPGP
1081 cards 2 status lines are returned:
1083 S KEY-FPR <hexstring>
1084 S KEY-CREATED-AT <seconds_since_epoch>
1085 S KEY-DATA [p|n] <hexdata>
1088 --force is required to overwrite an already existing key. The
1089 KEY-CREATED-AT is required for further processing because it is
1090 part of the hashed key material for the fingerprint.
1092 The public part of the key can also later be retrieved using the
1097 cmd_genkey (assuan_context_t ctx
, char *line
)
1099 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1102 int force
= has_option (line
, "--force");
1104 if ( IS_LOCKED (ctrl
) )
1105 return gpg_error (GPG_ERR_LOCKED
);
1107 /* Skip over options. */
1108 while ( *line
== '-' && line
[1] == '-' )
1110 while (*line
&& !spacep (line
))
1112 while (spacep (line
))
1116 return set_error (GPG_ERR_ASS_PARAMETER
, "no key number given");
1118 while (*line
&& !spacep (line
))
1122 if ((rc
= open_card (ctrl
, NULL
)))
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, pin_cb
, ctx
);
1134 TEST_CARD_REMOVAL (ctrl
, rc
);
1141 Get NBYTES of random from the card and send them back as data.
1143 Note, that this function may be even be used on a locked card.
1146 cmd_random (assuan_context_t ctx
, char *line
)
1148 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1151 unsigned char *buffer
;
1154 return set_error (GPG_ERR_ASS_PARAMETER
, "number of requested bytes missing");
1155 nbytes
= strtoul (line
, NULL
, 0);
1157 if ((rc
= open_card (ctrl
, NULL
)))
1161 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1163 buffer
= xtrymalloc (nbytes
);
1165 return out_of_core ();
1167 rc
= app_get_challenge (ctrl
->app_ctx
, nbytes
, buffer
);
1170 rc
= assuan_send_data (ctx
, buffer
, nbytes
);
1172 return rc
; /* that is already an assuan error code */
1176 TEST_CARD_REMOVAL (ctrl
, rc
);
1181 /* PASSWD [--reset] <chvno>
1183 Change the PIN or reset the retry counter of the card holder
1184 verfication vector CHVNO. */
1186 cmd_passwd (assuan_context_t ctx
, char *line
)
1188 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1191 int reset_mode
= has_option (line
, "--reset");
1193 if ( IS_LOCKED (ctrl
) )
1194 return gpg_error (GPG_ERR_LOCKED
);
1196 /* Skip over options. */
1197 while (*line
== '-' && line
[1] == '-')
1199 while (*line
&& !spacep (line
))
1201 while (spacep (line
))
1205 return set_error (GPG_ERR_ASS_PARAMETER
, "no CHV number given");
1207 while (*line
&& !spacep (line
))
1211 if ((rc
= open_card (ctrl
, NULL
)))
1215 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1217 chvnostr
= xtrystrdup (chvnostr
);
1219 return out_of_core ();
1220 rc
= app_change_pin (ctrl
->app_ctx
, ctrl
, chvnostr
, reset_mode
, pin_cb
, ctx
);
1222 log_error ("command passwd failed: %s\n", gpg_strerror (rc
));
1225 TEST_CARD_REMOVAL (ctrl
, rc
);
1232 Perform a VERIFY operation without doing anything else. This may
1233 be used to initialize a the PIN cache earlier to long lasting
1234 operations. Its use is highly application dependent.
1238 Perform a simple verify operation for CHV1 and CHV2, so that
1239 further operations won't ask for CHV2 and it is possible to do a
1240 cheap check on the PIN: If there is something wrong with the PIN
1241 entry system, only the regular CHV will get blocked and not the
1242 dangerous CHV3. IDSTR is the usual card's serial number in hex
1243 notation; an optional fingerprint part will get ignored. There
1244 is however a special mode if the IDSTR is sffixed with the
1245 literal string "[CHV3]": In this case the Admin PIN is checked
1246 if and only if the retry counter is still at 3.
1250 cmd_checkpin (assuan_context_t ctx
, char *line
)
1252 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1256 if ( IS_LOCKED (ctrl
) )
1257 return gpg_error (GPG_ERR_LOCKED
);
1259 if ((rc
= open_card (ctrl
, NULL
)))
1263 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1265 /* We have to use a copy of the key ID because the function may use
1266 the pin_cb which in turn uses the assuan line buffer and thus
1267 overwriting the original line with the keyid. */
1268 keyidstr
= xtrystrdup (line
);
1270 return out_of_core ();
1272 rc
= app_check_pin (ctrl
->app_ctx
,
1277 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc
));
1279 TEST_CARD_REMOVAL (ctrl
, rc
);
1286 Grant exclusive card access to this session. Note that there is
1287 no lock counter used and a second lock from the same session will
1288 be ignored. A single unlock (or RESET) unlocks the session.
1289 Return GPG_ERR_LOCKED if another session has locked the reader.
1291 If the option --wait is given the command will wait until a
1292 lock has been released.
1295 cmd_lock (assuan_context_t ctx
, char *line
)
1297 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1303 if (locked_session
!= ctrl
->server_local
)
1304 rc
= gpg_error (GPG_ERR_LOCKED
);
1307 locked_session
= ctrl
->server_local
;
1310 if (rc
&& has_option (line
, "--wait"))
1313 pth_sleep (1); /* Better implement an event mechanism. However,
1314 for card operations this should be
1316 /* FIXME: Need to check that the connection is still alive.
1317 This can be done by issuing status messages. */
1320 #endif /*USE_GNU_PTH*/
1323 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc
));
1330 Release exclusive card access.
1333 cmd_unlock (assuan_context_t ctx
, char *line
)
1335 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1340 if (locked_session
!= ctrl
->server_local
)
1341 rc
= gpg_error (GPG_ERR_LOCKED
);
1343 locked_session
= NULL
;
1346 rc
= gpg_error (GPG_ERR_NOT_LOCKED
);
1349 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc
));
1356 Multi purpose command to return certain information.
1357 Supported values of WHAT are:
1359 socket_name - Return the name of the socket.
1360 status - Return the status of the current slot (in the future, may
1361 also return the status of all slots). The status is a list of
1362 one-character flags. The following flags are currently defined:
1363 'u' Usable card present. This is the normal state during operation.
1364 'r' Card removed. A reset is necessary.
1365 These flags are exclusive.
1369 cmd_getinfo (assuan_context_t ctx
, char *line
)
1373 if (!strcmp (line
, "socket_name"))
1375 const char *s
= scd_get_socket_name ();
1378 rc
= assuan_send_data (ctx
, s
, strlen (s
));
1380 rc
= gpg_error (GPG_ERR_NO_DATA
);
1382 else if (!strcmp (line
, "status"))
1384 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1385 int slot
= ctrl
->reader_slot
;
1388 if (!ctrl
->server_local
->card_removed
&& slot
!= -1)
1390 struct slot_status_s
*ss
;
1392 if (!(slot
>= 0 && slot
< DIM(slot_table
)))
1395 ss
= &slot_table
[slot
];
1400 if (ss
->any
&& (ss
->status
& 1))
1403 rc
= assuan_send_data (ctx
, &flag
, 1);
1406 rc
= set_error (GPG_ERR_ASS_PARAMETER
, "unknown value for WHAT");
1413 Restart the current connection; this is a kind of warm reset. It
1414 deletes the context used by this connection but does not send a
1415 RESET to the card. Thus the card itself won't get reset.
1417 This is used by gpg-agent to reuse a primary pipe connection and
1418 may be used by clients to backup from a conflict in the serial
1419 command; i.e. to select another application.
1423 cmd_restart (assuan_context_t ctx
, char *line
)
1425 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1429 release_application (ctrl
->app_ctx
);
1430 ctrl
->app_ctx
= NULL
;
1432 if (locked_session
&& ctrl
->server_local
== locked_session
)
1434 locked_session
= NULL
;
1435 log_info ("implicitly unlocking due to RESTART\n");
1441 /* APDU [--atr] [--more] [hexstring]
1443 Send an APDU to the current reader. This command bypasses the high
1444 level functions and sends the data directly to the card. HEXSTRING
1445 is expected to be a proper APDU. If HEXSTRING is not given no
1446 commands are set to the card but the command will implictly check
1447 whether the card is ready for use.
1449 Using the option "--atr" returns the ATR of the card as a status
1450 message before any data like this:
1451 S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1
1453 Using the option --more handles the card status word MORE_DATA
1454 (61xx) and concatenate all reponses to one block.
1458 cmd_apdu (assuan_context_t ctx
, char *line
)
1460 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1462 unsigned char *apdu
;
1467 with_atr
= has_option (line
, "--atr");
1468 handle_more
= has_option (line
, "--more");
1470 /* Skip over options. */
1471 while ( *line
== '-' && line
[1] == '-' )
1473 while (*line
&& !spacep (line
))
1475 while (spacep (line
))
1479 if ( IS_LOCKED (ctrl
) )
1480 return gpg_error (GPG_ERR_LOCKED
);
1482 if ((rc
= open_card (ctrl
, NULL
)))
1492 atr
= apdu_get_atr (ctrl
->reader_slot
, &atrlen
);
1493 if (!atr
|| atrlen
> sizeof hexbuf
- 2 )
1495 rc
= gpg_error (GPG_ERR_INV_CARD
);
1498 for (i
=0; i
< atrlen
; i
++)
1499 sprintf (hexbuf
+2*i
, "%02X", atr
[i
]);
1501 send_status_info (ctrl
, "CARD-ATR", hexbuf
, strlen (hexbuf
), NULL
, 0);
1504 apdu
= hex_to_buffer (line
, &apdulen
);
1507 rc
= gpg_error_from_syserror ();
1512 unsigned char *result
= NULL
;
1515 rc
= apdu_send_direct (ctrl
->reader_slot
, apdu
, apdulen
, handle_more
,
1516 &result
, &resultlen
);
1518 log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc
));
1521 rc
= assuan_send_data (ctx
, result
, resultlen
);
1528 TEST_CARD_REMOVAL (ctrl
, rc
);
1536 /* Tell the assuan library about our commands */
1538 register_commands (assuan_context_t ctx
)
1542 int (*handler
)(assuan_context_t
, char *line
);
1544 { "SERIALNO", cmd_serialno
},
1545 { "LEARN", cmd_learn
},
1546 { "READCERT", cmd_readcert
},
1547 { "READKEY", cmd_readkey
},
1548 { "SETDATA", cmd_setdata
},
1549 { "PKSIGN", cmd_pksign
},
1550 { "PKAUTH", cmd_pkauth
},
1551 { "PKDECRYPT", cmd_pkdecrypt
},
1554 { "GETATTR", cmd_getattr
},
1555 { "SETATTR", cmd_setattr
},
1556 { "WRITEKEY", cmd_writekey
},
1557 { "GENKEY", cmd_genkey
},
1558 { "RANDOM", cmd_random
},
1559 { "PASSWD", cmd_passwd
},
1560 { "CHECKPIN", cmd_checkpin
},
1561 { "LOCK", cmd_lock
},
1562 { "UNLOCK", cmd_unlock
},
1563 { "GETINFO", cmd_getinfo
},
1564 { "RESTART", cmd_restart
},
1565 { "APDU", cmd_apdu
},
1570 for (i
=0; table
[i
].name
; i
++)
1572 rc
= assuan_register_command (ctx
, table
[i
].name
, table
[i
].handler
);
1576 assuan_set_hello_line (ctx
, "GNU Privacy Guard's Smartcard server ready");
1578 assuan_register_reset_notify (ctx
, reset_notify
);
1579 assuan_register_option_handler (ctx
, option_handler
);
1584 /* Startup the server. If FD is given as -1 this is simple pipe
1585 server, otherwise it is a regular server. */
1587 scd_command_handler (int fd
)
1590 assuan_context_t ctx
;
1591 struct server_control_s ctrl
;
1593 memset (&ctrl
, 0, sizeof ctrl
);
1594 scd_init_default_ctrl (&ctrl
);
1602 rc
= assuan_init_pipe_server (&ctx
, filedes
);
1606 rc
= assuan_init_socket_server_ext (&ctx
, fd
, 2);
1610 log_error ("failed to initialize the server: %s\n",
1614 rc
= register_commands (ctx
);
1617 log_error ("failed to register commands with Assuan: %s\n",
1621 assuan_set_pointer (ctx
, &ctrl
);
1623 /* Allocate and initialize the server object. Put it into the list
1624 of active sessions. */
1625 ctrl
.server_local
= xcalloc (1, sizeof *ctrl
.server_local
);
1626 ctrl
.server_local
->next_session
= session_list
;
1627 session_list
= ctrl
.server_local
;
1628 ctrl
.server_local
->ctrl_backlink
= &ctrl
;
1629 ctrl
.server_local
->assuan_ctx
= ctx
;
1632 assuan_set_log_stream (ctx
, log_get_stream ());
1634 /* We open the reader right at startup so that the ticker is able to
1635 update the status file. */
1636 if (ctrl
.reader_slot
== -1)
1638 ctrl
.reader_slot
= get_reader_slot ();
1641 /* Command processing loop. */
1644 rc
= assuan_accept (ctx
);
1651 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc
));
1655 rc
= assuan_process (ctx
);
1658 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc
));
1664 do_reset (&ctrl
, 0);
1666 /* Release the server object. */
1667 if (session_list
== ctrl
.server_local
)
1668 session_list
= ctrl
.server_local
->next_session
;
1671 struct server_local_s
*sl
;
1673 for (sl
=session_list
; sl
->next_session
; sl
= sl
->next_session
)
1674 if (sl
->next_session
== ctrl
.server_local
)
1676 if (!sl
->next_session
)
1678 sl
->next_session
= ctrl
.server_local
->next_session
;
1680 xfree (ctrl
.server_local
);
1682 /* Release the Assuan context. */
1683 assuan_deinit_server (ctx
);
1687 /* Send a line with status information via assuan and escape all given
1688 buffers. The variable elements are pairs of (char *, size_t),
1689 terminated with a (NULL, 0). */
1691 send_status_info (ctrl_t ctrl
, const char *keyword
, ...)
1694 const unsigned char *value
;
1698 assuan_context_t ctx
= ctrl
->server_local
->assuan_ctx
;
1700 va_start (arg_ptr
, keyword
);
1704 while ( (value
= va_arg (arg_ptr
, const unsigned char *)) )
1706 valuelen
= va_arg (arg_ptr
, size_t);
1708 continue; /* empty buffer */
1714 for ( ; valuelen
&& n
< DIM (buf
)-2; n
++, valuelen
--, value
++)
1716 if (*value
< ' ' || *value
== '+')
1718 sprintf (p
, "%%%02X", *value
);
1721 else if (*value
== ' ')
1728 assuan_write_status (ctx
, keyword
, buf
);
1734 /* This is the core of scd_update_reader_status_file but the caller
1735 needs to take care of the locking. */
1737 update_reader_status_file (void)
1740 unsigned int status
, changed
;
1742 /* Note, that we only try to get the status, because it does not
1743 make sense to wait here for a operation to complete. If we are
1744 busy working with a card, delays in the status file update should
1746 for (idx
=0; idx
< DIM(slot_table
); idx
++)
1748 struct slot_status_s
*ss
= slot_table
+ idx
;
1750 if (!ss
->valid
|| ss
->slot
== -1)
1751 continue; /* Not valid or reader not yet open. */
1753 if ( apdu_get_status (ss
->slot
, 0, &status
, &changed
) )
1754 continue; /* Get status failed. */
1756 if (!ss
->any
|| ss
->status
!= status
|| ss
->changed
!= changed
)
1761 struct server_local_s
*sl
;
1763 log_info ("updating status of slot %d to 0x%04X\n",
1766 /* FIXME: Should this be IDX instead of ss->slot? This
1767 depends on how client sessions will associate the reader
1768 status with their session. */
1769 sprintf (templ
, "reader_%d.status", ss
->slot
);
1770 fname
= make_filename (opt
.homedir
, templ
, NULL
);
1771 fp
= fopen (fname
, "w");
1774 fprintf (fp
, "%s\n",
1775 (status
& 1)? "USABLE":
1776 (status
& 4)? "ACTIVE":
1777 (status
& 2)? "PRESENT": "NOCARD");
1782 /* If a status script is executable, run it. */
1784 const char *args
[9], *envs
[2];
1785 char numbuf1
[30], numbuf2
[30], numbuf3
[30];
1786 char *homestr
, *envstr
;
1789 homestr
= make_filename (opt
.homedir
, NULL
);
1790 if (asprintf (&envstr
, "GNUPGHOME=%s", homestr
) < 0)
1791 log_error ("out of core while building environment\n");
1797 sprintf (numbuf1
, "%d", ss
->slot
);
1798 sprintf (numbuf2
, "0x%04X", ss
->status
);
1799 sprintf (numbuf3
, "0x%04X", status
);
1800 args
[0] = "--reader-port";
1802 args
[2] = "--old-code";
1804 args
[4] = "--new-code";
1806 args
[6] = "--status";
1807 args
[7] = ((status
& 1)? "USABLE":
1808 (status
& 4)? "ACTIVE":
1809 (status
& 2)? "PRESENT": "NOCARD");
1812 fname
= make_filename (opt
.homedir
, "scd-event", NULL
);
1813 err
= gnupg_spawn_process_detached (fname
, args
, envs
);
1814 if (err
&& gpg_err_code (err
) != GPG_ERR_ENOENT
)
1815 log_error ("failed to run event handler `%s': %s\n",
1816 fname
, gpg_strerror (err
));
1823 /* Set the card removed flag for all current sessions. We
1824 will set this on any card change because a reset or
1825 SERIALNO request must be done in any case. */
1827 update_card_removed (idx
, 1);
1830 ss
->status
= status
;
1831 ss
->changed
= changed
;
1833 /* Send a signal to all clients who applied for it. */
1834 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
1835 if (sl
->event_signal
&& sl
->assuan_ctx
)
1837 pid_t pid
= assuan_get_pid (sl
->assuan_ctx
);
1838 int signo
= sl
->event_signal
;
1840 log_info ("client pid is %d, sending signal %d\n",
1842 #ifndef HAVE_W32_SYSTEM
1843 if (pid
!= (pid_t
)(-1) && pid
&& signo
> 0)
1852 /* This function is called by the ticker thread to check for changes
1853 of the reader stati. It updates the reader status files and if
1854 requested by the caller also send a signal to the caller. */
1856 scd_update_reader_status_file (void)
1858 if (!pth_mutex_acquire (&status_file_update_lock
, 1, NULL
))
1859 return; /* locked - give up. */
1860 update_reader_status_file ();
1861 if (!pth_mutex_release (&status_file_update_lock
))
1862 log_error ("failed to release status_file_update lock\n");