1 /* command.c - SCdaemon command handler
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
37 #include "app-common.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
40 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
41 #define MAXLEN_PIN 100
44 #define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
47 /* Macro to flag a a removed card. */
48 #define TEST_CARD_REMOVAL(c,r) \
51 if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
52 || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED) \
53 update_card_removed ((c)->reader_slot, 1); \
56 #define IS_LOCKED(c) \
57 (locked_session && locked_session != (c)->server_local \
58 && (c)->reader_slot != -1 && locked_session->ctrl_backlink \
59 && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
62 /* Data used to associate an Assuan context with local server data.
63 This object describes the local properties of one session. */
64 struct server_local_s
{
65 /* We keep a list of all active sessions with the anchor at
66 SESSION_LIST (see below). This field is used for linking. */
67 struct server_local_s
*next_session
;
69 /* This object is usually assigned to a CTRL object (which is
70 globally visible). While enumeratin all sessions we sometimes
71 need to access data of the CTRL object; thus we keep a
75 /* The Assuan context used by this session/server. */
76 assuan_context_t assuan_ctx
;
78 int event_signal
; /* Or 0 if not used. */
80 /* True if the card has been removed and a reset is required to
81 continue operation. */
86 /* To keep track of all running sessions, we link all active server
87 contexts and the anchor in this variable. */
88 static struct server_local_s
*session_list
;
90 /* If a session has been locked we store a link to its server object
92 static struct server_local_s
*locked_session
;
97 /* Update the CARD_REMOVED element of all sessions using the reader
98 given by SLOT to VALUE */
100 update_card_removed (int slot
, int value
)
102 struct server_local_s
*sl
;
104 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
105 if (sl
->ctrl_backlink
106 && sl
->ctrl_backlink
->reader_slot
== slot
)
107 sl
->card_removed
= value
;
112 /* Check whether the option NAME appears in LINE */
114 has_option (const char *line
, const char *name
)
117 int n
= strlen (name
);
119 s
= strstr (line
, name
);
120 return (s
&& (s
== line
|| spacep (s
-1)) && (!s
[n
] || spacep (s
+n
)));
124 /* Reset the card and free the application context. With DO_CLOSE set
125 to true and this is the last session with a reference to teh
126 reader, close the reader and don't do just a reset. */
128 do_reset (ctrl_t ctrl
, int do_close
)
130 int slot
= ctrl
->reader_slot
;
134 card_close (ctrl
->card_ctx
);
135 ctrl
->card_ctx
= NULL
;
136 xfree (ctrl
->in_data
.value
);
137 ctrl
->in_data
.value
= NULL
;
141 release_application (ctrl
->app_ctx
);
142 ctrl
->app_ctx
= NULL
;
144 if (ctrl
->reader_slot
!= -1)
146 struct server_local_s
*sl
;
148 /* If we are the only session with the reader open we may close
149 it. If not, do a reset unless the a lock is held on the
151 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
152 if (sl
!= ctrl
->server_local
153 && sl
->ctrl_backlink
->reader_slot
== ctrl
->reader_slot
)
155 if (sl
) /* There is another session with the reader open. */
157 if ( IS_LOCKED (ctrl
) ) /* If it is locked, release it. */
158 ctrl
->reader_slot
= -1;
161 if (do_close
) /* Always mark reader unused. */
162 ctrl
->reader_slot
= -1;
163 else if (apdu_reset (ctrl
->reader_slot
)) /* Reset only if
166 /* The reset failed. Mark the reader as closed. */
167 ctrl
->reader_slot
= -1;
170 if (locked_session
&& ctrl
->server_local
== locked_session
)
172 locked_session
= NULL
;
173 log_debug ("implicitly unlocking due to RESET\n");
177 else /* No other session has the reader open. */
179 if (do_close
|| apdu_reset (ctrl
->reader_slot
))
181 apdu_close_reader (ctrl
->reader_slot
);
182 ctrl
->reader_slot
= -1;
184 if ( IS_LOCKED (ctrl
) )
186 log_debug ("WARNING: cleaning up stale session lock\n");
187 locked_session
= NULL
;
192 /* Reset card removed flag for the current reader. */
193 update_card_removed (slot
, 0);
198 reset_notify (assuan_context_t ctx
)
200 ctrl_t ctrl
= assuan_get_pointer (ctx
);
207 option_handler (assuan_context_t ctx
, const char *key
, const char *value
)
209 ctrl_t ctrl
= assuan_get_pointer (ctx
);
211 if (!strcmp (key
, "event-signal"))
213 /* A value of 0 is allowed to reset the event signal. */
214 int i
= *value
? atoi (value
) : -1;
216 return ASSUAN_Parameter_Error
;
217 ctrl
->server_local
->event_signal
= i
;
224 /* Return the slot of the current reader or open the reader if no
225 other sessions are using a reader. Note, that we currently support
226 only one reader but most of the code (except for this function)
227 should be able to cope with several readers. */
229 get_reader_slot (void)
231 struct server_local_s
*sl
;
234 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
235 if (sl
->ctrl_backlink
236 && (slot
= sl
->ctrl_backlink
->reader_slot
) != -1)
240 slot
= apdu_open_reader (opt
.reader_port
);
245 /* If the card has not yet been opened, do it. Note that this
246 function returns an Assuan error, so don't map the error a second
248 static assuan_error_t
249 open_card (ctrl_t ctrl
, const char *apptype
)
254 /* If we ever got a card not present error code, return that. Only
255 the SERIALNO command and a reset are able to clear from that
257 if (ctrl
->server_local
->card_removed
)
258 return map_to_assuan_status (gpg_error (GPG_ERR_CARD_REMOVED
));
261 return 0; /* Already initialized for one specific application. */
263 return 0; /* Already initialized using a card context. */
265 if ( IS_LOCKED (ctrl
) )
266 return gpg_error (GPG_ERR_EBUSY
);
268 if (ctrl
->reader_slot
!= -1)
269 slot
= ctrl
->reader_slot
;
271 slot
= get_reader_slot ();
272 ctrl
->reader_slot
= slot
;
274 err
= gpg_error (GPG_ERR_CARD
);
276 err
= select_application (ctrl
, slot
, apptype
, &ctrl
->app_ctx
);
278 && gpg_err_code (err
) != GPG_ERR_CARD_NOT_PRESENT
)
280 /* No application found - fall back to old mode. */
281 /* Note that we should rework the old code to use the
282 application paradigma too. */
283 /* If an APPTYPE was requested and it is not pkcs#15, we return
285 if (apptype
&& !(!strcmp (apptype
, "P15") || !strcmp (apptype
, "p15")))
286 err
= gpg_error (GPG_ERR_NOT_SUPPORTED
);
288 err
= card_open (&ctrl
->card_ctx
);
291 TEST_CARD_REMOVAL (ctrl
, err
);
292 return map_to_assuan_status (err
);
296 /* Do the percent and plus/space unescaping in place and return the
297 length of the valid buffer. */
299 percent_plus_unescape (unsigned char *string
)
301 unsigned char *p
= string
;
306 if (*string
== '%' && string
[1] && string
[2])
309 *p
++ = xtoi_2 (string
);
313 else if (*string
== '+')
331 /* SERIALNO [APPTYPE]
333 Return the serial number of the card using a status reponse. This
334 functon should be used to check for the presence of a card.
336 If APPTYPE is given, an application of that type is selected and an
337 error is returned if the application is not supported or available.
338 The default is to auto-select the application using a hardwired
339 preference system. Note, that a future extension to this function
340 may allow to specify a list and order of applications to try.
342 This function is special in that it can be used to reset the card.
343 Most other functions will return an error when a card change has
344 been detected and the use of this function is therefore required.
346 Background: We want to keep the client clear of handling card
347 changes between operations; i.e. the client can assume that all
348 operations are done on the same card unless he calls this function.
351 cmd_serialno (assuan_context_t ctx
, char *line
)
353 ctrl_t ctrl
= assuan_get_pointer (ctx
);
355 char *serial_and_stamp
;
359 /* Clear the remove flag so that the open_card is able to reread it. */
360 if (ctrl
->server_local
->card_removed
)
362 if ( IS_LOCKED (ctrl
) )
363 return gpg_error (GPG_ERR_EBUSY
);
367 if ((rc
= open_card (ctrl
, *line
? line
:NULL
)))
371 rc
= app_get_serial_and_stamp (ctrl
->app_ctx
, &serial
, &stamp
);
373 rc
= card_get_serial_and_stamp (ctrl
->card_ctx
, &serial
, &stamp
);
375 return map_to_assuan_status (rc
);
376 rc
= asprintf (&serial_and_stamp
, "%s %lu", serial
, (unsigned long)stamp
);
379 return ASSUAN_Out_Of_Core
;
381 assuan_write_status (ctx
, "SERIALNO", serial_and_stamp
);
382 free (serial_and_stamp
);
391 Learn all useful information of the currently inserted card. When
392 used without the force options, the command might do an INQUIRE
395 INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
397 The client should just send an "END" if the processing should go on
398 or a "CANCEL" to force the function to terminate with a Cancel
399 error message. The response of this command is a list of status
400 lines formatted as this:
404 This returns the type of the application, currently the strings:
406 P15 = PKCS-15 structure used
408 OPENPGP = OpenPGP card
410 are implemented. These strings are aliases for the AID
412 S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
414 If there is no certificate yet stored on the card a single "X" is
415 returned as the keygrip. In addition to the keypair info, information
416 about all certificates stored on the card is also returned:
418 S CERTINFO <certtype> <hexstring_with_id>
420 Where CERTTYPE is a number indicating the type of certificate:
422 100 := Regular X.509 cert
423 101 := Trusted X.509 cert
424 102 := Useful X.509 cert
425 110 := Root CA cert (DINSIG)
427 For certain cards, more information will be returned:
429 S KEY-FPR <no> <hexstring>
431 For OpenPGP cards this returns the stored fingerprints of the
432 keys. This can be used check whether a key is available on the
433 card. NO may be 1, 2 or 3.
435 S CA-FPR <no> <hexstring>
437 Similar to above, these are the fingerprints of keys assumed to be
440 S DISP-NAME <name_of_card_holder>
442 The name of the card holder as stored on the card; percent
443 escaping takes place, spaces are encoded as '+'
447 The URL to be used for locating the entire public key.
449 Note, that this function may be even be used on a locked card.
452 cmd_learn (assuan_context_t ctx
, char *line
)
454 ctrl_t ctrl
= assuan_get_pointer (ctx
);
458 if ((rc
= open_card (ctrl
, NULL
)))
461 /* Unless the force option is used we try a shortcut by identifying
462 the card using a serial number and inquiring the client with
463 that. The client may choose to cancel the operation if he already
464 knows about this card */
466 char *serial_and_stamp
;
471 rc
= app_get_serial_and_stamp (ctrl
->app_ctx
, &serial
, &stamp
);
473 rc
= card_get_serial_and_stamp (ctrl
->card_ctx
, &serial
, &stamp
);
475 return map_to_assuan_status (rc
);
476 rc
= asprintf (&serial_and_stamp
, "%s %lu", serial
, (unsigned long)stamp
);
479 return ASSUAN_Out_Of_Core
;
481 assuan_write_status (ctx
, "SERIALNO", serial_and_stamp
);
483 if (!has_option (line
, "--force"))
487 rc
= asprintf (&command
, "KNOWNCARDP %s", serial_and_stamp
);
490 free (serial_and_stamp
);
491 return ASSUAN_Out_Of_Core
;
494 rc
= assuan_inquire (ctx
, command
, NULL
, NULL
, 0);
495 free (command
); /* (must use standard free here) */
498 if (rc
!= ASSUAN_Canceled
)
499 log_error ("inquire KNOWNCARDP failed: %s\n",
500 assuan_strerror (rc
));
501 free (serial_and_stamp
);
504 /* not canceled, so we have to proceeed */
506 free (serial_and_stamp
);
509 /* If we are using the modern application paradigma, let the
510 application print out its collection of useful status
512 if (!rc
&& ctrl
->app_ctx
)
513 rc
= app_write_learn_status (ctrl
->app_ctx
, ctrl
);
515 /* Return information about the certificates. FIXME: Move this into
517 for (idx
=0; !rc
&& !ctrl
->app_ctx
; idx
++)
522 rc
= card_enum_certs (ctrl
->card_ctx
, idx
, &certid
, &certtype
);
527 buf
= xtrymalloc (40 + 1 + strlen (certid
) + 1);
529 rc
= gpg_error (gpg_err_code_from_errno (errno
));
532 sprintf (buf
, "%d %s", certtype
, certid
);
533 assuan_write_status (ctx
, "CERTINFO", buf
);
542 /* Return information about the keys. FIXME: Move this into an
544 for (idx
=0; !rc
&& !ctrl
->app_ctx
; idx
++)
546 unsigned char keygrip
[20];
550 rc
= card_enum_keypairs (ctrl
->card_ctx
, idx
, keygrip
, &keyid
);
551 if (gpg_err_code (rc
) == GPG_ERR_MISSING_CERT
&& keyid
)
553 /* This does happen with an incomplete personalized
554 card; i.e. during the time we have stored the key on the
555 card but not stored the certificate; probably becuase it
556 has not yet been received back from the CA. Note that we
557 must release KEYID in this case. */
565 buf
= p
= xtrymalloc (40 + 1 + strlen (keyid
) + 1);
567 rc
= gpg_error (gpg_err_code_from_errno (errno
));
576 for (i
=0; i
< 20; i
++, p
+= 2)
577 sprintf (p
, "%02X", keygrip
[i
]);
581 assuan_write_status (ctx
, "KEYPAIRINFO", buf
);
590 TEST_CARD_REMOVAL (ctrl
, rc
);
591 return map_to_assuan_status (rc
);
596 /* READCERT <hexified_certid>
598 Note, that this function may be even be used on a locked card.
601 cmd_readcert (assuan_context_t ctx
, char *line
)
603 ctrl_t ctrl
= assuan_get_pointer (ctx
);
608 if ((rc
= open_card (ctrl
, NULL
)))
611 line
= xstrdup (line
); /* Need a copy of the line. */
614 rc
= app_readcert (ctrl
->app_ctx
, line
, &cert
, &ncert
);
616 log_error ("app_readcert failed: %s\n", gpg_strerror (rc
));
620 rc
= card_read_cert (ctrl
->card_ctx
, line
, &cert
, &ncert
);
622 log_error ("card_read_cert failed: %s\n", gpg_strerror (rc
));
628 rc
= assuan_send_data (ctx
, cert
, ncert
);
634 TEST_CARD_REMOVAL (ctrl
, rc
);
635 return map_to_assuan_status (rc
);
639 /* READKEY <hexified_certid>
641 Return the public key for the given cert or key ID as an standard
644 Note, that this function may be even be used on a locked card.
647 cmd_readkey (assuan_context_t ctx
, char *line
)
649 ctrl_t ctrl
= assuan_get_pointer (ctx
);
651 unsigned char *cert
= NULL
;
653 ksba_cert_t kc
= NULL
;
656 if ((rc
= open_card (ctrl
, NULL
)))
659 line
= xstrdup (line
); /* Need a copy of the line. */
665 /* If the application supports the READKEY function we use that.
666 Otherwise we use the old way by extracting it from the
668 rc
= app_readkey (ctrl
->app_ctx
, line
, &pk
, &pklen
);
670 { /* Yeah, got that key - send it back. */
671 rc
= assuan_send_data (ctx
, pk
, pklen
);
673 rc
= map_assuan_err (rc
);
679 if (gpg_err_code (rc
) != GPG_ERR_UNSUPPORTED_OPERATION
)
680 log_error ("app_readkey failed: %s\n", gpg_strerror (rc
));
683 rc
= app_readcert (ctrl
->app_ctx
, line
, &cert
, &ncert
);
685 log_error ("app_readcert failed: %s\n", gpg_strerror (rc
));
690 rc
= card_read_cert (ctrl
->card_ctx
, line
, &cert
, &ncert
);
692 log_error ("card_read_cert failed: %s\n", gpg_strerror (rc
));
699 rc
= ksba_cert_new (&kc
);
705 rc
= ksba_cert_init_from_mem (kc
, cert
, ncert
);
708 log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc
));
712 p
= ksba_cert_get_public_key (kc
);
715 rc
= gpg_error (GPG_ERR_NO_PUBKEY
);
719 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
720 rc
= assuan_send_data (ctx
, p
, n
);
721 rc
= map_assuan_err (rc
);
726 ksba_cert_release (kc
);
728 TEST_CARD_REMOVAL (ctrl
, rc
);
729 return map_to_assuan_status (rc
);
735 /* SETDATA <hexstring>
737 The client should use this command to tell us the data he want to
740 cmd_setdata (assuan_context_t ctx
, char *line
)
742 ctrl_t ctrl
= assuan_get_pointer (ctx
);
747 if (locked_session
&& locked_session
!= ctrl
->server_local
)
748 return gpg_error (GPG_ERR_EBUSY
);
750 /* Parse the hexstring. */
751 for (p
=line
,n
=0; hexdigitp (p
); p
++, n
++)
754 return set_error (Parameter_Error
, "invalid hexstring");
756 return set_error (Parameter_Error
, "no data given");
758 return set_error (Parameter_Error
, "odd number of digits");
760 buf
= xtrymalloc (n
);
762 return ASSUAN_Out_Of_Core
;
764 ctrl
->in_data
.value
= buf
;
765 ctrl
->in_data
.valuelen
= n
;
766 for (p
=line
, n
=0; n
< ctrl
->in_data
.valuelen
; p
+= 2, n
++)
774 pin_cb (void *opaque
, const char *info
, char **retstr
)
776 assuan_context_t ctx
= opaque
;
779 unsigned char *value
;
783 log_debug ("asking for PIN '%s'\n", info
);
785 rc
= asprintf (&command
, "NEEDPIN %s", info
);
787 return gpg_error (gpg_err_code_from_errno (errno
));
789 /* FIXME: Write an inquire function which returns the result in
791 rc
= assuan_inquire (ctx
, command
, &value
, &valuelen
, MAXLEN_PIN
);
794 return map_assuan_err (rc
);
796 if (!valuelen
|| value
[valuelen
-1])
798 /* We require that the returned value is an UTF-8 string */
800 return gpg_error (GPG_ERR_INV_RESPONSE
);
807 /* PKSIGN <hexified_id>
811 cmd_pksign (assuan_context_t ctx
, char *line
)
813 ctrl_t ctrl
= assuan_get_pointer (ctx
);
815 unsigned char *outdata
;
819 if ( IS_LOCKED (ctrl
) )
820 return gpg_error (GPG_ERR_EBUSY
);
822 if ((rc
= open_card (ctrl
, NULL
)))
825 /* We have to use a copy of the key ID because the function may use
826 the pin_cb which in turn uses the assuan line buffer and thus
827 overwriting the original line with the keyid */
828 keyidstr
= xtrystrdup (line
);
830 return ASSUAN_Out_Of_Core
;
833 rc
= app_sign (ctrl
->app_ctx
,
834 keyidstr
, GCRY_MD_SHA1
,
836 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
837 &outdata
, &outdatalen
);
839 rc
= card_sign (ctrl
->card_ctx
,
840 keyidstr
, GCRY_MD_SHA1
,
842 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
843 &outdata
, &outdatalen
);
847 log_error ("card_sign failed: %s\n", gpg_strerror (rc
));
851 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
854 return rc
; /* that is already an assuan error code */
857 TEST_CARD_REMOVAL (ctrl
, rc
);
858 return map_to_assuan_status (rc
);
861 /* PKAUTH <hexified_id>
865 cmd_pkauth (assuan_context_t ctx
, char *line
)
867 ctrl_t ctrl
= assuan_get_pointer (ctx
);
869 unsigned char *outdata
;
873 if ( IS_LOCKED (ctrl
) )
874 return gpg_error (GPG_ERR_EBUSY
);
876 if ((rc
= open_card (ctrl
, NULL
)))
880 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
882 /* We have to use a copy of the key ID because the function may use
883 the pin_cb which in turn uses the assuan line buffer and thus
884 overwriting the original line with the keyid */
885 keyidstr
= xtrystrdup (line
);
887 return ASSUAN_Out_Of_Core
;
889 rc
= app_auth (ctrl
->app_ctx
,
892 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
893 &outdata
, &outdatalen
);
897 log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc
));
901 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
904 return rc
; /* that is already an assuan error code */
907 TEST_CARD_REMOVAL (ctrl
, rc
);
908 return map_to_assuan_status (rc
);
911 /* PKDECRYPT <hexified_id>
915 cmd_pkdecrypt (assuan_context_t ctx
, char *line
)
917 ctrl_t ctrl
= assuan_get_pointer (ctx
);
919 unsigned char *outdata
;
923 if ( IS_LOCKED (ctrl
) )
924 return gpg_error (GPG_ERR_EBUSY
);
926 if ((rc
= open_card (ctrl
, NULL
)))
929 keyidstr
= xtrystrdup (line
);
931 return ASSUAN_Out_Of_Core
;
933 rc
= app_decipher (ctrl
->app_ctx
,
936 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
937 &outdata
, &outdatalen
);
939 rc
= card_decipher (ctrl
->card_ctx
,
942 ctrl
->in_data
.value
, ctrl
->in_data
.valuelen
,
943 &outdata
, &outdatalen
);
947 log_error ("card_create_signature failed: %s\n", gpg_strerror (rc
));
951 rc
= assuan_send_data (ctx
, outdata
, outdatalen
);
954 return rc
; /* that is already an assuan error code */
957 TEST_CARD_REMOVAL (ctrl
, rc
);
958 return map_to_assuan_status (rc
);
964 This command is used to retrieve data from a smartcard. The
965 allowed names depend on the currently selected smartcard
966 application. NAME must be percent and '+' escaped. The value is
967 returned through status message, see the LEARN command for details.
969 However, the current implementation assumes that Name is not escaped;
970 this works as long as noone uses arbitrary escaping.
972 Note, that this function may even be used on a locked card.
975 cmd_getattr (assuan_context_t ctx
, char *line
)
977 ctrl_t ctrl
= assuan_get_pointer (ctx
);
981 if ((rc
= open_card (ctrl
, NULL
)))
985 for (; *line
&& !spacep (line
); line
++)
990 /* (We ignore any garbage for now.) */
992 /* FIXME: Applications should not return sensistive data if the card
994 rc
= app_getattr (ctrl
->app_ctx
, ctrl
, keyword
);
996 TEST_CARD_REMOVAL (ctrl
, rc
);
997 return map_to_assuan_status (rc
);
1001 /* SETATTR <name> <value>
1003 This command is used to store data on a a smartcard. The allowed
1004 names and values are depend on the currently selected smartcard
1005 application. NAME and VALUE must be percent and '+' escaped.
1007 However, the curent implementation assumes that Name is not escaped;
1008 this works as long as noone uses arbitrary escaping.
1010 A PIN will be requested for most NAMEs. See the corresponding
1011 setattr function of the actually used application (app-*.c) for
1014 cmd_setattr (assuan_context_t ctx
, char *orig_line
)
1016 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1021 char *line
, *linebuf
;
1023 if ( IS_LOCKED (ctrl
) )
1024 return gpg_error (GPG_ERR_EBUSY
);
1026 if ((rc
= open_card (ctrl
, NULL
)))
1029 /* We need to use a copy of LINE, because PIN_CB uses the same
1030 context and thus reuses the Assuan provided LINE. */
1031 line
= linebuf
= xtrystrdup (orig_line
);
1033 return ASSUAN_Out_Of_Core
;
1036 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
1040 while (spacep (line
))
1042 nbytes
= percent_plus_unescape (line
);
1044 rc
= app_setattr (ctrl
->app_ctx
, keyword
, pin_cb
, ctx
, line
, nbytes
);
1047 TEST_CARD_REMOVAL (ctrl
, rc
);
1048 return map_to_assuan_status (rc
);
1051 /* GENKEY [--force] <no>
1053 Generate a key on-card identified by NO, which is application
1054 specific. Return values are application specific. For OpenPGP
1055 cards 2 status lines are returned:
1057 S KEY-FPR <hexstring>
1058 S KEY-CREATED-AT <seconds_since_epoch>
1059 S KEY-DATA [p|n] <hexdata>
1062 --force is required to overwriet an already existing key. The
1063 KEY-CREATED-AT is required for further processing because it is
1064 part of the hashed key material for the fingerprint.
1066 The public part of the key can also later be retrieved using the
1071 cmd_genkey (assuan_context_t ctx
, char *line
)
1073 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1076 int force
= has_option (line
, "--force");
1078 if ( IS_LOCKED (ctrl
) )
1079 return gpg_error (GPG_ERR_EBUSY
);
1081 /* Skip over options. */
1082 while ( *line
== '-' && line
[1] == '-' )
1084 while (*line
&& !spacep (line
))
1086 while (spacep (line
))
1090 return set_error (Parameter_Error
, "no key number given");
1092 while (*line
&& !spacep (line
))
1096 if ((rc
= open_card (ctrl
, NULL
)))
1100 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1102 keyno
= xtrystrdup (keyno
);
1104 return ASSUAN_Out_Of_Core
;
1105 rc
= app_genkey (ctrl
->app_ctx
, ctrl
, keyno
, force
? 1:0, pin_cb
, ctx
);
1108 TEST_CARD_REMOVAL (ctrl
, rc
);
1109 return map_to_assuan_status (rc
);
1115 Get NBYTES of random from the card and send them back as data.
1117 Note, that this function may be even be used on a locked card.
1120 cmd_random (assuan_context_t ctx
, char *line
)
1122 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1125 unsigned char *buffer
;
1128 return set_error (Parameter_Error
, "number of requested bytes missing");
1129 nbytes
= strtoul (line
, NULL
, 0);
1131 if ((rc
= open_card (ctrl
, NULL
)))
1135 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1137 buffer
= xtrymalloc (nbytes
);
1139 return ASSUAN_Out_Of_Core
;
1141 rc
= app_get_challenge (ctrl
->app_ctx
, nbytes
, buffer
);
1144 rc
= assuan_send_data (ctx
, buffer
, nbytes
);
1146 return rc
; /* that is already an assuan error code */
1150 TEST_CARD_REMOVAL (ctrl
, rc
);
1151 return map_to_assuan_status (rc
);
1155 /* PASSWD [--reset] <chvno>
1157 Change the PIN or reset thye retry counter of the card holder
1158 verfication vector CHVNO. */
1160 cmd_passwd (assuan_context_t ctx
, char *line
)
1162 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1165 int reset_mode
= has_option (line
, "--reset");
1167 if ( IS_LOCKED (ctrl
) )
1168 return gpg_error (GPG_ERR_EBUSY
);
1170 /* Skip over options. */
1171 while (*line
== '-' && line
[1] == '-')
1173 while (*line
&& !spacep (line
))
1175 while (spacep (line
))
1179 return set_error (Parameter_Error
, "no CHV number given");
1181 while (*line
&& !spacep (line
))
1185 if ((rc
= open_card (ctrl
, NULL
)))
1189 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1191 chvnostr
= xtrystrdup (chvnostr
);
1193 return ASSUAN_Out_Of_Core
;
1194 rc
= app_change_pin (ctrl
->app_ctx
, ctrl
, chvnostr
, reset_mode
, pin_cb
, ctx
);
1196 log_error ("command passwd failed: %s\n", gpg_strerror (rc
));
1199 TEST_CARD_REMOVAL (ctrl
, rc
);
1200 return map_to_assuan_status (rc
);
1204 /* CHECKPIN <hexified_id>
1208 cmd_checkpin (assuan_context_t ctx
, char *line
)
1210 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1214 if ( IS_LOCKED (ctrl
) )
1215 return gpg_error (GPG_ERR_EBUSY
);
1217 if ((rc
= open_card (ctrl
, NULL
)))
1221 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
1223 /* We have to use a copy of the key ID because the function may use
1224 the pin_cb which in turn uses the assuan line buffer and thus
1225 overwriting the original line with the keyid. */
1226 keyidstr
= xtrystrdup (line
);
1228 return ASSUAN_Out_Of_Core
;
1230 rc
= app_check_pin (ctrl
->app_ctx
,
1235 log_error ("app_check_pin failed: %s\n", gpg_strerror (rc
));
1237 TEST_CARD_REMOVAL (ctrl
, rc
);
1238 return map_to_assuan_status (rc
);
1244 Grant exclusive card access to this session. Note that there is
1245 no lock counter used and a second lock from the same session will
1246 get ignore. A single unlock (or RESET) unlocks the session.
1247 Return GPG_ERR_EBUSY if another session has locked the reader.
1249 If the option --wait is given the command will wait until a
1250 lock has been released.
1253 cmd_lock (assuan_context_t ctx
, char *line
)
1255 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1261 if (locked_session
!= ctrl
->server_local
)
1262 rc
= gpg_error (GPG_ERR_EBUSY
);
1265 locked_session
= ctrl
->server_local
;
1268 if (rc
&& has_option (line
, "--wait"))
1270 pth_sleep (1); /* Better implement an event mechanism. However,
1271 for card operations this should be
1275 #endif /*USE_GNU_PTH*/
1278 log_error ("cmd_lock failed: %s\n", gpg_strerror (rc
));
1279 return map_to_assuan_status (rc
);
1285 Release exclusive card access.
1288 cmd_unlock (assuan_context_t ctx
, char *line
)
1290 ctrl_t ctrl
= assuan_get_pointer (ctx
);
1295 if (locked_session
!= ctrl
->server_local
)
1296 rc
= gpg_error (GPG_ERR_EBUSY
);
1298 locked_session
= NULL
;
1301 rc
= gpg_error (GPG_ERR_NOT_LOCKED
);
1304 log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc
));
1305 return map_to_assuan_status (rc
);
1312 /* Tell the assuan library about our commands */
1314 register_commands (assuan_context_t ctx
)
1318 int (*handler
)(assuan_context_t
, char *line
);
1320 { "SERIALNO", cmd_serialno
},
1321 { "LEARN", cmd_learn
},
1322 { "READCERT", cmd_readcert
},
1323 { "READKEY", cmd_readkey
},
1324 { "SETDATA", cmd_setdata
},
1325 { "PKSIGN", cmd_pksign
},
1326 { "PKAUTH", cmd_pkauth
},
1327 { "PKDECRYPT", cmd_pkdecrypt
},
1330 { "GETATTR", cmd_getattr
},
1331 { "SETATTR", cmd_setattr
},
1332 { "GENKEY", cmd_genkey
},
1333 { "RANDOM", cmd_random
},
1334 { "PASSWD", cmd_passwd
},
1335 { "CHECKPIN", cmd_checkpin
},
1336 { "LOCK", cmd_lock
},
1337 { "UNLOCK", cmd_unlock
},
1342 for (i
=0; table
[i
].name
; i
++)
1344 rc
= assuan_register_command (ctx
, table
[i
].name
, table
[i
].handler
);
1348 assuan_set_hello_line (ctx
, "GNU Privacy Guard's Smartcard server ready");
1350 assuan_register_reset_notify (ctx
, reset_notify
);
1351 assuan_register_option_handler (ctx
, option_handler
);
1356 /* Startup the server. If LISTEN_FD is given as -1, this is simple
1357 piper server, otherwise it is a regular server */
1359 scd_command_handler (int listen_fd
)
1362 assuan_context_t ctx
;
1363 struct server_control_s ctrl
;
1365 memset (&ctrl
, 0, sizeof ctrl
);
1366 scd_init_default_ctrl (&ctrl
);
1368 if (listen_fd
== -1)
1374 rc
= assuan_init_pipe_server (&ctx
, filedes
);
1378 rc
= assuan_init_socket_server (&ctx
, listen_fd
);
1382 log_error ("failed to initialize the server: %s\n",
1383 assuan_strerror(rc
));
1386 rc
= register_commands (ctx
);
1389 log_error ("failed to register commands with Assuan: %s\n",
1390 assuan_strerror(rc
));
1393 assuan_set_pointer (ctx
, &ctrl
);
1395 /* Allocate and initialize the server object. Put it into the list
1396 of active sessions. */
1397 ctrl
.server_local
= xcalloc (1, sizeof *ctrl
.server_local
);
1398 ctrl
.server_local
->next_session
= session_list
;
1399 session_list
= ctrl
.server_local
;
1400 ctrl
.server_local
->ctrl_backlink
= &ctrl
;
1401 ctrl
.server_local
->assuan_ctx
= ctx
;
1404 assuan_set_log_stream (ctx
, log_get_stream ());
1406 /* We open the reader right at startup so that the ticker is able to
1407 update the status file. */
1408 if (ctrl
.reader_slot
== -1)
1410 ctrl
.reader_slot
= get_reader_slot ();
1413 /* Command processing loop. */
1416 rc
= assuan_accept (ctx
);
1423 log_info ("Assuan accept problem: %s\n", assuan_strerror (rc
));
1427 rc
= assuan_process (ctx
);
1430 log_info ("Assuan processing failed: %s\n", assuan_strerror (rc
));
1436 do_reset (&ctrl
, 1);
1438 /* Release the server object. */
1439 if (session_list
== ctrl
.server_local
)
1440 session_list
= ctrl
.server_local
->next_session
;
1443 struct server_local_s
*sl
;
1445 for (sl
=session_list
; sl
->next_session
; sl
= sl
->next_session
)
1446 if (sl
->next_session
== ctrl
.server_local
)
1448 if (!sl
->next_session
)
1450 sl
->next_session
= ctrl
.server_local
->next_session
;
1452 xfree (ctrl
.server_local
);
1454 /* Release the Assuan context. */
1455 assuan_deinit_server (ctx
);
1459 /* Send a line with status information via assuan and escape all given
1460 buffers. The variable elements are pairs of (char *, size_t),
1461 terminated with a (NULL, 0). */
1463 send_status_info (ctrl_t ctrl
, const char *keyword
, ...)
1466 const unsigned char *value
;
1470 assuan_context_t ctx
= ctrl
->server_local
->assuan_ctx
;
1472 va_start (arg_ptr
, keyword
);
1476 while ( (value
= va_arg (arg_ptr
, const unsigned char *)) )
1478 valuelen
= va_arg (arg_ptr
, size_t);
1480 continue; /* empty buffer */
1486 for ( ; valuelen
&& n
< DIM (buf
)-2; n
++, valuelen
--, value
++)
1488 if (*value
< ' ' || *value
== '+')
1490 sprintf (p
, "%%%02X", *value
);
1493 else if (*value
== ' ')
1500 assuan_write_status (ctx
, keyword
, buf
);
1506 /* This function is called by the ticker thread to check for changes
1507 of the reader stati. It updates the reader status files and if
1508 requested by the caller also send a signal to the caller. */
1510 scd_update_reader_status_file (void)
1514 unsigned int status
;
1515 unsigned int changed
;
1519 unsigned int status
, changed
;
1521 /* Note, that we only try to get the status, because it does not
1522 make sense to wait here for a operation to complete. If we are
1523 busy working with a card, delays in the status file update should
1525 for (slot
=0; (slot
< DIM(last
)
1526 &&!apdu_enum_reader (slot
, &used
)); slot
++)
1527 if (used
&& !apdu_get_status (slot
, 0, &status
, &changed
))
1529 if (!last
[slot
].any
|| last
[slot
].status
!= status
1530 || last
[slot
].changed
!= changed
)
1535 struct server_local_s
*sl
;
1537 log_info ("updating status of slot %d to 0x%04X\n", slot
, status
);
1539 sprintf (templ
, "reader_%d.status", slot
);
1540 fname
= make_filename (opt
.homedir
, templ
, NULL
);
1541 fp
= fopen (fname
, "w");
1544 fprintf (fp
, "%s\n",
1545 (status
& 1)? "USABLE":
1546 (status
& 4)? "ACTIVE":
1547 (status
& 2)? "PRESENT": "NOCARD");
1552 /* Set the card removed flag for all current sessions. We
1553 will set this on any card change because a reset or
1554 SERIALNO request must be done in any case. */
1556 update_card_removed (slot
, 1);
1559 last
[slot
].status
= status
;
1560 last
[slot
].changed
= changed
;
1563 /* Send a signal to all clients who applied for it. */
1564 for (sl
=session_list
; sl
; sl
= sl
->next_session
)
1565 if (sl
->event_signal
&& sl
->assuan_ctx
)
1567 pid_t pid
= assuan_get_pid (sl
->assuan_ctx
);
1568 int signo
= sl
->event_signal
;
1570 log_info ("client pid is %d, sending signal %d\n",
1572 #ifndef HAVE_W32_SYSTEM
1573 if (pid
!= (pid_t
)(-1) && pid
&& signo
> 0)