comparison simtool/chv.c @ 108:6f80cfdc7e05

fc-simtool: CHV commands implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 26 Jan 2021 00:51:59 +0000
parents
children 2adb802b2a98
comparison
equal deleted inserted replaced
107:ba2c796259e9 108:6f80cfdc7e05
1 /*
2 * This module implements the standard set of CHV commands
3 * for GSM 11.11 SIMs.
4 */
5
6 #include <sys/types.h>
7 #include <ctype.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <pcsclite.h>
11 #include <winscard.h>
12 #include "globals.h"
13
14 static
15 encode_pin_entry(arg, dest)
16 char *arg;
17 u_char *dest;
18 {
19 unsigned n;
20
21 n = 0;
22 while (*arg) {
23 if (!isdigit(*arg)) {
24 fprintf(stderr,
25 "error: PIN argument contains a non-digit character\n");
26 return(-1);
27 }
28 if (n >= 8) {
29 fprintf(stderr, "error: PIN argument is too long\n");
30 return(-1);
31 }
32 *dest++ = *arg++;
33 n++;
34 }
35 for (; n < 8; n++)
36 *dest++ = 0xFF;
37 return(0);
38 }
39
40 cmd_verify_chv(argc, argv)
41 char **argv;
42 {
43 u_char cmd[13];
44 int rc;
45
46 /* VERIFY CHV command APDU */
47 cmd[0] = 0xA0;
48 cmd[1] = 0x20;
49 cmd[2] = 0x00;
50 switch (argv[0][10]) {
51 case '1':
52 cmd[3] = 0x01;
53 break;
54 case '2':
55 cmd[3] = 0x02;
56 break;
57 default:
58 fprintf(stderr, "BUG in verify-chvN command\n");
59 return(-1);
60 }
61 cmd[4] = 8;
62 rc = encode_pin_entry(argv[1], cmd + 5);
63 if (rc < 0)
64 return(rc);
65 rc = apdu_exchange(cmd, 13);
66 if (rc < 0)
67 return(rc);
68 if (sim_resp_sw != 0x9000) {
69 fprintf(stderr, "bad SW response: %04X\n", sim_resp_sw);
70 return(-1);
71 }
72 return(0);
73 }
74
75 cmd_change_chv(argc, argv)
76 char **argv;
77 {
78 u_char cmd[21];
79 int rc;
80
81 /* CHANGE CHV command APDU */
82 cmd[0] = 0xA0;
83 cmd[1] = 0x24;
84 cmd[2] = 0x00;
85 switch (argv[0][10]) {
86 case '1':
87 cmd[3] = 0x01;
88 break;
89 case '2':
90 cmd[3] = 0x02;
91 break;
92 default:
93 fprintf(stderr, "BUG in change-chvN command\n");
94 return(-1);
95 }
96 cmd[4] = 16;
97 rc = encode_pin_entry(argv[1], cmd + 5);
98 if (rc < 0)
99 return(rc);
100 rc = encode_pin_entry(argv[2], cmd + 13);
101 if (rc < 0)
102 return(rc);
103 rc = apdu_exchange(cmd, 21);
104 if (rc < 0)
105 return(rc);
106 if (sim_resp_sw != 0x9000) {
107 fprintf(stderr, "bad SW response: %04X\n", sim_resp_sw);
108 return(-1);
109 }
110 return(0);
111 }
112
113 cmd_disable_chv(argc, argv)
114 char **argv;
115 {
116 u_char cmd[13];
117 int rc;
118
119 /* DISABLE CHV command APDU */
120 cmd[0] = 0xA0;
121 cmd[1] = 0x26;
122 cmd[2] = 0x00;
123 cmd[3] = 0x01;
124 cmd[4] = 8;
125 rc = encode_pin_entry(argv[1], cmd + 5);
126 if (rc < 0)
127 return(rc);
128 rc = apdu_exchange(cmd, 13);
129 if (rc < 0)
130 return(rc);
131 if (sim_resp_sw != 0x9000) {
132 fprintf(stderr, "bad SW response: %04X\n", sim_resp_sw);
133 return(-1);
134 }
135 return(0);
136 }
137
138 cmd_enable_chv(argc, argv)
139 char **argv;
140 {
141 u_char cmd[13];
142 int rc;
143
144 /* ENABLE CHV command APDU */
145 cmd[0] = 0xA0;
146 cmd[1] = 0x28;
147 cmd[2] = 0x00;
148 cmd[3] = 0x01;
149 cmd[4] = 8;
150 rc = encode_pin_entry(argv[1], cmd + 5);
151 if (rc < 0)
152 return(rc);
153 rc = apdu_exchange(cmd, 13);
154 if (rc < 0)
155 return(rc);
156 if (sim_resp_sw != 0x9000) {
157 fprintf(stderr, "bad SW response: %04X\n", sim_resp_sw);
158 return(-1);
159 }
160 return(0);
161 }
162
163 cmd_unblock_chv(argc, argv)
164 char **argv;
165 {
166 u_char cmd[21];
167 int rc;
168
169 /* UNBLOCK CHV command APDU */
170 cmd[0] = 0xA0;
171 cmd[1] = 0x2C;
172 cmd[2] = 0x00;
173 switch (argv[0][11]) {
174 case '1':
175 cmd[3] = 0x00;
176 break;
177 case '2':
178 cmd[3] = 0x02;
179 break;
180 default:
181 fprintf(stderr, "BUG in unblock-chvN command\n");
182 return(-1);
183 }
184 cmd[4] = 16;
185 rc = encode_pin_entry(argv[1], cmd + 5);
186 if (rc < 0)
187 return(rc);
188 rc = encode_pin_entry(argv[2], cmd + 13);
189 if (rc < 0)
190 return(rc);
191 rc = apdu_exchange(cmd, 21);
192 if (rc < 0)
193 return(rc);
194 if (sim_resp_sw != 0x9000) {
195 fprintf(stderr, "bad SW response: %04X\n", sim_resp_sw);
196 return(-1);
197 }
198 return(0);
199 }