From 855d14d390e8dd8464f2f38187dbccb19a13e815 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 26 Jan 2021 17:42:55 +0100 Subject: [PATCH] scd: Extend iso7816_select_path * scd/iso7816.c (iso7816_select_path): Add arg top_fd. * scd/app-nks.c (do_readkey): Adjust for this change (select_ef_by_path: Ditto. * common/tlv.h: Include membuf.h. -- Including membuf.h is just for easier backporting. In 2.3 it is actually required in tlv.h but in 2.2 we right now only use it indirect. --- common/tlv.h | 2 ++ scd/app-nks.c | 2 +- scd/app-p15.c | 6 +++--- scd/iso7816.c | 18 +++++++++++++----- scd/iso7816.h | 3 ++- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/common/tlv.h b/common/tlv.h index ba4ea2e42..0894e5d05 100644 --- a/common/tlv.h +++ b/common/tlv.h @@ -30,6 +30,8 @@ #ifndef SCD_TLV_H #define SCD_TLV_H 1 +#include "membuf.h" + enum tlv_tag_class { CLASS_UNIVERSAL = 0, diff --git a/scd/app-nks.c b/scd/app-nks.c index 3cbf1e414..d7a4dbd36 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -628,7 +628,7 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyid, unsigned int flags, return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); /* 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), 0); if (err) return err; /* Due to the above select we need to re-select our application. */ diff --git a/scd/app-p15.c b/scd/app-p15.c index 21f7726cd..687c6ad32 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -501,7 +501,7 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) if (app->app_local->direct_path_selection) { - err = iso7816_select_path (app->slot, path+1, pathlen-1); + err = iso7816_select_path (app->slot, path+1, pathlen-1, 0); if (err) { log_error ("p15: error selecting path "); @@ -4104,7 +4104,7 @@ app_select_p15 (app_t app) Using the 2f02 just works. */ unsigned short path[1] = { 0x2f00 }; - rc = iso7816_select_path (slot, path, 1); + rc = iso7816_select_path (slot, path, 1, 0); if (!rc) { direct = 1; @@ -4112,7 +4112,7 @@ app_select_p15 (app_t app) if (def_home_df) { path[0] = def_home_df; - rc = iso7816_select_path (slot, path, 1); + rc = iso7816_select_path (slot, path, 1, 0); } } } diff --git a/scd/iso7816.c b/scd/iso7816.c index 450590175..dcb2845c7 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -193,18 +193,26 @@ iso7816_select_file (int slot, int tag, int is_dir) } -/* Do a select file command with a direct path. */ +/* 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) +iso7816_select_path (int slot, const unsigned short *path, size_t pathlen, + 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; diff --git a/scd/iso7816.h b/scd/iso7816.h index 2cbfe6185..f7934bb5b 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -68,7 +68,8 @@ gpg_error_t iso7816_select_application_ext (int slot, 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); + const unsigned short *path, size_t pathlen, + unsigned short top_df); gpg_error_t iso7816_list_directory (int slot, int list_dirs, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_apdu_direct (int slot,