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:
parent
c3dd53a65d
commit
5a5288d051
120
scd/app-common.h
120
scd/app-common.h
@ -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 --*/
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
168
scd/command.c
168
scd/command.c
@ -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)
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user