# HG changeset patch # User Mychaela Falconia # Date 1615688509 0 # Node ID 45ea06eaa9fdc2bb164180f0bb8d309fe57b0893 # Parent 11f4f8a8fa33513f8532e95be1595d52f6974c50 fc-pcsc-backend main program put together diff -r 11f4f8a8fa33 -r 45ea06eaa9fd .hgignore --- a/.hgignore Sun Mar 14 01:22:37 2021 +0000 +++ b/.hgignore Sun Mar 14 02:21:49 2021 +0000 @@ -3,4 +3,5 @@ \.[oa]$ ^pcsc/fc-pcsc-atr$ +^pcsc/fc-pcsc-backend$ ^pcsc/fc-pcsc-list$ diff -r 11f4f8a8fa33 -r 45ea06eaa9fd pcsc/Makefile --- a/pcsc/Makefile Sun Mar 14 01:22:37 2021 +0000 +++ b/pcsc/Makefile Sun Mar 14 02:21:49 2021 +0000 @@ -1,12 +1,13 @@ CC= gcc CFLAGS= -O2 -I/usr/include/PCSC -PROGS= fc-pcsc-atr fc-pcsc-list +PROGS= fc-pcsc-atr fc-pcsc-backend fc-pcsc-list INSTALL_PREFIX= /opt/freecalypso INSTBIN=${INSTALL_PREFIX}/bin ATR_OBJS= atrfunc.o atrmain.o connect.o context.o rdselect.o +MAIN_OBJS= atrfunc.o connect.o context.o main.o rdselect.o LIST_OBJS= context.o rdlist.o all: ${PROGS} @@ -14,6 +15,9 @@ fc-pcsc-atr: ${ATR_OBJS} ${CC} ${CFLAGS} -o $@ ${ATR_OBJS} -lpcsclite +fc-pcsc-backend: ${MAIN_OBJS} + ${CC} ${CFLAGS} -o $@ ${MAIN_OBJS} -lpcsclite + fc-pcsc-list: ${LIST_OBJS} ${CC} ${CFLAGS} -o $@ ${LIST_OBJS} -lpcsclite diff -r 11f4f8a8fa33 -r 45ea06eaa9fd pcsc/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pcsc/main.c Sun Mar 14 02:21:49 2021 +0000 @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include + +extern SCARDCONTEXT hContext; +extern SCARDHANDLE hCard; +extern char *selected_reader; + +static +decode_hex_digit(c) +{ + if (isdigit(c)) + return c - '0'; + else if (islower(c)) + return c - 'a' + 10; + else + return c - 'A' + 10; +} + +static +parse_hex_input(inbuf, outbuf) + char *inbuf; + u_char *outbuf; +{ + char *cp; + unsigned count; + + count = 0; + for (cp = inbuf; ; ) { + while (isspace(*cp)) + cp++; + if (!*cp) + break; + if (!isxdigit(cp[0]) || !isxdigit(cp[1])) { + printf("error: invalid hex APDU input\n"); + return(-1); + } + if (count >= 260) { + printf("error: command APDU is too long\n"); + return(-1); + } + outbuf[count++] = (decode_hex_digit(cp[0]) << 4) | + decode_hex_digit(cp[1]); + cp += 2; + } + return count; +} + +static void +apdu_exchange(cmd_apdu, cmd_apdu_len) + u_char *cmd_apdu; + unsigned cmd_apdu_len; +{ + LONG rv; + DWORD dwRecvLength; + u_char sim_resp_data[258]; + unsigned n; + + dwRecvLength = 258; + rv = SCardTransmit(hCard, SCARD_PCI_T0, cmd_apdu, cmd_apdu_len, NULL, + sim_resp_data, &dwRecvLength); + if (rv != SCARD_S_SUCCESS) { + printf("SCardTransmit error: %s\n", pcsc_stringify_error(rv)); + return; + } + if (dwRecvLength < 2) { + printf( + "error: SCardTransmit response is shorter than 2 SW bytes\n"); + return; + } + for (n = 0; n < dwRecvLength; n++) + printf("%02X", sim_resp_data[n]); + putchar('\n'); +} + +main(argc, argv) + char **argv; +{ + char inbuf[576]; + u_char cmd[260]; + int rc; + + parse_reader_select_opt(argc, argv); + setup_pcsc_context(); + get_reader_list(); + select_reader_by_num(); + printf("R %s\n", selected_reader); + connect_to_card(); + retrieve_atr("A"); + putchar('\n'); + + while (fgets(inbuf, sizeof inbuf, stdin)) { + rc = parse_hex_input(inbuf, cmd); + if (rc < 0) + continue; + if (rc < 5) { + printf("error: command APDU is too short\n"); + continue; + } + apdu_exchange(cmd, rc); + } + + SCardDisconnect(hCard, SCARD_UNPOWER_CARD); + SCardReleaseContext(hContext); + exit(0); +}