vicc: move detailed description to APDU class for generic use
This commit is contained in:
@@ -67,34 +67,38 @@ SW = {
|
|||||||
SW_MESSAGES = {
|
SW_MESSAGES = {
|
||||||
0x9000: 'Normal processing (No further qualification)',
|
0x9000: 'Normal processing (No further qualification)',
|
||||||
|
|
||||||
0x6200: 'Warning processing (State of non-volatile memory is unchanged): '
|
0x6200: 'Warning processing (State of NVM is unchanged): '
|
||||||
'No information given',
|
'No information given',
|
||||||
0x6281: 'Warning processing (State of non-volatile memory is unchanged): '
|
0x6281: 'Warning processing (State of NVM is unchanged): '
|
||||||
'Part of returned data may be corrupted',
|
'Part of returned data may be corrupted',
|
||||||
0x6282: 'Warning processing (State of non-volatile memory is unchanged): '
|
0x6282: 'Warning processing (State of NVM is unchanged): '
|
||||||
'End of file or record reached before reading Ne bytes',
|
'End of file or record reached before reading Ne bytes',
|
||||||
0x6283: 'Warning processing (State of non-volatile memory is unchanged): '
|
0x6283: 'Warning processing (State of NVM is unchanged): '
|
||||||
'Selected file deactivated',
|
'Selected file deactivated',
|
||||||
0x6284: 'Warning processing (State of non-volatile memory is unchanged): '
|
0x6284: 'Warning processing (State of NVM is unchanged): '
|
||||||
'File control information not formatted according to 5.3.3',
|
'File control information not formatted according to 5.3.3',
|
||||||
0x6285: 'Warning processing (State of non-volatile memory is unchanged): '
|
0x6285: 'Warning processing (State of NVM is unchanged): '
|
||||||
'Selected file in termination state',
|
'Selected file in termination state',
|
||||||
0x6286: 'Warning processing (State of non-volatile memory is unchanged): '
|
0x6286: 'Warning processing (State of NVM is unchanged): '
|
||||||
'No input data available from a sensor on the card',
|
'No input data available from a sensor on the card',
|
||||||
|
0x6287: 'Warning processing (State of NVM is unchanged): '
|
||||||
|
'At least one of the referenced records is deactivated',
|
||||||
|
|
||||||
0x6300: 'Warning processing (State of non-volatile memory has changed): '
|
0x6300: 'Warning processing (State of NVM may have changed): '
|
||||||
'No information given',
|
'No information given',
|
||||||
0x6381: 'Warning processing (State of non-volatile memory has changed): '
|
0x6340: 'Warning processing (State of NVM may have changed): '
|
||||||
|
'Unsuccessful comparison',
|
||||||
|
0x6381: 'Warning processing (State of NVM may have changed): '
|
||||||
'File filled up by the last write',
|
'File filled up by the last write',
|
||||||
|
|
||||||
0x6400: 'Execution error (State of non-volatile memory is unchanged): '
|
0x6400: 'Execution error (State of NVM is unchanged): '
|
||||||
'Execution error',
|
'Execution error',
|
||||||
0x6401: 'Execution error (State of non-volatile memory is unchanged): '
|
0x6401: 'Execution error (State of NVM is unchanged): '
|
||||||
'Immediate response required by the card',
|
'Immediate response required by the card',
|
||||||
|
|
||||||
0x6500: 'Execution error (State of non-volatile memory has changed): '
|
0x6500: 'Execution error (State of NVM may have changed): '
|
||||||
'No information given',
|
'No information given',
|
||||||
0x6581: 'Execution error (State of non-volatile memory has changed): '
|
0x6581: 'Execution error (State of NVM may have changed): '
|
||||||
'Memory failure',
|
'Memory failure',
|
||||||
|
|
||||||
0x6700: 'Checking error: Wrong length; no further indication',
|
0x6700: 'Checking error: Wrong length; no further indication',
|
||||||
@@ -167,6 +171,9 @@ for i in range(0, 0xff):
|
|||||||
SW_MESSAGES[0x6600 + i] = 'Execution error (Security-related issues)'
|
SW_MESSAGES[0x6600 + i] = 'Execution error (Security-related issues)'
|
||||||
SW_MESSAGES[0x6C00 + i] = 'Checking error (Wrong Le field; ' + str(i) + \
|
SW_MESSAGES[0x6C00 + i] = 'Checking error (Wrong Le field; ' + str(i) + \
|
||||||
' available data bytes)'
|
' available data bytes)'
|
||||||
|
if i >= 0xC0:
|
||||||
|
SW_MESSAGES[0x6300 + i] = 'Warning processing (State of NVM may have changed); ' + str(i - 0xC0) + \
|
||||||
|
' further allowed tries)'
|
||||||
|
|
||||||
|
|
||||||
class SwError(Exception):
|
class SwError(Exception):
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import logging
|
|||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
|
||||||
from virtualsmartcard.ConstantDefinitions import MAX_EXTENDED_LE, MAX_SHORT_LE
|
from virtualsmartcard.ConstantDefinitions import MAX_EXTENDED_LE, MAX_SHORT_LE
|
||||||
from virtualsmartcard.SWutils import SwError, SW
|
from virtualsmartcard.SWutils import SwError, SW
|
||||||
from virtualsmartcard.SmartcardFilesystem import make_property
|
from virtualsmartcard.SmartcardFilesystem import make_property
|
||||||
@@ -351,8 +350,6 @@ class Iso7816OS(SmartcardOS):
|
|||||||
answer = self.formatResult(Iso7816OS.seekable(c.ins),
|
answer = self.formatResult(Iso7816OS.seekable(c.ins),
|
||||||
c.effective_Le, result, sw, sm)
|
c.effective_Le, result, sw, sm)
|
||||||
except SwError as e:
|
except SwError as e:
|
||||||
logging.debug(traceback.format_exc().rstrip())
|
|
||||||
logging.info(e.message)
|
|
||||||
sw = e.sw
|
sw = e.sw
|
||||||
result = b""
|
result = b""
|
||||||
answer = self.formatResult(False, 0, result, sw, sm)
|
answer = self.formatResult(False, 0, result, sw, sm)
|
||||||
@@ -602,20 +599,25 @@ class VirtualICC(object):
|
|||||||
logging.warning("Expected %u bytes, but received only %u",
|
logging.warning("Expected %u bytes, but received only %u",
|
||||||
size, len(msg))
|
size, len(msg))
|
||||||
|
|
||||||
logging.info("Command APDU (%d bytes):\n %s\n", len(msg),
|
logging.info("Command APDU (%d bytes):\n %s", len(msg),
|
||||||
hexdump(msg, indent=2))
|
hexdump(msg, indent=2))
|
||||||
|
proprietary = False
|
||||||
try:
|
try:
|
||||||
logging.debug(str(C_APDU(msg)))
|
parsed = C_APDU(msg)
|
||||||
|
logging.debug(str(parsed))
|
||||||
|
if parsed.CLA & 0b10000000 == 0b10000000:
|
||||||
|
proprietary = True
|
||||||
except:
|
except:
|
||||||
pass
|
proprietary = True
|
||||||
|
|
||||||
answer = self.os.execute(msg)
|
answer = self.os.execute(msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logging.debug(str(R_APDU(answer)))
|
if not proprietary:
|
||||||
|
logging.debug(str(R_APDU(answer)))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
logging.info("Response APDU (%d bytes):\n %s\n", len(answer),
|
logging.info("Response APDU (%d bytes):\n %s", len(answer),
|
||||||
hexdump(answer, indent=2))
|
hexdump(answer, indent=2))
|
||||||
|
|
||||||
self.__sendToVPICC(answer)
|
self.__sendToVPICC(answer)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import binascii
|
|||||||
import string
|
import string
|
||||||
import struct
|
import struct
|
||||||
from virtualsmartcard.ConstantDefinitions import MAX_SHORT_LE, MAX_EXTENDED_LE
|
from virtualsmartcard.ConstantDefinitions import MAX_SHORT_LE, MAX_EXTENDED_LE
|
||||||
|
from virtualsmartcard.SWutils import SW_MESSAGES
|
||||||
|
|
||||||
|
|
||||||
def stringtoint(data):
|
def stringtoint(data):
|
||||||
@@ -201,11 +202,33 @@ class APDU(object):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
result = "%s(%s)" % (self.__class__.__name__,
|
result = "%s(%s)" % (self.__class__.__name__,
|
||||||
", ".join(self._format_fields()))
|
", ".join(self._format_fields()))
|
||||||
|
|
||||||
if len(self.data) > 0:
|
if len(self.data) > 0:
|
||||||
return result + ":\n " + hexdump(self.data, indent=2)
|
result = result + "\n " + hexdump(self.data, indent=2)
|
||||||
else:
|
|
||||||
return result
|
if hasattr(self, "SW"):
|
||||||
|
sw_int = int.from_bytes(self.SW, 'big')
|
||||||
|
if sw_int in SW_MESSAGES.keys():
|
||||||
|
result = result + '\n' + SW_MESSAGES[sw_int]
|
||||||
|
|
||||||
|
if hasattr(self, "CLA"):
|
||||||
|
debug_CLA = []
|
||||||
|
if self.CLA & 0b10000000 == 0b10000000:
|
||||||
|
debug_CLA.append('proprietary class')
|
||||||
|
if self.CLA & 0b00010000 == 0b00010000:
|
||||||
|
debug_CLA.append('command chaining')
|
||||||
|
if self.CLA & 0b00001100 == 0b00000100:
|
||||||
|
debug_CLA.append('proprietary secure messaging')
|
||||||
|
if self.CLA & 0b00001100 == 0b00001000:
|
||||||
|
debug_CLA.append('secure messaging (command header not processed)')
|
||||||
|
if self.CLA & 0b00001100 == 0b00001100:
|
||||||
|
debug_CLA.append('secure messaging (command header authenticated)')
|
||||||
|
if self.CLA & 0b00000011:
|
||||||
|
debug_CLA.append('logical channel %d' % self.CLA & 0b00000011)
|
||||||
|
if debug_CLA:
|
||||||
|
result = result + '\n' + ', '.join(debug_CLA)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
parts = self._format_fields()
|
parts = self._format_fields()
|
||||||
|
|||||||
Reference in New Issue
Block a user