- cats-test and picc_to_pcsc are using the same pcsc abstraction. this reduces the code to maintain

- partial rewrite of picc_to_pcsc to reduce memory leaks and add fault tolerancy


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@300 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2010-10-07 10:41:45 +00:00
parent 320cca0731
commit 480cf4d722
10 changed files with 223 additions and 931 deletions

View File

@@ -53,22 +53,6 @@
#define PCSC_TLV_ELEMENT_SIZE 6
static void
printb(const char *label, unsigned char *buf, size_t len)
{
size_t i = 0;
printf("%s", label);
while (i < len) {
printf("%02X", buf[i]);
i++;
if (i%20)
printf(" ");
else if (i != len)
printf("\n");
}
printf("\n");
}
static LONG parse_EstablishPACEChannel_OutputData(
unsigned char output[], unsigned int output_length)
{
@@ -188,7 +172,7 @@ main(int argc, char *argv[])
SCARDHANDLE hCard;
LPSTR readers = NULL;
BYTE sendbuf[16], recvbuf[1024];
DWORD ctl, recvlen;
DWORD ctl, recvlen, protocol;
time_t t_start, t_end;
size_t l, pinlen = 0;
char *pin = NULL;
@@ -216,15 +200,15 @@ main(int argc, char *argv[])
r = pcsc_connect(readernum, SCARD_SHARE_DIRECT, 0, &hContext, &readers,
&hCard);
&hCard, &protocol);
if (r != SCARD_S_SUCCESS)
goto err;
#define SIMULATE_BUERGERCLIENT 1
#ifdef SIMULATE_BUERGERCLIENT
r = SCardReconnect(hCard, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0,
SCARD_LEAVE_CARD, &ctl);
r = SCardReconnect(hCard, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_ANY,
SCARD_LEAVE_CARD, &protocol);
if (r != SCARD_S_SUCCESS) {
fprintf(stderr, "Could not reconnect\n");
goto err;
@@ -250,18 +234,16 @@ main(int argc, char *argv[])
};
LPBYTE buf0 = bufs0;
DWORD lens0[] = {4, 4, 4, 4, 7, 14, 7, 20, 7, 7, 5, 5, 5, 5, 5, 7, 20};
SCARD_IO_REQUEST pioRecvPci;
for (l = 0; l < sizeof(lens0)/sizeof(DWORD); l++) {
recvlen = sizeof(recvbuf);
r = SCardTransmit(hCard, SCARD_PCI_T0, buf0, lens0[l], &pioRecvPci,
recvbuf, &recvlen);
r = pcsc_transmit(protocol, hCard, buf0, lens0[l], recvbuf, &recvlen);
if (r != SCARD_S_SUCCESS) {
fprintf(stderr, "Simulation of Buergerclient failed\n");
goto err;
}
buf0 += lens0[l];
}
r = SCardReconnect(hCard, SCARD_SHARE_DIRECT, 0, SCARD_LEAVE_CARD, &ctl);
r = SCardReconnect(hCard, SCARD_SHARE_DIRECT, 0, SCARD_LEAVE_CARD, &protocol);
if (r != SCARD_S_SUCCESS) {
fprintf(stderr, "Could not reconnect\n");
goto err;
@@ -338,8 +320,8 @@ main(int argc, char *argv[])
#define SIMULATE_TA_CA 1
#ifdef SIMULATE_TA_CA
r = SCardReconnect(hCard, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0,
SCARD_LEAVE_CARD, &ctl);
r = SCardReconnect(hCard, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_ANY,
SCARD_LEAVE_CARD, &protocol);
if (r != SCARD_S_SUCCESS) {
fprintf(stderr, "Could not reconnect\n");
goto err;
@@ -376,11 +358,9 @@ main(int argc, char *argv[])
LPBYTE buf1 = bufs1;
DWORD lens1[] = {20, 233, 21, 328, 88, 5, 69, 7, 7, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 75};
SCARD_IO_REQUEST ridpioRecvPci;
for (l = 0; l < sizeof(lens1)/sizeof(DWORD); l++) {
recvlen = sizeof(recvbuf);
r = SCardTransmit(hCard, SCARD_PCI_T0, buf1, lens1[l], &ridpioRecvPci,
recvbuf, &recvlen);
r = pcsc_transmit(protocol, hCard, buf1, lens1[l], recvbuf, &recvlen);
if (r != SCARD_S_SUCCESS) {
fprintf(stderr,
"Simulation of Terminal and Chip Authentication failed\n");
@@ -388,33 +368,16 @@ main(int argc, char *argv[])
}
buf1 += lens1[l];
}
r = SCardReconnect(hCard, SCARD_SHARE_DIRECT, 0, SCARD_LEAVE_CARD, &ctl);
r = SCardReconnect(hCard, SCARD_SHARE_DIRECT, 0, SCARD_LEAVE_CARD, &protocol);
if (r != SCARD_S_SUCCESS) {
fprintf(stderr, "Could not reconnect\n");
goto err;
}
#endif
r = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
if (r != SCARD_S_SUCCESS)
goto err;
r = SCardFreeMemory(hContext, readers);
if (r != SCARD_S_SUCCESS)
goto err;
exit(0);
err:
#ifdef HAVE_PCSCLITE_H
if (r != SCARD_S_SUCCESS)
puts(pcsc_stringify_error(r));
#endif
if (readers)
SCardFreeMemory(hContext, readers);
stringify_error(r);
pcsc_disconnect(hContext, hCard, readers);
exit(1);
exit(r == SCARD_S_SUCCESS ? 0 : 1);
}

View File

@@ -22,8 +22,9 @@
#include "pcscutil.h"
LONG
pcsc_connect(unsigned int readernum, DWORD dwShareMode, DWORD dwPreferredProtocol,
SCARDCONTEXT *hContext, LPSTR *readers, LPSCARDHANDLE phCard)
pcsc_connect(unsigned int readernum, DWORD dwShareMode, DWORD dwPreferredProtocols,
SCARDCONTEXT *hContext, LPSTR *readers, LPSCARDHANDLE phCard,
LPDWORD pdwActiveProtocol)
{
LONG r;
DWORD ctl, readerslen;
@@ -57,8 +58,8 @@ pcsc_connect(unsigned int readernum, DWORD dwShareMode, DWORD dwPreferredProtoco
}
r = SCardConnect(hContext, reader, dwShareMode, dwPreferredProtocol,
phCard, &ctl);
r = SCardConnect(hContext, reader, dwShareMode, dwPreferredProtocols,
phCard, pdwActiveProtocol);
if (r != SCARD_S_SUCCESS) {
fprintf(stderr, "Could not connect to %s\n", reader);
goto err;
@@ -68,3 +69,56 @@ pcsc_connect(unsigned int readernum, DWORD dwShareMode, DWORD dwPreferredProtoco
err:
return r;
}
void
pcsc_disconnect(SCARDCONTEXT hContext, SCARDHANDLE hCard, LPSTR readers)
{
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
SCardFreeMemory(hContext, readers);
SCardReleaseContext(hContext);
}
LONG
pcsc_transmit(DWORD dwActiveProtocol, SCARDHANDLE hCard,
LPCBYTE pbSendBuffer, DWORD cbSendLength,
LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
{
LONG r;
SCARD_IO_REQUEST ioRecvPci;
switch (dwActiveProtocol) {
case SCARD_PROTOCOL_T0:
r = SCardTransmit(hCard, SCARD_PCI_T0, pbSendBuffer, cbSendLength,
&ioRecvPci, pbRecvBuffer, pcbRecvLength);
break;
case SCARD_PROTOCOL_T1:
r = SCardTransmit(hCard, SCARD_PCI_T1, pbSendBuffer, cbSendLength,
&ioRecvPci, pbRecvBuffer, pcbRecvLength);
break;
default:
fprintf(stderr, "Could not transmit with unknown protocol %u\n",
(unsigned int) dwActiveProtocol);
r = SCARD_E_PROTO_MISMATCH;
break;
}
return r;
}
void
printb(const char *label, unsigned char *buf, size_t len)
{
size_t i = 0;
printf("%s", label);
while (i < len) {
printf("%02X", buf[i]);
i++;
if (i%20)
printf(" ");
else if (i != len)
printf("\n");
}
printf("\n");
}

View File

@@ -23,8 +23,12 @@
#include "config.h"
#endif
#include <stdio.h>
#ifdef HAVE_PCSCLITE_H
#include <pcsclite.h>
#define stringify_error(r) { if (r != SCARD_S_SUCCESS) fputs(pcsc_stringify_error(r), stderr); }
#else
#define stringify_error(r) { if (r != SCARD_S_SUCCESS) fprintf(stderr, "PC/SC error code %u\n", (unsigned int) r); }
#endif
#ifdef HAVE_READER_H
@@ -38,7 +42,19 @@ extern "C" {
LONG
pcsc_connect(unsigned int readernum, DWORD dwShareMode, DWORD dwPreferredProtocol,
SCARDCONTEXT *hContext, LPSTR *readers, LPSCARDHANDLE phCard);
SCARDCONTEXT *hContext, LPSTR *readers, LPSCARDHANDLE phCard,
LPDWORD pdwActiveProtocol);
void
pcsc_disconnect(SCARDCONTEXT hContext, SCARDHANDLE hCard, LPSTR readers);
LONG
pcsc_transmit(DWORD dwActiveProtocol, SCARDHANDLE hCard,
LPCBYTE pbSendBuffer, DWORD cbSendLength,
LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
void
printb(const char *label, unsigned char *buf, size_t len);
#ifdef __cplusplus
}

View File

@@ -1,689 +0,0 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# Makefile. Generated from Makefile.in by configure.
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
pkgdatadir = $(datadir)/picc_to_pcsc
pkgincludedir = $(includedir)/picc_to_pcsc
pkglibdir = $(libdir)/picc_to_pcsc
pkglibexecdir = $(libexecdir)/picc_to_pcsc
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
compile depcomp install-sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
distdir dist dist-all distcheck
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d "$(distdir)" \
|| { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr "$(distdir)"; }; }
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = ${SHELL} /home/fm/work/vsmartcard/picc_to_pcsc/missing --run aclocal-1.11
AMTAR = ${SHELL} /home/fm/work/vsmartcard/picc_to_pcsc/missing --run tar
AUTOCONF = ${SHELL} /home/fm/work/vsmartcard/picc_to_pcsc/missing --run autoconf
AUTOHEADER = ${SHELL} /home/fm/work/vsmartcard/picc_to_pcsc/missing --run autoheader
AUTOMAKE = ${SHELL} /home/fm/work/vsmartcard/picc_to_pcsc/missing --run automake-1.11
AWK = mawk
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = gcc -E
CPPFLAGS =
CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
ECHO_C =
ECHO_N = -n
ECHO_T =
EGREP = /bin/grep -E
EXEEXT =
GREP = /bin/grep
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
LDFLAGS =
LIBOBJS =
LIBS =
LTLIBOBJS =
MAKEINFO = ${SHELL} /home/fm/work/vsmartcard/picc_to_pcsc/missing --run makeinfo
MKDIR_P = /bin/mkdir -p
OBJEXT = o
PACKAGE = picc_to_pcsc
PACKAGE_BUGREPORT = oepen@informatik.hu-berlin.de
PACKAGE_NAME = picc_to_pcsc
PACKAGE_STRING = picc_to_pcsc 0.1
PACKAGE_TARNAME = picc_to_pcsc
PACKAGE_URL =
PACKAGE_VERSION = 0.1
PATH_SEPARATOR = :
PCSC_CFLAGS = -I/usr/include/PCSC
PCSC_LIBS = -lpcsclite
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR =
PKG_CONFIG_PATH =
PYTHON = /usr/bin/python
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux2
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 2.5
SET_MAKE =
SHELL = /bin/bash
STRIP =
VERSION = 0.1
abs_builddir = /home/fm/work/vsmartcard/picc_to_pcsc
abs_srcdir = /home/fm/work/vsmartcard/picc_to_pcsc
abs_top_builddir = /home/fm/work/vsmartcard/picc_to_pcsc
abs_top_srcdir = /home/fm/work/vsmartcard/picc_to_pcsc
ac_ct_CC = gcc
am__include = include
am__leading_dot = .
am__quote =
am__tar = ${AMTAR} chof - "$$tardir"
am__untar = ${AMTAR} xf -
bindir = ${exec_prefix}/bin
build_alias =
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host_alias =
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /home/fm/work/vsmartcard/picc_to_pcsc/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = /bin/mkdir -p
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgpyexecdir = ${pyexecdir}/picc_to_pcsc
pkgpythondir = ${pythondir}/picc_to_pcsc
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${exec_prefix}/lib/python2.5/site-packages
pythondir = ${prefix}/lib/python2.5/site-packages
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
sysconfdir = ${prefix}/etc
target_alias =
top_build_prefix =
top_builddir = .
top_srcdir = .
SUBDIRS = src
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-lzma: distdir
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
$(am__remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@$(am__cd) '$(distuninstallcheck_dir)' \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
ctags-recursive install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am am--refresh check check-am clean clean-generic \
ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
distclean distclean-generic distclean-hdr distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
pdf-am ps ps-am tags tags-recursive uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -22,8 +22,9 @@ saved_CPPFLAGS="$CPPFLAGS"
saved_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $PCSC_CFLAGS"
LIBS="$LDFLAGS $PCSC_LIBS"
AC_CHECK_HEADERS(winscard.h,,
[ AC_MSG_ERROR([winscard.h not found, install libpcsclite or use ./configure PCSC_CFLAGS=...]) ])
AC_CHECK_HEADERS(winscard.h, [], [ AC_MSG_ERROR([winscard.h not found, install PC/SC Lite or similar or use ./configure PCSC_CFLAGS=...]) ])
AC_CHECK_HEADERS(reader.h, [AC_DEFINE(HAVE_READER_H, 1, [use reader.h from PC/SC Lite])], [])
AC_CHECK_HEADERS(pcsclite.h, [AC_DEFINE(HAVE_PCSCLITE_H, 1, [use pcsclite.h from PC/SC Lite])], [])
AC_MSG_CHECKING([for SCardEstablishContext])
AC_TRY_LINK_FUNC(SCardEstablishContext, [ AC_MSG_RESULT([yes]) ],
[ AC_MSG_ERROR([libpcsclite not found, use ./configure PCSC_LIBS=...]) ])

View File

@@ -3,8 +3,8 @@ EXTRA_DIST = picc.py
bin_PROGRAMS = picc_to_pcsc
bin_SCRIPTS = picc.py
picc_to_pcsc_SOURCES = picc_to_pcsc.c
picc_to_pcsc_SOURCES = picc_to_pcsc.c pcscutil.c
picc_to_pcsc_LDADD = $(PCSC_LIBS)
picc_to_pcsc_CFLAGS = $(PCSC_CFLAGS)
noinst_HEADERS = picc_to_pcsc.h
noinst_HEADERS = picc_to_pcsc.h pcscutil.h

1
picc_to_pcsc/src/pcscutil.c Symbolic link
View File

@@ -0,0 +1 @@
../../ccid/src/pcscutil.c

1
picc_to_pcsc/src/pcscutil.h Symbolic link
View File

@@ -0,0 +1 @@
../../ccid/src/pcscutil.h

View File

@@ -10,8 +10,13 @@
#include <unistd.h>
#include <winscard.h>
#include <string.h>
#include <errno.h>
#include "picc_to_pcsc.h"
#include "pcscutil.h"
static FILE *fd; /*filehandle used for PICCDEV*/
static sighandler_t register_sig(int signo, sighandler_t sighandler) {
struct sigaction new_sig, old_sig;
@@ -25,179 +30,63 @@ static sighandler_t register_sig(int signo, sighandler_t sighandler) {
}
char* perform_initialization(int num)
{
char *readers, *str;
DWORD size=0;
LONG r;
r = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hcontext);
if (r != SCARD_S_SUCCESS) {
fprintf(stderr, "pc/sc error: %s\n", pcsc_stringify_error(r));
SCardReleaseContext(hcontext);
return NULL;
}
r = SCardListReaders(hcontext, NULL, NULL, &size);
if (size == 0)
r = SCARD_E_UNKNOWN_READER;
if (r != SCARD_S_SUCCESS) {
fprintf(stderr, "pc/sc error: %s\n", pcsc_stringify_error(r));
SCardReleaseContext(hcontext);
return NULL;
}
/* get all readers */
readers = (char*)malloc(size);
if (readers == NULL) {
fprintf(stderr, "pc/sc error: %s\n",
pcsc_stringify_error(SCARD_E_NO_MEMORY));
SCardReleaseContext(hcontext);
return NULL;
}
r = SCardListReaders(hcontext, NULL, readers, &size);
if (r != SCARD_S_SUCCESS) {
free(readers);
fprintf(stderr, "pc/sc error: %s\n", pcsc_stringify_error(r));
SCardReleaseContext(hcontext);
return NULL;
}
/* name of reader number num*/
str = readers;
for (size = 0; size < num; size++) {
/* go to the next name */
str += strlen(str) + 1;
/* no more readers available? */
if (strlen(str) == 0) {
free(readers);
fprintf(stderr, "pc/sc error: %s\n",
pcsc_stringify_error(SCARD_E_UNKNOWN_READER));
SCardReleaseContext(hcontext);
return NULL;
}
}
strcpy(reader_name, str);
free(readers);
rstate.dwCurrentState = SCARD_STATE_UNAWARE;
rstate.szReader = reader_name;
return reader_name;
}
void setup(void) {
/*setup environment, open device, set global filehandle*/
DWORD dwActiveProtocol;
LONG pcsc_result;
perform_initialization(2); /*Right num for PICC?*/
printf("Initialised reader: %s\n",reader_name);
pcsc_result = SCardConnect(hcontext, reader_name,
SCARD_SHARE_EXCLUSIVE, (SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1),
&hcard, &dwActiveProtocol);
if (pcsc_result == SCARD_S_SUCCESS) {
pcsc_result = SCardGetStatusChange(hcontext, 1, &rstate, 1);
if (pcsc_result != SCARD_S_SUCCESS) fprintf(stderr,"%s\n",pcsc_stringify_error(pcsc_result));
} else {
fprintf(stderr,"%s\n",pcsc_stringify_error(pcsc_result));
}
/*Register our signal handlers*/
register_sig(SIGINT,checkSig);
/*Open the device*/
fd = fopen(PICCDEV, "a+"); /*O_NOCTTY ?*/
if (fd == NULL) {
fprintf(stderr,"Failed to open %s. Exiting.\n", PICCDEV);
exit(-1);
} else printf("Initialisation completed\n");
}
void checkSig(int signo){
if (signo == SIGINT)
printf("Received SIGINT, exiting.\n");
cleanup();
}
void printHex(char *title, unsigned char *msg, unsigned int length) {
int n = 0;
printf("%s: \t",title);
while (n<length) {
printf("%x ",msg[n]);
n++;
}
printf("\n");
}
void cleanup(void) {
int releaseContext;
/*Power down card*/
SCardDisconnect(hcard, SCARD_UNPOWER_CARD);
releaseContext = SCardReleaseContext(hcontext);
if (releaseContext != SCARD_S_SUCCESS) {
printf("%s\n",pcsc_stringify_error(releaseContext));
}
printf("Smartcard disconnected\n");
/*Close the device*/
fclose(fd);
/*Die*/
exit(0);
}
unsigned int read_from_device(unsigned char *inputBuffer) {
char *line = NULL;
size_t linelen=0;
if(getline(&line, &linelen, fd) != -1) {
printf("%s\n",line);
fflush(stdout);
} else {line = NULL;}// cleanup();} //Should we quit when we encounter an EOL?
unsigned int length=0;
unsigned char *buf=NULL;
if (line != NULL && line[0] == '0') { //Ignore empty lines and 'RESET' lines
sscanf(line, "%x : ", &length );
buf = malloc(length);
if(buf == NULL) { fprintf(stderr, "WAHH!\n"); return 0; }
int pos=0;
while(sscanf(line+(pos*3+5), " %x ", (unsigned int *) &(buf[pos])) == 1) {
printf("[%02X]", buf[pos]);
if(++pos >= length) break;
}
printf("Have %i bytes, should have %i bytes\n", pos, length);
memcpy(inputBuffer,buf,length);
}
int picc_decode(char *inbuf, size_t inlen,
unsigned char **outbuf, size_t *outlen)
{
size_t pos;
unsigned char buf[0xffff];
char *end, *p;
unsigned long int b, length;
if(line != NULL) {
free(line);
}
if(buf != NULL) {
free(buf);
}
return length;
}
if (inbuf == NULL || inlen == 0 || inbuf[0] == '\0') {
//Ignore empty lines and 'RESET' lines
*outlen = 0;
return 0;
}
int transmit_to_pcsc(unsigned char *inputBuffer, unsigned int inputLength, unsigned char *outputBuffer, unsigned int *outputLength) {
errno = 0;
length = strtoul(inbuf, &end, 16);
if (errno)
goto err;
printHex("APDU", inputBuffer, inputLength);
unsigned int dwRecvLength = MAX_BUFFER_SIZE;
int result;
result = SCardTransmit(hcard, SCARD_PCI_T1, inputBuffer,
inputLength, NULL, outputBuffer, (DWORD*) &dwRecvLength);
/* check for ':' right behind the length */
if (inbuf+inlen < end+1 || end[0] != ':')
goto err;
end++;
p = realloc(*outbuf, length);
if (!p)
goto err;
*outbuf = p;
*outlen = length;
pos = 0;
while(inbuf+inlen > end && length > pos) {
b = strtoul(end, &end, 16);
if (errno || b > 0xff)
goto err;
(*outbuf)[pos++] = b;
}
/*Check response code */
if (result != SCARD_S_SUCCESS) {
fprintf(stderr,"SCardTransmit failed.\n");
fprintf(stderr,"dwRecvLength = %d maximum is:%d\n",dwRecvLength,MAX_BUFFER_SIZE);
fprintf(stderr,"%s\n",pcsc_stringify_error(result));
return -1;
} else {
printf("Received %d Byte\n",dwRecvLength);
printHex("RAPDU", outputBuffer, dwRecvLength);
*outputLength = dwRecvLength;
}
return 0;
err:
*outlen = 0;
return -1;
}
void write_to_device(unsigned char *buffer, unsigned int msgLength) {
@@ -217,25 +106,89 @@ void write_to_device(unsigned char *buffer, unsigned int msgLength) {
free(foo);
}
int main (int argv, char **args) {
unsigned char inputBuffer[MAX_BUFFER_SIZE];
unsigned char outputBuffer[MAX_BUFFER_SIZE];
unsigned int inputLength, outputLength = MAX_BUFFER_SIZE;
int status;
setup();
int main (int argc, char **argv)
{
/*printf("%s:%d\n", __FILE__, __LINE__);*/
unsigned char *inputBuffer = NULL;
size_t inputLength;
BYTE outputBuffer[MAX_BUFFER_SIZE];
DWORD outputLength;
while(1) {
inputLength = read_from_device(inputBuffer);
if (inputLength == 0) continue;
fflush(fd);
status = transmit_to_pcsc(inputBuffer,inputLength,outputBuffer,&outputLength);
if (!status) {
write_to_device(outputBuffer, outputLength);
//fprintf(fd,"0002: 90 00\0");
} else {
printf("Failed\n");
}
}
cleanup();
return 0;
LPSTR readers = NULL;
LONG r;
DWORD ctl, protocol;
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
char *read = NULL;
size_t readlen = 0;
ssize_t linelen;
unsigned int readernum = 0;
if (argc > 1) {
if (argc > 2) {
fprintf(stderr, "Usage: "
"%s [reader number] [PIN]\n", argv[0]);
}
if (sscanf(argv[1], "%u", &readernum) != 1) {
fprintf(stderr, "Could not get number of reader\n");
exit(2);
}
}
/*Register signal handlers*/
register_sig(SIGINT,checkSig);
/*Open the device*/
fd = fopen(PICCDEV, "a+"); /*O_NOCTTY ?*/
if (fd == NULL) {
fprintf(stderr,"Failed to open %s. Exiting.\n", PICCDEV);
exit(-1);
} else
printf("Initialisation completed\n");
r = pcsc_connect(readernum, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_ANY,
&hContext, &readers, &hCard, &protocol);
if (r != SCARD_S_SUCCESS)
goto err;
while(1) {
linelen = getline(&read, &readlen, fd);
if (linelen < 0) {
if (linelen < 0) {
fprintf(stderr,"Error reading from %s\n", PICCDEV);
goto err;
}
}
if (linelen == 0)
continue;
fflush(fd);
printf("%s\n", read);
if (picc_decode(read, linelen, &inputBuffer, &inputLength) < 0)
continue;
printb("C-APDU:\n", inputBuffer, inputLength);
outputLength = MAX_BUFFER_SIZE;
r = pcsc_transmit(protocol, hCard, inputBuffer, inputLength, outputBuffer, &outputLength);
if (r != SCARD_S_SUCCESS)
goto err;
printb("R-APDU:\n", outputBuffer, outputLength);
write_to_device(outputBuffer, outputLength);
//fprintf(fd,"0002: 90 00\0");
}
cleanup();
err:
stringify_error(r);
pcsc_disconnect(hContext, hCard, readers);
exit(r == SCARD_S_SUCCESS ? 0 : 1);
}

View File

@@ -4,18 +4,10 @@
#define PICCDEV "/dev/ttyACM0"
typedef void (*sighandler_t)(int);
/*Global variables*/
FILE *fd; /*filehandle used for PICCDEV*/
SCARDCONTEXT hcontext;
SCARDHANDLE hcard;
SCARD_READERSTATE rstate;
char reader_name[MAX_READERNAME];
static sighandler_t register_sig(int signo, sighandler_t sighandler);
void checkSig(int signo);
unsigned int read_from_device(unsigned char *inputBuffer);
int transmit_to_pcsc(unsigned char *inputBuffer, unsigned int inputLength, unsigned char *outputBuffer, unsigned int *outputLength);
void write_to_device(unsigned char *buffer, unsigned int msglength);
void setup(void);
void cleanup(void);