comparison 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
comparison
equal deleted inserted replaced
8:34bbb0585cab 9:c9ef9e91dd8e
1 #include <sys/types.h>
2 #include <ctype.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <strings.h>
7
8 extern FILE *cpipeF, *rpipeF;
9
10 u_char sim_resp_data[258];
11 unsigned sim_resp_data_len, sim_resp_sw;
12
13 static void
14 send_cmd(cmd_apdu, cmd_apdu_len)
15 u_char *cmd_apdu;
16 unsigned cmd_apdu_len;
17 {
18 unsigned n;
19
20 for (n = 0; n < cmd_apdu_len; n++)
21 fprintf(cpipeF, "%02X", cmd_apdu[n]);
22 putc('\n', cpipeF);
23 fflush(cpipeF);
24 }
25
26 static
27 parse_response_hex_string(input)
28 char *input;
29 {
30 char *cp;
31
32 sim_resp_data_len = 0;
33 for (cp = input; *cp; cp += 2) {
34 if (!isxdigit(cp[0]) || !isxdigit(cp[1])) {
35 fprintf(stderr,
36 "comm error: invalid hex string from back end\n");
37 return(-1);
38 }
39 sim_resp_data[sim_resp_data_len++] =
40 (decode_hex_digit(cp[0]) << 4) |
41 decode_hex_digit(cp[1]);
42 }
43 return(0);
44 }
45
46 apdu_exchange(cmd_apdu, cmd_apdu_len)
47 u_char *cmd_apdu;
48 unsigned cmd_apdu_len;
49 {
50 char inbuf[518], *cp;
51 u_char *sw;
52 int rc;
53
54 send_cmd(cmd_apdu, cmd_apdu_len);
55 if (!fgets(inbuf, sizeof inbuf, rpipeF)) {
56 fprintf(stderr, "comm error: EOF reading from back end\n");
57 return(-1);
58 }
59 cp = index(inbuf, '\n');
60 if (!cp) {
61 fprintf(stderr,
62 "comm error: response from back end has no newline\n");
63 return(-1);
64 }
65 *cp = '\0';
66 if (!inbuf[0]) {
67 fprintf(stderr,
68 "comm error: response from back end is an empty line\n");
69 return(-1);
70 }
71 if (!isxdigit(inbuf[0]) || !isxdigit(inbuf[1]) || !isxdigit(inbuf[2])
72 || !isxdigit(inbuf[3])) {
73 /* we got a back end error message */
74 fprintf(stderr, "%s\n", inbuf);
75 return(-1);
76 }
77 rc = parse_response_hex_string(inbuf);
78 if (rc < 0)
79 return(rc);
80 sim_resp_data_len -= 2;
81 sw = sim_resp_data + sim_resp_data_len;
82 sim_resp_sw = (sw[0] << 8) | sw[1];
83 return(0);
84 }