1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-06-15 18:41:03 +02:00

scd: Split data structures into app and card related objects.

* scd/app-common.h (struct card_ctx_s): New.
(struct app_ctx_s): Factor card specific fields out to card_ctx_s.
(app_get_slot): New.
* scd/scdaemon.h (card_t): New.
(struct server_control_s): Rename field app_ctx to card_ctx and change
all users.
* scd/app-dinsig.c: Use app_get_slot and adjust for chang in card
related fields.
* scd/app-geldkarte.c: Ditto.
* scd/app-nks.c: Ditto.
* scd/app-openpgp.c: Ditto.
* scd/app-p15.c: Ditto.
* scd/app-sc-hsm.c: Ditto.
* scd/app.c: Lost of changes to adjust for the changed data
structures.  Change all callers.
(app_list_lock): Rename to card_list_lock.
(app_top): Remove.
(card_top): New.
(lock_app): Rename to lock_card and change arg type.
(unlock_app): Rename to unlock_card.
(app_dump_state): Print card and app info.
(app_reset): Rename to card_reset.
(app_new_register): Change for the new data structure.
(deallocate_card): Dealloc card and all apps.
(app_ref): Rename to card_ref.
(app_unref): Rename to card_unref.
(app_unref_locked): Rename to card_unref_locked.
(card_get_serialno): New.
* scd/command.c (cmd_pkdecrypt): Actually use the looked up card and
former app object and not the standard one from the context.
--

Although quite large, this is a straightforward change to separate
card/token related data from card application related data.  Before
this change there was a one-to-one relation between card and
application and no way to represent several applications on a card.
The new data structure will allow for such a representation.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-06-19 08:50:40 +02:00
parent c3dd53a65d
commit 5a5288d051
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
11 changed files with 774 additions and 617 deletions

View File

@ -46,29 +46,53 @@
struct app_local_s; /* Defined by all app-*.c. */ struct app_local_s; /* Defined by all app-*.c. */
struct app_ctx_s {
struct app_ctx_s *next; /* The object describing a card. */
struct card_ctx_s {
struct card_ctx_s *next;
npth_mutex_t lock; npth_mutex_t lock;
/* Number of connections currently using this application context. /* Number of connections currently using this application context. */
If this is not 0 the application has been initialized and the
function pointers may be used. Note that for unsupported
operations the particular function pointer is set to NULL */
unsigned int ref_count; unsigned int ref_count;
/* Used reader slot. */ /* Used reader slot. */
int slot; int slot;
const char *cardtype; /* NULL or string with the token's type. */
unsigned int cardversion;/* Firmware version of the token or 0. */
unsigned int card_status;
/* The serial number is associated with the card and not with a
* specific app. If a card uses different serial numbers for its
* applications, our code picks the serial number of a specific
* application and uses that. */
unsigned char *serialno; /* Serialnumber in raw form, allocated. */ unsigned char *serialno; /* Serialnumber in raw form, allocated. */
size_t serialnolen; /* Length in octets of serialnumber. */ size_t serialnolen; /* Length in octets of serialnumber. */
const char *cardtype; /* NULL or string with the token's type. */
const char *apptype; /* A linked list of applications used on this card. The app at the
unsigned int cardversion;/* Firmware version of the token or 0. */ * head of the list is the currently active app; To work with the
unsigned int appversion; /* Version of the application or 0. */ * other apps, switching to that app might be needed. Switching will
unsigned int card_status; * put the active app at the head of the list. */
app_t app;
/* Various flags. */
unsigned int reset_requested:1; unsigned int reset_requested:1;
unsigned int periodical_check_needed:1; unsigned int periodical_check_needed:1;
};
/* The object describing a card's applications. A card may have
* several applications and it is usuallay required to explicity
* switch between applications. */
struct app_ctx_s {
struct app_ctx_s *next;
card_t card; /* Link back to the card. */
const char *apptype;
unsigned int appversion; /* Version of the application or 0. */
unsigned int did_chv1:1; unsigned int did_chv1:1;
unsigned int force_chv1:1; /* True if the card does not cache CHV1. */ unsigned int force_chv1:1; /* True if the card does not cache CHV1. */
unsigned int did_chv2:1; unsigned int did_chv2:1;
@ -141,6 +165,16 @@ enum
}; };
/* Helper to get the slot from an APP object. */
static inline int
app_get_slot (app_t app)
{
if (app && app->card)
return app->card->slot;
return -1;
}
/*-- app-help.c --*/ /*-- app-help.c --*/
unsigned int app_help_count_bits (const unsigned char *a, size_t len); unsigned int app_help_count_bits (const unsigned char *a, size_t len);
gpg_error_t app_help_get_keygrip_string_pk (const void *pk, size_t pklen, gpg_error_t app_help_get_keygrip_string_pk (const void *pk, size_t pklen,
@ -154,75 +188,77 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff);
/*-- app.c --*/ /*-- app.c --*/
void app_update_priority_list (const char *arg); void app_update_priority_list (const char *arg);
void app_send_card_list (ctrl_t ctrl); void app_send_card_list (ctrl_t ctrl);
char *card_get_serialno (card_t card);
char *app_get_serialno (app_t app); char *app_get_serialno (app_t app);
void app_dump_state (void); void app_dump_state (void);
void application_notify_card_reset (int slot); void application_notify_card_reset (int slot);
gpg_error_t check_application_conflict (const char *name, app_t app); gpg_error_t check_application_conflict (const char *name, card_t card);
gpg_error_t app_reset (app_t app, ctrl_t ctrl, int send_reset); gpg_error_t card_reset (card_t card, ctrl_t ctrl, int send_reset);
gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app, gpg_error_t select_application (ctrl_t ctrl, const char *name, card_t *r_app,
int scan, const unsigned char *serialno_bin, int scan, const unsigned char *serialno_bin,
size_t serialno_bin_len); size_t serialno_bin_len);
char *get_supported_applications (void); char *get_supported_applications (void);
app_t app_ref (app_t app); card_t card_ref (card_t card);
void app_unref (app_t app); void card_unref (card_t card);
void app_unref_locked (app_t app); void card_unref_locked (card_t card);
gpg_error_t app_munge_serialno (app_t app); gpg_error_t app_munge_serialno (card_t card);
gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl, gpg_error_t app_write_learn_status (card_t card, ctrl_t ctrl,
unsigned int flags); unsigned int flags);
gpg_error_t app_readcert (app_t app, ctrl_t ctrl, const char *certid, gpg_error_t app_readcert (card_t card, ctrl_t ctrl, const char *certid,
unsigned char **cert, size_t *certlen); unsigned char **cert, size_t *certlen);
gpg_error_t app_readkey (app_t app, ctrl_t ctrl, gpg_error_t app_readkey (card_t card, ctrl_t ctrl,
const char *keyid, unsigned int flags, const char *keyid, unsigned int flags,
unsigned char **pk, size_t *pklen); unsigned char **pk, size_t *pklen);
gpg_error_t app_getattr (app_t app, ctrl_t ctrl, const char *name); gpg_error_t app_getattr (card_t card, ctrl_t ctrl, const char *name);
gpg_error_t app_setattr (app_t app, ctrl_t ctrl, const char *name, gpg_error_t app_setattr (card_t card, ctrl_t ctrl, const char *name,
gpg_error_t (*pincb)(void*, const char *, char **), gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg, void *pincb_arg,
const unsigned char *value, size_t valuelen); const unsigned char *value, size_t valuelen);
gpg_error_t app_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, gpg_error_t app_sign (card_t card, ctrl_t ctrl,
gpg_error_t (*pincb)(void*, const char *, char **), const char *keyidstr, int hashalgo,
void *pincb_arg,
const void *indata, size_t indatalen,
unsigned char **outdata, size_t *outdatalen );
gpg_error_t app_auth (app_t app, ctrl_t ctrl, const char *keyidstr,
gpg_error_t (*pincb)(void*, const char *, char **), gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg, void *pincb_arg,
const void *indata, size_t indatalen, const void *indata, size_t indatalen,
unsigned char **outdata, size_t *outdatalen); unsigned char **outdata, size_t *outdatalen);
gpg_error_t app_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t app_auth (card_t card, ctrl_t ctrl, const char *keyidstr,
gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
unsigned char **outdata, size_t *outdatalen);
gpg_error_t app_decipher (card_t card, ctrl_t ctrl, const char *keyidstr,
gpg_error_t (*pincb)(void*, const char *, char **), gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg, void *pincb_arg,
const void *indata, size_t indatalen, const void *indata, size_t indatalen,
unsigned char **outdata, size_t *outdatalen, unsigned char **outdata, size_t *outdatalen,
unsigned int *r_info); unsigned int *r_info);
gpg_error_t app_writecert (app_t app, ctrl_t ctrl, gpg_error_t app_writecert (card_t card, ctrl_t ctrl,
const char *certidstr, const char *certidstr,
gpg_error_t (*pincb)(void*, const char *, char **), gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg, void *pincb_arg,
const unsigned char *keydata, size_t keydatalen); const unsigned char *keydata, size_t keydatalen);
gpg_error_t app_writekey (app_t app, ctrl_t ctrl, gpg_error_t app_writekey (card_t card, ctrl_t ctrl,
const char *keyidstr, unsigned int flags, const char *keyidstr, unsigned int flags,
gpg_error_t (*pincb)(void*, const char *, char **), gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg, void *pincb_arg,
const unsigned char *keydata, size_t keydatalen); const unsigned char *keydata, size_t keydatalen);
gpg_error_t app_genkey (app_t app, ctrl_t ctrl, gpg_error_t app_genkey (card_t card, ctrl_t ctrl,
const char *keynostr, const char *keytype, const char *keynostr, const char *keytype,
unsigned int flags, time_t createtime, unsigned int flags, time_t createtime,
gpg_error_t (*pincb)(void*, const char *, char **), gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg); void *pincb_arg);
gpg_error_t app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, gpg_error_t app_get_challenge (card_t card, ctrl_t ctrl, size_t nbytes,
unsigned char *buffer); unsigned char *buffer);
gpg_error_t app_change_pin (app_t app, ctrl_t ctrl, gpg_error_t app_change_pin (card_t card, ctrl_t ctrl,
const char *chvnostr, unsigned int flags, const char *chvnostr, unsigned int flags,
gpg_error_t (*pincb)(void*, const char *, char **), gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg); void *pincb_arg);
gpg_error_t app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t app_check_pin (card_t card, ctrl_t ctrl, const char *keyidstr,
gpg_error_t (*pincb)(void*, const char *, char **), gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg); void *pincb_arg);
app_t app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str); card_t app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str);
/*-- app-openpgp.c --*/ /*-- app-openpgp.c --*/

View File

@ -101,7 +101,7 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
/* Return the certificate of the card holder. */ /* Return the certificate of the card holder. */
fid = 0xC000; fid = 0xC000;
len = app_help_read_length_of_cert (app->slot, fid, &certoff); len = app_help_read_length_of_cert (app_get_slot (app), fid, &certoff);
if (!len) if (!len)
return 0; /* Card has not been personalized. */ return 0; /* Card has not been personalized. */
@ -114,7 +114,8 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
/* Now we need to read the certificate, so that we can get the /* Now we need to read the certificate, so that we can get the
public key out of it. */ public key out of it. */
err = iso7816_read_binary (app->slot, certoff, len-certoff, &der, &derlen); err = iso7816_read_binary (app_get_slot (app), certoff, len-certoff,
&der, &derlen);
if (err) if (err)
{ {
log_info ("error reading entire certificate from FID 0x%04X: %s\n", log_info ("error reading entire certificate from FID 0x%04X: %s\n",
@ -193,14 +194,14 @@ do_readcert (app_t app, const char *certid,
/* Read the entire file. fixme: This could be optimized by first /* Read the entire file. fixme: This could be optimized by first
reading the header to figure out how long the certificate reading the header to figure out how long the certificate
actually is. */ actually is. */
err = iso7816_select_file (app->slot, fid, 0); err = iso7816_select_file (app_get_slot (app), fid, 0);
if (err) if (err)
{ {
log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err)); log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
return err; return err;
} }
err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); err = iso7816_read_binary (app_get_slot (app), 0, 0, &buffer, &buflen);
if (err) if (err)
{ {
log_error ("error reading certificate from FID 0x%04X: %s\n", log_error ("error reading certificate from FID 0x%04X: %s\n",
@ -293,7 +294,7 @@ verify_pin (app_t app,
pininfo.maxlen = 8; pininfo.maxlen = 8;
if (!opt.disable_pinpad if (!opt.disable_pinpad
&& !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) ) && !iso7816_check_pinpad (app_get_slot (app), ISO7816_VERIFY, &pininfo) )
{ {
rc = pincb (pincb_arg, rc = pincb (pincb_arg,
_("||Please enter your PIN at the reader's pinpad"), _("||Please enter your PIN at the reader's pinpad"),
@ -304,7 +305,7 @@ verify_pin (app_t app,
gpg_strerror (rc)); gpg_strerror (rc));
return rc; return rc;
} }
rc = iso7816_verify_kp (app->slot, 0x81, &pininfo); rc = iso7816_verify_kp (app_get_slot (app), 0x81, &pininfo);
/* Dismiss the prompt. */ /* Dismiss the prompt. */
pincb (pincb_arg, NULL, NULL); pincb (pincb_arg, NULL, NULL);
} }
@ -345,7 +346,8 @@ verify_pin (app_t app,
return gpg_error (GPG_ERR_BAD_PIN); return gpg_error (GPG_ERR_BAD_PIN);
} }
rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); rc = iso7816_verify (app_get_slot (app), 0x81,
pinvalue, strlen (pinvalue));
if (gpg_err_code (rc) == GPG_ERR_INV_VALUE) if (gpg_err_code (rc) == GPG_ERR_INV_VALUE)
{ {
/* We assume that ISO 9564-1 encoding is used and we failed /* We assume that ISO 9564-1 encoding is used and we failed
@ -366,7 +368,8 @@ verify_pin (app_t app,
paddedpin[i++] = (((*s - '0') << 4) | 0x0f); paddedpin[i++] = (((*s - '0') << 4) | 0x0f);
while (i < sizeof paddedpin) while (i < sizeof paddedpin)
paddedpin[i++] = 0xff; paddedpin[i++] = 0xff;
rc = iso7816_verify (app->slot, 0x81, paddedpin, sizeof paddedpin); rc = iso7816_verify (app_get_slot (app), 0x81,
paddedpin, sizeof paddedpin);
} }
xfree (pinvalue); xfree (pinvalue);
} }
@ -482,7 +485,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
rc = verify_pin (app, pincb, pincb_arg); rc = verify_pin (app, pincb, pincb_arg);
if (!rc) if (!rc)
rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0, rc = iso7816_compute_ds (app_get_slot (app), 0, data, datalen, 0,
outdata, outdatalen); outdata, outdatalen);
return rc; return rc;
} }
@ -532,7 +535,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
return err; return err;
} }
err = iso7816_change_reference_data (app->slot, 0x81, err = iso7816_change_reference_data (app_get_slot (app), 0x81,
oldpin, oldpinlen, oldpin, oldpinlen,
pinvalue, strlen (pinvalue)); pinvalue, strlen (pinvalue));
xfree (pinvalue); xfree (pinvalue);
@ -547,7 +550,7 @@ gpg_error_t
app_select_dinsig (app_t app) app_select_dinsig (app_t app)
{ {
static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 }; static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
int slot = app->slot; int slot = app_get_slot (app);
int rc; int rc;
rc = iso7816_select_application (slot, aid, sizeof aid, 0); rc = iso7816_select_application (slot, aid, sizeof aid, 0);

View File

@ -277,7 +277,7 @@ app_select_geldkarte (app_t app)
static char const aid[] = static char const aid[] =
{ 0xD2, 0x76, 0x00, 0x00, 0x25, 0x45, 0x50, 0x02, 0x00 }; { 0xD2, 0x76, 0x00, 0x00, 0x25, 0x45, 0x50, 0x02, 0x00 };
gpg_error_t err; gpg_error_t err;
int slot = app->slot; int slot = app_get_slot (app);
unsigned char *result = NULL; unsigned char *result = NULL;
size_t resultlen; size_t resultlen;
struct app_local_s *ld; struct app_local_s *ld;
@ -316,17 +316,17 @@ app_select_geldkarte (app_t app)
app->fnc.deinit = do_deinit; app->fnc.deinit = do_deinit;
/* If we don't have a serialno yet construct it from the EF_ID. */ /* If we don't have a serialno yet construct it from the EF_ID. */
if (!app->serialno) if (!app->card->serialno)
{ {
app->serialno = xtrymalloc (10); app->card->serialno = xtrymalloc (10);
if (!app->serialno) if (!app->card->serialno)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
goto leave; goto leave;
} }
memcpy (app->serialno, result, 10); memcpy (app->card->serialno, result, 10);
app->serialnolen = 10; app->card->serialnolen = 10;
err = app_munge_serialno (app); err = app_munge_serialno (app->card);
if (err) if (err)
goto leave; goto leave;
} }

View File

@ -151,13 +151,15 @@ keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr)
int i; int i;
int offset[2] = { 0, 0 }; int offset[2] = { 0, 0 };
err = iso7816_select_file (app->slot, fid, 0); err = iso7816_select_file (app_get_slot (app), fid, 0);
if (err) if (err)
return err; return err;
err = iso7816_read_record (app->slot, 1, 1, 0, &buffer[0], &buflen[0]); err = iso7816_read_record (app_get_slot (app), 1, 1, 0,
&buffer[0], &buflen[0]);
if (err) if (err)
return err; return err;
err = iso7816_read_record (app->slot, 2, 1, 0, &buffer[1], &buflen[1]); err = iso7816_read_record (app_get_slot (app), 2, 1, 0,
&buffer[1], &buflen[1]);
if (err) if (err)
{ {
xfree (buffer[0]); xfree (buffer[0]);
@ -272,7 +274,7 @@ get_chv_status (app_t app, int sigg, int pwid)
command[2] = 0x00; command[2] = 0x00;
command[3] = pwid; command[3] = pwid;
if (apdu_send_direct (app->slot, 0, (unsigned char *)command, if (apdu_send_direct (app_get_slot (app), 0, (unsigned char *)command,
4, 0, NULL, &result, &resultlen)) 4, 0, NULL, &result, &resultlen))
rc = -1; /* Error. */ rc = -1; /* Error. */
else if (resultlen < 2) else if (resultlen < 2)
@ -406,7 +408,7 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int is_sigg)
{ {
size_t len; size_t len;
len = app_help_read_length_of_cert (app->slot, len = app_help_read_length_of_cert (app_get_slot (app),
filelist[i].fid, NULL); filelist[i].fid, NULL);
if (len) if (len)
{ {
@ -528,14 +530,14 @@ do_readcert (app_t app, const char *certid,
/* Read the entire file. fixme: This could be optimized by first /* Read the entire file. fixme: This could be optimized by first
reading the header to figure out how long the certificate reading the header to figure out how long the certificate
actually is. */ actually is. */
err = iso7816_select_file (app->slot, fid, 0); err = iso7816_select_file (app_get_slot (app), fid, 0);
if (err) if (err)
{ {
log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err)); log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
return err; return err;
} }
err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); err = iso7816_read_binary (app_get_slot (app), 0, 0, &buffer, &buflen);
if (err) if (err)
{ {
log_error ("error reading certificate from FID 0x%04X: %s\n", log_error ("error reading certificate from FID 0x%04X: %s\n",
@ -633,13 +635,14 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyid, unsigned int flags,
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
/* Access the KEYD file which is always in the master directory. */ /* Access the KEYD file which is always in the master directory. */
err = iso7816_select_path (app->slot, path, DIM (path)); err = iso7816_select_path (app_get_slot (app), path, DIM (path));
if (err) if (err)
return err; return err;
/* Due to the above select we need to re-select our application. */ /* Due to the above select we need to re-select our application. */
app->app_local->need_app_select = 1; app->app_local->need_app_select = 1;
/* Get the two records. */ /* Get the two records. */
err = iso7816_read_record (app->slot, 5, 1, 0, &buffer[0], &buflen[0]); err = iso7816_read_record (app_get_slot (app), 5, 1, 0,
&buffer[0], &buflen[0]);
if (err) if (err)
return err; return err;
if (all_zero_p (buffer[0], buflen[0])) if (all_zero_p (buffer[0], buflen[0]))
@ -647,7 +650,8 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyid, unsigned int flags,
xfree (buffer[0]); xfree (buffer[0]);
return gpg_error (GPG_ERR_NOT_FOUND); return gpg_error (GPG_ERR_NOT_FOUND);
} }
err = iso7816_read_record (app->slot, 6, 1, 0, &buffer[1], &buflen[1]); err = iso7816_read_record (app_get_slot (app), 6, 1, 0,
&buffer[1], &buflen[1]);
if (err) if (err)
{ {
xfree (buffer[0]); xfree (buffer[0]);
@ -760,7 +764,7 @@ do_writekey (app_t app, ctrl_t ctrl,
/* mse[10] = 0x82; /\* RSA public exponent of up to 4 bytes. *\/ */ /* mse[10] = 0x82; /\* RSA public exponent of up to 4 bytes. *\/ */
/* mse[12] = rsa_e_len; */ /* mse[12] = rsa_e_len; */
/* memcpy (mse+12, rsa_e, rsa_e_len); */ /* memcpy (mse+12, rsa_e, rsa_e_len); */
/* err = iso7816_manage_security_env (app->slot, 0x81, 0xB6, */ /* err = iso7816_manage_security_env (app_get_slot (app), 0x81, 0xB6, */
/* mse, sizeof mse); */ /* mse, sizeof mse); */
leave: leave:
@ -803,7 +807,7 @@ verify_pin (app_t app, int pwid, const char *desc,
pininfo.maxlen = 16; pininfo.maxlen = 16;
if (!opt.disable_pinpad if (!opt.disable_pinpad
&& !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) ) && !iso7816_check_pinpad (app_get_slot (app), ISO7816_VERIFY, &pininfo) )
{ {
rc = pincb (pincb_arg, desc, NULL); rc = pincb (pincb_arg, desc, NULL);
if (rc) if (rc)
@ -813,7 +817,7 @@ verify_pin (app_t app, int pwid, const char *desc,
return rc; return rc;
} }
rc = iso7816_verify_kp (app->slot, pwid, &pininfo); rc = iso7816_verify_kp (app_get_slot (app), pwid, &pininfo);
pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */
} }
else else
@ -834,7 +838,8 @@ verify_pin (app_t app, int pwid, const char *desc,
return rc; return rc;
} }
rc = iso7816_verify (app->slot, pwid, pinvalue, strlen (pinvalue)); rc = iso7816_verify (app_get_slot (app), pwid,
pinvalue, strlen (pinvalue));
xfree (pinvalue); xfree (pinvalue);
} }
@ -972,7 +977,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
mse[3] = 0x84; /* Private key reference. */ mse[3] = 0x84; /* Private key reference. */
mse[4] = 1; mse[4] = 1;
mse[5] = kid; mse[5] = kid;
rc = iso7816_manage_security_env (app->slot, 0x41, 0xB6, rc = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xB6,
mse, sizeof mse); mse, sizeof mse);
} }
/* Verify using PW1.CH. */ /* Verify using PW1.CH. */
@ -980,7 +985,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
rc = verify_pin (app, 0, NULL, pincb, pincb_arg); rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
/* Compute the signature. */ /* Compute the signature. */
if (!rc) if (!rc)
rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0, rc = iso7816_compute_ds (app_get_slot (app), 0, data, datalen, 0,
outdata, outdatalen); outdata, outdatalen);
return rc; return rc;
} }
@ -1047,7 +1052,7 @@ do_decipher (app_t app, const char *keyidstr,
mse[3] = 0x84; /* Private key reference. */ mse[3] = 0x84; /* Private key reference. */
mse[4] = 1; mse[4] = 1;
mse[5] = kid; mse[5] = kid;
rc = iso7816_manage_security_env (app->slot, 0x41, 0xB8, rc = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xB8,
mse, sizeof mse); mse, sizeof mse);
} }
else else
@ -1057,7 +1062,7 @@ do_decipher (app_t app, const char *keyidstr,
0x80, 1, 0x10, /* Select algorithm RSA. */ 0x80, 1, 0x10, /* Select algorithm RSA. */
0x84, 1, 0x81 /* Select local secret key 1 for decryption. */ 0x84, 1, 0x81 /* Select local secret key 1 for decryption. */
}; };
rc = iso7816_manage_security_env (app->slot, 0xC1, 0xB8, rc = iso7816_manage_security_env (app_get_slot (app), 0xC1, 0xB8,
mse, sizeof mse); mse, sizeof mse);
} }
@ -1068,7 +1073,8 @@ do_decipher (app_t app, const char *keyidstr,
/* Note that we need to use extended length APDUs for TCOS 3 cards. /* Note that we need to use extended length APDUs for TCOS 3 cards.
Command chaining does not work. */ Command chaining does not work. */
if (!rc) if (!rc)
rc = iso7816_decipher (app->slot, app->app_local->nks_version > 2? 1:0, rc = iso7816_decipher (app_get_slot (app),
app->app_local->nks_version > 2? 1:0,
indata, indatalen, 0, 0x81, indata, indatalen, 0, 0x81,
outdata, outdatalen); outdata, outdatalen);
return rc; return rc;
@ -1260,13 +1266,13 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr,
} }
memcpy (data, oldpin, oldpinlen); memcpy (data, oldpin, oldpinlen);
memcpy (data+oldpinlen, newpin, newpinlen); memcpy (data+oldpinlen, newpin, newpinlen);
err = iso7816_reset_retry_counter_with_rc (app->slot, pwid, err = iso7816_reset_retry_counter_with_rc (app_get_slot (app), pwid,
data, datalen); data, datalen);
wipememory (data, datalen); wipememory (data, datalen);
xfree (data); xfree (data);
} }
else else
err = iso7816_change_reference_data (app->slot, pwid, err = iso7816_change_reference_data (app_get_slot (app), pwid,
oldpin, oldpinlen, oldpin, oldpinlen,
newpin, newpinlen); newpin, newpinlen);
leave: leave:
@ -1347,9 +1353,11 @@ switch_application (app_t app, int enable_sigg)
log_info ("app-nks: switching to %s\n", enable_sigg? "SigG":"NKS"); log_info ("app-nks: switching to %s\n", enable_sigg? "SigG":"NKS");
if (enable_sigg) if (enable_sigg)
err = iso7816_select_application (app->slot, aid_sigg, sizeof aid_sigg, 0); err = iso7816_select_application (app_get_slot (app),
aid_sigg, sizeof aid_sigg, 0);
else else
err = iso7816_select_application (app->slot, aid_nks, sizeof aid_nks, 0); err = iso7816_select_application (app_get_slot (app),
aid_nks, sizeof aid_nks, 0);
if (!err && enable_sigg && app->app_local->nks_version >= 3 if (!err && enable_sigg && app->app_local->nks_version >= 3
&& !app->app_local->sigg_msig_checked) && !app->app_local->sigg_msig_checked)
@ -1362,9 +1370,10 @@ switch_application (app_t app, int enable_sigg)
app->app_local->sigg_msig_checked = 1; app->app_local->sigg_msig_checked = 1;
app->app_local->sigg_is_msig = 1; app->app_local->sigg_is_msig = 1;
err = iso7816_select_file (app->slot, 0x5349, 0); err = iso7816_select_file (app_get_slot (app), 0x5349, 0);
if (!err) if (!err)
err = iso7816_read_record (app->slot, 1, 1, 0, &buffer, &buflen); err = iso7816_read_record (app_get_slot (app), 1, 1, 0,
&buffer, &buflen);
if (!err) if (!err)
{ {
tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen); tmpl = find_tlv (buffer, buflen, 0x7a, &tmpllen);
@ -1396,7 +1405,7 @@ switch_application (app_t app, int enable_sigg)
gpg_error_t gpg_error_t
app_select_nks (app_t app) app_select_nks (app_t app)
{ {
int slot = app->slot; int slot = app_get_slot (app);
int rc; int rc;
rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0); rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0);

View File

@ -338,7 +338,7 @@ get_cached_data (app_t app, int tag,
else else
exmode = 0; exmode = 0;
err = iso7816_get_data (app->slot, exmode, tag, &p, &len); err = iso7816_get_data (app_get_slot (app), exmode, tag, &p, &len);
if (err) if (err)
return err; return err;
if (len) if (len)
@ -469,7 +469,7 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
if (app->appversion > 0x0100 && data_objects[i].get_immediate_in_v11) if (app->appversion > 0x0100 && data_objects[i].get_immediate_in_v11)
{ {
exmode = 0; exmode = 0;
rc = iso7816_get_data (app->slot, exmode, tag, &buffer, &buflen); rc = iso7816_get_data (app_get_slot (app), exmode, tag, &buffer, &buflen);
if (rc) if (rc)
{ {
*r_rc = rc; *r_rc = rc;
@ -811,7 +811,7 @@ store_fpr (app_t app, int keynumber, u32 timestamp, unsigned char *fpr,
tag2 = 0xCE + keynumber; tag2 = 0xCE + keynumber;
flush_cache_item (app, 0xCD); flush_cache_item (app, 0xCD);
rc = iso7816_put_data (app->slot, 0, tag, fpr, 20); rc = iso7816_put_data (app_get_slot (app), 0, tag, fpr, 20);
if (rc) if (rc)
log_error (_("failed to store the fingerprint: %s\n"),gpg_strerror (rc)); log_error (_("failed to store the fingerprint: %s\n"),gpg_strerror (rc));
@ -824,7 +824,7 @@ store_fpr (app_t app, int keynumber, u32 timestamp, unsigned char *fpr,
buf[2] = timestamp >> 8; buf[2] = timestamp >> 8;
buf[3] = timestamp; buf[3] = timestamp;
rc = iso7816_put_data (app->slot, 0, tag2, buf, 4); rc = iso7816_put_data (app_get_slot (app), 0, tag2, buf, 4);
if (rc) if (rc)
log_error (_("failed to store the creation date: %s\n"), log_error (_("failed to store the creation date: %s\n"),
gpg_strerror (rc)); gpg_strerror (rc));
@ -1691,7 +1691,7 @@ get_public_key (app_t app, int keyno)
le_value = 256; /* Use legacy value. */ le_value = 256; /* Use legacy value. */
} }
err = iso7816_read_public_key (app->slot, exmode, err = iso7816_read_public_key (app_get_slot (app), exmode,
(keyno == 0? "\xB6" : (keyno == 0? "\xB6" :
keyno == 1? "\xB8" : "\xA4"), keyno == 1? "\xB8" : "\xA4"),
2, le_value, &buffer, &buflen); 2, le_value, &buffer, &buflen);
@ -2161,7 +2161,7 @@ verify_a_chv (app_t app,
/* Special case for def_chv2 mechanism. */ /* Special case for def_chv2 mechanism. */
if (opt.verbose) if (opt.verbose)
log_info (_("using default PIN as %s\n"), "CHV2"); log_info (_("using default PIN as %s\n"), "CHV2");
rc = iso7816_verify (app->slot, 0x82, "123456", 6); rc = iso7816_verify (app_get_slot (app), 0x82, "123456", 6);
if (rc) if (rc)
{ {
/* Verification of CHV2 with the default PIN failed, /* Verification of CHV2 with the default PIN failed,
@ -2194,7 +2194,7 @@ verify_a_chv (app_t app,
} }
if (!opt.disable_pinpad if (!opt.disable_pinpad
&& !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) && !iso7816_check_pinpad (app_get_slot (app), ISO7816_VERIFY, &pininfo)
&& !check_pinpad_request (app, &pininfo, 0)) && !check_pinpad_request (app, &pininfo, 0))
{ {
/* The reader supports the verify command through the pinpad. /* The reader supports the verify command through the pinpad.
@ -2210,7 +2210,7 @@ verify_a_chv (app_t app,
gpg_strerror (rc)); gpg_strerror (rc));
return rc; return rc;
} }
rc = iso7816_verify_kp (app->slot, 0x80+chvno, &pininfo); rc = iso7816_verify_kp (app_get_slot (app), 0x80+chvno, &pininfo);
/* Dismiss the prompt. */ /* Dismiss the prompt. */
pincb (pincb_arg, NULL, NULL); pincb (pincb_arg, NULL, NULL);
@ -2241,7 +2241,8 @@ verify_a_chv (app_t app,
rc = pin2hash_if_kdf (app, chvno, *pinvalue, pinlen); rc = pin2hash_if_kdf (app, chvno, *pinvalue, pinlen);
if (!rc) if (!rc)
rc = iso7816_verify (app->slot, 0x80+chvno, *pinvalue, *pinlen); rc = iso7816_verify (app_get_slot (app),
0x80 + chvno, *pinvalue, *pinlen);
} }
if (rc) if (rc)
@ -2281,7 +2282,7 @@ verify_chv2 (app_t app,
the card is not configured to require a verification before the card is not configured to require a verification before
each CHV1 controlled operation (force_chv1) and if we are not each CHV1 controlled operation (force_chv1) and if we are not
using the pinpad (PINVALUE == NULL). */ using the pinpad (PINVALUE == NULL). */
rc = iso7816_verify (app->slot, 0x81, pinvalue, pinlen); rc = iso7816_verify (app_get_slot (app), 0x81, pinvalue, pinlen);
if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)
rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
if (rc) if (rc)
@ -2369,7 +2370,8 @@ verify_chv3 (app_t app,
return rc; return rc;
if (!opt.disable_pinpad if (!opt.disable_pinpad
&& !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) && !iso7816_check_pinpad (app_get_slot (app),
ISO7816_VERIFY, &pininfo)
&& !check_pinpad_request (app, &pininfo, 1)) && !check_pinpad_request (app, &pininfo, 1))
{ {
/* The reader supports the verify command through the pinpad. */ /* The reader supports the verify command through the pinpad. */
@ -2382,7 +2384,7 @@ verify_chv3 (app_t app,
gpg_strerror (rc)); gpg_strerror (rc));
return rc; return rc;
} }
rc = iso7816_verify_kp (app->slot, 0x83, &pininfo); rc = iso7816_verify_kp (app_get_slot (app), 0x83, &pininfo);
/* Dismiss the prompt. */ /* Dismiss the prompt. */
pincb (pincb_arg, NULL, NULL); pincb (pincb_arg, NULL, NULL);
} }
@ -2411,7 +2413,7 @@ verify_chv3 (app_t app,
rc = pin2hash_if_kdf (app, 3, pinvalue, &pinlen); rc = pin2hash_if_kdf (app, 3, pinvalue, &pinlen);
if (!rc) if (!rc)
rc = iso7816_verify (app->slot, 0x83, pinvalue, pinlen); rc = iso7816_verify (app_get_slot (app), 0x83, pinvalue, pinlen);
xfree (pinvalue); xfree (pinvalue);
} }
@ -2510,7 +2512,8 @@ do_setattr (app_t app, const char *name,
exmode = -254; /* Command chaining with max. 254 bytes. */ exmode = -254; /* Command chaining with max. 254 bytes. */
else else
exmode = 0; exmode = 0;
rc = iso7816_put_data (app->slot, exmode, table[idx].tag, value, valuelen); rc = iso7816_put_data (app_get_slot (app),
exmode, table[idx].tag, value, valuelen);
if (rc) if (rc)
log_error ("failed to set '%s': %s\n", table[idx].name, gpg_strerror (rc)); log_error ("failed to set '%s': %s\n", table[idx].name, gpg_strerror (rc));
@ -2567,7 +2570,7 @@ clear_chv_status (app_t app, int chvno)
apdu[2] = 0xff; apdu[2] = 0xff;
apdu[3] = 0x80+chvno; apdu[3] = 0x80+chvno;
err = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL); err = iso7816_apdu_direct (app_get_slot (app), apdu, 4, 0, NULL, NULL, NULL);
if (err) if (err)
{ {
if (gpg_err_code (err) == GPG_ERR_INV_VALUE) if (gpg_err_code (err) == GPG_ERR_INV_VALUE)
@ -2578,7 +2581,8 @@ clear_chv_status (app_t app, int chvno)
if (chvno == 1) if (chvno == 1)
{ {
apdu[3]++; apdu[3]++;
err = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL); err = iso7816_apdu_direct (app_get_slot (app),
apdu, 4, 0, NULL, NULL, NULL);
app->did_chv1 = app->did_chv2 = 0; app->did_chv1 = app->did_chv2 = 0;
} }
else if (chvno == 2) else if (chvno == 2)
@ -2689,7 +2693,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
/* Version 2 cards. */ /* Version 2 cards. */
if (!opt.disable_pinpad if (!opt.disable_pinpad
&& !iso7816_check_pinpad (app->slot, && !iso7816_check_pinpad (app_get_slot (app),
ISO7816_CHANGE_REFERENCE_DATA, &pininfo) ISO7816_CHANGE_REFERENCE_DATA, &pininfo)
&& !check_pinpad_request (app, &pininfo, chvno == 3)) && !check_pinpad_request (app, &pininfo, chvno == 3))
use_pinpad = 1; use_pinpad = 1;
@ -2832,7 +2836,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
rc = pin2hash_if_kdf (app, 0, buffer+pinlen0, &pinlen); rc = pin2hash_if_kdf (app, 0, buffer+pinlen0, &pinlen);
} }
if (!rc) if (!rc)
rc = iso7816_reset_retry_counter_with_rc (app->slot, 0x81, rc = iso7816_reset_retry_counter_with_rc (app_get_slot (app), 0x81,
buffer, pinlen0+pinlen); buffer, pinlen0+pinlen);
wipememory (buffer, pinlen0 + pinlen); wipememory (buffer, pinlen0 + pinlen);
xfree (buffer); xfree (buffer);
@ -2849,31 +2853,37 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
{ {
rc = pin2hash_if_kdf (app, 0, pinvalue, &pinlen); rc = pin2hash_if_kdf (app, 0, pinvalue, &pinlen);
if (!rc) if (!rc)
rc = iso7816_put_data (app->slot, 0, 0xD3, pinvalue, pinlen); rc = iso7816_put_data (app_get_slot (app),
0, 0xD3, pinvalue, pinlen);
} }
} }
else if (reset_mode) else if (reset_mode)
{ {
rc = pin2hash_if_kdf (app, 1, pinvalue, &pinlen); rc = pin2hash_if_kdf (app, 1, pinvalue, &pinlen);
if (!rc) if (!rc)
rc = iso7816_reset_retry_counter (app->slot, 0x81, pinvalue, pinlen); rc = iso7816_reset_retry_counter (app_get_slot (app),
0x81, pinvalue, pinlen);
if (!rc && !app->app_local->extcap.is_v2) if (!rc && !app->app_local->extcap.is_v2)
rc = iso7816_reset_retry_counter (app->slot, 0x82, pinvalue, pinlen); rc = iso7816_reset_retry_counter (app_get_slot (app),
0x82, pinvalue, pinlen);
} }
else if (!app->app_local->extcap.is_v2) else if (!app->app_local->extcap.is_v2)
{ {
/* Version 1 cards. */ /* Version 1 cards. */
if (chvno == 1 || chvno == 2) if (chvno == 1 || chvno == 2)
{ {
rc = iso7816_change_reference_data (app->slot, 0x81, NULL, 0, rc = iso7816_change_reference_data (app_get_slot (app),
0x81, NULL, 0,
pinvalue, strlen (pinvalue)); pinvalue, strlen (pinvalue));
if (!rc) if (!rc)
rc = iso7816_change_reference_data (app->slot, 0x82, NULL, 0, rc = iso7816_change_reference_data (app_get_slot (app),
0x82, NULL, 0,
pinvalue, strlen (pinvalue)); pinvalue, strlen (pinvalue));
} }
else /* CHVNO == 3 */ else /* CHVNO == 3 */
{ {
rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, NULL, 0, rc = iso7816_change_reference_data (app_get_slot (app),
0x80 + chvno, NULL, 0,
pinvalue, strlen (pinvalue)); pinvalue, strlen (pinvalue));
} }
} }
@ -2894,7 +2904,8 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
gpg_strerror (rc)); gpg_strerror (rc));
goto leave; goto leave;
} }
rc = iso7816_change_reference_data_kp (app->slot, 0x80 + chvno, 0, rc = iso7816_change_reference_data_kp (app_get_slot (app),
0x80 + chvno, 0,
&pininfo); &pininfo);
pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */
} }
@ -2904,7 +2915,8 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
if (!rc) if (!rc)
rc = pin2hash_if_kdf (app, chvno, pinvalue, &pinlen); rc = pin2hash_if_kdf (app, chvno, pinvalue, &pinlen);
if (!rc) if (!rc)
rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, rc = iso7816_change_reference_data (app_get_slot (app),
0x80 + chvno,
oldpinvalue, pinlen0, oldpinvalue, pinlen0,
pinvalue, pinlen); pinvalue, pinlen);
} }
@ -2947,7 +2959,7 @@ does_key_exist (app_t app, int keyidx, int generating, int force)
assert (keyidx >=0 && keyidx <= 2); assert (keyidx >=0 && keyidx <= 2);
if (iso7816_get_data (app->slot, 0, 0x006E, &buffer, &buflen)) if (iso7816_get_data (app_get_slot (app), 0, 0x006E, &buffer, &buflen))
{ {
log_error (_("error reading application data\n")); log_error (_("error reading application data\n"));
return gpg_error (GPG_ERR_GENERAL); return gpg_error (GPG_ERR_GENERAL);
@ -3261,7 +3273,7 @@ change_keyattr (app_t app, int keyno, const unsigned char *buf, size_t buflen,
return err; return err;
/* Change the attribute. */ /* Change the attribute. */
err = iso7816_put_data (app->slot, 0, 0xC1+keyno, buf, buflen); err = iso7816_put_data (app_get_slot (app), 0, 0xC1+keyno, buf, buflen);
if (err) if (err)
log_error ("error changing key attribute (key=%d)\n", keyno+1); log_error ("error changing key attribute (key=%d)\n", keyno+1);
else else
@ -3653,7 +3665,7 @@ rsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
exmode = -254; exmode = -254;
else else
exmode = 0; exmode = 0;
err = iso7816_put_data_odd (app->slot, exmode, 0x3fff, err = iso7816_put_data_odd (app_get_slot (app), exmode, 0x3fff,
template, template_len); template, template_len);
} }
else else
@ -3703,7 +3715,7 @@ rsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
goto leave; goto leave;
/* Store the key. */ /* Store the key. */
err = iso7816_put_data (app->slot, 0, err = iso7816_put_data (app_get_slot (app), 0,
(app->appversion > 0x0007? 0xE0:0xE9)+keyno, (app->appversion > 0x0007? 0xE0:0xE9)+keyno,
template, template_len); template, template_len);
} }
@ -3975,7 +3987,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
exmode = -254; exmode = -254;
else else
exmode = 0; exmode = 0;
err = iso7816_put_data_odd (app->slot, exmode, 0x3fff, err = iso7816_put_data_odd (app_get_slot (app), exmode, 0x3fff,
template, template_len); template, template_len);
xfree (template); xfree (template);
} }
@ -4143,7 +4155,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, const char *keytype,
log_info (_("please wait while key is being generated ...\n")); log_info (_("please wait while key is being generated ...\n"));
start_at = time (NULL); start_at = time (NULL);
err = iso7816_generate_keypair (app->slot, exmode, 0x80, 0, err = iso7816_generate_keypair (app_get_slot (app), exmode, 0x80, 0,
(keyno == 0? "\xB6" : (keyno == 0? "\xB6" :
keyno == 1? "\xB8" : "\xA4"), keyno == 1? "\xB8" : "\xA4"),
2, le_value, &buffer, &buflen); 2, le_value, &buffer, &buflen);
@ -4325,9 +4337,9 @@ check_keyidstr (app_t app, const char *keyidstr, int keyno)
for (s=keyidstr, n=0; n < 16; s += 2, n++) for (s=keyidstr, n=0; n < 16; s += 2, n++)
tmp_sn[n] = xtoi_2 (s); tmp_sn[n] = xtoi_2 (s);
if (app->serialnolen != 16) if (app->card->serialnolen != 16)
return gpg_error (GPG_ERR_INV_CARD); return gpg_error (GPG_ERR_INV_CARD);
if (memcmp (app->serialno, tmp_sn, 16)) if (memcmp (app->card->serialno, tmp_sn, 16))
return gpg_error (GPG_ERR_WRONG_CARD); return gpg_error (GPG_ERR_WRONG_CARD);
} }
@ -4485,7 +4497,8 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
char *pinvalue; char *pinvalue;
int pinlen; int pinlen;
rc = verify_a_chv (app, pincb, pincb_arg, 1, sigcount, &pinvalue, &pinlen); rc = verify_a_chv (app, pincb, pincb_arg, 1, sigcount,
&pinvalue, &pinlen);
if (rc) if (rc)
return rc; return rc;
@ -4498,7 +4511,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
pinpad has been used. */ pinpad has been used. */
if (!app->did_chv2 && pinvalue && !app->app_local->extcap.is_v2) if (!app->did_chv2 && pinvalue && !app->app_local->extcap.is_v2)
{ {
rc = iso7816_verify (app->slot, 0x82, pinvalue, pinlen); rc = iso7816_verify (app_get_slot (app), 0x82, pinvalue, pinlen);
if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)
rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
if (rc) if (rc)
@ -4526,7 +4539,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
exmode = 0; exmode = 0;
le_value = 0; le_value = 0;
} }
rc = iso7816_compute_ds (app->slot, exmode, data, datalen, le_value, rc = iso7816_compute_ds (app_get_slot (app), exmode, data, datalen, le_value,
outdata, outdatalen); outdata, outdatalen);
if (gpg_err_code (rc) == GPG_ERR_TIMEOUT) if (gpg_err_code (rc) == GPG_ERR_TIMEOUT)
clear_chv_status (app, 1); clear_chv_status (app, 1);
@ -4605,7 +4618,7 @@ do_auth (app_t app, const char *keyidstr,
exmode = 0; exmode = 0;
le_value = 0; le_value = 0;
} }
rc = iso7816_internal_authenticate (app->slot, exmode, rc = iso7816_internal_authenticate (app_get_slot (app), exmode,
indata, indatalen, le_value, indata, indatalen, le_value,
outdata, outdatalen); outdata, outdatalen);
if (gpg_err_code (rc) == GPG_ERR_TIMEOUT) if (gpg_err_code (rc) == GPG_ERR_TIMEOUT)
@ -4800,7 +4813,7 @@ do_decipher (app_t app, const char *keyidstr,
else else
exmode = le_value = 0; exmode = le_value = 0;
rc = iso7816_decipher (app->slot, exmode, rc = iso7816_decipher (app_get_slot (app), exmode,
indata, indatalen, le_value, padind, indata, indatalen, le_value, padind,
outdata, outdatalen); outdata, outdatalen);
xfree (fixbuf); xfree (fixbuf);
@ -4938,10 +4951,10 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, const char *keygrip_str)
char buf[65]; char buf[65];
int data = (action == KEYGRIP_ACTION_SEND_DATA); int data = (action == KEYGRIP_ACTION_SEND_DATA);
if (DIM (buf) < 2 * app->serialnolen + 1) if (DIM (buf) < 2 * app->card->serialnolen + 1)
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
bin2hex (app->serialno, app->serialnolen, buf); bin2hex (app->card->serialno, app->card->serialnolen, buf);
if (keygrip_str == NULL) if (keygrip_str == NULL)
{ {
@ -5198,7 +5211,7 @@ gpg_error_t
app_select_openpgp (app_t app) app_select_openpgp (app_t app)
{ {
static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 }; static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
int slot = app->slot; int slot = app_get_slot (app);
int rc; int rc;
unsigned char *buffer; unsigned char *buffer;
size_t buflen; size_t buflen;
@ -5236,9 +5249,9 @@ app_select_openpgp (app_t app)
app->appversion |= buffer[7]; app->appversion |= buffer[7];
manufacturer = (buffer[8]<<8 | buffer[9]); manufacturer = (buffer[8]<<8 | buffer[9]);
xfree (app->serialno); xfree (app->card->serialno);
app->serialno = buffer; app->card->serialno = buffer;
app->serialnolen = buflen; app->card->serialnolen = buflen;
buffer = NULL; buffer = NULL;
app->app_local = xtrycalloc (1, sizeof *app->app_local); app->app_local = xtrycalloc (1, sizeof *app->app_local);
if (!app->app_local) if (!app->app_local)

View File

@ -443,7 +443,7 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen)
if (app->app_local->direct_path_selection) if (app->app_local->direct_path_selection)
{ {
err = iso7816_select_path (app->slot, path+1, pathlen-1); err = iso7816_select_path (app_get_slot (app), path+1, pathlen-1);
if (err) if (err)
{ {
log_error ("error selecting path "); log_error ("error selecting path ");
@ -461,7 +461,8 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen)
supported by the card. */ supported by the card. */
for (i=0; i < pathlen; i++) for (i=0; i < pathlen; i++)
{ {
err = iso7816_select_file (app->slot, path[i], !(i+1 == pathlen)); err = iso7816_select_file (app_get_slot (app),
path[i], !(i+1 == pathlen));
if (err) if (err)
{ {
log_error ("error selecting part %d from path ", i); log_error ("error selecting part %d from path ", i);
@ -612,7 +613,8 @@ read_ef_odf (app_t app, unsigned short odf_fid)
unsigned short value; unsigned short value;
size_t offset; size_t offset;
err = select_and_read_binary (app->slot, odf_fid, "ODF", &buffer, &buflen); err = select_and_read_binary (app_get_slot (app), odf_fid, "ODF",
&buffer, &buflen);
if (err) if (err)
return err; return err;
@ -826,7 +828,8 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
if (!fid) if (!fid)
return gpg_error (GPG_ERR_NO_DATA); /* No private keys. */ return gpg_error (GPG_ERR_NO_DATA); /* No private keys. */
err = select_and_read_binary (app->slot, fid, "PrKDF", &buffer, &buflen); err = select_and_read_binary (app_get_slot (app), fid, "PrKDF",
&buffer, &buflen);
if (err) if (err)
return err; return err;
@ -1282,7 +1285,8 @@ read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
if (!fid) if (!fid)
return gpg_error (GPG_ERR_NO_DATA); /* No certificates. */ return gpg_error (GPG_ERR_NO_DATA); /* No certificates. */
err = select_and_read_binary (app->slot, fid, "CDF", &buffer, &buflen); err = select_and_read_binary (app_get_slot (app), fid, "CDF",
&buffer, &buflen);
if (err) if (err)
return err; return err;
@ -1555,7 +1559,8 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
if (!fid) if (!fid)
return gpg_error (GPG_ERR_NO_DATA); /* No authentication objects. */ return gpg_error (GPG_ERR_NO_DATA); /* No authentication objects. */
err = select_and_read_binary (app->slot, fid, "AODF", &buffer, &buflen); err = select_and_read_binary (app_get_slot (app), fid, "AODF",
&buffer, &buflen);
if (err) if (err)
return err; return err;
@ -2216,7 +2221,7 @@ read_ef_tokeninfo (app_t app)
int class, tag, constructed, ndef; int class, tag, constructed, ndef;
unsigned long ul; unsigned long ul;
err = select_and_read_binary (app->slot, 0x5032, "TokenInfo", err = select_and_read_binary (app_get_slot (app), 0x5032, "TokenInfo",
&buffer, &buflen); &buffer, &buflen);
if (err) if (err)
return err; return err;
@ -2294,13 +2299,13 @@ read_p15_info (app_t app)
{ {
/* If we don't have a serial number yet but the TokenInfo provides /* If we don't have a serial number yet but the TokenInfo provides
one, use that. */ one, use that. */
if (!app->serialno && app->app_local->serialno) if (!app->card->serialno && app->app_local->serialno)
{ {
app->serialno = app->app_local->serialno; app->card->serialno = app->app_local->serialno;
app->serialnolen = app->app_local->serialnolen; app->card->serialnolen = app->app_local->serialnolen;
app->app_local->serialno = NULL; app->app_local->serialno = NULL;
app->app_local->serialnolen = 0; app->app_local->serialnolen = 0;
err = app_munge_serialno (app); err = app_munge_serialno (app->card);
if (err) if (err)
return err; return err;
} }
@ -2553,7 +2558,8 @@ readcert_by_cdf (app_t app, cdf_object_t cdf,
if (err) if (err)
goto leave; goto leave;
err = iso7816_read_binary (app->slot, cdf->off, cdf->len, &buffer, &buflen); err = iso7816_read_binary (app_get_slot (app), cdf->off, cdf->len,
&buffer, &buflen);
if (!err && (!buflen || *buffer == 0xff)) if (!err && (!buflen || *buffer == 0xff))
err = gpg_error (GPG_ERR_NOT_FOUND); err = gpg_error (GPG_ERR_NOT_FOUND);
if (err) if (err)
@ -2713,7 +2719,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
err = select_ef_by_path (app, path, DIM(path) ); err = select_ef_by_path (app, path, DIM(path) );
if (!err) if (!err)
err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); err = iso7816_read_binary (app_get_slot (app), 0, 0,
&buffer, &buflen);
if (err) if (err)
{ {
log_error ("error accessing EF(ID): %s\n", gpg_strerror (err)); log_error ("error accessing EF(ID): %s\n", gpg_strerror (err));
@ -2758,7 +2765,7 @@ micardo_mse (app_t app, unsigned short fid)
unsigned char msebuf[10]; unsigned char msebuf[10];
/* Read the KeyD file containing extra information on keys. */ /* Read the KeyD file containing extra information on keys. */
err = iso7816_select_file (app->slot, 0x0013, 0); err = iso7816_select_file (app_get_slot (app), 0x0013, 0);
if (err) if (err)
{ {
log_error ("error reading EF_keyD: %s\n", gpg_strerror (err)); log_error ("error reading EF_keyD: %s\n", gpg_strerror (err));
@ -2772,7 +2779,8 @@ micardo_mse (app_t app, unsigned short fid)
size_t n, nn; size_t n, nn;
const unsigned char *p, *pp; const unsigned char *p, *pp;
err = iso7816_read_record (app->slot, recno, 1, 0, &buffer, &buflen); err = iso7816_read_record (app_get_slot (app), recno, 1, 0,
&buffer, &buflen);
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
break; /* ready */ break; /* ready */
if (err) if (err)
@ -2811,7 +2819,8 @@ micardo_mse (app_t app, unsigned short fid)
/* Restore the security environment to SE_NUM if needed */ /* Restore the security environment to SE_NUM if needed */
if (se_num) if (se_num)
{ {
err = iso7816_manage_security_env (app->slot, 0xf3, se_num, NULL, 0); err = iso7816_manage_security_env (app_get_slot (app),
0xf3, se_num, NULL, 0);
if (err) if (err)
{ {
log_error ("restoring SE to %d failed: %s\n", log_error ("restoring SE to %d failed: %s\n",
@ -2826,7 +2835,7 @@ micardo_mse (app_t app, unsigned short fid)
msebuf[2] = 0x80; msebuf[2] = 0x80;
msebuf[3] = (refdata >> 8); msebuf[3] = (refdata >> 8);
msebuf[4] = refdata; msebuf[4] = refdata;
err = iso7816_manage_security_env (app->slot, 0x41, 0xb6, msebuf, 5); err = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xb6, msebuf, 5);
if (err) if (err)
{ {
log_error ("setting SE to reference file %04hX failed: %s\n", log_error ("setting SE to reference file %04hX failed: %s\n",
@ -2948,7 +2957,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
mse[3] = 0x84; /* Private key reference tag. */ mse[3] = 0x84; /* Private key reference tag. */
mse[4] = prkdf->key_reference_valid? prkdf->key_reference : 0x82; mse[4] = prkdf->key_reference_valid? prkdf->key_reference : 0x82;
err = iso7816_manage_security_env (app->slot, err = iso7816_manage_security_env (app_get_slot (app),
0x41, 0xB6, 0x41, 0xB6,
mse, sizeof mse); mse, sizeof mse);
no_data_padding = 1; no_data_padding = 1;
@ -3101,7 +3110,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
else else
pinvaluelen = strlen (pinvalue); pinvaluelen = strlen (pinvalue);
err = iso7816_verify (app->slot, err = iso7816_verify (app_get_slot (app),
aodf->pin_reference_valid? aodf->pin_reference : 0, aodf->pin_reference_valid? aodf->pin_reference : 0,
pinvalue, pinvaluelen); pinvalue, pinvaluelen);
xfree (pinvalue); xfree (pinvalue);
@ -3170,7 +3179,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
mse[1] = 1; mse[1] = 1;
mse[2] = prkdf->key_reference; mse[2] = prkdf->key_reference;
err = iso7816_manage_security_env (app->slot, err = iso7816_manage_security_env (app_get_slot (app),
0x41, 0xB6, 0x41, 0xB6,
mse, sizeof mse); mse, sizeof mse);
} }
@ -3181,11 +3190,14 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
} }
if (hashalgo == MD_USER_TLS_MD5SHA1) if (hashalgo == MD_USER_TLS_MD5SHA1)
err = iso7816_compute_ds (app->slot, 0, data, 36, 0, outdata, outdatalen); err = iso7816_compute_ds (app_get_slot (app),
0, data, 36, 0, outdata, outdatalen);
else if (no_data_padding) else if (no_data_padding)
err = iso7816_compute_ds (app->slot, 0, data+15, 20, 0,outdata,outdatalen); err = iso7816_compute_ds (app_get_slot (app),
0, data+15, 20, 0,outdata,outdatalen);
else else
err = iso7816_compute_ds (app->slot, 0, data, 35, 0, outdata, outdatalen); err = iso7816_compute_ds (app_get_slot (app),
0, data, 35, 0, outdata, outdatalen);
return err; return err;
} }
@ -3280,7 +3292,7 @@ read_home_df (int slot, int *r_belpic)
gpg_error_t gpg_error_t
app_select_p15 (app_t app) app_select_p15 (app_t app)
{ {
int slot = app->slot; int slot = app_get_slot (app);
int rc; int rc;
unsigned short def_home_df = 0; unsigned short def_home_df = 0;
card_type_t card_type = CARD_TYPE_UNKNOWN; card_type_t card_type = CARD_TYPE_UNKNOWN;
@ -3298,7 +3310,7 @@ app_select_p15 (app_t app)
Using the 2f02 just works. */ Using the 2f02 just works. */
unsigned short path[1] = { 0x2f00 }; unsigned short path[1] = { 0x2f00 };
rc = iso7816_select_path (app->slot, path, 1); rc = iso7816_select_path (app_get_slot (app), path, 1);
if (!rc) if (!rc)
{ {
direct = 1; direct = 1;
@ -3306,7 +3318,7 @@ app_select_p15 (app_t app)
if (def_home_df) if (def_home_df)
{ {
path[0] = def_home_df; path[0] = def_home_df;
rc = iso7816_select_path (app->slot, path, 1); rc = iso7816_select_path (app_get_slot (app), path, 1);
} }
} }
} }
@ -3330,7 +3342,7 @@ app_select_p15 (app_t app)
size_t atrlen; size_t atrlen;
int i; int i;
atr = apdu_get_atr (app->slot, &atrlen); atr = apdu_get_atr (app_get_slot (app), &atrlen);
if (!atr) if (!atr)
rc = gpg_error (GPG_ERR_INV_CARD); rc = gpg_error (GPG_ERR_INV_CARD);
else else
@ -3381,8 +3393,8 @@ app_select_p15 (app_t app)
prototype card right here because we need to access to prototype card right here because we need to access to
EF(TokenInfo). We mark such a serial number by the using a EF(TokenInfo). We mark such a serial number by the using a
prefix of FF0100. */ prefix of FF0100. */
if (app->serialnolen == 12 if (app->card->serialnolen == 12
&& !memcmp (app->serialno, "\xD2\x76\0\0\0\0\0\0\0\0\0\0", 12)) && !memcmp (app->card->serialno, "\xD2\x76\0\0\0\0\0\0\0\0\0\0", 12))
{ {
/* This is a German card with a silly serial number. Try to get /* This is a German card with a silly serial number. Try to get
the serial number from the EF(TokenInfo). . */ the serial number from the EF(TokenInfo). . */
@ -3390,16 +3402,16 @@ app_select_p15 (app_t app)
/* FIXME: actually get it from EF(TokenInfo). */ /* FIXME: actually get it from EF(TokenInfo). */
p = xtrymalloc (3 + app->serialnolen); p = xtrymalloc (3 + app->card->serialnolen);
if (!p) if (!p)
rc = gpg_error (gpg_err_code_from_errno (errno)); rc = gpg_error (gpg_err_code_from_errno (errno));
else else
{ {
memcpy (p, "\xff\x01", 3); memcpy (p, "\xff\x01", 3);
memcpy (p+3, app->serialno, app->serialnolen); memcpy (p+3, app->card->serialno, app->card->serialnolen);
app->serialnolen += 3; app->card->serialnolen += 3;
xfree (app->serialno); xfree (app->card->serialno);
app->serialno = p; app->card->serialno = p;
} }
} }

View File

@ -283,7 +283,7 @@ get_cached_data (app_t app, int tag,
} }
} }
err = iso7816_get_data_odd (app->slot, 0, tag, &p, &len); err = iso7816_get_data_odd (app_get_slot (app), 0, tag, &p, &len);
if (err) if (err)
return err; return err;
@ -737,18 +737,18 @@ get_dispserialno (app_t app, int failmode)
{ {
char *result; char *result;
if (app->serialno && app->serialnolen == 3+1+4 if (app->card && app->card->serialno && app->card->serialnolen == 3+1+4
&& !memcmp (app->serialno, "\xff\x02\x00", 3)) && !memcmp (app->card->serialno, "\xff\x02\x00", 3))
{ {
/* This is a 4 byte S/N of a Yubikey which seems to be printed /* This is a 4 byte S/N of a Yubikey which seems to be printed
* on the token in decimal. Maybe they will print larger S/N * on the token in decimal. Maybe they will print larger S/N
* also in decimal but we can't be sure, thus do it only for * also in decimal but we can't be sure, thus do it only for
* these 32 bit numbers. */ * these 32 bit numbers. */
unsigned long sn; unsigned long sn;
sn = app->serialno[4] * 16777216; sn = app->card->serialno[4] * 16777216;
sn += app->serialno[5] * 65536; sn += app->card->serialno[5] * 65536;
sn += app->serialno[6] * 256; sn += app->card->serialno[6] * 256;
sn += app->serialno[7]; sn += app->card->serialno[7];
result = xtryasprintf ("yk-%lu", sn); result = xtryasprintf ("yk-%lu", sn);
} }
else if (failmode) else if (failmode)
@ -786,7 +786,7 @@ get_chv_status (app_t app, const char *keyrefstr)
apdu[1] = ISO7816_VERIFY; apdu[1] = ISO7816_VERIFY;
apdu[2] = 0x00; apdu[2] = 0x00;
apdu[3] = keyref; apdu[3] = keyref;
if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL)) if (!iso7816_apdu_direct (app_get_slot (app), apdu, 4, 0, &sw, NULL, NULL))
result = -5; /* No need to verification. */ result = -5; /* No need to verification. */
else if (sw == 0x6a88 || sw == 0x6a80) else if (sw == 0x6a88 || sw == 0x6a80)
result = -2; /* No such PIN. */ result = -2; /* No such PIN. */
@ -938,7 +938,7 @@ auth_adm_key (app_t app, const unsigned char *value, size_t valuelen)
tmpl[2] = 0x80; tmpl[2] = 0x80;
tmpl[3] = 0; /* (Empty witness requests a witness.) */ tmpl[3] = 0; /* (Empty witness requests a witness.) */
tmpllen = 4; tmpllen = 4;
err = iso7816_general_authenticate (app->slot, 0, err = iso7816_general_authenticate (app_get_slot (app), 0,
PIV_ALGORITHM_3DES_ECB_0, 0x9B, PIV_ALGORITHM_3DES_ECB_0, 0x9B,
tmpl, tmpllen, 0, tmpl, tmpllen, 0,
&outdata, &outdatalen); &outdata, &outdatalen);
@ -971,7 +971,7 @@ auth_adm_key (app_t app, const unsigned char *value, size_t valuelen)
tmpl[23] = 0; tmpl[23] = 0;
tmpllen = 24; tmpllen = 24;
xfree (outdata); xfree (outdata);
err = iso7816_general_authenticate (app->slot, 0, err = iso7816_general_authenticate (app_get_slot (app), 0,
PIV_ALGORITHM_3DES_ECB_0, 0x9B, PIV_ALGORITHM_3DES_ECB_0, 0x9B,
tmpl, tmpllen, 0, tmpl, tmpllen, 0,
&outdata, &outdatalen); &outdata, &outdatalen);
@ -1045,7 +1045,8 @@ set_adm_key (app_t app, const unsigned char *value, size_t valuelen)
apdu[6] = 0x9b; apdu[6] = 0x9b;
apdu[7] = 24; apdu[7] = 24;
memcpy (apdu+8, value, 24); memcpy (apdu+8, value, 24);
err = iso7816_apdu_direct (app->slot, apdu, 8+24, 0, &sw, NULL, NULL); err = iso7816_apdu_direct (app_get_slot (app), apdu, 8+24, 0,
&sw, NULL, NULL);
wipememory (apdu+8, 24); wipememory (apdu+8, 24);
if (err) if (err)
log_error ("piv: setting admin key failed; sw=%04x\n", sw); log_error ("piv: setting admin key failed; sw=%04x\n", sw);
@ -1426,7 +1427,7 @@ do_readcert (app_t app, const char *certid,
apdu[1] = 0xf9; /* Yubikey: Get attestation cert. */ apdu[1] = 0xf9; /* Yubikey: Get attestation cert. */
apdu[2] = xtoi_2 (certid+9); apdu[2] = xtoi_2 (certid+9);
apdu[3] = 0; apdu[3] = 0;
err = iso7816_apdu_direct (app->slot, apdu, 4, 1, err = iso7816_apdu_direct (app_get_slot (app), apdu, 4, 1,
NULL, &result, &resultlen); NULL, &result, &resultlen);
if (!err) if (!err)
{ {
@ -1880,7 +1881,7 @@ verify_chv (app_t app, int keyref, int force,
apdu[1] = ISO7816_VERIFY; apdu[1] = ISO7816_VERIFY;
apdu[2] = 0x00; apdu[2] = 0x00;
apdu[3] = keyref; apdu[3] = keyref;
if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL)) if (!iso7816_apdu_direct (app_get_slot (app), apdu, 4, 0, &sw, NULL, NULL))
{ {
if (!force) /* No need to verification. */ if (!force) /* No need to verification. */
return 0; /* All fine. */ return 0; /* All fine. */
@ -1896,7 +1897,7 @@ verify_chv (app_t app, int keyref, int force,
if (err) if (err)
return err; return err;
err = iso7816_verify (app->slot, keyref, pin, pinlen); err = iso7816_verify (app_get_slot (app), keyref, pin, pinlen);
wipememory (pin, pinlen); wipememory (pin, pinlen);
xfree (pin); xfree (pin);
if (err) if (err)
@ -1957,7 +1958,8 @@ do_change_chv (app_t app, ctrl_t ctrl, const char *pwidstr,
apdu[1] = ISO7816_VERIFY; apdu[1] = ISO7816_VERIFY;
apdu[2] = 0xff; apdu[2] = 0xff;
apdu[3] = keyref; apdu[3] = keyref;
err = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL); err = iso7816_apdu_direct (app_get_slot (app), apdu, 4, 0,
NULL, NULL, NULL);
goto leave; goto leave;
} }
@ -1979,7 +1981,7 @@ do_change_chv (app_t app, ctrl_t ctrl, const char *pwidstr,
apdu[1] = ISO7816_VERIFY; apdu[1] = ISO7816_VERIFY;
apdu[2] = 0x00; apdu[2] = 0x00;
apdu[3] = keyref; apdu[3] = keyref;
if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL)) if (!iso7816_apdu_direct (app_get_slot (app), apdu, 4, 0, &sw, NULL, NULL))
remaining = -1; /* Already verified, thus full number of tries. */ remaining = -1; /* Already verified, thus full number of tries. */
else if ((sw & 0xfff0) == 0x63C0) else if ((sw & 0xfff0) == 0x63C0)
remaining = (sw & 0x000f); /* PIN has REMAINING tries left. */ remaining = (sw & 0x000f); /* PIN has REMAINING tries left. */
@ -1996,7 +1998,7 @@ do_change_chv (app_t app, ctrl_t ctrl, const char *pwidstr,
* old is wrong. This is not possible for the PUK, though. */ * old is wrong. This is not possible for the PUK, though. */
if (keyref != 0x81) if (keyref != 0x81)
{ {
err = iso7816_verify (app->slot, keyref, oldpin, oldpinlen); err = iso7816_verify (app_get_slot (app), keyref, oldpin, oldpinlen);
if (err) if (err)
{ {
log_error ("CHV %02X verification failed: %s\n", log_error ("CHV %02X verification failed: %s\n",
@ -2021,7 +2023,8 @@ do_change_chv (app_t app, ctrl_t ctrl, const char *pwidstr,
} }
memcpy (buf, oldpin, oldpinlen); memcpy (buf, oldpin, oldpinlen);
memcpy (buf+oldpinlen, newpin, newpinlen); memcpy (buf+oldpinlen, newpin, newpinlen);
err = iso7816_reset_retry_counter_with_rc (app->slot, targetkeyref, err = iso7816_reset_retry_counter_with_rc (app_get_slot (app),
targetkeyref,
buf, oldpinlen+newpinlen); buf, oldpinlen+newpinlen);
xfree (buf); xfree (buf);
if (err) if (err)
@ -2030,7 +2033,7 @@ do_change_chv (app_t app, ctrl_t ctrl, const char *pwidstr,
} }
else else
{ {
err = iso7816_change_reference_data (app->slot, keyref, err = iso7816_change_reference_data (app_get_slot (app), keyref,
oldpin, oldpinlen, oldpin, oldpinlen,
newpin, newpinlen); newpin, newpinlen);
if (err) if (err)
@ -2269,7 +2272,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
goto leave; goto leave;
/* Note: the -1 requests command chaining. */ /* Note: the -1 requests command chaining. */
err = iso7816_general_authenticate (app->slot, -1, err = iso7816_general_authenticate (app_get_slot (app), -1,
mechanism, keyref, mechanism, keyref,
apdudata, (int)apdudatalen, 0, apdudata, (int)apdudatalen, 0,
&outdata, &outdatalen); &outdata, &outdatalen);
@ -2492,7 +2495,7 @@ do_decipher (app_t app, const char *keyidstr,
goto leave; goto leave;
/* Note: the -1 requests command chaining. */ /* Note: the -1 requests command chaining. */
err = iso7816_general_authenticate (app->slot, -1, err = iso7816_general_authenticate (app_get_slot (app), -1,
mechanism, keyref, mechanism, keyref,
apdudata, (int)apdudatalen, 0, apdudata, (int)apdudatalen, 0,
&outdata, &outdatalen); &outdata, &outdatalen);
@ -2693,7 +2696,7 @@ writekey_rsa (app_t app, data_object_t dobj, int keyref,
if (err) if (err)
goto leave; goto leave;
err = iso7816_send_apdu (app->slot, err = iso7816_send_apdu (app_get_slot (app),
-1, /* Use command chaining. */ -1, /* Use command chaining. */
0, /* Class */ 0, /* Class */
0xfe, /* Ins: Yubikey Import Asym. Key. */ 0xfe, /* Ins: Yubikey Import Asym. Key. */
@ -2715,7 +2718,7 @@ writekey_rsa (app_t app, data_object_t dobj, int keyref,
if (err) if (err)
goto leave; goto leave;
tmpl[0] = PIV_ALGORITHM_RSA; tmpl[0] = PIV_ALGORITHM_RSA;
err = put_data (app->slot, dobj->tag, err = put_data (app_get_slot (app), dobj->tag,
(int)0x80, (size_t)1, tmpl, (int)0x80, (size_t)1, tmpl,
(int)0x7f49, (size_t)apdudatalen, apdudata, (int)0x7f49, (size_t)apdudatalen, apdudata,
(int)0, (size_t)0, NULL); (int)0, (size_t)0, NULL);
@ -2845,7 +2848,7 @@ writekey_ecc (app_t app, data_object_t dobj, int keyref,
if (err) if (err)
goto leave; goto leave;
err = iso7816_send_apdu (app->slot, err = iso7816_send_apdu (app_get_slot (app),
-1, /* Use command chaining. */ -1, /* Use command chaining. */
0, /* Class */ 0, /* Class */
0xfe, /* Ins: Yubikey Import Asym. Key. */ 0xfe, /* Ins: Yubikey Import Asym. Key. */
@ -2866,7 +2869,7 @@ writekey_ecc (app_t app, data_object_t dobj, int keyref,
if (err) if (err)
goto leave; goto leave;
tmpl[0] = mechanism; tmpl[0] = mechanism;
err = put_data (app->slot, dobj->tag, err = put_data (app_get_slot (app), dobj->tag,
(int)0x80, (size_t)1, tmpl, (int)0x80, (size_t)1, tmpl,
(int)0x7f49, (size_t)apdudatalen, apdudata, (int)0x7f49, (size_t)apdudatalen, apdudata,
(int)0, (size_t)0, NULL); (int)0, (size_t)0, NULL);
@ -2952,7 +2955,7 @@ do_writekey (app_t app, ctrl_t ctrl,
/* First clear an existing key. We do this by writing an empty 7f49 /* First clear an existing key. We do this by writing an empty 7f49
* tag. This will return GPG_ERR_NO_PUBKEY on a later read. */ * tag. This will return GPG_ERR_NO_PUBKEY on a later read. */
flush_cached_data (app, dobj->tag); flush_cached_data (app, dobj->tag);
err = put_data (app->slot, dobj->tag, err = put_data (app_get_slot (app), dobj->tag,
(int)0x7f49, (size_t)0, "", (int)0x7f49, (size_t)0, "",
(int)0, (size_t)0, NULL); (int)0, (size_t)0, NULL);
if (err) if (err)
@ -3180,7 +3183,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype,
tmpl[3] = 1; tmpl[3] = 1;
tmpl[4] = mechanism; tmpl[4] = mechanism;
tmpllen = 5; tmpllen = 5;
err = iso7816_generate_keypair (app->slot, 0, 0, keyref, err = iso7816_generate_keypair (app_get_slot (app), 0, 0, keyref,
tmpl, tmpllen, 0, &buffer, &buflen); tmpl, tmpllen, 0, &buffer, &buflen);
if (err) if (err)
{ {
@ -3210,7 +3213,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype,
tmpl[0] = mechanism; tmpl[0] = mechanism;
flush_cached_data (app, dobj->tag); flush_cached_data (app, dobj->tag);
err = put_data (app->slot, dobj->tag, err = put_data (app_get_slot (app), dobj->tag,
(int)0x80, (size_t)1, tmpl, (int)0x80, (size_t)1, tmpl,
(int)0x7f49, (size_t)keydatalen, keydata, (int)0x7f49, (size_t)keydatalen, keydata,
(int)0, (size_t)0, NULL); (int)0, (size_t)0, NULL);
@ -3281,7 +3284,7 @@ do_writecert (app_t app, ctrl_t ctrl,
goto leave; goto leave;
} }
err = put_data (app->slot, dobj->tag, err = put_data (app_get_slot (app), dobj->tag,
(int)0x70, (size_t)certlen, cert,/* Certificate */ (int)0x70, (size_t)certlen, cert,/* Certificate */
(int)0x71, (size_t)1, "", /* No compress */ (int)0x71, (size_t)1, "", /* No compress */
(int)0xfe, (size_t)0, "", /* Empty LRC. */ (int)0xfe, (size_t)0, "", /* Empty LRC. */
@ -3395,7 +3398,7 @@ app_select_piv (app_t app)
{ {
static char const aid[] = { 0xA0, 0x00, 0x00, 0x03, 0x08, /* RID=NIST */ static char const aid[] = { 0xA0, 0x00, 0x00, 0x03, 0x08, /* RID=NIST */
0x00, 0x00, 0x10, 0x00 /* PIX=PIV */ }; 0x00, 0x00, 0x10, 0x00 /* PIX=PIV */ };
int slot = app->slot; int slot = app_get_slot (app);
gpg_error_t err; gpg_error_t err;
unsigned char *apt = NULL; unsigned char *apt = NULL;
size_t aptlen; size_t aptlen;
@ -3463,7 +3466,7 @@ app_select_piv (app_t app)
goto leave; goto leave;
} }
if (app->cardtype && !strcmp (app->cardtype, "yubikey")) if (app->card->cardtype && !strcmp (app->card->cardtype, "yubikey"))
app->app_local->flags.yubikey = 1; app->app_local->flags.yubikey = 1;

View File

@ -484,7 +484,8 @@ read_ef_prkd (app_t app, unsigned short fid, prkdf_object_t *prkdresult,
if (!fid) if (!fid)
return gpg_error (GPG_ERR_NO_DATA); /* No private keys. */ return gpg_error (GPG_ERR_NO_DATA); /* No private keys. */
err = select_and_read_binary (app->slot, fid, "PrKDF", &buffer, &buflen, 255); err = select_and_read_binary (app_get_slot (app),
fid, "PrKDF", &buffer, &buflen, 255);
if (err) if (err)
return err; return err;
@ -832,7 +833,7 @@ read_ef_prkd (app_t app, unsigned short fid, prkdf_object_t *prkdresult,
xfree (buffer); xfree (buffer);
buffer = NULL; buffer = NULL;
buflen = 0; buflen = 0;
err = select_and_read_binary (app->slot, err = select_and_read_binary (app_get_slot (app),
((SC_HSM_EE_PREFIX << 8) | (fid & 0xFF)), ((SC_HSM_EE_PREFIX << 8) | (fid & 0xFF)),
"CertEF", &buffer, &buflen, 1); "CertEF", &buffer, &buflen, 1);
if (!err && buffer[0] == 0x30) if (!err && buffer[0] == 0x30)
@ -953,7 +954,8 @@ read_ef_cd (app_t app, unsigned short fid, cdf_object_t *result)
if (!fid) if (!fid)
return gpg_error (GPG_ERR_NO_DATA); /* No certificates. */ return gpg_error (GPG_ERR_NO_DATA); /* No certificates. */
err = select_and_read_binary (app->slot, fid, "CDF", &buffer, &buflen, 255); err = select_and_read_binary (app_get_slot (app), fid, "CDF",
&buffer, &buflen, 255);
if (err) if (err)
return err; return err;
@ -1202,7 +1204,7 @@ read_serialno(app_t app)
size_t n, objlen, hdrlen, chrlen; size_t n, objlen, hdrlen, chrlen;
int class, tag, constructed, ndef; int class, tag, constructed, ndef;
err = select_and_read_binary (app->slot, 0x2F02, "EF.C_DevAut", err = select_and_read_binary (app_get_slot (app), 0x2F02, "EF.C_DevAut",
&buffer, &buflen, 512); &buffer, &buflen, 512);
if (err) if (err)
return err; return err;
@ -1229,15 +1231,15 @@ read_serialno(app_t app)
} }
chrlen -= 5; chrlen -= 5;
app->serialno = xtrymalloc (chrlen); app->card->serialno = xtrymalloc (chrlen);
if (!app->serialno) if (!app->card->serialno)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
goto leave; goto leave;
} }
app->serialnolen = chrlen; app->card->serialnolen = chrlen;
memcpy (app->serialno, chr, chrlen); memcpy (app->card->serialno, chr, chrlen);
leave: leave:
xfree (buffer); xfree (buffer);
@ -1260,7 +1262,7 @@ read_meta (app_t app)
if (err) if (err)
return err; return err;
err = list_ef (app->slot, &eflist, &eflistlen); err = list_ef (app_get_slot (app), &eflist, &eflistlen);
if (err) if (err)
return err; return err;
@ -1454,7 +1456,7 @@ readcert_by_cdf (app_t app, cdf_object_t cdf,
return 0; return 0;
} }
err = select_and_read_binary (app->slot, cdf->fid, "CD", err = select_and_read_binary (app_get_slot (app), cdf->fid, "CD",
&buffer, &buflen, 4096); &buffer, &buflen, 4096);
if (err) if (err)
{ {
@ -1592,7 +1594,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
} }
else if (!strcmp (name, "$DISPSERIALNO")) else if (!strcmp (name, "$DISPSERIALNO"))
{ {
send_status_info (ctrl, name, app->serialno, app->serialnolen, NULL, 0); send_status_info (ctrl, name,
app->card->serialno, app->card->serialnolen, NULL, 0);
return 0; return 0;
} }
@ -1693,8 +1696,8 @@ verify_pin (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
char *prompt; char *prompt;
int sw; int sw;
sw = apdu_send_simple (app->slot, 0, 0x00, ISO7816_VERIFY, 0x00, 0x81, sw = apdu_send_simple (app_get_slot (app),
-1, NULL); 0, 0x00, ISO7816_VERIFY, 0x00, 0x81, -1, NULL);
if (sw == SW_SUCCESS) if (sw == SW_SUCCESS)
return 0; /* PIN already verified */ return 0; /* PIN already verified */
@ -1719,7 +1722,7 @@ verify_pin (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
prompt = "||Please enter the PIN"; prompt = "||Please enter the PIN";
if (!opt.disable_pinpad if (!opt.disable_pinpad
&& !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo) ) && !iso7816_check_pinpad (app_get_slot (app), ISO7816_VERIFY, &pininfo) )
{ {
err = pincb (pincb_arg, prompt, NULL); err = pincb (pincb_arg, prompt, NULL);
if (err) if (err)
@ -1728,7 +1731,7 @@ verify_pin (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
return err; return err;
} }
err = iso7816_verify_kp (app->slot, 0x81, &pininfo); err = iso7816_verify_kp (app_get_slot (app), 0x81, &pininfo);
pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */
} }
else else
@ -1740,7 +1743,8 @@ verify_pin (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
return err; return err;
} }
err = iso7816_verify (app->slot, 0x81, pinvalue, strlen(pinvalue)); err = iso7816_verify (app_get_slot (app),
0x81, pinvalue, strlen(pinvalue));
xfree (pinvalue); xfree (pinvalue);
} }
if (err) if (err)
@ -1883,7 +1887,8 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
if (err) if (err)
return err; return err;
sw = apdu_send_le (app->slot, 1, 0x80, 0x68, prkdf->key_reference, algoid, sw = apdu_send_le (app_get_slot (app),
1, 0x80, 0x68, prkdf->key_reference, algoid,
cdsblklen, cdsblk, 0, outdata, outdatalen); cdsblklen, cdsblk, 0, outdata, outdatalen);
return iso7816_map_sw (sw); return iso7816_map_sw (sw);
} }
@ -2018,7 +2023,8 @@ do_decipher (app_t app, const char *keyidstr,
if (err) if (err)
return err; return err;
sw = apdu_send_le (app->slot, 1, 0x80, 0x62, prkdf->key_reference, 0x21, sw = apdu_send_le (app_get_slot (app),
1, 0x80, 0x62, prkdf->key_reference, 0x21,
p1blklen, p1blk, 0, &rspdata, &rspdatalen); p1blklen, p1blk, 0, &rspdata, &rspdatalen);
err = iso7816_map_sw (sw); err = iso7816_map_sw (sw);
if (err) if (err)
@ -2044,7 +2050,7 @@ do_decipher (app_t app, const char *keyidstr,
gpg_error_t gpg_error_t
app_select_sc_hsm (app_t app) app_select_sc_hsm (app_t app)
{ {
int slot = app->slot; int slot = app_get_slot (app);
int rc; int rc;
rc = iso7816_select_application (slot, sc_hsm_aid, sizeof sc_hsm_aid, 0); rc = iso7816_select_application (slot, sc_hsm_aid, sizeof sc_hsm_aid, 0);

703
scd/app.c

File diff suppressed because it is too large Load Diff

View File

@ -145,10 +145,10 @@ hex_to_buffer (const char *string, size_t *r_length)
static void static void
do_reset (ctrl_t ctrl, int send_reset) do_reset (ctrl_t ctrl, int send_reset)
{ {
app_t app = ctrl->app_ctx; card_t card = ctrl->card_ctx;
if (app) if (card)
app_reset (app, ctrl, IS_LOCKED (ctrl)? 0: send_reset); card_reset (card, ctrl, IS_LOCKED (ctrl)? 0: send_reset);
/* If we hold a lock, unlock now. */ /* If we hold a lock, unlock now. */
if (locked_session && ctrl->server_local == locked_session) if (locked_session && ctrl->server_local == locked_session)
@ -157,6 +157,8 @@ do_reset (ctrl_t ctrl, int send_reset)
log_info ("implicitly unlocking due to RESET\n"); log_info ("implicitly unlocking due to RESET\n");
} }
} }
static gpg_error_t static gpg_error_t
reset_notify (assuan_context_t ctx, char *line) reset_notify (assuan_context_t ctx, char *line)
@ -211,10 +213,10 @@ open_card (ctrl_t ctrl)
if ( IS_LOCKED (ctrl) ) if ( IS_LOCKED (ctrl) )
return gpg_error (GPG_ERR_LOCKED); return gpg_error (GPG_ERR_LOCKED);
if (ctrl->app_ctx) if (ctrl->card_ctx)
return 0; return 0;
return select_application (ctrl, NULL, &ctrl->app_ctx, 0, NULL, 0); return select_application (ctrl, NULL, &ctrl->card_ctx, 0, NULL, 0);
} }
/* Explicitly open a card for a specific use of APPTYPE or SERIALNO. */ /* Explicitly open a card for a specific use of APPTYPE or SERIALNO. */
@ -224,22 +226,24 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
gpg_error_t err; gpg_error_t err;
unsigned char *serialno_bin = NULL; unsigned char *serialno_bin = NULL;
size_t serialno_bin_len = 0; size_t serialno_bin_len = 0;
app_t app = ctrl->app_ctx; card_t card = ctrl->card_ctx;
/* If we are already initialized for one specific application we /* If we are already initialized for one specific application we
need to check that the client didn't requested a specific need to check that the client didn't requested a specific
application different from the one in use before we continue. */ application different from the one in use before we continue. */
if (apptype && ctrl->app_ctx) /* FIXME: Extend to allow switching between apps. */
return check_application_conflict (apptype, ctrl->app_ctx); if (apptype && ctrl->card_ctx)
return check_application_conflict (apptype, ctrl->card_ctx);
/* Re-scan USB devices. Release APP, before the scan. */ /* Re-scan USB devices. Release CARD, before the scan. */
ctrl->app_ctx = NULL; /* FIXME: Is a card_unref sufficient or do we need to deallocate? */
app_unref (app); ctrl->card_ctx = NULL;
card_unref (card);
if (serialno) if (serialno)
serialno_bin = hex_to_buffer (serialno, &serialno_bin_len); serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
err = select_application (ctrl, apptype, &ctrl->app_ctx, 1, err = select_application (ctrl, apptype, &ctrl->card_ctx, 1,
serialno_bin, serialno_bin_len); serialno_bin, serialno_bin_len);
xfree (serialno_bin); xfree (serialno_bin);
@ -313,7 +317,7 @@ cmd_serialno (assuan_context_t ctx, char *line)
c->server_local->card_removed = 0; c->server_local->card_removed = 0;
} }
serial = app_get_serialno (ctrl->app_ctx); serial = card_get_serialno (ctrl->card_ctx);
if (!serial) if (!serial)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
@ -411,18 +415,18 @@ cmd_learn (assuan_context_t ctx, char *line)
{ {
const char *reader; const char *reader;
char *serial; char *serial;
app_t app = ctrl->app_ctx; card_t card = ctrl->card_ctx;
if (!app) if (!card)
return gpg_error (GPG_ERR_CARD_NOT_PRESENT); return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
reader = apdu_get_reader_name (app->slot); reader = apdu_get_reader_name (card->slot);
if (!reader) if (!reader)
return out_of_core (); return out_of_core ();
send_status_direct (ctrl, "READER", reader); send_status_direct (ctrl, "READER", reader);
/* No need to free the string of READER. */ /* No need to free the string of READER. */
serial = app_get_serialno (ctrl->app_ctx); serial = card_get_serialno (ctrl->card_ctx);
if (!serial) if (!serial)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
@ -461,7 +465,7 @@ cmd_learn (assuan_context_t ctx, char *line)
/* Let the application print out its collection of useful status /* Let the application print out its collection of useful status
information. */ information. */
if (!rc) if (!rc)
rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo); rc = app_write_learn_status (ctrl->card_ctx, ctrl, only_keypairinfo);
return rc; return rc;
} }
@ -484,7 +488,7 @@ cmd_readcert (assuan_context_t ctx, char *line)
return rc; return rc;
line = xstrdup (line); /* Need a copy of the line. */ line = xstrdup (line); /* Need a copy of the line. */
rc = app_readcert (ctrl->app_ctx, ctrl, line, &cert, &ncert); rc = app_readcert (ctrl->card_ctx, ctrl, line, &cert, &ncert);
if (rc) if (rc)
log_error ("app_readcert failed: %s\n", gpg_strerror (rc)); log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
xfree (line); xfree (line);
@ -536,7 +540,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
/* If the application supports the READKEY function we use that. /* If the application supports the READKEY function we use that.
Otherwise we use the old way by extracting it from the Otherwise we use the old way by extracting it from the
certificate. */ certificate. */
rc = app_readkey (ctrl->app_ctx, ctrl, line, rc = app_readkey (ctrl->card_ctx, ctrl, line,
opt_info? APP_READKEY_FLAG_INFO : 0, opt_info? APP_READKEY_FLAG_INFO : 0,
opt_nokey? NULL : &pk, &pklen); opt_nokey? NULL : &pk, &pklen);
if (!rc) if (!rc)
@ -545,7 +549,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
|| gpg_err_code (rc) == GPG_ERR_NOT_FOUND) || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{ {
/* Fall back to certificate reading. */ /* Fall back to certificate reading. */
rc = app_readcert (ctrl->app_ctx, ctrl, line, &cert, &ncert); rc = app_readcert (ctrl->card_ctx, ctrl, line, &cert, &ncert);
if (rc) if (rc)
{ {
log_error ("app_readcert failed: %s\n", gpg_strerror (rc)); log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
@ -757,7 +761,7 @@ cmd_pksign (assuan_context_t ctx, char *line)
size_t outdatalen; size_t outdatalen;
char *keyidstr; char *keyidstr;
int hash_algo; int hash_algo;
app_t app; card_t card;
int direct = 0; int direct = 0;
if (has_option (line, "--hash=rmd160")) if (has_option (line, "--hash=rmd160"))
@ -791,27 +795,27 @@ cmd_pksign (assuan_context_t ctx, char *line)
if (!keyidstr) if (!keyidstr)
return out_of_core (); return out_of_core ();
/* When it's a keygrip, we directly use APP, with no change of /* When it's a keygrip, we directly use the card, with no change of
ctrl->app_ctx. */ ctrl->card_ctx. */
if (strlen (keyidstr) == 40) if (strlen (keyidstr) == 40)
{ {
app = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr); card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr);
direct = 1; direct = 1;
} }
else else
app = ctrl->app_ctx; card = ctrl->card_ctx;
if (app) if (card)
{ {
if (direct) if (direct)
app_ref (app); card_ref (card);
rc = app_sign (app, ctrl, rc = app_sign (card, ctrl,
keyidstr, hash_algo, keyidstr, hash_algo,
pin_cb, ctx, pin_cb, ctx,
ctrl->in_data.value, ctrl->in_data.valuelen, ctrl->in_data.value, ctrl->in_data.valuelen,
&outdata, &outdatalen); &outdata, &outdatalen);
if (direct) if (direct)
app_unref (app); card_unref (card);
} }
else else
rc = gpg_error (GPG_ERR_NO_SECKEY); rc = gpg_error (GPG_ERR_NO_SECKEY);
@ -843,13 +847,13 @@ cmd_pkauth (assuan_context_t ctx, char *line)
unsigned char *outdata; unsigned char *outdata;
size_t outdatalen; size_t outdatalen;
char *keyidstr; char *keyidstr;
app_t app; card_t card;
int direct = 0; int direct = 0;
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
if (!ctrl->app_ctx) if (!ctrl->card_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
/* We have to use a copy of the key ID because the function may use /* We have to use a copy of the key ID because the function may use
@ -859,25 +863,25 @@ cmd_pkauth (assuan_context_t ctx, char *line)
if (!keyidstr) if (!keyidstr)
return out_of_core (); return out_of_core ();
/* When it's a keygrip, we directly use APP, with no change of /* When it's a keygrip, we directly use CARD, with no change of
ctrl->app_ctx. */ ctrl->card_ctx. */
if (strlen (keyidstr) == 40) if (strlen (keyidstr) == 40)
{ {
app = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr); card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr);
direct = 1; direct = 1;
} }
else else
app = ctrl->app_ctx; card = ctrl->card_ctx;
if (app) if (card)
{ {
if (direct) if (direct)
app_ref (app); card_ref (card);
rc = app_auth (app, ctrl, keyidstr, pin_cb, ctx, rc = app_auth (card, ctrl, keyidstr, pin_cb, ctx,
ctrl->in_data.value, ctrl->in_data.valuelen, ctrl->in_data.value, ctrl->in_data.valuelen,
&outdata, &outdatalen); &outdata, &outdatalen);
if (direct) if (direct)
app_unref (app); card_unref (card);
} }
else else
rc = gpg_error (GPG_ERR_NO_SECKEY); rc = gpg_error (GPG_ERR_NO_SECKEY);
@ -910,7 +914,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
size_t outdatalen; size_t outdatalen;
char *keyidstr; char *keyidstr;
unsigned int infoflags; unsigned int infoflags;
app_t app; card_t card;
int direct = 0; int direct = 0;
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
@ -920,25 +924,25 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
if (!keyidstr) if (!keyidstr)
return out_of_core (); return out_of_core ();
/* When it's a keygrip, we directly use APP, with no change of /* When it's a keygrip, we directly use CARD, with no change of
ctrl->app_ctx. */ ctrl->card_ctx. */
if (strlen (keyidstr) == 40) if (strlen (keyidstr) == 40)
{ {
app = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr); card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr);
direct = 1; direct = 1;
} }
else else
app = ctrl->app_ctx; card = ctrl->card_ctx;
if (app) if (card)
{ {
if (direct) if (direct)
app_ref (app); card_ref (card);
rc = app_decipher (ctrl->app_ctx, ctrl, keyidstr, pin_cb, ctx, rc = app_decipher (card, ctrl, keyidstr, pin_cb, ctx,
ctrl->in_data.value, ctrl->in_data.valuelen, ctrl->in_data.value, ctrl->in_data.valuelen,
&outdata, &outdatalen, &infoflags); &outdata, &outdatalen, &infoflags);
if (direct) if (direct)
app_unref (app); card_unref (card);
} }
else else
rc = gpg_error (GPG_ERR_NO_SECKEY); rc = gpg_error (GPG_ERR_NO_SECKEY);
@ -999,7 +1003,7 @@ cmd_getattr (assuan_context_t ctx, char *line)
/* FIXME: Applications should not return sensitive data if the card /* FIXME: Applications should not return sensitive data if the card
is locked. */ is locked. */
rc = app_getattr (ctrl->app_ctx, ctrl, keyword); rc = app_getattr (ctrl->card_ctx, ctrl, keyword);
return rc; return rc;
} }
@ -1061,7 +1065,7 @@ cmd_setattr (assuan_context_t ctx, char *orig_line)
assuan_end_confidential (ctx); assuan_end_confidential (ctx);
if (!err) if (!err)
{ {
err = app_setattr (ctrl->app_ctx, ctrl, keyword, pin_cb, ctx, err = app_setattr (ctrl->card_ctx, ctrl, keyword, pin_cb, ctx,
value, nbytes); value, nbytes);
wipememory (value, nbytes); wipememory (value, nbytes);
xfree (value); xfree (value);
@ -1071,7 +1075,7 @@ cmd_setattr (assuan_context_t ctx, char *orig_line)
else else
{ {
nbytes = percent_plus_unescape_inplace (line, 0); nbytes = percent_plus_unescape_inplace (line, 0);
err = app_setattr (ctrl->app_ctx, ctrl, keyword, pin_cb, ctx, err = app_setattr (ctrl->card_ctx, ctrl, keyword, pin_cb, ctx,
(const unsigned char*)line, nbytes); (const unsigned char*)line, nbytes);
} }
@ -1112,7 +1116,7 @@ cmd_writecert (assuan_context_t ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
if (!ctrl->app_ctx) if (!ctrl->card_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
certid = xtrystrdup (certid); certid = xtrystrdup (certid);
@ -1129,7 +1133,7 @@ cmd_writecert (assuan_context_t ctx, char *line)
} }
/* Write the certificate to the card. */ /* Write the certificate to the card. */
rc = app_writecert (ctrl->app_ctx, ctrl, certid, rc = app_writecert (ctrl->card_ctx, ctrl, certid,
pin_cb, ctx, certdata, certdatalen); pin_cb, ctx, certdata, certdatalen);
xfree (certid); xfree (certid);
xfree (certdata); xfree (certdata);
@ -1174,7 +1178,7 @@ cmd_writekey (assuan_context_t ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
if (!ctrl->app_ctx) if (!ctrl->card_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
keyid = xtrystrdup (keyid); keyid = xtrystrdup (keyid);
@ -1192,7 +1196,7 @@ cmd_writekey (assuan_context_t ctx, char *line)
} }
/* Write the key to the card. */ /* Write the key to the card. */
rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0, rc = app_writekey (ctrl->card_ctx, ctrl, keyid, force? 1:0,
pin_cb, ctx, keydata, keydatalen); pin_cb, ctx, keydata, keydatalen);
xfree (keyid); xfree (keyid);
xfree (keydata); xfree (keydata);
@ -1266,7 +1270,7 @@ cmd_genkey (assuan_context_t ctx, char *line)
if ((err = open_card (ctrl))) if ((err = open_card (ctrl)))
goto leave; goto leave;
if (!ctrl->app_ctx) if (!ctrl->card_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
keyref = keyref_buffer = xtrystrdup (keyref); keyref = keyref_buffer = xtrystrdup (keyref);
@ -1275,7 +1279,7 @@ cmd_genkey (assuan_context_t ctx, char *line)
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
goto leave; goto leave;
} }
err = app_genkey (ctrl->app_ctx, ctrl, keyref, opt_algo, err = app_genkey (ctrl->card_ctx, ctrl, keyref, opt_algo,
force? APP_GENKEY_FLAG_FORCE : 0, force? APP_GENKEY_FLAG_FORCE : 0,
timestamp, pin_cb, ctx); timestamp, pin_cb, ctx);
@ -1310,14 +1314,14 @@ cmd_random (assuan_context_t ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
if (!ctrl->app_ctx) if (!ctrl->card_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
buffer = xtrymalloc (nbytes); buffer = xtrymalloc (nbytes);
if (!buffer) if (!buffer)
return out_of_core (); return out_of_core ();
rc = app_get_challenge (ctrl->app_ctx, ctrl, nbytes, buffer); rc = app_get_challenge (ctrl->card_ctx, ctrl, nbytes, buffer);
if (!rc) if (!rc)
{ {
rc = assuan_send_data (ctx, buffer, nbytes); rc = assuan_send_data (ctx, buffer, nbytes);
@ -1371,13 +1375,13 @@ cmd_passwd (assuan_context_t ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
if (!ctrl->app_ctx) if (!ctrl->card_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
chvnostr = xtrystrdup (chvnostr); chvnostr = xtrystrdup (chvnostr);
if (!chvnostr) if (!chvnostr)
return out_of_core (); return out_of_core ();
rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx); rc = app_change_pin (ctrl->card_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
if (rc) if (rc)
log_error ("command passwd failed: %s\n", gpg_strerror (rc)); log_error ("command passwd failed: %s\n", gpg_strerror (rc));
xfree (chvnostr); xfree (chvnostr);
@ -1428,7 +1432,7 @@ cmd_checkpin (assuan_context_t ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
if (!ctrl->app_ctx) if (!ctrl->card_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
/* We have to use a copy of the key ID because the function may use /* We have to use a copy of the key ID because the function may use
@ -1438,7 +1442,7 @@ cmd_checkpin (assuan_context_t ctx, char *line)
if (!idstr) if (!idstr)
return out_of_core (); return out_of_core ();
rc = app_check_pin (ctrl->app_ctx, ctrl, idstr, pin_cb, ctx); rc = app_check_pin (ctrl->card_ctx, ctrl, idstr, pin_cb, ctx);
xfree (idstr); xfree (idstr);
if (rc) if (rc)
log_error ("app_check_pin failed: %s\n", gpg_strerror (rc)); log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
@ -1641,14 +1645,14 @@ static gpg_error_t
cmd_restart (assuan_context_t ctx, char *line) cmd_restart (assuan_context_t ctx, char *line)
{ {
ctrl_t ctrl = assuan_get_pointer (ctx); ctrl_t ctrl = assuan_get_pointer (ctx);
app_t app = ctrl->app_ctx; card_t card = ctrl->card_ctx;
(void)line; (void)line;
if (app) if (card)
{ {
ctrl->app_ctx = NULL; ctrl->card_ctx = NULL;
app_unref (app); card_unref (card);
} }
if (locked_session && ctrl->server_local == locked_session) if (locked_session && ctrl->server_local == locked_session)
{ {
@ -1670,10 +1674,10 @@ cmd_disconnect (assuan_context_t ctx, char *line)
(void)line; (void)line;
if (!ctrl->app_ctx) if (!ctrl->card_ctx)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
apdu_disconnect (ctrl->app_ctx->slot); apdu_disconnect (ctrl->card_ctx->slot);
return 0; return 0;
} }
@ -1702,7 +1706,7 @@ static gpg_error_t
cmd_apdu (assuan_context_t ctx, char *line) cmd_apdu (assuan_context_t ctx, char *line)
{ {
ctrl_t ctrl = assuan_get_pointer (ctx); ctrl_t ctrl = assuan_get_pointer (ctx);
app_t app; card_t card;
int rc; int rc;
unsigned char *apdu; unsigned char *apdu;
size_t apdulen; size_t apdulen;
@ -1732,8 +1736,8 @@ cmd_apdu (assuan_context_t ctx, char *line)
if ((rc = open_card (ctrl))) if ((rc = open_card (ctrl)))
return rc; return rc;
app = ctrl->app_ctx; card = ctrl->card_ctx;
if (!app) if (!card)
return gpg_error (GPG_ERR_CARD_NOT_PRESENT); return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
if (with_atr) if (with_atr)
@ -1742,7 +1746,7 @@ cmd_apdu (assuan_context_t ctx, char *line)
size_t atrlen; size_t atrlen;
char hexbuf[400]; char hexbuf[400];
atr = apdu_get_atr (app->slot, &atrlen); atr = apdu_get_atr (card->slot, &atrlen);
if (!atr || atrlen > sizeof hexbuf - 2 ) if (!atr || atrlen > sizeof hexbuf - 2 )
{ {
rc = gpg_error (GPG_ERR_INV_CARD); rc = gpg_error (GPG_ERR_INV_CARD);
@ -1787,7 +1791,7 @@ cmd_apdu (assuan_context_t ctx, char *line)
unsigned char *result = NULL; unsigned char *result = NULL;
size_t resultlen; size_t resultlen;
rc = apdu_send_direct (app->slot, exlen, rc = apdu_send_direct (card->slot, exlen,
apdu, apdulen, handle_more, apdu, apdulen, handle_more,
NULL, &result, &resultlen); NULL, &result, &resultlen);
if (rc) if (rc)
@ -1851,7 +1855,7 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
int action; int action;
char *keygrip_str; char *keygrip_str;
ctrl_t ctrl = assuan_get_pointer (ctx); ctrl_t ctrl = assuan_get_pointer (ctx);
app_t a; card_t card;
list_mode = has_option (line, "--list"); list_mode = has_option (line, "--list");
opt_data = has_option (line, "--data"); opt_data = has_option (line, "--data");
@ -1867,9 +1871,9 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
else else
action = KEYGRIP_ACTION_WRITE_STATUS; action = KEYGRIP_ACTION_WRITE_STATUS;
a = app_do_with_keygrip (ctrl, action, keygrip_str); card = app_do_with_keygrip (ctrl, action, keygrip_str);
if (!list_mode && !a) if (!list_mode && !card)
return gpg_error (GPG_ERR_NOT_FOUND); return gpg_error (GPG_ERR_NOT_FOUND);
return 0; return 0;
} }
@ -2180,7 +2184,7 @@ popup_prompt (void *opaque, int on)
/* Helper to send the clients a status change notification. Note that /* Helper to send the clients a status change notification. Note that
* this fucntion assumes that APP is already locked. */ * this fucntion assumes that APP is already locked. */
void void
send_client_notifications (app_t app, int removal) send_client_notifications (card_t card, int removal)
{ {
struct { struct {
pid_t pid; pid_t pid;
@ -2195,7 +2199,7 @@ send_client_notifications (app_t app, int removal)
struct server_local_s *sl; struct server_local_s *sl;
for (sl=session_list; sl; sl = sl->next_session) for (sl=session_list; sl; sl = sl->next_session)
if (sl->ctrl_backlink && sl->ctrl_backlink->app_ctx == app) if (sl->ctrl_backlink && sl->ctrl_backlink->card_ctx == card)
{ {
pid_t pid; pid_t pid;
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
@ -2206,9 +2210,9 @@ send_client_notifications (app_t app, int removal)
if (removal) if (removal)
{ {
sl->ctrl_backlink->app_ctx = NULL; sl->ctrl_backlink->card_ctx = NULL;
sl->card_removed = 1; sl->card_removed = 1;
app_unref_locked (app); card_unref_locked (card);
} }
if (!sl->event_signal || !sl->assuan_ctx) if (!sl->event_signal || !sl->assuan_ctx)

View File

@ -84,6 +84,7 @@ struct
#define DBG_READER (opt.debug & DBG_READER_VALUE) #define DBG_READER (opt.debug & DBG_READER_VALUE)
struct server_local_s; struct server_local_s;
struct card_ctx_s;
struct app_ctx_s; struct app_ctx_s;
struct server_control_s struct server_control_s
@ -101,7 +102,7 @@ struct server_control_s
associated. Note that this is shared with the other connections: associated. Note that this is shared with the other connections:
All connections accessing the same reader are using the same All connections accessing the same reader are using the same
application context. */ application context. */
struct app_ctx_s *app_ctx; struct card_ctx_s *card_ctx;
/* Helper to store the value we are going to sign */ /* Helper to store the value we are going to sign */
struct struct
@ -111,6 +112,7 @@ struct server_control_s
} in_data; } in_data;
}; };
typedef struct card_ctx_s *card_t;
typedef struct app_ctx_s *app_t; typedef struct app_ctx_s *app_t;
/*-- scdaemon.c --*/ /*-- scdaemon.c --*/
@ -130,8 +132,8 @@ void send_keyinfo (ctrl_t ctrl, int data, const char *keygrip_str,
void popup_prompt (void *opaque, int on); void popup_prompt (void *opaque, int on);
/* Take care: this function assumes that APP is locked. */ /* Take care: this function assumes that CARD is locked. */
void send_client_notifications (app_t app, int removal); void send_client_notifications (card_t card, int removal);
void scd_kick_the_loop (void); void scd_kick_the_loop (void);
int get_active_connection_count (void); int get_active_connection_count (void);