diff --git a/pcsc-relay/src/pcsc-relay.c b/pcsc-relay/src/pcsc-relay.c index cac7577..3e629e7 100644 --- a/pcsc-relay/src/pcsc-relay.c +++ b/pcsc-relay/src/pcsc-relay.c @@ -179,6 +179,8 @@ int main (int argc, char **argv) viccport = args_info.vicc_port_arg; if (args_info.vicc_hostname_given) vicchostname = args_info.vicc_hostname_arg; + if (args_info.vicc_atr_given) + viccatr = args_info.vicc_atr_arg; verbose = args_info.verbose_given; diff --git a/pcsc-relay/src/pcsc-relay.ggo.in b/pcsc-relay/src/pcsc-relay.ggo.in index 09730cd..53faea5 100644 --- a/pcsc-relay/src/pcsc-relay.ggo.in +++ b/pcsc-relay/src/pcsc-relay.ggo.in @@ -44,6 +44,10 @@ option "vicc-hostname" N "Hostname for connecting to virtual smart card reader" string default="wait for an incoming connection" optional +option "vicc-atr" A + "ATR" + string default="3B80800101" + optional text " Report bugs to @PACKAGE_BUGREPORT@ diff --git a/pcsc-relay/src/pcsc-relay.h b/pcsc-relay/src/pcsc-relay.h index dce304a..9eb1dc8 100644 --- a/pcsc-relay/src/pcsc-relay.h +++ b/pcsc-relay/src/pcsc-relay.h @@ -61,6 +61,7 @@ extern unsigned int vpcdport; extern char *vpcdhostname; extern unsigned int viccport; extern char *vicchostname; +extern char *viccatr; void hexdump(const char *label, unsigned char *buf, size_t len); diff --git a/pcsc-relay/src/vicc.c b/pcsc-relay/src/vicc.c index 7f4a4d5..a100de1 100644 --- a/pcsc-relay/src/vicc.c +++ b/pcsc-relay/src/vicc.c @@ -30,6 +30,9 @@ unsigned int viccport = VPCDPORT; char *vicchostname = NULL; +char *viccatr = "3B80800101"; +unsigned char atr[256]; +size_t atr_len = 0; @@ -41,6 +44,32 @@ static int _vicc_connect(driver_data_t **driver_data) if (!driver_data) return 0; + if (viccatr) { + size_t i; + unsigned char *hex = viccatr; + unsigned char *bin = atr; + atr_len = strlen(viccatr); + if (atr_len % 2 != 0) { + RELAY_ERROR("Length of ATR needs to be even\n"); + return 0; + } + atr_len /= 2; + if (atr_len > sizeof atr) { + RELAY_ERROR("ATR too long\n"); + return 0; + } + while (*hex) { + if (sscanf(hex, "%2hhX", bin) != 1) { + RELAY_ERROR("bad ATR\n"); + return 0; + } + hex += 2; + bin += 1; + } + } else { + atr_len = 0; + } + ctx = vicc_init(vicchostname, viccport); if (!ctx) { @@ -77,7 +106,6 @@ static int vicc_receive_capdu(driver_data_t *driver_data, int r = 0; ssize_t size; - const unsigned char atr[] = {0x3B, 0x80, 0x80, 0x01, 0x01}; if (!len) goto err; @@ -98,7 +126,7 @@ static int vicc_receive_capdu(driver_data_t *driver_data, // ignore reset, power on, power off break; case VPCD_CTRL_ATR: - if (vicc_transmit(ctx, sizeof atr, atr, NULL) < 0) { + if (vicc_transmit(ctx, atr_len, atr, NULL) < 0) { RELAY_ERROR("could not send ATR\n"); goto err; }