diff --git a/virtualsmartcard/src/vpicc/vicc.in b/virtualsmartcard/src/vpicc/vicc.in index 18f64a2..5c698f6 100644 --- a/virtualsmartcard/src/vpicc/vicc.in +++ b/virtualsmartcard/src/vpicc/vicc.in @@ -35,7 +35,7 @@ parser.add_option("-r", "--reader", action="store", type="int", help="Number of reader for relaying") parser.add_option("-t", "--type", action="store", type="choice", default='iso7816', - choices=['iso7816', 'cryptoflex', 'ePass', 'relay'], + choices=['iso7816', 'cryptoflex', 'ePass', 'nPA', 'relay'], help="Type of Smartcard [default: %default]") (options, args) = parser.parse_args() diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py b/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py index b632401..a6ca087 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py @@ -140,6 +140,14 @@ class CardGenerator(object): self.mf = 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): """Generate the Filesystem and SAM of a cryptoflex card""" self.mf = CryptoflexMF() @@ -156,6 +164,8 @@ class CardGenerator(object): self.__generate_ePass() elif self.type == 'cryptoflex': self.__generate_cryptoflex() + elif self.type == 'nPA': + self.__generate_nPA() else: return (None, None) @@ -218,7 +228,7 @@ if __name__ == "__main__": parser = OptionParser() parser.add_option("-t", "--type", action="store", type="choice", default='iso7816', - choices=['iso7816', 'cryptoflex', 'ePass'], + choices=['iso7816', 'cryptoflex', 'ePass', 'nPA'], help="Type of Smartcard [default: %default]") parser.add_option("-f", "--file", action="store", type="string", dest="filename", default=None, diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py index 296a874..1b8620d 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py @@ -330,6 +330,76 @@ class Iso7816OS(SmartcardOS): 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): 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 if card_type == "iso7816" or card_type == "ePass": self.os = Iso7816OS(MF, SAM) + elif card_type == "nPA": + self.os = nPAOS(MF, SAM) elif card_type == "cryptoflex": self.os = CryptoflexOS(MF, SAM) elif card_type == "relay":