]>
Commit | Line | Data |
---|---|---|
fe346768 | 1 | //----------------------------------------------------------------------------- |
2 | // Copyright (C) 2017 Merlok | |
3 | // | |
4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, | |
5 | // at your option, any later version. See the LICENSE.txt file for the text of | |
6 | // the license. | |
7 | //----------------------------------------------------------------------------- | |
8 | // APDU status bytes information | |
9 | //----------------------------------------------------------------------------- | |
10 | ||
11 | #include "apduinfo.h" | |
12 | ||
13 | const APDUCode APDUCodeTable[] = { | |
14 | // ID Type Description | |
15 | {"XXXX", APDUCODE_TYPE_NONE, ""}, // blank string | |
16 | {"6---", APDUCODE_TYPE_ERROR, "Class not supported."}, | |
17 | {"61--", APDUCODE_TYPE_INFO, "Response bytes still available"}, | |
18 | {"61XX", APDUCODE_TYPE_INFO, "Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE."}, | |
19 | {"62--", APDUCODE_TYPE_WARNING, "State of non-volatile memory unchanged"}, | |
20 | {"6200", APDUCODE_TYPE_WARNING, "No information given (NV-Ram not changed)"}, | |
21 | {"6201", APDUCODE_TYPE_WARNING, "NV-Ram not changed 1."}, | |
22 | {"6281", APDUCODE_TYPE_WARNING, "Part of returned data may be corrupted"}, | |
23 | {"6282", APDUCODE_TYPE_WARNING, "End of file/record reached before reading Le bytes"}, | |
24 | {"6283", APDUCODE_TYPE_WARNING, "Selected file invalidated"}, | |
25 | {"6284", APDUCODE_TYPE_WARNING, "Selected file is not valid. FCI not formated according to ISO"}, | |
26 | {"6285", APDUCODE_TYPE_WARNING, "No input data available from a sensor on the card. No Purse Engine enslaved for R3bc"}, | |
27 | {"62A2", APDUCODE_TYPE_WARNING, "Wrong R-MAC"}, | |
28 | {"62A4", APDUCODE_TYPE_WARNING, "Card locked (during reset( ))"}, | |
29 | {"62CX", APDUCODE_TYPE_WARNING, "Counter with value x (command dependent)"}, | |
30 | {"62F1", APDUCODE_TYPE_WARNING, "Wrong C-MAC"}, | |
31 | {"62F3", APDUCODE_TYPE_WARNING, "Internal reset"}, | |
32 | {"62F5", APDUCODE_TYPE_WARNING, "Default agent locked"}, | |
33 | {"62F7", APDUCODE_TYPE_WARNING, "Cardholder locked"}, | |
34 | {"62F8", APDUCODE_TYPE_WARNING, "Basement is current agent"}, | |
35 | {"62F9", APDUCODE_TYPE_WARNING, "CALC Key Set not unblocked"}, | |
36 | {"62FX", APDUCODE_TYPE_WARNING, "-"}, | |
37 | {"62XX", APDUCODE_TYPE_WARNING, "RFU"}, | |
38 | {"63--", APDUCODE_TYPE_WARNING, "State of non-volatile memory changed"}, | |
39 | {"6300", APDUCODE_TYPE_WARNING, "No information given (NV-Ram changed)"}, | |
40 | {"6381", APDUCODE_TYPE_WARNING, "File filled up by the last write. Loading/updating is not allowed."}, | |
41 | {"6382", APDUCODE_TYPE_WARNING, "Card key not supported."}, | |
42 | {"6383", APDUCODE_TYPE_WARNING, "Reader key not supported."}, | |
43 | {"6384", APDUCODE_TYPE_WARNING, "Plaintext transmission not supported."}, | |
44 | {"6385", APDUCODE_TYPE_WARNING, "Secured transmission not supported."}, | |
45 | {"6386", APDUCODE_TYPE_WARNING, "Volatile memory is not available."}, | |
46 | {"6387", APDUCODE_TYPE_WARNING, "Non-volatile memory is not available."}, | |
47 | {"6388", APDUCODE_TYPE_WARNING, "Key number not valid."}, | |
48 | {"6389", APDUCODE_TYPE_WARNING, "Key length is not correct."}, | |
49 | {"63C0", APDUCODE_TYPE_WARNING, "Verify fail, no try left."}, | |
50 | {"63C1", APDUCODE_TYPE_WARNING, "Verify fail, 1 try left."}, | |
51 | {"63C2", APDUCODE_TYPE_WARNING, "Verify fail, 2 tries left."}, | |
52 | {"63C3", APDUCODE_TYPE_WARNING, "Verify fail, 3 tries left."}, | |
53 | {"63CX", APDUCODE_TYPE_WARNING, "The counter has reached the value 'x' (0 = x = 15) (command dependent)."}, | |
54 | {"63F1", APDUCODE_TYPE_WARNING, "More data expected."}, | |
55 | {"63F2", APDUCODE_TYPE_WARNING, "More data expected and proactive command pending."}, | |
56 | {"63FX", APDUCODE_TYPE_WARNING, "-"}, | |
57 | {"63XX", APDUCODE_TYPE_WARNING, "RFU"}, | |
58 | {"64--", APDUCODE_TYPE_ERROR, "State of non-volatile memory unchanged"}, | |
59 | {"6400", APDUCODE_TYPE_ERROR, "No information given (NV-Ram not changed)"}, | |
60 | {"6401", APDUCODE_TYPE_ERROR, "Command timeout. Immediate response required by the card."}, | |
61 | {"64XX", APDUCODE_TYPE_ERROR, "RFU"}, | |
62 | {"65--", APDUCODE_TYPE_ERROR, "State of non-volatile memory changed"}, | |
63 | {"6500", APDUCODE_TYPE_ERROR, "No information given"}, | |
64 | {"6501", APDUCODE_TYPE_ERROR, "Write error. Memory failure. There have been problems in writing or reading the EEPROM. Other hardware problems may also bring this error."}, | |
65 | {"6581", APDUCODE_TYPE_ERROR, "Memory failure"}, | |
66 | {"65FX", APDUCODE_TYPE_ERROR, "-"}, | |
67 | {"65XX", APDUCODE_TYPE_ERROR, "RFU"}, | |
68 | {"66--", APDUCODE_TYPE_SECURITY, " "}, | |
69 | {"6600", APDUCODE_TYPE_SECURITY, "Error while receiving (timeout)"}, | |
70 | {"6601", APDUCODE_TYPE_SECURITY, "Error while receiving (character parity error)"}, | |
71 | {"6602", APDUCODE_TYPE_SECURITY, "Wrong checksum"}, | |
72 | {"6603", APDUCODE_TYPE_SECURITY, "The current DF file without FCI"}, | |
73 | {"6604", APDUCODE_TYPE_SECURITY, "No SF or KF under the current DF"}, | |
74 | {"6669", APDUCODE_TYPE_SECURITY, "Incorrect Encryption/Decryption Padding"}, | |
75 | {"66XX", APDUCODE_TYPE_SECURITY, "-"}, | |
76 | {"67--", APDUCODE_TYPE_ERROR, " "}, | |
77 | {"6700", APDUCODE_TYPE_ERROR, "Wrong length"}, | |
78 | {"67XX", APDUCODE_TYPE_ERROR, "length incorrect (procedure)(ISO 7816-3)"}, | |
79 | {"68--", APDUCODE_TYPE_ERROR, "Functions in CLA not supported"}, | |
80 | {"6800", APDUCODE_TYPE_ERROR, "No information given (The request function is not supported by the card)"}, | |
81 | {"6881", APDUCODE_TYPE_ERROR, "Logical channel not supported"}, | |
82 | {"6882", APDUCODE_TYPE_ERROR, "Secure messaging not supported"}, | |
83 | {"6883", APDUCODE_TYPE_ERROR, "Last command of the chain expected"}, | |
84 | {"6884", APDUCODE_TYPE_ERROR, "Command chaining not supported"}, | |
85 | {"68FX", APDUCODE_TYPE_ERROR, "-"}, | |
86 | {"68XX", APDUCODE_TYPE_ERROR, "RFU"}, | |
87 | {"69--", APDUCODE_TYPE_ERROR, "Command not allowed"}, | |
88 | {"6900", APDUCODE_TYPE_ERROR, "No information given (Command not allowed)"}, | |
89 | {"6901", APDUCODE_TYPE_ERROR, "Command not accepted (inactive state)"}, | |
90 | {"6981", APDUCODE_TYPE_ERROR, "Command incompatible with file structure"}, | |
91 | {"6982", APDUCODE_TYPE_ERROR, "Security condition not satisfied."}, | |
92 | {"6983", APDUCODE_TYPE_ERROR, "Authentication method blocked"}, | |
93 | {"6984", APDUCODE_TYPE_ERROR, "Referenced data reversibly blocked (invalidated)"}, | |
94 | {"6985", APDUCODE_TYPE_ERROR, "Conditions of use not satisfied."}, | |
95 | {"6986", APDUCODE_TYPE_ERROR, "Command not allowed (no current EF)"}, | |
96 | {"6987", APDUCODE_TYPE_ERROR, "Expected secure messaging (SM) object missing"}, | |
97 | {"6988", APDUCODE_TYPE_ERROR, "Incorrect secure messaging (SM) data object"}, | |
98 | {"698D", APDUCODE_TYPE_NONE, "Reserved"}, | |
99 | {"6996", APDUCODE_TYPE_ERROR, "Data must be updated again"}, | |
100 | {"69E1", APDUCODE_TYPE_ERROR, "POL1 of the currently Enabled Profile prevents this action."}, | |
101 | {"69F0", APDUCODE_TYPE_ERROR, "Permission Denied"}, | |
102 | {"69F1", APDUCODE_TYPE_ERROR, "Permission Denied - Missing Privilege"}, | |
103 | {"69FX", APDUCODE_TYPE_ERROR, "-"}, | |
104 | {"69XX", APDUCODE_TYPE_ERROR, "RFU"}, | |
105 | {"6A--", APDUCODE_TYPE_ERROR, "Wrong parameter(s) P1-P2"}, | |
106 | {"6A00", APDUCODE_TYPE_ERROR, "No information given (Bytes P1 and/or P2 are incorrect)"}, | |
107 | {"6A80", APDUCODE_TYPE_ERROR, "The parameters in the data field are incorrect."}, | |
108 | {"6A81", APDUCODE_TYPE_ERROR, "Function not supported"}, | |
109 | {"6A82", APDUCODE_TYPE_ERROR, "File not found"}, | |
110 | {"6A83", APDUCODE_TYPE_ERROR, "Record not found"}, | |
111 | {"6A84", APDUCODE_TYPE_ERROR, "There is insufficient memory space in record or file"}, | |
112 | {"6A85", APDUCODE_TYPE_ERROR, "Lc inconsistent with TLV structure"}, | |
113 | {"6A86", APDUCODE_TYPE_ERROR, "Incorrect P1 or P2 parameter."}, | |
114 | {"6A87", APDUCODE_TYPE_ERROR, "Lc inconsistent with P1-P2"}, | |
115 | {"6A88", APDUCODE_TYPE_ERROR, "Referenced data not found"}, | |
116 | {"6A89", APDUCODE_TYPE_ERROR, "File already exists"}, | |
117 | {"6A8A", APDUCODE_TYPE_ERROR, "DF name already exists."}, | |
118 | {"6AF0", APDUCODE_TYPE_ERROR, "Wrong parameter value"}, | |
119 | {"6AFX", APDUCODE_TYPE_ERROR, "-"}, | |
120 | {"6AXX", APDUCODE_TYPE_ERROR, "RFU"}, | |
121 | {"6B--", APDUCODE_TYPE_ERROR, " "}, | |
122 | {"6B00", APDUCODE_TYPE_ERROR, "Wrong parameter(s) P1-P2"}, | |
123 | {"6BXX", APDUCODE_TYPE_ERROR, "Reference incorrect (procedure byte), (ISO 7816-3)"}, | |
124 | {"6C--", APDUCODE_TYPE_ERROR, "Wrong length Le"}, | |
125 | {"6C00", APDUCODE_TYPE_ERROR, "Incorrect P3 length."}, | |
126 | {"6CXX", APDUCODE_TYPE_ERROR, "Bad length value in Le; 'xx' is the correct exact Le"}, | |
127 | {"6D--", APDUCODE_TYPE_ERROR, " "}, | |
128 | {"6D00", APDUCODE_TYPE_ERROR, "Instruction code not supported or invalid"}, | |
129 | {"6DXX", APDUCODE_TYPE_ERROR, "Instruction code not programmed or invalid (procedure byte), (ISO 7816-3)"}, | |
130 | {"6E--", APDUCODE_TYPE_ERROR, " "}, | |
131 | {"6E00", APDUCODE_TYPE_ERROR, "Class not supported"}, | |
132 | {"6EXX", APDUCODE_TYPE_ERROR, "Instruction class not supported (procedure byte), (ISO 7816-3)"}, | |
133 | {"6F--", APDUCODE_TYPE_ERROR, "Internal exception"}, | |
134 | {"6F00", APDUCODE_TYPE_ERROR, "Command aborted - more exact diagnosis not possible (e.g., operating system error)."}, | |
ec087218 | 135 | {"6FFF", APDUCODE_TYPE_ERROR, "Card dead (overuse, ...)"}, |
fe346768 | 136 | {"6FXX", APDUCODE_TYPE_ERROR, "No precise diagnosis (procedure byte), (ISO 7816-3)"}, |
137 | {"9---", APDUCODE_TYPE_NONE, ""}, | |
138 | {"9000", APDUCODE_TYPE_INFO, "Command successfully executed (OK)."}, | |
139 | {"9004", APDUCODE_TYPE_WARNING, "PIN not succesfully verified, 3 or more PIN tries left"}, | |
140 | {"9008", APDUCODE_TYPE_NONE, "Key/file not found"}, | |
141 | {"9080", APDUCODE_TYPE_WARNING, "Unblock Try Counter has reached zero"}, | |
142 | {"9100", APDUCODE_TYPE_NONE, "OK"}, | |
143 | {"9101", APDUCODE_TYPE_NONE, "States.activity, States.lock Status or States.lockable has wrong value"}, | |
144 | {"9102", APDUCODE_TYPE_NONE, "Transaction number reached its limit"}, | |
145 | {"910C", APDUCODE_TYPE_NONE, "No changes"}, | |
146 | {"910E", APDUCODE_TYPE_NONE, "Insufficient NV-Memory to complete command"}, | |
147 | {"911C", APDUCODE_TYPE_NONE, "Command code not supported"}, | |
148 | {"911E", APDUCODE_TYPE_NONE, "CRC or MAC does not match data"}, | |
149 | {"9140", APDUCODE_TYPE_NONE, "Invalid key number specified"}, | |
150 | {"917E", APDUCODE_TYPE_NONE, "Length of command string invalid"}, | |
151 | {"919D", APDUCODE_TYPE_NONE, "Not allow the requested command"}, | |
152 | {"919E", APDUCODE_TYPE_NONE, "Value of the parameter invalid"}, | |
153 | {"91A0", APDUCODE_TYPE_NONE, "Requested AID not present on PICC"}, | |
154 | {"91A1", APDUCODE_TYPE_NONE, "Unrecoverable error within application"}, | |
155 | {"91AE", APDUCODE_TYPE_NONE, "Authentication status does not allow the requested command"}, | |
156 | {"91AF", APDUCODE_TYPE_NONE, "Additional data frame is expected to be sent"}, | |
157 | {"91BE", APDUCODE_TYPE_NONE, "Out of boundary"}, | |
158 | {"91C1", APDUCODE_TYPE_NONE, "Unrecoverable error within PICC"}, | |
159 | {"91CA", APDUCODE_TYPE_NONE, "Previous Command was not fully completed"}, | |
160 | {"91CD", APDUCODE_TYPE_NONE, "PICC was disabled by an unrecoverable error"}, | |
161 | {"91CE", APDUCODE_TYPE_NONE, "Number of Applications limited to 28"}, | |
162 | {"91DE", APDUCODE_TYPE_NONE, "File or application already exists"}, | |
163 | {"91EE", APDUCODE_TYPE_NONE, "Could not complete NV-write operation due to loss of power"}, | |
164 | {"91F0", APDUCODE_TYPE_NONE, "Specified file number does not exist"}, | |
165 | {"91F1", APDUCODE_TYPE_NONE, "Unrecoverable error within file"}, | |
166 | {"920x", APDUCODE_TYPE_INFO, "Writing to EEPROM successful after 'x' attempts."}, | |
167 | {"9210", APDUCODE_TYPE_ERROR, "Insufficient memory. No more storage available."}, | |
168 | {"9240", APDUCODE_TYPE_ERROR, "Writing to EEPROM not successful."}, | |
169 | {"9301", APDUCODE_TYPE_NONE, "Integrity error"}, | |
170 | {"9302", APDUCODE_TYPE_NONE, "Candidate S2 invalid"}, | |
171 | {"9303", APDUCODE_TYPE_ERROR, "Application is permanently locked"}, | |
172 | {"9400", APDUCODE_TYPE_ERROR, "No EF selected."}, | |
173 | {"9401", APDUCODE_TYPE_NONE, "Candidate currency code does not match purse currency"}, | |
174 | {"9402", APDUCODE_TYPE_NONE, "Candidate amount too high"}, | |
175 | {"9402", APDUCODE_TYPE_ERROR, "Address range exceeded."}, | |
176 | {"9403", APDUCODE_TYPE_NONE, "Candidate amount too low"}, | |
177 | {"9404", APDUCODE_TYPE_ERROR, "FID not found, record not found or comparison pattern not found."}, | |
178 | {"9405", APDUCODE_TYPE_NONE, "Problems in the data field"}, | |
179 | {"9406", APDUCODE_TYPE_ERROR, "Required MAC unavailable"}, | |
180 | {"9407", APDUCODE_TYPE_NONE, "Bad currency : purse engine has no slot with R3bc currency"}, | |
181 | {"9408", APDUCODE_TYPE_NONE, "R3bc currency not supported in purse engine"}, | |
182 | {"9408", APDUCODE_TYPE_ERROR, "Selected file type does not match command."}, | |
183 | {"9580", APDUCODE_TYPE_NONE, "Bad sequence"}, | |
184 | {"9681", APDUCODE_TYPE_NONE, "Slave not found"}, | |
185 | {"9700", APDUCODE_TYPE_NONE, "PIN blocked and Unblock Try Counter is 1 or 2"}, | |
186 | {"9702", APDUCODE_TYPE_NONE, "Main keys are blocked"}, | |
187 | {"9704", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 3 or more PIN tries left"}, | |
188 | {"9784", APDUCODE_TYPE_NONE, "Base key"}, | |
189 | {"9785", APDUCODE_TYPE_NONE, "Limit exceeded - C-MAC key"}, | |
190 | {"9786", APDUCODE_TYPE_NONE, "SM error - Limit exceeded - R-MAC key"}, | |
191 | {"9787", APDUCODE_TYPE_NONE, "Limit exceeded - sequence counter"}, | |
192 | {"9788", APDUCODE_TYPE_NONE, "Limit exceeded - R-MAC length"}, | |
193 | {"9789", APDUCODE_TYPE_NONE, "Service not available"}, | |
194 | {"9802", APDUCODE_TYPE_ERROR, "No PIN defined."}, | |
195 | {"9804", APDUCODE_TYPE_ERROR, "Access conditions not satisfied, authentication failed."}, | |
196 | {"9835", APDUCODE_TYPE_ERROR, "ASK RANDOM or GIVE RANDOM not executed."}, | |
197 | {"9840", APDUCODE_TYPE_ERROR, "PIN verification not successful."}, | |
198 | {"9850", APDUCODE_TYPE_ERROR, "INCREASE or DECREASE could not be executed because a limit has been reached."}, | |
199 | {"9862", APDUCODE_TYPE_ERROR, "Authentication Error, application specific (incorrect MAC)"}, | |
200 | {"9900", APDUCODE_TYPE_NONE, "1 PIN try left"}, | |
201 | {"9904", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 1 PIN try left"}, | |
202 | {"9985", APDUCODE_TYPE_NONE, "Wrong status - Cardholder lock"}, | |
203 | {"9986", APDUCODE_TYPE_ERROR, "Missing privilege"}, | |
204 | {"9987", APDUCODE_TYPE_NONE, "PIN is not installed"}, | |
205 | {"9988", APDUCODE_TYPE_NONE, "Wrong status - R-MAC state"}, | |
206 | {"9A00", APDUCODE_TYPE_NONE, "2 PIN try left"}, | |
207 | {"9A04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, 2 PIN try left"}, | |
208 | {"9A71", APDUCODE_TYPE_NONE, "Wrong parameter value - Double agent AID"}, | |
209 | {"9A72", APDUCODE_TYPE_NONE, "Wrong parameter value - Double agent Type"}, | |
210 | {"9D05", APDUCODE_TYPE_ERROR, "Incorrect certificate type"}, | |
211 | {"9D07", APDUCODE_TYPE_ERROR, "Incorrect session data size"}, | |
212 | {"9D08", APDUCODE_TYPE_ERROR, "Incorrect DIR file record size"}, | |
213 | {"9D09", APDUCODE_TYPE_ERROR, "Incorrect FCI record size"}, | |
214 | {"9D0A", APDUCODE_TYPE_ERROR, "Incorrect code size"}, | |
215 | {"9D10", APDUCODE_TYPE_ERROR, "Insufficient memory to load application"}, | |
216 | {"9D11", APDUCODE_TYPE_ERROR, "Invalid AID"}, | |
217 | {"9D12", APDUCODE_TYPE_ERROR, "Duplicate AID"}, | |
218 | {"9D13", APDUCODE_TYPE_ERROR, "Application previously loaded"}, | |
219 | {"9D14", APDUCODE_TYPE_ERROR, "Application history list full"}, | |
220 | {"9D15", APDUCODE_TYPE_ERROR, "Application not open"}, | |
221 | {"9D17", APDUCODE_TYPE_ERROR, "Invalid offset"}, | |
222 | {"9D18", APDUCODE_TYPE_ERROR, "Application already loaded"}, | |
223 | {"9D19", APDUCODE_TYPE_ERROR, "Invalid certificate"}, | |
224 | {"9D1A", APDUCODE_TYPE_ERROR, "Invalid signature"}, | |
225 | {"9D1B", APDUCODE_TYPE_ERROR, "Invalid KTU"}, | |
226 | {"9D1D", APDUCODE_TYPE_ERROR, "MSM controls not set"}, | |
227 | {"9D1E", APDUCODE_TYPE_ERROR, "Application signature does not exist"}, | |
228 | {"9D1F", APDUCODE_TYPE_ERROR, "KTU does not exist"}, | |
229 | {"9D20", APDUCODE_TYPE_ERROR, "Application not loaded"}, | |
230 | {"9D21", APDUCODE_TYPE_ERROR, "Invalid Open command data length"}, | |
231 | {"9D30", APDUCODE_TYPE_ERROR, "Check data parameter is incorrect (invalid start address)"}, | |
232 | {"9D31", APDUCODE_TYPE_ERROR, "Check data parameter is incorrect (invalid length)"}, | |
233 | {"9D32", APDUCODE_TYPE_ERROR, "Check data parameter is incorrect (illegal memory check area)"}, | |
234 | {"9D40", APDUCODE_TYPE_ERROR, "Invalid MSM Controls ciphertext"}, | |
235 | {"9D41", APDUCODE_TYPE_ERROR, "MSM controls already set"}, | |
236 | {"9D42", APDUCODE_TYPE_ERROR, "Set MSM Controls data length less than 2 bytes"}, | |
237 | {"9D43", APDUCODE_TYPE_ERROR, "Invalid MSM Controls data length"}, | |
238 | {"9D44", APDUCODE_TYPE_ERROR, "Excess MSM Controls ciphertext"}, | |
239 | {"9D45", APDUCODE_TYPE_ERROR, "Verification of MSM Controls data failed"}, | |
240 | {"9D50", APDUCODE_TYPE_ERROR, "Invalid MCD Issuer production ID"}, | |
241 | {"9D51", APDUCODE_TYPE_ERROR, "Invalid MCD Issuer ID"}, | |
242 | {"9D52", APDUCODE_TYPE_ERROR, "Invalid set MSM controls data date"}, | |
243 | {"9D53", APDUCODE_TYPE_ERROR, "Invalid MCD number"}, | |
244 | {"9D54", APDUCODE_TYPE_ERROR, "Reserved field error"}, | |
245 | {"9D55", APDUCODE_TYPE_ERROR, "Reserved field error"}, | |
246 | {"9D56", APDUCODE_TYPE_ERROR, "Reserved field error"}, | |
247 | {"9D57", APDUCODE_TYPE_ERROR, "Reserved field error"}, | |
248 | {"9D60", APDUCODE_TYPE_ERROR, "MAC verification failed"}, | |
249 | {"9D61", APDUCODE_TYPE_ERROR, "Maximum number of unblocks reached"}, | |
250 | {"9D62", APDUCODE_TYPE_ERROR, "Card was not blocked"}, | |
251 | {"9D63", APDUCODE_TYPE_ERROR, "Crypto functions not available"}, | |
252 | {"9D64", APDUCODE_TYPE_ERROR, "No application loaded"}, | |
253 | {"9E00", APDUCODE_TYPE_NONE, "PIN not installed"}, | |
254 | {"9E04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, PIN not installed"}, | |
255 | {"9F00", APDUCODE_TYPE_NONE, "PIN blocked and Unblock Try Counter is 3"}, | |
256 | {"9F04", APDUCODE_TYPE_NONE, "PIN not succesfully verified, PIN blocked and Unblock Try Counter is 3"}, | |
257 | {"9FXX", APDUCODE_TYPE_NONE, "Command successfully executed; 'xx' bytes of data are available and can be requested using GET RESPONSE."}, | |
2d4db387 | 258 | {"9XXX", APDUCODE_TYPE_NONE, "Application related status, (ISO 7816-3)"} |
fe346768 | 259 | }; |
5bcb3496 | 260 | const size_t APDUCodeTableLen = sizeof(APDUCodeTable)/sizeof(APDUCode); |
fe346768 | 261 | |
262 | int CodeCmp(const char *code1, const char *code2) { | |
263 | int xsymb = 0; | |
264 | int cmp = 0; | |
265 | for (int i = 0; i < 4; i++) { | |
266 | if (code1[i] == code2[i]) | |
267 | cmp++; | |
268 | if (code1[i] == 'X' || code2[i] == 'X') | |
269 | xsymb++; | |
270 | } | |
271 | if (cmp == 4) | |
272 | return 0; | |
273 | ||
274 | if (cmp + xsymb == 4) | |
275 | return xsymb; | |
276 | ||
277 | return -1; | |
278 | } | |
279 | ||
5bcb3496 | 280 | const APDUCode* const GetAPDUCode(uint8_t sw1, uint8_t sw2) { |
77499f6f | 281 | char buf[5] = {0}; |
78a94ff9 | 282 | int res; |
2d4db387 | 283 | int mineq = APDUCodeTableLen; |
78a94ff9 | 284 | int mineqindx = 0; |
fe346768 | 285 | |
2d4db387 | 286 | sprintf(buf, "%02X%02X", sw1, sw2); |
fe346768 | 287 | |
5bcb3496 | 288 | for (int i = 0; i < APDUCodeTableLen; i++) { |
78a94ff9 | 289 | res = CodeCmp(APDUCodeTable[i].ID, buf); |
290 | ||
291 | // equal | |
292 | if (res == 0) { | |
fe346768 | 293 | return &APDUCodeTable[i]; |
294 | } | |
78a94ff9 | 295 | |
296 | // with some 'X' | |
297 | if (res > 0 && mineq > res) { | |
298 | mineq = res; | |
299 | mineqindx = i; | |
300 | } | |
fe346768 | 301 | } |
302 | ||
78a94ff9 | 303 | // if we have not equal, but with some 'X' |
2d4db387 | 304 | if (mineqindx < APDUCodeTableLen) { |
78a94ff9 | 305 | return &APDUCodeTable[mineqindx]; |
306 | } | |
307 | ||
fe346768 | 308 | return NULL; |
309 | } | |
310 | ||
5bcb3496 | 311 | const char* GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) { |
312 | const APDUCode *cd = GetAPDUCode(sw1, sw2); | |
fe346768 | 313 | if (cd) |
314 | return cd->Description; | |
315 | else | |
316 | return APDUCodeTable[0].Description; //empty string | |
317 | } |