aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/tlv.h2
-rw-r--r--scd/app-nks.c2
-rw-r--r--scd/app-p15.c6
-rw-r--r--scd/iso7816.c18
-rw-r--r--scd/iso7816.h3
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/<topdf>/<path>. */
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,