From 7620473cd007c074b0625a678caa6105a4c87142 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 27 Jan 2021 18:31:12 +0100 Subject: [PATCH] scd: Define new status word * scd/apdu.h (SW_NO_CURRENT_EF): New. -- This merely to show better diagnostics. Used for example by CardOS 5.3. --- scd/apdu.c | 1 + scd/apdu.h | 1 + scd/iso7816.c | 22 ++++++++++++++-------- scd/iso7816.h | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index 9b473d56a..fa0fb7c43 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -548,6 +548,7 @@ apdu_strerror (int rc) case SW_CHV_BLOCKED : return "CHV blocked"; case SW_REF_DATA_INV : return "referenced data invalidated"; case SW_USE_CONDITIONS : return "use conditions not satisfied"; + case SW_NO_CURRENT_EF : return "no current EF selected"; case SW_BAD_PARAMETER : return "bad parameter"; case SW_NOT_SUPPORTED : return "not supported"; case SW_FILE_NOT_FOUND : return "file not found"; diff --git a/scd/apdu.h b/scd/apdu.h index d042c7cde..fd03ae6f0 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -39,6 +39,7 @@ enum { SW_CHV_BLOCKED = 0x6983, SW_REF_DATA_INV = 0x6984, /* Referenced data invalidated. */ SW_USE_CONDITIONS = 0x6985, + SW_NO_CURRENT_EF = 0x6986, /* No current EF selected. */ SW_BAD_PARAMETER = 0x6a80, /* (in the data field) */ SW_NOT_SUPPORTED = 0x6a81, SW_FILE_NOT_FOUND = 0x6a82, diff --git a/scd/iso7816.c b/scd/iso7816.c index c68aab075..a796553d7 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -63,6 +63,7 @@ map_sw (int sw) case SW_CHV_WRONG: ec = GPG_ERR_BAD_PIN; break; case SW_CHV_BLOCKED: ec = GPG_ERR_PIN_BLOCKED; break; case SW_USE_CONDITIONS: ec = GPG_ERR_USE_CONDITIONS; break; + case SW_NO_CURRENT_EF: ec = GPG_ERR_ENOENT; break; case SW_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break; case SW_BAD_PARAMETER: ec = GPG_ERR_INV_VALUE; break; case SW_FILE_NOT_FOUND: ec = GPG_ERR_ENOENT; break; @@ -185,27 +186,32 @@ iso7816_select_file (int slot, int tag, int is_dir) } -/* Do a select file command with a direct path. If FROM_CDF is set - * the starting point is the current direcory file (feature depends on - * the card). */ +/* Do a select file command with a direct path. If TOPDF is set, the + * actual used path is 3f00//. */ gpg_error_t iso7816_select_path (int slot, const unsigned short *path, size_t pathlen, - int from_cdf) + unsigned short topdf) { int sw, p0, p1; unsigned char buffer[100]; - int buflen; + int buflen = 0; - if (pathlen/2 >= sizeof buffer) + if (pathlen*2 + 2 >= sizeof buffer) return gpg_error (GPG_ERR_TOO_LARGE); - for (buflen = 0; pathlen; pathlen--, path++) + if (topdf) + { + buffer[buflen++] = topdf >> 8; + buffer[buflen++] = topdf; + } + + for (; pathlen; pathlen--, path++) { buffer[buflen++] = (*path >> 8); buffer[buflen++] = *path; } - p0 = from_cdf? 0x09 : 0x08; + p0 = 0x08; p1 = 0x0c; /* No FC return. */ sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE, p0, p1, buflen, (char*)buffer ); diff --git a/scd/iso7816.h b/scd/iso7816.h index 06ee5eaa1..d9fd3eb69 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -69,7 +69,7 @@ gpg_error_t iso7816_select_mf (int slot); gpg_error_t iso7816_select_file (int slot, int tag, int is_dir); gpg_error_t iso7816_select_path (int slot, const unsigned short *path, size_t pathlen, - int from_cdf); + unsigned short topdf); gpg_error_t iso7816_list_directory (int slot, int list_dirs, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_send_apdu (int slot, int extended_mode,