FreeCalypso > hg > freecalypso-hwlab
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 } |