diff --git a/picc_to_pcsc/AUTHORS b/pcsc-relay/AUTHORS similarity index 100% rename from picc_to_pcsc/AUTHORS rename to pcsc-relay/AUTHORS diff --git a/picc_to_pcsc/COPYING b/pcsc-relay/COPYING similarity index 100% rename from picc_to_pcsc/COPYING rename to pcsc-relay/COPYING diff --git a/picc_to_pcsc/ChangeLog b/pcsc-relay/ChangeLog similarity index 100% rename from picc_to_pcsc/ChangeLog rename to pcsc-relay/ChangeLog diff --git a/picc_to_pcsc/Makefile.am b/pcsc-relay/Makefile.am similarity index 100% rename from picc_to_pcsc/Makefile.am rename to pcsc-relay/Makefile.am diff --git a/picc_to_pcsc/NEWS b/pcsc-relay/NEWS similarity index 100% rename from picc_to_pcsc/NEWS rename to pcsc-relay/NEWS diff --git a/picc_to_pcsc/README b/pcsc-relay/README similarity index 100% rename from picc_to_pcsc/README rename to pcsc-relay/README diff --git a/picc_to_pcsc/configure.ac b/pcsc-relay/configure.ac similarity index 100% rename from picc_to_pcsc/configure.ac rename to pcsc-relay/configure.ac diff --git a/pcsc-relay/src/Makefile.am b/pcsc-relay/src/Makefile.am new file mode 100644 index 0000000..91bc563 --- /dev/null +++ b/pcsc-relay/src/Makefile.am @@ -0,0 +1,10 @@ +EXTRA_DIST = picc.py + +bin_PROGRAMS = pcsc-relay +bin_SCRIPTS = picc.py + +pcsc_relay_SOURCES = pcsc-relay.c pcscutil.c opicc.c lnfc.c +pcsc_relay_LDADD = $(PCSC_LIBS) $(LIBNFC_LIBS) +pcsc_relay_CFLAGS = $(PCSC_CFLAGS) $(LIBNFC_CFLAGS) + +noinst_HEADERS = pcscutil.h pcsc-relay.h diff --git a/pcsc-relay/src/lnfc.c b/pcsc-relay/src/lnfc.c new file mode 100644 index 0000000..0d70960 --- /dev/null +++ b/pcsc-relay/src/lnfc.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2010 Frank Morgner + * + * This file is part of pcsc-relay. + * + * pcsc-relay is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * pcsc-relay is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * pcsc-relay. If not, see . + */ +#include +#include +#include + +#include "pcsc-relay.h" + +struct lnfc_data { + /* PN53X only supports short APDUs */ + byte_t abtCapdu[4+1+0xff+1]; + size_t szCapduLen; + nfc_device_t *pndTarget; +}; + + +static int lnfc_connect(void **driver_data) +{ + struct lnfc_data *data; + nfc_target_t ntEmulatedTarget = { + .nm.nmt = NMT_ISO14443A, + .nm.nbr = NBR_106, + }; + + if (!driver_data) + return 0; + + + data = realloc(*driver_data, sizeof *data); + if (!data) + return 0; + memset(data, 0, sizeof *data); + *driver_data = data; + + /* FIXME + * ntEmulatedTarget.nti.nai.abtUid + * ntEmulatedTarget.nti.nai.abtAtqa + * ntEmulatedTarget.nti.nai.btSak + * ntEmulatedTarget.nti.nai.abtAts + */ + // We can only emulate a short UID, so fix length & ATQA bit: + ntEmulatedTarget.nti.nai.szUidLen = 4; + ntEmulatedTarget.nti.nai.abtAtqa[1] &= (0xFF-0x40); + // First byte of UID is always automatically replaced by 0x08 in this mode anyway + ntEmulatedTarget.nti.nai.abtUid[0] = 0x08; + // ATS is always automatically replaced by PN532, we've no control on it: + // ATS = (05) 75 33 92 03 + // (TL) T0 TA TB TC + // | | | +-- CID supported, NAD supported + // | | +----- FWI=9 SFGI=2 => FWT=154ms, SFGT=1.21ms + // | +-------- DR=2,4 DS=2,4 => supports 106, 212 & 424bps in both directions + // +----------- TA,TB,TC, FSCI=5 => FSC=64 + // It seems hazardous to tell we support NAD if the tag doesn't support NAD but I don't know how to disable it + // PC/SC pseudo-ATR = 3B 80 80 01 01 if there is no historical bytes + + // Creates ATS and copy max 48 bytes of Tk: + /* + byte_t * pbtTk; + size_t szTk; + pbtTk = iso14443a_locate_historical_bytes (ntEmulatedTarget.nti.nai.abtAts, ntEmulatedTarget.nti.nai.szAtsLen, &szTk); + szTk = (szTk > 48) ? 48 : szTk; + byte_t pbtTkt[48]; + memcpy(pbtTkt, pbtTk, szTk); + ntEmulatedTarget.nti.nai.abtAts[0] = 0x75; + ntEmulatedTarget.nti.nai.abtAts[1] = 0x33; + ntEmulatedTarget.nti.nai.abtAts[2] = 0x92; + ntEmulatedTarget.nti.nai.abtAts[3] = 0x03; + ntEmulatedTarget.nti.nai.szAtsLen = 4 + szTk; + memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk); + */ + + // Try to open the NFC emulator device + data->pndTarget = nfc_connect (NULL); + if (data->pndTarget == NULL) { + if (verbose || debug) + fprintf (stderr, "Error connecting NFC emulator device\n"); + return 0; + } + + if (verbose) + printf ("Connected to the NFC emulator device: %s\n", data->pndTarget->acName); + + if (!nfc_target_init (data->pndTarget, &ntEmulatedTarget, data->abtCapdu, &data->szCapduLen)) { + if (verbose || debug) + fprintf (stderr, "%s", "Initialization of NFC emulator failed"); + nfc_disconnect (data->pndTarget); + return 0; + } + if (debug) + printf ("%s\n", "Done, relaying frames now!"); + + + return 1; +} + +static int lnfc_disconnect(void *driver_data) +{ + struct lnfc_data *data = driver_data; + + + nfc_disconnect (data->pndTarget); + + + return 1; +} + +static int lnfc_receive_capdu(void *driver_data, + unsigned char **capdu, size_t *len) +{ + struct lnfc_data *data = driver_data; + + if (!data || !capdu || !len) + return 0; + + + // Receive external reader command through target + if (!nfc_target_receive_bytes(data->pndTarget, data->abtCapdu, &data->szCapduLen)) { + if (verbose || debug) + nfc_perror (data->pndTarget, "nfc_target_receive_bytes"); + return 0; + } + + + return 1; +} + +static int lnfc_send_rapdu(void *driver_data, + const unsigned char *rapdu, size_t len) +{ + struct lnfc_data *data = driver_data; + + if (!data || !rapdu) + return 0; + + + if (!nfc_target_send_bytes(data->pndTarget, rapdu, len)) + nfc_perror (data->pndTarget, "nfc_target_send_bytes"); + + + return 1; +} + + +struct rf_driver driver_libnfc = { + .data = NULL, + .connect = lnfc_connect, + .disconnect = lnfc_disconnect, + .receive_capdu = lnfc_receive_capdu, + .send_rapdu = lnfc_send_rapdu, +}; diff --git a/picc_to_pcsc/src/opicc.c b/pcsc-relay/src/opicc.c similarity index 72% rename from picc_to_pcsc/src/opicc.c rename to pcsc-relay/src/opicc.c index d13bb10..4bd75f7 100644 --- a/picc_to_pcsc/src/opicc.c +++ b/pcsc-relay/src/opicc.c @@ -1,30 +1,31 @@ /* * Copyright (C) 2010 Frank Morgner * - * This file is part of ccid. + * This file is part of pcsc-relay. * - * ccid is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. + * pcsc-relay is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. * - * ccid is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. + * pcsc-relay is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * * You should have received a copy of the GNU General Public License along with - * ccid. If not, see . + * pcsc-relay. If not, see . */ #include #include +#include #include "config.h" #include "pcsc-relay.h" struct picc_data { - char *read; - size_t readlen; + char *buf; + size_t buflen; FILE *fd; }; static size_t picc_encode_rapdu(const unsigned char *inbuf, size_t inlen, char **outbuf); @@ -114,18 +115,19 @@ noapdu: static int picc_connect(void **driver_data) { - struct picc_data *p; + struct picc_data *data; if (!driver_data) return 0; - p = realloc(*driver_data, sizeof *p); - if (!p) + data = realloc(*driver_data, sizeof *data); + if (!data) return 0; - *driver_data = p; + memset(data, 0, sizeof *data); + *driver_data = data; - p->fd = fopen(PICCDEV, "a+"); /*O_NOCTTY ?*/ - if (!p->fd) { + data->fd = fopen(PICCDEV, "a+"); /*O_NOCTTY ?*/ + if (!data->fd) { if (debug || verbose) fprintf(stderr,"Error opening %s\n", PICCDEV); return 0; @@ -139,8 +141,12 @@ static int picc_connect(void **driver_data) static int picc_disconnect(void *driver_data) { struct picc_data *data = driver_data; - if (data && data->fd) - fclose(data->fd); + if (data) { + if (data->fd) + fclose(data->fd); + if (data->buf) + free(data->buf); + } return 1; } @@ -156,7 +162,7 @@ static int picc_receive_capdu(void *driver_data, /* read C-APDU */ - linelen = getline(&data->read, &data->readlen, data->fd); + linelen = getline(&data->buf, &data->buflen, data->fd); if (linelen < 0) { if (linelen < 0) { if (debug || verbose) @@ -171,11 +177,11 @@ static int picc_receive_capdu(void *driver_data, fflush(data->fd); if (debug) - printf("%s\n", data->read); + printf("%s\n", data->buf); /* decode C-APDU */ - *len = picc_decode_apdu(data->read, linelen, capdu); + *len = picc_decode_apdu(data->buf, linelen, capdu); return 1; } @@ -183,7 +189,6 @@ static int picc_receive_capdu(void *driver_data, static int picc_send_rapdu(void *driver_data, const unsigned char *rapdu, size_t len) { - char *buf = NULL; size_t buflen; struct picc_data *data = driver_data; @@ -192,21 +197,20 @@ static int picc_send_rapdu(void *driver_data, /* encode R-APDU */ - buflen = picc_encode_rapdu(rapdu, len, &buf); + buflen = picc_encode_rapdu(rapdu, len, &data->buf); + if (buflen > data->buflen) + data->buflen = buflen; /* write R-APDU */ if (debug) - printf("INF: Writing R-APDU\n\n%s\n\n", buf); + printf("INF: Writing R-APDU\n\n%s\n\n", data->buf); - if (fprintf(data->fd,"%s\r\n", (char *) buf) < 0 + if (fprintf(data->fd,"%s\r\n", (char *) data->buf) < 0 || fflush(data->fd) != 0) { - free(buf); return 0; } - free(buf); - return 1; } diff --git a/picc_to_pcsc/src/pcsc-relay.c b/pcsc-relay/src/pcsc-relay.c similarity index 92% rename from picc_to_pcsc/src/pcsc-relay.c rename to pcsc-relay/src/pcsc-relay.c index 18bb401..d5560fe 100644 --- a/picc_to_pcsc/src/pcsc-relay.c +++ b/pcsc-relay/src/pcsc-relay.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2010 Dominik Oepen, Frank Morgner * - * This file is part of picc_to_pcsc. + * This file is part of pcsc-relay. * - * picc_to_pcsc is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free + * pcsc-relay is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * - * picc_to_pcsc is distributed in the hope that it will be useful, but WITHOUT + * pcsc-relay is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with - * picc_to_pcsc. If not, see . + * pcsc-relay. If not, see . */ #include #include diff --git a/picc_to_pcsc/src/pcsc-relay.h b/pcsc-relay/src/pcsc-relay.h similarity index 54% rename from picc_to_pcsc/src/pcsc-relay.h rename to pcsc-relay/src/pcsc-relay.h index 8ffc7a4..4c3b787 100644 --- a/picc_to_pcsc/src/pcsc-relay.h +++ b/pcsc-relay/src/pcsc-relay.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2010 Frank Morgner * - * This file is part of ccid. + * This file is part of pcsc-relay. * - * ccid is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. + * pcsc-relay is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. * - * ccid is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. + * pcsc-relay is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * * You should have received a copy of the GNU General Public License along with - * ccid. If not, see . + * pcsc-relay. If not, see . */ /** * @file diff --git a/picc_to_pcsc/src/pcscutil.c b/pcsc-relay/src/pcscutil.c similarity index 100% rename from picc_to_pcsc/src/pcscutil.c rename to pcsc-relay/src/pcscutil.c diff --git a/picc_to_pcsc/src/pcscutil.h b/pcsc-relay/src/pcscutil.h similarity index 100% rename from picc_to_pcsc/src/pcscutil.h rename to pcsc-relay/src/pcscutil.h diff --git a/picc_to_pcsc/src/picc.py b/pcsc-relay/src/picc.py similarity index 100% rename from picc_to_pcsc/src/picc.py rename to pcsc-relay/src/picc.py diff --git a/picc_to_pcsc/src/Makefile.am b/picc_to_pcsc/src/Makefile.am deleted file mode 100644 index 0e1b7d7..0000000 --- a/picc_to_pcsc/src/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -EXTRA_DIST = picc.py - -bin_PROGRAMS = pcsc-relay -bin_SCRIPTS = picc.py - -pcsc_relay_SOURCES = pcsc-relay.c pcscutil.c opicc.c -pcsc_relay_LDADD = $(PCSC_LIBS) -pcsc_relay_CFLAGS = $(PCSC_CFLAGS) - -noinst_HEADERS = pcscutil.h pcsc-relay.h