completed renaming. fixed memory loss in openpicc driver. implemented libnfc driver.

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@349 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2010-11-10 11:28:12 +00:00
parent d4ee5d391f
commit 41dccee8eb
16 changed files with 225 additions and 55 deletions

View File

@@ -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

166
pcsc-relay/src/lnfc.c Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include <nfc/nfc.h>
#include <stdlib.h>
#include <string.h>
#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,
};

View File

@@ -1,30 +1,31 @@
/* /*
* Copyright (C) 2010 Frank Morgner * 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 * pcsc-relay is free software: you can redistribute it and/or modify it under
* terms of the GNU General Public License as published by the Free Software * the terms of the GNU General Public License as published by the Free
* Foundation, either version 3 of the License, or (at your option) any later * Software Foundation, either version 3 of the License, or (at your option)
* version. * any later version.
* *
* ccid is distributed in the hope that it will be useful, but WITHOUT ANY * pcsc-relay is distributed in the hope that it will be useful, but WITHOUT
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* details. * more details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* ccid. If not, see <http://www.gnu.org/licenses/>. * pcsc-relay. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "config.h" #include "config.h"
#include "pcsc-relay.h" #include "pcsc-relay.h"
struct picc_data { struct picc_data {
char *read; char *buf;
size_t readlen; size_t buflen;
FILE *fd; FILE *fd;
}; };
static size_t picc_encode_rapdu(const unsigned char *inbuf, size_t inlen, char **outbuf); 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) static int picc_connect(void **driver_data)
{ {
struct picc_data *p; struct picc_data *data;
if (!driver_data) if (!driver_data)
return 0; return 0;
p = realloc(*driver_data, sizeof *p); data = realloc(*driver_data, sizeof *data);
if (!p) if (!data)
return 0; return 0;
*driver_data = p; memset(data, 0, sizeof *data);
*driver_data = data;
p->fd = fopen(PICCDEV, "a+"); /*O_NOCTTY ?*/ data->fd = fopen(PICCDEV, "a+"); /*O_NOCTTY ?*/
if (!p->fd) { if (!data->fd) {
if (debug || verbose) if (debug || verbose)
fprintf(stderr,"Error opening %s\n", PICCDEV); fprintf(stderr,"Error opening %s\n", PICCDEV);
return 0; return 0;
@@ -139,8 +141,12 @@ static int picc_connect(void **driver_data)
static int picc_disconnect(void *driver_data) static int picc_disconnect(void *driver_data)
{ {
struct picc_data *data = driver_data; struct picc_data *data = driver_data;
if (data && data->fd) if (data) {
fclose(data->fd); if (data->fd)
fclose(data->fd);
if (data->buf)
free(data->buf);
}
return 1; return 1;
} }
@@ -156,7 +162,7 @@ static int picc_receive_capdu(void *driver_data,
/* read C-APDU */ /* 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 (linelen < 0) { if (linelen < 0) {
if (debug || verbose) if (debug || verbose)
@@ -171,11 +177,11 @@ static int picc_receive_capdu(void *driver_data,
fflush(data->fd); fflush(data->fd);
if (debug) if (debug)
printf("%s\n", data->read); printf("%s\n", data->buf);
/* decode C-APDU */ /* decode C-APDU */
*len = picc_decode_apdu(data->read, linelen, capdu); *len = picc_decode_apdu(data->buf, linelen, capdu);
return 1; return 1;
} }
@@ -183,7 +189,6 @@ static int picc_receive_capdu(void *driver_data,
static int picc_send_rapdu(void *driver_data, static int picc_send_rapdu(void *driver_data,
const unsigned char *rapdu, size_t len) const unsigned char *rapdu, size_t len)
{ {
char *buf = NULL;
size_t buflen; size_t buflen;
struct picc_data *data = driver_data; struct picc_data *data = driver_data;
@@ -192,21 +197,20 @@ static int picc_send_rapdu(void *driver_data,
/* encode R-APDU */ /* 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 */ /* write R-APDU */
if (debug) 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) { || fflush(data->fd) != 0) {
free(buf);
return 0; return 0;
} }
free(buf);
return 1; return 1;
} }

View File

@@ -1,20 +1,20 @@
/* /*
* Copyright (C) 2010 Dominik Oepen, Frank Morgner * 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 * pcsc-relay is free software: you can redistribute it and/or modify it under
* under the terms of the GNU General Public License as published by the Free * 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) * Software Foundation, either version 3 of the License, or (at your option)
* any later version. * 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 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. * more details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* picc_to_pcsc. If not, see <http://www.gnu.org/licenses/>. * pcsc-relay. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

View File

@@ -1,20 +1,20 @@
/* /*
* Copyright (C) 2010 Frank Morgner * 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 * pcsc-relay is free software: you can redistribute it and/or modify it under
* terms of the GNU General Public License as published by the Free Software * the terms of the GNU General Public License as published by the Free
* Foundation, either version 3 of the License, or (at your option) any later * Software Foundation, either version 3 of the License, or (at your option)
* version. * any later version.
* *
* ccid is distributed in the hope that it will be useful, but WITHOUT ANY * pcsc-relay is distributed in the hope that it will be useful, but WITHOUT
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* details. * more details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* ccid. If not, see <http://www.gnu.org/licenses/>. * pcsc-relay. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* @file * @file

View File

@@ -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