diff --git a/npa/src/pace-tool.c b/npa/src/pace-tool.c
index 3e19dea..8ecb428 100644
--- a/npa/src/pace-tool.c
+++ b/npa/src/pace-tool.c
@@ -70,6 +70,7 @@ static sc_reader_t *reader;
#define OPT_VERBOSE 'v'
#define OPT_INFO 'o'
#define OPT_CARD 'c'
+#define OPT_TRVERSION 'n'
static const struct option options[] = {
{ "help", no_argument, NULL, OPT_HELP },
@@ -86,6 +87,7 @@ static const struct option options[] = {
{ "resume-pin", no_argument, NULL, OPT_RESUME_PIN },
{ "unblock-pin", no_argument, NULL, OPT_UNBLOCK_PIN },
{ "translate", optional_argument, NULL, OPT_TRANSLATE },
+ { "tr-03110v", required_argument, NULL, OPT_TRVERSION },
{ "verbose", no_argument, NULL, OPT_VERBOSE },
{ "info", no_argument, NULL, OPT_INFO },
{ NULL, 0, NULL, 0 }
@@ -105,6 +107,7 @@ static const char *option_help[] = {
"Resume PIN (uses CAN to activate last retry)",
"Unblock PIN (uses PUK to activate three more retries)",
"APDUs to send through SM channel (default: stdin)",
+ "Version of TR-03110 (default: 2, for version 2 and later)",
"Use (several times) to be more verbose",
"Print version, available readers and drivers.",
};
@@ -188,7 +191,7 @@ main (int argc, char **argv)
memset(&pace_output, 0, sizeof pace_output);
while (1) {
- i = getopt_long(argc, argv, "hr:i::u::a::z::bC:D:N::RUt::voc:", options, &oindex);
+ i = getopt_long(argc, argv, "hr:i::u::a::z::bC:D:N::RUt::voc:n:", options, &oindex);
if (i == -1)
break;
switch (i) {
@@ -274,6 +277,12 @@ main (int argc, char **argv)
file = optarg;
}
break;
+ case OPT_TRVERSION:
+ if (sscanf(optarg, "%d", &pace_input.tr_version) != 1) {
+ parse_error(argv[0], options, option_help, optarg, oindex);
+ exit(2);
+ }
+ break;
case '?':
/* fall through */
default:
diff --git a/npa/src/pace.c b/npa/src/pace.c
index 7f2b105..7e02166 100644
--- a/npa/src/pace.c
+++ b/npa/src/pace.c
@@ -1098,7 +1098,7 @@ int EstablishPACEChannel(struct sm_ctx *oldpacectx, sc_card_t *card,
r = SC_ERROR_INTERNAL;
goto err;
}
- pctx->tr_version = PACE_TR_VERSION_2_02;
+ pctx->tr_version = pace_input.tr_version;
r = pace_mse_set_at(oldpacectx, card, info->protocol, pace_input.pin_id,
chat, &pace_output->mse_set_at_sw1, &pace_output->mse_set_at_sw2);
diff --git a/npa/src/pace/pace.h b/npa/src/pace/pace.h
index dd13e26..b8b89ac 100644
--- a/npa/src/pace/pace.h
+++ b/npa/src/pace/pace.h
@@ -100,6 +100,9 @@ const char *pace_secret_name(enum s_type pin_id);
* Input data for EstablishPACEChannel()
*/
struct establish_pace_channel_input {
+ /** Version of TR-03110 to use with PACE */
+ enum tr_version tr_version;
+
/** Type of secret (CAN, MRZ, PIN or PUK). You may use enum s_type from \c */
unsigned char pin_id;