diff --git a/virtualsmartcard/src/vpicc/Makefile.am b/virtualsmartcard/src/vpicc/Makefile.am index 34838bd..1432c5b 100644 --- a/virtualsmartcard/src/vpicc/Makefile.am +++ b/virtualsmartcard/src/vpicc/Makefile.am @@ -19,6 +19,7 @@ vpicc_PYTHON = virtualsmartcard/CardGenerator.py \ vpicccards_PYTHON = virtualsmartcard/cards/__init__.py \ virtualsmartcard/cards/ePass.py \ + virtualsmartcard/cards/nPA.py \ virtualsmartcard/cards/cryptoflex.py do_subst = sed -e 's,[@]PYTHON[@],$(PYTHON),g' diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py b/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py index a6ca087..eb3ebc4 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py @@ -27,6 +27,7 @@ from virtualsmartcard.CryptoUtils import protect_string, read_protected_string from virtualsmartcard.SmartcardSAM import SAM from virtualsmartcard.cards.cryptoflex import CryptoflexSAM, CryptoflexMF from virtualsmartcard.cards.ePass import PassportSAM +from virtualsmartcard.cards.nPA import nPA_SAM # pgp directory #self.mf.append(DF(parent=self.mf, @@ -147,6 +148,7 @@ class CardGenerator(object): self.mf = MF() self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011c, shortfid=0x1c, data=card_access)) + self.sam = nPA_SAM() def __generate_cryptoflex(self): """Generate the Filesystem and SAM of a cryptoflex card""" diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py index 1b8620d..14e784c 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py @@ -331,76 +331,6 @@ 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): Iso7816OS.__init__(self, mf, sam, ins2handler, maxle) @@ -591,7 +521,8 @@ class VirtualICC(object): if card_type == "iso7816" or card_type == "ePass": self.os = Iso7816OS(MF, SAM) elif card_type == "nPA": - self.os = nPAOS(MF, SAM) + self.os = Iso7816OS(MF, SAM) + self.os.atr = '\x3B\x8A\x80\x01\x80\x31\xF8\x73\xF7\x41\xE0\x82\x90\x00\x75' elif card_type == "cryptoflex": self.os = CryptoflexOS(MF, SAM) elif card_type == "relay": diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/cards/nPA.py b/virtualsmartcard/src/vpicc/virtualsmartcard/cards/nPA.py new file mode 100644 index 0000000..e832650 --- /dev/null +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/cards/nPA.py @@ -0,0 +1,54 @@ +# +# Copyright (C) 2011 Dominik Oepen +# +# This file is part of virtualsmartcard. +# +# virtualsmartcard is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# virtualsmartcard is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# virtualsmartcard. If not, see . + +from virtualsmartcard.SmartcardSAM import SAM +from virtualsmartcard.SEutils import ControlReferenceTemplate +from virtualsmartcard.SWutils import SwError, SW +from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE +from virtualsmartcard.TLVutils import unpack, bertlv_pack + +import hashlib, struct +from os import urandom + +class nPA__AT_CRT(ControlReferenceTemplate): + def __init__(self): + ControlReferenceTemplate(CRT_TEMPLATE["AT"]) + + def parse_SE_config(self, config) + try: + ControlReferenceTemplate.parse_SE_config(self, config) + except SwError, e: + structure = unpack(config) + for tlv in structure: + tag, length, value = structure + if tag == 0x7f4c: + chat = CHAT(bertlv_pack([tlv]) + print chat + elif tag == 0x67: + auxiliary_data = value + else: + raise SwError(SW["ERR_REFNOTUSABLE"]) + +class nPA_SAM(SAM): + """ + SAM for ICAO ePassport. Implements Basic access control and key derivation + for Secure Messaging. + """ + def __init__(self, mf): + SAM.__init__(self, None, None, mf) + self.current_SE.at = nPA_AT_CRT()