vicc: move detailed description to APDU class for generic use

This commit is contained in:
Frank Morgner
2022-05-09 22:26:58 +02:00
parent 63e366d348
commit b57b383a1d
3 changed files with 57 additions and 25 deletions

View File

@@ -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):

View File

@@ -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)

View File

@@ -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()