diff libcommon/apdu.c @ 9:c9ef9e91dd8e

new libcommon, initial version
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 14 Mar 2021 06:55:38 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/apdu.c	Sun Mar 14 06:55:38 2021 +0000
@@ -0,0 +1,84 @@
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+extern FILE *cpipeF, *rpipeF;
+
+u_char sim_resp_data[258];
+unsigned sim_resp_data_len, sim_resp_sw;
+
+static void
+send_cmd(cmd_apdu, cmd_apdu_len)
+	u_char *cmd_apdu;
+	unsigned cmd_apdu_len;
+{
+	unsigned n;
+
+	for (n = 0; n < cmd_apdu_len; n++)
+		fprintf(cpipeF, "%02X", cmd_apdu[n]);
+	putc('\n', cpipeF);
+	fflush(cpipeF);
+}
+
+static
+parse_response_hex_string(input)
+	char *input;
+{
+	char *cp;
+
+	sim_resp_data_len = 0;
+	for (cp = input; *cp; cp += 2) {
+		if (!isxdigit(cp[0]) || !isxdigit(cp[1])) {
+			fprintf(stderr,
+			"comm error: invalid hex string from back end\n");
+			return(-1);
+		}
+		sim_resp_data[sim_resp_data_len++] =
+			(decode_hex_digit(cp[0]) << 4) |
+			decode_hex_digit(cp[1]);
+	}
+	return(0);
+}
+
+apdu_exchange(cmd_apdu, cmd_apdu_len)
+	u_char *cmd_apdu;
+	unsigned cmd_apdu_len;
+{
+	char inbuf[518], *cp;
+	u_char *sw;
+	int rc;
+
+	send_cmd(cmd_apdu, cmd_apdu_len);
+	if (!fgets(inbuf, sizeof inbuf, rpipeF)) {
+		fprintf(stderr, "comm error: EOF reading from back end\n");
+		return(-1);
+	}
+	cp = index(inbuf, '\n');
+	if (!cp) {
+		fprintf(stderr,
+			"comm error: response from back end has no newline\n");
+		return(-1);
+	}
+	*cp = '\0';
+	if (!inbuf[0]) {
+		fprintf(stderr,
+		"comm error: response from back end is an empty line\n");
+		return(-1);
+	}
+	if (!isxdigit(inbuf[0]) || !isxdigit(inbuf[1]) || !isxdigit(inbuf[2])
+	    || !isxdigit(inbuf[3])) {
+		/* we got a back end error message */
+		fprintf(stderr, "%s\n", inbuf);
+		return(-1);
+	}
+	rc = parse_response_hex_string(inbuf);
+	if (rc < 0)
+		return(rc);
+	sim_resp_data_len -= 2;
+	sw = sim_resp_data + sim_resp_data_len;
+	sim_resp_sw = (sw[0] << 8) | sw[1];
+	return(0);
+}