Status word decoding

git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@18 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
henryk 2005-09-29 17:16:27 +00:00
parent 2e29202aae
commit 3f36321e51
3 changed files with 79 additions and 15 deletions

View File

@ -270,6 +270,49 @@ class Cyberflex_Card(Java_Card):
"reset_keyset": (cmd_resetkeyset, "reset_keyset",
"""Reset the keyset to the default keyset for this card.""")
} )
STATUS_WORDS = dict(Java_Card.STATUS_WORDS)
STATUS_WORDS.update( {
"\x62\x83": "The Card Manager is locked (SelectApplication).",
"\x63\x00": "Authentication of the host cryptogram failed.",
"\x63\x10": "More data is available for return than is specified in the Le value.",
"\x64\x00": "Technical problem that has no specified diagnosis.",
"\x65\x81": "Memory failure.",
"\x67\x00": "The specified length of the input data (Lc) is incorrect.",
"\x69\x81": "No key is specified (GetResponse, called internally).",
"\x69\x82": "Security status not satisfied. For example, MAC verification failed, the authentication key is locked, or the current security domain requires DAP verification and no verification data was included with the command.",
"\x69\x83": "The key is blocked (GetResponse, called internally).",
"\x69\x85": """A requirement for using the command is not satisfied. For example:
+ Command issued outside of a secure channel.
+ Current application does not have the required application privilege
or life cycle state.
+ The required preceding command was not present.
+ The object to delete is referenced by another object on the card.""",
"\x69\x87": "The MAC or other verification data is missing (Install).",
"\x69\x99": "Application selection failed (SelectApplication).",
"\x6A\x80": """Invalid or inconsistent input data, including input data that is inconsistent with a command header parameter, and LV/TLV-format elements in the input data that are not self-consistent. For example:
+ Incorrect number of padding bytes, incorrect key used for
encryption, or the specified key set or key index value is invalid.
+ Referenced AID is not found in the card registry or package, or the
newly specified AID already exists in the registry.
+ Inappropriate application privilege byte value (installing security
domain), or card already has a default selected application
(specifying default selected application).
+ First block of input data for a load file is not preceded by the
correct tag and/or valid length, or the load file refers to a
nonexistent package.""",
"\x6A\x81": "Target is locked (SelectApplication).",
"\x6A\x82": "Registry contains no valid application (or no additional valid application) with the specified AID (SelectApplication).",
"\x6A\x84": "Insufficient EEPROM memory available to add the object to the card.",
"\x6A\x86": "Incorrect or unsupported value is specified for P1, P2, or both.",
"\x6A\x88": "Data referred to in P1, P2, or both is not found.",
"\x6D\x00": "Unsupported value entered for the INS byte.",
"\x6E\x00": "Unsupported value entered for the CLA byte.",
"\x6F\x00": "JVM error that has no specified diagnosis.",
"\x90\x00": "Command succeeded.",
"\x94\x81": "Target has an invalid life cycle state.",
"\x94\x84": "Unsupported algorithm ID in input data (PutKey).",
"\x94\x85": "Invalid key check value in input data (PutKey).",
} )
if __name__ == "__main__":
c = Cyberflex_Card()

View File

@ -1,4 +1,4 @@
import crypto_utils, utils, pycsc
import crypto_utils, utils, pycsc, binascii
DEBUG = True
@ -8,6 +8,9 @@ class Card:
ATRS = []
DRIVER_NAME = "Generic"
COMMANDS = {}
STATUS_WORDS = {
SW_OK: "Normal execution"
}
def __init__(self, card = None):
if card is None:
@ -16,6 +19,9 @@ class Card:
self.card = card
self._i = 0
self.last_apdu = None
self.last_sw = None
self.sw_changed = False
def _check_apdu(apdu):
if len(apdu) < 4 or ((len(apdu) > 5) and len(apdu) != (ord(apdu[4])+5)):
@ -24,6 +30,19 @@ class Card:
return True
_check_apdu = staticmethod(_check_apdu)
def _real_send(self, apdu):
if not Card._check_apdu(apdu):
raise Exception, "Invalid APDU"
if DEBUG:
print ">> " + utils.hexdump(apdu, indent = 3)
result = self.card.transmit(apdu)
self.last_apdu = apdu
self.last_sw = result[-2:]
self.sw_changed = True
if DEBUG:
print "<< " + utils.hexdump(result, indent = 3)
return result
def send_apdu(self, apdu):
if not Card._check_apdu(apdu):
raise Exception, "Invalid APDU"
@ -32,29 +51,18 @@ class Card:
if hasattr(self, "before_send"):
apdu = self.before_send(apdu)
if not Card._check_apdu(apdu):
raise Exception, "Invalid APDU"
if DEBUG:
print ">> " + utils.hexdump(apdu, indent = 3)
result = self.card.transmit(apdu)
if DEBUG:
print "<< " + utils.hexdump(result, indent = 3)
result = self._real_send(apdu)
if result[0] == '\x61':
## Need to call GetResponse
gr_apdu = self.APDU_GET_RESPONSE + result[1]
if not Card._check_apdu(gr_apdu):
raise Exception, "Invalid APDU"
if DEBUG:
print ">> " + utils.hexdump(gr_apdu, indent = 3)
result = self.card.transmit(gr_apdu)
if DEBUG:
print "<< " + utils.hexdump(result, indent = 3)
result = self._real_send(gr_apdu)
if DEBUG:
print "Ending transaction %i\n%s\n" % (self._i, '-'*80)
self._i = self._i + 1
return result
def can_handle(cls, ATR):
@ -69,3 +77,11 @@ class Card:
def get_prompt(self):
return "(%s)" % self.DRIVER_NAME
def decode_statusword(self):
if self.last_sw is None:
return "No command executed so far"
elif self.last_sw[0] == "\x61":
return "%i (0x%02x) bytes of response data can be retrieved with GetResponse." % ( (ord(self.last_sw[1])) * 2 )
else:
return self.STATUS_WORDS.get(self.last_sw, "Unknown SW: %s" % binascii.b2a_hex(self.last_sw))

View File

@ -117,6 +117,8 @@ if __name__ == "__main__":
if line == "":
continue
card.sw_changed = False
parts = line.split()
cmd = parts[0]
if card.COMMANDS.has_key(cmd.lower()):
@ -151,3 +153,6 @@ if __name__ == "__main__":
else:
print "Unknown command"
if card.sw_changed:
print card.decode_statusword()