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 }