- Move CryptoflexMF to cards.cryptoflex

- A little bit of code cleanup in SmartcardFilesystem.py


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@501 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
oepen
2011-08-23 10:49:35 +00:00
parent 4694e1fd1a
commit f04529b1f1
3 changed files with 145 additions and 145 deletions

View File

@@ -25,7 +25,7 @@ from virtualsmartcard.SmartcardFilesystem import MF, DF, TransparentStructureEF
from virtualsmartcard.ConstantDefinitions import FDB
from virtualsmartcard.CryptoUtils import protect_string, read_protected_string
import virtualsmartcard.SmartcardSAM
from virtualsmartcard.cards.cryptoflex import CryptoflexSAM
from virtualsmartcard.cards.cryptoflex import CryptoflexSAM, CryptoflexMF
from virtualsmartcard.cards.ePass import PassportSAM
# pgp directory
@@ -132,8 +132,6 @@ class CardGenerator(object):
self.sam = PassportSAM(self.mf)
def __generate_cryptoflex(self):
from virtualsmartcard.SmartcardFilesystem import CryptoflexMF
self.mf = CryptoflexMF()
self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x0002,
filedescriptor=0x01,

View File

@@ -22,9 +22,9 @@
"""
from pickle import dumps, loads
import logging
from virtualsmartcard.ConstantDefinitions import *
from virtualsmartcard.ConstantDefinitions import DCB, FDB, FID, LCB, REF
from virtualsmartcard.TLVutils import *
from virtualsmartcard.SWutils import *
from virtualsmartcard.SWutils import SW, SwError
from virtualsmartcard.utils import stringtoint, inttostring
def isEqual(list): # {{{
@@ -100,7 +100,7 @@ def getfile_byrefdataobj(mf, refdataobjs): # {{{
# }}}
def write(old, newlist, offsets, datacoding, maxsize=None): # {{{
"""Returns the status bytes and the result of a writeoperation according to
"""Returns the status bytes and the result of a write operation according to
the given data coding.
@param old: string of old data
@@ -169,7 +169,7 @@ def get_indexes(items, reference=REF["IDENTIFIER_FIRST"], index_current=0): # {{
if (reference in [REF["IDENTIFIER_FIRST"],
REF["IDENTIFIER_LAST"]]
or index_current == -1):
# Read first occurence OR
# Read first occurrence OR
# Read last occurrence OR
# No current record (and next/previous occurrence)
indexes = range(0, len(items))
@@ -355,39 +355,39 @@ class File(object): # {{{
tlv_data.append(tag, newlength, newvalue)
self.setdec(attribute, tlv_data)
def readbinary(*argz, **args):
def readbinary(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
def writebinary(*argz, **args):
def writebinary(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
def updatebinary(*argz, **args):
def updatebinary(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
def erasebinary(*argz, **args):
def erasebinary(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
def readrecord(*argz, **args):
def readrecord(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
def writerecord(*argz, **args):
def writerecord(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
def appendrecord(*argz, **args):
def appendrecord(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
def updaterecord(*argz, **args):
def updaterecord(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
def select(*argz, **args):
def select(self, *argz, **args):
"""Only a template, will raise an error."""
raise SwError(SW["ERR_INCOMPATIBLEWITHFILE"])
# }}}
@@ -1631,130 +1631,3 @@ class RecordStructureEF(EF): # {{{
r.identifier = None
return SW["NORMAL"]
# }}}
class CryptoflexMF(MF): # {{{
@staticmethod
def create(p1, p2, data):
if data[0:2] != "\xff\xff":
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
args = {
"parent": None,
"filedescriptor": 0,
"fid": stringtoint(data[4:6]),
}
if data[6] == "\x01":
args["data"] = chr(0)*stringtoint(data[2:4])
args["filedescriptor"] = FDB["EFSTRUCTURE_TRANSPARENT"]
file = TransparentStructureEF(**args)
elif data[6] == "\x02":
if len(data)>16:
args["maxrecordsize"] = stringtoint(data[16])
elif p2:
# if given a number of records
args["maxrecordsize"] = (stringtoint(data[2:4])/p2)
args["filedescriptor"] = FDB["EFSTRUCTURE_LINEAR_FIXED_NOFURTHERINFO"]
file = RecordStructureEF(**args)
elif data[6] == "\x03":
args["filedescriptor"] = FDB["EFSTRUCTURE_LINEAR_VARIABLE_NOFURTHERINFO"]
file = RecordStructureEF(**args)
elif data[6] == "\x04":
args["filedescriptor"] = FDB["EFSTRUCTURE_CYCLIC_NOFURTHERINFO"]
file = RecordStructureEF(**args)
elif data[6] == "\x38":
if data[12] != "\x03":
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
file = DF(**args)
else:
logging.error("unknown type: 0x%x" % ord(data[6]))
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
return [file]
def recordHandlingDecode(self, p1, p2):
if p2 < 4:
p1 = 0
return MF.recordHandlingDecode(self, p1, p2)
def dataUnitsDecodePlain(self, p1, p2, data):
ef = self.currentEF()
# FIXME: Cyberflex Access TM Software Development Kit Release 3C
# enforces the following:
# offsets = [(p2 << 8) + p1]
# but smartcard_login-0.1.1 requires:
offsets = [(p1 << 8) + p2]
datalist = [data]
return ef, offsets, datalist
def selectFile(self, p1, p2, data):
"""
Function for instruction 0xa4. Takes the parameter bytes 'p1', 'p2' as
integers and 'data' as binary string. Returns the status bytes as two
byte long integer and the response data as binary string.
"""
P2_FCI = 0
P2_FCP = 1 << 2
P2_FMD = 2 << 2
P2_NONE = 3 << 2
file = self._selectFile(p1, p2, data)
if isinstance(file, EF):
size = inttostring(min(0xffff, len(file.getenc('data'))), 2) # File size (body only)
extra = chr(0) # RFU
if isinstance(file, RecordStructureEF) and file.hasFixedRecordSize() and not file.isCyclic():
extra += chr(0) + chr(min(file.records, 0xff)) # Length of records
elif isinstance(file, DF):
size = inttostring(0xffff, 2) # Number of unused EEPROM bytes available in the DF
efcount = 0
dfcount = 0
chv1 = None
chv2 = None
chv1lifecycle = 0
chv2lifecycle = 0
for f in self.content:
if f.fid == 0x0000:
chv1 = f
chv1lifecycle = f.lifecycle & 1
if f.fid == 0x0100:
chv2 = f
chv2lifecycle = f.lifecycle & 1
if isinstance(f, EF):
efcount += 1
if isinstance(f, DF):
dfcount += 1
if chv1:
extra = chr(1) # TODO LSB correct?
else:
extra = chr(0) # TODO LSB correct?
extra += chr(efcount)
extra += chr(dfcount)
extra += chr(0) # TODO Number of PINs and unblock CHV PINs
extra += chr(0) # RFU
if chv1:
extra += chr(0) # TODO Number of remaining CHV1 attempts
extra += chr(0) # TODO Number of remaining unblock CHV1 attempts
if chv2:
extra += chr(0) # TODO CHV2 key status
extra += chr(0) # TODO CHV2 unblocking key status
data = inttostring(0, 2) # RFU
data += size
data += inttostring(file.fid, 2)
data += inttostring(file.filedescriptor) # File type
data += inttostring(0, 4) # ACs TODO
data += chr(file.lifecycle & 1) # File status
data += chr(len(extra))
data += extra
self.current = file
return SW["NORMAL"], data
# }}}

View File

@@ -19,9 +19,13 @@
from virtualsmartcard.SmartcardSAM import SAM
from virtualsmartcard.SEutils import Security_Environment
from virtualsmartcard.SWutils import SwError, SW
from virtualsmartcard.utils import inttostring
from virtualsmartcard.utils import inttostring, stringtoint
from virtualsmartcard import TLVutils
from virtualsmartcard.SmartcardFilesystem import MF, TransparentStructureEF, \
RecordStructureEF, DF, EF
from virtualsmartcard.ConstantDefinitions import FDB
import struct, logging
class CryptoflexSE(Security_Environment):
@@ -118,4 +122,129 @@ class CryptoflexSAM(SAM):
sw, data = SAM.internal_authenticate(self, p1, p2, data)
if data != "":
data = data[::-1]
return sw, data
return sw, data
class CryptoflexMF(MF): # {{{
@staticmethod
def create(p1, p2, data):
if data[0:2] != "\xff\xff":
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
args = {
"parent": None,
"filedescriptor": 0,
"fid": stringtoint(data[4:6]),
}
if data[6] == "\x01":
args["data"] = chr(0)*stringtoint(data[2:4])
args["filedescriptor"] = FDB["EFSTRUCTURE_TRANSPARENT"]
file = TransparentStructureEF(**args)
elif data[6] == "\x02":
if len(data)>16:
args["maxrecordsize"] = stringtoint(data[16])
elif p2:
# if given a number of records
args["maxrecordsize"] = (stringtoint(data[2:4])/p2)
args["filedescriptor"] = FDB["EFSTRUCTURE_LINEAR_FIXED_NOFURTHERINFO"]
file = RecordStructureEF(**args)
elif data[6] == "\x03":
args["filedescriptor"] = FDB["EFSTRUCTURE_LINEAR_VARIABLE_NOFURTHERINFO"]
file = RecordStructureEF(**args)
elif data[6] == "\x04":
args["filedescriptor"] = FDB["EFSTRUCTURE_CYCLIC_NOFURTHERINFO"]
file = RecordStructureEF(**args)
elif data[6] == "\x38":
if data[12] != "\x03":
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
file = DF(**args)
else:
logging.error("unknown type: 0x%x" % ord(data[6]))
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
return [file]
def recordHandlingDecode(self, p1, p2):
if p2 < 4:
p1 = 0
return MF.recordHandlingDecode(self, p1, p2)
def dataUnitsDecodePlain(self, p1, p2, data):
ef = self.currentEF()
# FIXME: Cyberflex Access TM Software Development Kit Release 3C
# enforces the following:
# offsets = [(p2 << 8) + p1]
# but smartcard_login-0.1.1 requires:
offsets = [(p1 << 8) + p2]
datalist = [data]
return ef, offsets, datalist
def selectFile(self, p1, p2, data):
"""
Function for instruction 0xa4. Takes the parameter bytes 'p1', 'p2' as
integers and 'data' as binary string. Returns the status bytes as two
byte long integer and the response data as binary string.
"""
P2_FCI = 0
P2_FCP = 1 << 2
P2_FMD = 2 << 2
P2_NONE = 3 << 2
file = self._selectFile(p1, p2, data)
if isinstance(file, EF):
size = inttostring(min(0xffff, len(file.getenc('data'))), 2) # File size (body only)
extra = chr(0) # RFU
if isinstance(file, RecordStructureEF) and file.hasFixedRecordSize() and not file.isCyclic():
extra += chr(0) + chr(min(file.records, 0xff)) # Length of records
elif isinstance(file, DF):
size = inttostring(0xffff, 2) # Number of unused EEPROM bytes available in the DF
efcount = 0
dfcount = 0
chv1 = None
chv2 = None
chv1lifecycle = 0
chv2lifecycle = 0
for f in self.content:
if f.fid == 0x0000:
chv1 = f
chv1lifecycle = f.lifecycle & 1
if f.fid == 0x0100:
chv2 = f
chv2lifecycle = f.lifecycle & 1
if isinstance(f, EF):
efcount += 1
if isinstance(f, DF):
dfcount += 1
if chv1:
extra = chr(1) # TODO LSB correct?
else:
extra = chr(0) # TODO LSB correct?
extra += chr(efcount)
extra += chr(dfcount)
extra += chr(0) # TODO Number of PINs and unblock CHV PINs
extra += chr(0) # RFU
if chv1:
extra += chr(0) # TODO Number of remaining CHV1 attempts
extra += chr(0) # TODO Number of remaining unblock CHV1 attempts
if chv2:
extra += chr(0) # TODO CHV2 key status
extra += chr(0) # TODO CHV2 unblocking key status
data = inttostring(0, 2) # RFU
data += size
data += inttostring(file.fid, 2)
data += inttostring(file.filedescriptor) # File type
data += inttostring(0, 4) # ACs TODO
data += chr(file.lifecycle & 1) # File status
data += chr(len(extra))
data += extra
self.current = file
return SW["NORMAL"], data
# }}}