1 """ISO7816-4 error checking strategy.
2
3 __author__ = "http://www.gemalto.com"
4
5 Copyright 2001-2012 gemalto
6 Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
7
8 This file is part of pyscard.
9
10 pyscard is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14
15 pyscard is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with pyscard; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 """
24
25 from __future__ import print_function
26 from smartcard.sw.ErrorChecker import ErrorChecker
27 import smartcard.sw.SWExceptions
28
29 iso7816_4SW = {
30 0x62: (smartcard.sw.SWExceptions.WarningProcessingException,
31 {0x00: "Response padded/ More APDU commands expected",
32 0x81: "Part of returned data may be corrupted",
33 0x82: "End of file/record reached before reading Le bytes",
34 0x83: "File invalidated",
35 0x84: "FCI not correctly formatted",
36 0xFF: "Correct execution, response padded"}),
37
38 0x63: (smartcard.sw.SWExceptions.WarningProcessingException,
39 {0x00: "Authentication failed",
40 0x81: "File filled up by the last write",
41 0xC0: "PIN verification failed. 0 tries before blocking PIN",
42 0xC1: "PIN verification failed. 1 tries before blocking PIN",
43 0xC2: "PIN verification failed. 2 tries before blocking PIN",
44 0xC3: "PIN verification failed. 3 tries before blocking PIN",
45 0xC4: "PIN verification failed. 4 tries before blocking PIN",
46 0xC5: "PIN verification failed. 5 tries before blocking PIN",
47 0xC6: "PIN verification failed. 6 tries before blocking PIN",
48 0xC7: "PIN verification failed. 7 tries before blocking PIN",
49 0xC8: "PIN verification failed. 8 tries before blocking PIN",
50 0xC9: "PIN verification failed. 9 tries before blocking PIN",
51 0xCA: "PIN verification failed. 10 tries before blocking PIN",
52 0xCB: "PIN verification failed. 11 tries before blocking PIN",
53 0xCC: "PIN verification failed. 12 tries before blocking PIN",
54 0xCD: "PIN verification failed. 13 tries before blocking PIN",
55 0xCE: "PIN verification failed. 14 tries before blocking PIN",
56 0xCF: "PIN verification failed. 15 tries before blocking PIN"}),
57
58 0x64: (smartcard.sw.SWExceptions.ExecutionErrorException,
59 {0x00: "Integrity error detected in EEPROM"}),
60
61 0x67: (smartcard.sw.SWExceptions.CheckingErrorException,
62 {0x00: "Wrong length in Lc"}),
63
64 0x68: (smartcard.sw.SWExceptions.CheckingErrorException,
65 {0x81: "Logical channel not supported",
66 0x82: "Secure messaging not supported"}),
67
68 0x69: (smartcard.sw.SWExceptions.CheckingErrorException,
69 {0x81: "Command incompatible with file structure.",
70 0x82: "Security status not satisfied",
71 0x83: "Authentification method blocked",
72 0x84: "Referenced data invalid",
73 0x85: "Conditions of use not satisfied",
74 0x86: "Command not allowed (no current EF)",
75 0x87: "Secure messaging data object missing.",
76 0x88: "Secure messaging data object incorrect"}),
77
78 0x6A: (smartcard.sw.SWExceptions.CheckingErrorException,
79 {0x80: "Incorrect parameters in the data field",
80 0x81: "Function not supported",
81 0x82: "File not found",
82 0x83: "Record not found",
83 0x84: "Not enough memory space in the file",
84 0x85: "Lc inconsistent with TLV structure",
85 0x86: "Incorrect parameters P1-P2",
86 0x87: "Lc is inconsistent with P1-P2",
87 0x88: "Referenced data not found"}),
88
89 0x6B: (smartcard.sw.SWExceptions.CheckingErrorException,
90 {0x00: "Incorrect parameters P1-P2"}),
91
92 0x6D: (smartcard.sw.SWExceptions.CheckingErrorException,
93 {0x00: "Instruction (INS) not supported"}),
94
95 0x6E: (smartcard.sw.SWExceptions.CheckingErrorException,
96 {0x00: "Class (CLA) not supported"}),
97
98 0x6F: (smartcard.sw.SWExceptions.CheckingErrorException,
99 {0x00: "Fatal error"}),
100 }
101
102
104 """ISO7816-4 error checking strategy.
105
106 This strategy raises the following exceptions:
107 - sw1 sw2
108 - 62 00 81 82 83 84 FF WarningProcessingException
109 - 63 00 81 C0->CF WarningProcessingException
110 - 64 00 ExecutionErrorException
111 - 67 00 CheckingErrorException
112 - 68 81 82 CheckingErrorException
113 - 69 81->88 99? c1? CheckingErrorException
114 - 6a 80->88 CheckingErrorException
115 - 6b 00 CheckingErrorException
116 - 6d 00 CheckingErrorException
117 - 6e 00 CheckingErrorException
118 - 6f 00 CheckingErrorException
119
120 This checker does not raise exceptions on undefined sw1 values, e.g.:
121 - sw1 sw2
122 - 65 any
123 - 66 any
124 - 6c any
125
126 and on undefined sw2 values, e.g.:
127 - sw1 sw2
128 - 62 80 85
129 - 6b any except 00
130
131
132 Use another checker in the error checking chain, e.g., the
133 ISO7816_4SW1ErrorChecker, to raise exceptions on these undefined
134 values.
135 """
136
138 """Called to test data, sw1 and sw2 for error.
139
140 @param data: apdu response data
141 @param sw1, sw2: apdu data status words
142
143 Derived classes must raise a L{smartcard.sw.SWException} upon error."""
144 if sw1 in iso7816_4SW:
145 exception, sw2dir = iso7816_4SW[sw1]
146 if type(sw2dir) == type({}):
147 try:
148 message = sw2dir[sw2]
149 raise exception(data, sw1, sw2, message)
150 except KeyError:
151 pass
152
153 if __name__ == '__main__':
154 """Small sample illustrating the use of ISO7816_4ErrorChecker."""
155 ecs = ISO7816_4ErrorChecker()
156 ecs([], 0x90, 0x00)
157 try:
158 ecs([], 0x6b, 0x00)
159 except smartcard.sw.SWExceptions.CheckingErrorException as e:
160 print(str(e) + " %x %x" % (e.sw1, e.sw2))
161