FreeCalypso > hg > fc-sim-tools
view pcsc/main.c @ 58:871281cb0555
doc/Low-level-commands: apdu-checksw documented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 23 Mar 2021 00:21:02 +0000 |
parents | 60fd23186e2e |
children |
line wrap: on
line source
#include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <pcsclite.h> #include <winscard.h> 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'); fflush(stdout); for (; fgets(inbuf, sizeof inbuf, stdin); fflush(stdout)) { 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); }