diff --git a/ccid/configure.ac b/ccid/configure.ac index 4a3ca05..ad16051 100644 --- a/ccid/configure.ac +++ b/ccid/configure.ac @@ -101,11 +101,11 @@ AM_COND_IF(WITH_PACE, [AC_DEFINE(WITH_PACE, 1, [enable PACE support])]) AM_COND_IF(WITH_PACE, [AC_DEFINE(BUERGERCLIENT_WORKAROUND, 1, [Always get EF.CardAccess, when connecting to a smart card. This is a workaround for the recent Buergerclient])]) -# --enable-ccid-test -AC_ARG_ENABLE(ccid-test, - AS_HELP_STRING([--enable-ccid-test], [Enable test of PACE smartcard reader]), - [enable_ccid_test="${enableval}"], [enable_ccid_test=no]) -if test "x$enable_ccid_test" != xno ; then +# --disable-cats +AC_ARG_ENABLE(cats, + AS_HELP_STRING([--enable-cats], [Disable tool for CAT-S and CAT-C (pinpad readers with PACE support)]), + [enable_cats="${enableval}"], [enable_cats=yes]) +if test "x$enable_cats" != xno ; then PKG_CHECK_EXISTS([libpcsclite > 1.4.102], [PKG_CHECK_MODULES([PCSC], [libpcsclite > 1.4.102])], [AC_MSG_WARN([libpcsclite > 1.4.102 not found by pkg-config])]) @@ -128,8 +128,9 @@ if test "x$enable_ccid_test" != xno ; then CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" - enable_ccid_test=yes + enable_cats=yes fi +AM_CONDITIONAL(WITH_CATS, test "${enable_ccid}" != "no") # Checks for header files. @@ -154,6 +155,7 @@ ccid-emulator has been configured with following options: Version: ${PACKAGE_VERSION} User binaries: $(eval eval eval echo "${bindir}") +Libraries: $(eval eval eval echo "${libdir}") Configuration files: $(eval eval eval echo "${sysconfdir}") @@ -173,9 +175,9 @@ OPENSSL_LIBS: ${OPENSSL_LIBS} PCSC_CFLAGS: ${PCSC_CFLAGS} PCSC_LIBS: ${PCSC_LIBS} -emulator support: ${enable_ccid} +CCID emulator: ${enable_ccid} PACE support: ${enable_pace} -PACE test for reader ${enable_ccid_test} +CAT-S/CAT-C Tool: ${enable_cats} EOF diff --git a/ccid/src/Makefile.am b/ccid/src/Makefile.am index 1a21b3f..5660601 100644 --- a/ccid/src/Makefile.am +++ b/ccid/src/Makefile.am @@ -8,9 +8,9 @@ ccid_emulator_SOURCES = ccid.c usbstring.c usb.c binutil.c ccid_emulator_LDADD = $(OPENSC_LIBS) $(OPENSSL_LIBS) $(PTHREAD_LIBS) ccid_emulator_CFLAGS = $(OPENSC_CFLAGS) $(OPENSSL_CFLAGS) $(PTHREAD_CFLAGS) -ccid_test_SOURCES = ccid-test.c -ccid_test_LDADD = $(PCSC_LIBS) -ccid_test_CFLAGS = $(PCSC_CFLAGS) +cats_tool_SOURCES = cats-tool.c +cats_tool_LDADD = $(PCSC_LIBS) +cats_tool_CFLAGS = $(PCSC_CFLAGS) pace_tool_SOURCES = pace-tool.c binutil.c pace_tool_LDADD = $(OPENSC_LIBS) $(OPENSSL_LIBS) libpace.la @@ -24,7 +24,12 @@ noinst_HEADERS = \ usbstring.h if WITH_CCID -bin_PROGRAMS += ccid-emulator ccid-test +bin_PROGRAMS += ccid-emulator +endif + + +if WITH_CATS +bin_PROGRAMS += cats-tool endif diff --git a/ccid/src/ccid-test.c b/ccid/src/cats-tool.c similarity index 64% rename from ccid/src/ccid-test.c rename to ccid/src/cats-tool.c index 9705cab..f40d54f 100644 --- a/ccid/src/ccid-test.c +++ b/ccid/src/cats-tool.c @@ -23,14 +23,14 @@ #include #include -#ifdef HAVE_ARPA_INIT_H -#include -#endif - #ifdef HAVE_CONFIG_H #include "config.h" #endif +#ifdef HAVE_ARPA_INIT_H +#include +#endif + #ifdef HAVE_PCSCLITE_H #include #endif @@ -171,7 +171,7 @@ static LONG parse_EstablishPACEChannel_OutputData( parsed += length_IDicc; if (parsed != output_length) { - fprintf(stderr, "Overrun by %d bytes", output_length - parsed); + fprintf(stderr, "Overrun by %d bytes\n", output_length - parsed); return SCARD_F_INTERNAL_ERROR; } @@ -181,82 +181,68 @@ static LONG parse_EstablishPACEChannel_OutputData( int main(int argc, char *argv[]) { - LONG rv; + LONG r; SCARDCONTEXT hContext; SCARDHANDLE hCard; - LPSTR mszReaders = NULL; - int num, l; + LPSTR readers = NULL; char *reader; - DWORD pace_ioctl = 0; - BYTE pbSendBufferCapabilities [] = { - 0x01, /* idxFunction = GetReadersPACECapabilities */ - 0x00, /* lengthInputData */ - 0x00, /* lengthInputData */ - }; - BYTE pbSendBufferEstablish [] = { - 0x02, /* idxFunction = EstabishPACEChannel */ - 0x00, /* lengthInputData */ - 0x00, /* lengthInputData */ - 0x03, /* PACE with PIN */ - 0x00, /* length CHAT */ - 0x00, /* length PIN */ - /*0x06, [> length PIN <]*/ - /*'2',*/ - /*'6',*/ - /*'3',*/ - /*'4',*/ - /*'1',*/ - /*'1',*/ - 0x00, /* length certificate description */ - 0x00, /* length certificate description */ - }; - BYTE pbRecvBuffer[1024]; - DWORD dwActiveProtocol, dwRecvLength, dwReaders, i; + BYTE sendbuf[16], recvbuf[1024]; + DWORD ctl, recvlen, readerslen; time_t t_start, t_end; - - uint16_t lengthInputData = sizeof(pbSendBufferEstablish) - 3; - memcpy(pbSendBufferEstablish + 1, &lengthInputData, 2); + size_t l, pinlen = 0; + char *pin = NULL; + unsigned int readernum = 0, i; if (argc > 1) { - if (argc > 2 || sscanf(argv[1], "%d", &num) != 1) { - fprintf(stderr, "Usage: %s [reader_num]\n", argv[0]); + if (argc > 2 && sscanf(argv[1], "%u", &readernum) != 1) { + fprintf(stderr, "Could not get number of reader\n"); exit(2); } - } else - num = 0; + if (argc == 2) { + pin = argv[2]; + pinlen = strlen(pin); + if (pinlen < 5 || pinlen > 6) { + fprintf(stderr, "PIN too long\n"); + exit(2); + } + } + if (argc > 3) { + fprintf(stderr, "Usage: " + "%s [reader number] [PIN]\n", argv[0]); + } + } - rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); - if (rv != SCARD_S_SUCCESS) { - fprintf(stderr, "Could not connect to PC/SC Service"); + r = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); + if (r != SCARD_S_SUCCESS) { + fprintf(stderr, "Could not connect to PC/SC Service\n"); goto err; } - dwReaders = SCARD_AUTOALLOCATE; - rv = SCardListReaders(hContext, NULL, (LPSTR)&mszReaders, &dwReaders); - if (rv != SCARD_S_SUCCESS) { - fprintf(stderr, "Could not get readers"); + readerslen = SCARD_AUTOALLOCATE; + r = SCardListReaders(hContext, NULL, (LPSTR) &readers, &readerslen); + if (r != SCARD_S_SUCCESS) { + fprintf(stderr, "Could not get readers\n"); goto err; } - for (reader = mszReaders, i = 0; dwReaders > 0; - l = strlen(reader) + 1, dwReaders -= l, reader += l, i++) { + for (reader = readers, i = 0; readerslen > 0; + l = strlen(reader) + 1, readerslen -= l, reader += l, i++) { - if (i == num) + if (i == readernum) break; } - if (dwReaders <= 0) { - fprintf(stderr, "Could not find reader number %d\n", num); - rv = SCARD_E_UNKNOWN_READER; + if (readerslen <= 0) { + fprintf(stderr, "Could not find reader number %d\n", readernum); + r = SCARD_E_UNKNOWN_READER; goto err; } - rv = SCardConnect(hContext, reader, SCARD_SHARE_DIRECT, 0, &hCard, - &dwActiveProtocol); - if (rv != SCARD_S_SUCCESS) { + r = SCardConnect(hContext, reader, SCARD_SHARE_DIRECT, 0, &hCard, &ctl); + if (r != SCARD_S_SUCCESS) { fprintf(stderr, "Could not connect to %s\n", reader); goto err; } @@ -264,66 +250,77 @@ main(int argc, char *argv[]) /* does the reader support PACE? */ - rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, - pbRecvBuffer, sizeof(pbRecvBuffer), &dwRecvLength); - if (rv != SCARD_S_SUCCESS) { + r = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, + recvbuf, sizeof(recvbuf), &recvlen); + if (r != SCARD_S_SUCCESS) { fprintf(stderr, "Could not get the reader's features\n"); goto err; } - printb("reader's features\n", pbRecvBuffer, dwRecvLength); - for (i = 0; i <= dwRecvLength-PCSC_TLV_ELEMENT_SIZE; i += PCSC_TLV_ELEMENT_SIZE) { - if (pbRecvBuffer[i] == FEATURE_EXECUTE_PACE) { - memcpy(&pace_ioctl, pbRecvBuffer+i+2, 4); + ctl = 0; + for (i = 0; i <= recvlen-PCSC_TLV_ELEMENT_SIZE; i += PCSC_TLV_ELEMENT_SIZE) { + if (recvbuf[i] == FEATURE_EXECUTE_PACE) { + memcpy(&ctl, recvbuf+i+2, 4); break; } } - if (0 == pace_ioctl) { + if (0 == ctl) { printf("Reader does not support PACE\n"); goto err; } /* convert to host byte order to use for SCardControl */ - pace_ioctl = ntohl(pace_ioctl); + ctl = ntohl(ctl); - - rv = SCardControl(hCard, pace_ioctl, - pbSendBufferCapabilities, sizeof(pbSendBufferCapabilities), - pbRecvBuffer, sizeof(pbRecvBuffer), &dwRecvLength); - if (rv != SCARD_S_SUCCESS) { + sendbuf[0] = 0x01; /* idxFunction = GetReadersPACECapabilities */ + sendbuf[1] = 0x00; /* lengthInputData */ + sendbuf[2] = 0x00; /* lengthInputData */ + r = SCardControl(hCard, ctl, + sendbuf, 2, + recvbuf, sizeof(recvbuf), &recvlen); + if (r != SCARD_S_SUCCESS) { fprintf(stderr, "Could not get reader's PACE capabilities\n"); goto err; } - printb("ReadersPACECapabilities ", pbRecvBuffer, dwRecvLength); + printb("ReadersPACECapabilities ", recvbuf, recvlen); - dwRecvLength = 0; + sendbuf[0] = 0x02; /* idxFunction = EstabishPACEChannel */ + sendbuf[1] = (8+pinlen)>>8; /* lengthInputData */ + sendbuf[2] = (8+pinlen)&0xff; /* lengthInputData */ + sendbuf[3] = 0x03; /* PACE with PIN */ + sendbuf[4] = 0x00, /* length CHAT */ + sendbuf[5] = 0x00, /* length PIN */ + sendbuf[6] = pinlen; /* length PIN */ + memcpy(sendbuf+7, pin, pinlen); /* PIN */ + sendbuf[7+pinlen] = 0x00; /* length certificate description */ + sendbuf[8+pinlen] = 0x00; /* length certificate description */ t_start = time(NULL); - rv = SCardControl(hCard, pace_ioctl, - pbSendBufferEstablish, sizeof(pbSendBufferEstablish), - pbRecvBuffer, sizeof(pbRecvBuffer), &dwRecvLength); + r = SCardControl(hCard, ctl, + sendbuf, 8+pinlen, + recvbuf, sizeof(recvbuf), &recvlen); t_end = time(NULL); - if (rv != SCARD_S_SUCCESS) { + if (r != SCARD_S_SUCCESS) { fprintf(stderr, "Could not establish PACE channel\n"); goto err; } printf("EstablishPACEChannel successfull, received %d bytes\n", - dwRecvLength); - printb("EstablishPACEChannel\n", pbRecvBuffer, dwRecvLength); + recvlen); + printb("EstablishPACEChannel\n", recvbuf, recvlen); - rv = parse_EstablishPACEChannel_OutputData(pbRecvBuffer, dwRecvLength); - if (rv != SCARD_S_SUCCESS) + r = parse_EstablishPACEChannel_OutputData(recvbuf, recvlen); + if (r != SCARD_S_SUCCESS) goto err; printf("Established PACE channel returned in %.0fs.\n", difftime(t_end, t_start)); - rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD); - if (rv != SCARD_S_SUCCESS) + r = SCardDisconnect(hCard, SCARD_LEAVE_CARD); + if (r != SCARD_S_SUCCESS) goto err; - rv = SCardFreeMemory(hContext, mszReaders); - if (rv != SCARD_S_SUCCESS) + r = SCardFreeMemory(hContext, readers); + if (r != SCARD_S_SUCCESS) goto err; @@ -331,10 +328,10 @@ main(int argc, char *argv[]) err: #ifdef HAVE_PCSCLITE_H - puts(pcsc_stringify_error(rv)); + puts(pcsc_stringify_error(r)); #endif - if (mszReaders) - SCardFreeMemory(hContext, mszReaders); + if (readers) + SCardFreeMemory(hContext, readers); exit(1);