minimal nPA emulation. use it to fetch and print a chat. uses pypace
git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@643 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -35,7 +35,7 @@ parser.add_option("-r", "--reader", action="store", type="int",
|
|||||||
help="Number of reader for relaying")
|
help="Number of reader for relaying")
|
||||||
parser.add_option("-t", "--type", action="store", type="choice",
|
parser.add_option("-t", "--type", action="store", type="choice",
|
||||||
default='iso7816',
|
default='iso7816',
|
||||||
choices=['iso7816', 'cryptoflex', 'ePass', 'relay'],
|
choices=['iso7816', 'cryptoflex', 'ePass', 'nPA', 'relay'],
|
||||||
help="Type of Smartcard [default: %default]")
|
help="Type of Smartcard [default: %default]")
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,14 @@ class CardGenerator(object):
|
|||||||
self.mf = mf
|
self.mf = mf
|
||||||
self.sam = PassportSAM(self.mf)
|
self.sam = PassportSAM(self.mf)
|
||||||
|
|
||||||
|
def __generate_nPA(self):
|
||||||
|
from virtualsmartcard.SmartcardSAM import SAM
|
||||||
|
|
||||||
|
card_access = "\x31\x81\xb3\x30\x0d\x06\x08\x04\x00\x7f\x00\x07\x02\x02\x02\x02\x01\x02\x30\x12\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x03\x02\x02\x02\x01\x02\x02\x01\x41\x30\x12\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x03\x02\x02\x02\x01\x02\x02\x01\x45\x30\x12\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x04\x02\x02\x02\x01\x02\x02\x01\x0d\x30\x1c\x06\x09\x04\x00\x7f\x00\x07\x02\x02\x03\x02\x30\x0c\x06\x07\x04\x00\x7f\x00\x07\x01\x02\x02\x01\x0d\x02\x01\x41\x30\x1c\x06\x09\x04\x00\x7f\x00\x07\x02\x02\x03\x02\x30\x0c\x06\x07\x04\x00\x7f\x00\x07\x01\x02\x02\x01\x0d\x02\x01\x45\x30\x2a\x06\x08\x04\x00\x7f\x00\x07\x02\x02\x06\x16\x1e\x68\x74\x74\x70\x3a\x2f\x2f\x62\x73\x69\x2e\x62\x75\x6e\x64\x2e\x64\x65\x2f\x63\x69\x66\x2f\x6e\x70\x61\x2e\x78\x6d\x6c"
|
||||||
|
|
||||||
|
self.mf = MF()
|
||||||
|
self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011c, shortfid=0x1c, data=card_access))
|
||||||
|
|
||||||
def __generate_cryptoflex(self):
|
def __generate_cryptoflex(self):
|
||||||
"""Generate the Filesystem and SAM of a cryptoflex card"""
|
"""Generate the Filesystem and SAM of a cryptoflex card"""
|
||||||
self.mf = CryptoflexMF()
|
self.mf = CryptoflexMF()
|
||||||
@@ -156,6 +164,8 @@ class CardGenerator(object):
|
|||||||
self.__generate_ePass()
|
self.__generate_ePass()
|
||||||
elif self.type == 'cryptoflex':
|
elif self.type == 'cryptoflex':
|
||||||
self.__generate_cryptoflex()
|
self.__generate_cryptoflex()
|
||||||
|
elif self.type == 'nPA':
|
||||||
|
self.__generate_nPA()
|
||||||
else:
|
else:
|
||||||
return (None, None)
|
return (None, None)
|
||||||
|
|
||||||
@@ -218,7 +228,7 @@ if __name__ == "__main__":
|
|||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
parser.add_option("-t", "--type", action="store", type="choice",
|
parser.add_option("-t", "--type", action="store", type="choice",
|
||||||
default='iso7816',
|
default='iso7816',
|
||||||
choices=['iso7816', 'cryptoflex', 'ePass'],
|
choices=['iso7816', 'cryptoflex', 'ePass', 'nPA'],
|
||||||
help="Type of Smartcard [default: %default]")
|
help="Type of Smartcard [default: %default]")
|
||||||
parser.add_option("-f", "--file", action="store", type="string",
|
parser.add_option("-f", "--file", action="store", type="string",
|
||||||
dest="filename", default=None,
|
dest="filename", default=None,
|
||||||
|
|||||||
@@ -330,6 +330,76 @@ class Iso7816OS(SmartcardOS):
|
|||||||
|
|
||||||
return answer
|
return answer
|
||||||
|
|
||||||
|
|
||||||
|
class nPAOS(Iso7816OS):
|
||||||
|
def __init__(self, mf, sam):
|
||||||
|
# ugly hack to parse MSE:SET AT
|
||||||
|
# This should better be integrated in the secuirty environment
|
||||||
|
ins2handler = {
|
||||||
|
0x0c: mf.eraseRecord,
|
||||||
|
0x0e: mf.eraseBinaryPlain,
|
||||||
|
0x0f: mf.eraseBinaryEncapsulated,
|
||||||
|
0x22: self.manage_security_environment,
|
||||||
|
0xa0: mf.searchBinaryPlain,
|
||||||
|
0xa1: mf.searchBinaryEncapsulated,
|
||||||
|
0xa4: mf.selectFile,
|
||||||
|
0xb0: mf.readBinaryPlain,
|
||||||
|
0xb1: mf.readBinaryEncapsulated,
|
||||||
|
0xb2: mf.readRecordPlain,
|
||||||
|
0xb3: mf.readRecordEncapsulated,
|
||||||
|
0xc0: self.getResponse,
|
||||||
|
0xca: mf.getDataPlain,
|
||||||
|
0xcb: mf.getDataEncapsulated,
|
||||||
|
0xd0: mf.writeBinaryPlain,
|
||||||
|
0xd1: mf.writeBinaryEncapsulated,
|
||||||
|
0xd2: mf.writeRecord,
|
||||||
|
0xd6: mf.updateBinaryPlain,
|
||||||
|
0xd7: mf.updateBinaryEncapsulated,
|
||||||
|
0xda: mf.putDataPlain,
|
||||||
|
0xdb: mf.putDataEncapsulated,
|
||||||
|
0xdc: mf.updateRecordPlain,
|
||||||
|
0xdd: mf.updateRecordEncapsulated,
|
||||||
|
0xe0: mf.createFile,
|
||||||
|
0xe2: mf.appendRecord,
|
||||||
|
0xe4: mf.deleteFile,
|
||||||
|
}
|
||||||
|
Iso7816OS.__init__(self, mf, sam, ins2handler, MAX_EXTENDED_LE)
|
||||||
|
# TODO
|
||||||
|
self.atr = '\x3B\x8A\x80\x01\x80\x31\xF8\x73\xF7\x41\xE0\x82\x90\x00\x75'
|
||||||
|
|
||||||
|
def manage_security_environment(self, p1, p2, data):
|
||||||
|
from TLVutils import bertlv_pack, bertlv_unpack
|
||||||
|
if (p1, p2) == (0xc1, 0xa4):
|
||||||
|
# PACE
|
||||||
|
tlv_data = bertlv_unpack(data)
|
||||||
|
for tag, length, value in tlv_data:
|
||||||
|
if tag == 0x80:
|
||||||
|
mechanism = value
|
||||||
|
#print "mechanism %r"% mechanism
|
||||||
|
elif tag == 0x83:
|
||||||
|
ref_public_key = value
|
||||||
|
#print "ref_public_key %r"% ref_public_key
|
||||||
|
elif tag == 0x84:
|
||||||
|
ref_private_key = value
|
||||||
|
#print "ref_private_key %r"% ref_private_key
|
||||||
|
elif tag == 0x67:
|
||||||
|
auxiliary_data = value
|
||||||
|
#print "auxiliary_data %r"% auxiliary_data
|
||||||
|
elif tag == 0x7f4c:
|
||||||
|
from chat import CHAT
|
||||||
|
chat = CHAT(bertlv_pack([[tag, length, value]]))
|
||||||
|
print(chat)
|
||||||
|
raise SwError(SW["ERR_INSNOTSUPPORTED"])
|
||||||
|
|
||||||
|
elif (p1, p2) == (0x41, 0xa4):
|
||||||
|
# CA/RI
|
||||||
|
raise SwError(SW["ERR_INSNOTSUPPORTED"])
|
||||||
|
elif (p1, p2) == (0x81, 0xa4):
|
||||||
|
# TA
|
||||||
|
raise SwError(SW["ERR_INSNOTSUPPORTED"])
|
||||||
|
else:
|
||||||
|
raise SwError(SW["ERR_INCORRECTP1P2"])
|
||||||
|
|
||||||
|
|
||||||
class CryptoflexOS(Iso7816OS):
|
class CryptoflexOS(Iso7816OS):
|
||||||
def __init__(self, mf, sam, ins2handler=None, maxle=MAX_SHORT_LE):
|
def __init__(self, mf, sam, ins2handler=None, maxle=MAX_SHORT_LE):
|
||||||
@@ -520,6 +590,8 @@ class VirtualICC(object):
|
|||||||
#Generate an OS object of the correct card_type
|
#Generate an OS object of the correct card_type
|
||||||
if card_type == "iso7816" or card_type == "ePass":
|
if card_type == "iso7816" or card_type == "ePass":
|
||||||
self.os = Iso7816OS(MF, SAM)
|
self.os = Iso7816OS(MF, SAM)
|
||||||
|
elif card_type == "nPA":
|
||||||
|
self.os = nPAOS(MF, SAM)
|
||||||
elif card_type == "cryptoflex":
|
elif card_type == "cryptoflex":
|
||||||
self.os = CryptoflexOS(MF, SAM)
|
self.os = CryptoflexOS(MF, SAM)
|
||||||
elif card_type == "relay":
|
elif card_type == "relay":
|
||||||
|
|||||||
Reference in New Issue
Block a user