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