Example #1
0
 def __generate_cryptoflex(self):
     """Generate the Filesystem and SAM of a cryptoflex card"""
     from virtualsmartcard.cards.cryptoflex import CryptoflexMF
     from virtualsmartcard.cards.cryptoflex import CryptoflexSAM
     self.mf = CryptoflexMF()
     self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x0002,
                    filedescriptor=0x01,
                    data="\x00\x00\x00\x01\x00\x01\x00\x00"))  # EF.ICCSN
     self.sam = CryptoflexSAM(self.mf)
Example #2
0
 def __generate_cryptoflex(self):
     """Generate the Filesystem and SAM of a cryptoflex card"""
     from virtualsmartcard.cards.cryptoflex import CryptoflexMF, CryptoflexSAM
     self.mf = CryptoflexMF()
     self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x0002,
                    filedescriptor=0x01,
                    data="\x00\x00\x00\x01\x00\x01\x00\x00")) #EF.ICCSN
     self.sam = CryptoflexSAM(self.mf)
Example #3
0
    def __generate_iso_card(self):
        default_pin = "1234"
        default_cardno = "1234567890"

        logging.warning("Using default SAM parameters. PIN=%s, Card Nr=%s"
                        % (default_pin, default_cardno))
        # TODO: Use user provided data
        self.sam = SAM(default_pin, default_cardno)

        self.mf = MF(filedescriptor=FDB["DF"])
        self.sam.set_MF(self.mf)
Example #4
0
class CardGenerator(object):
    """This class is used to generate the SAM and filesystem for the
    different supported card types. It is also able used for persistent storage
    (in encrypted form) of the card on disks. """

    def __init__(self, card_type=None, sam=None, mf=None):
        self.type = card_type
        self.mf = mf
        self.sam = sam
        self.password = None
        self.datagroups = {}

    def __generate_iso_card(self):
        default_pin = "1234"
        default_cardno = "1234567890"

        logging.warning("Using default SAM parameters. PIN=%s, Card Nr=%s"
                        % (default_pin, default_cardno))
        # TODO: Use user provided data
        self.sam = SAM(default_pin, default_cardno)

        self.mf = MF(filedescriptor=FDB["DF"])
        self.sam.set_MF(self.mf)

    def __generate_ePass(self):
        """Generate the MF and SAM of an ICAO passport. This method is
        responsible for generating the filesystem and filling it with content.
        Therefore it must interact with the user by prompting for the MRZ and
        optionally for the path to a photo."""
        from PIL import Image
        from virtualsmartcard.cards.ePass import PassportSAM

        # TODO: Sanity checks
        MRZ = raw_input("Please enter the MRZ as one string: ")

        readline.set_completer_delims("")
        readline.parse_and_bind("tab: complete")

        picturepath = raw_input("Please enter the path to an image: ")
        picturepath = picturepath.strip()

        # MRZ1 = "P<UTOERIKSSON<<ANNA<MARIX<<<<<<<<<<<<<<<<<<<"
        # MRZ2 = "L898902C<3UTO6908061F9406236ZE184226B<<<<<14"
        # MRZ = MRZ1 + MRZ2

        try:
            im = Image.open(picturepath)
            pic_width, pic_height = im.size
            fd = open(picturepath, "rb")
            picture = fd.read()
            fd.close()
        except IOError:
            logging.warning("Failed to open file: " + picturepath)
            pic_width = 0
            pic_height = 0
            picture = None

        mf = MF()

        # We need a MF with Application DF \xa0\x00\x00\x02G\x10\x01
        df = DF(parent=mf, fid=4, dfname='\xa0\x00\x00\x02G\x10\x01',
                bertlv_data=[])

        # EF.COM
        COM = pack([(0x5F01, 4, "0107"), (0x5F36, 6, "040000"),
                    (0x5C, 2, "6175")])
        COM = pack(((0x60, len(COM), COM),))
        df.append(TransparentStructureEF(parent=df, fid=0x011E,
                  filedescriptor=0, data=COM))

        # EF.DG1
        DG1 = pack([(0x5F1F, len(MRZ), MRZ)])
        DG1 = pack([(0x61, len(DG1), DG1)])
        df.append(TransparentStructureEF(parent=df, fid=0x0101,
                  filedescriptor=0, data=DG1))

        # EF.DG2
        if picture is not None:
            IIB = "\x00\x01" + inttostring(pic_width, 2) +\
                    inttostring(pic_height, 2) + 6 * "\x00"
            length = 32 + len(picture)  # 32 is the length of IIB + FIB
            FIB = inttostring(length, 4) + 16 * "\x00"
            FRH = "FAC" + "\x00" + "010" + "\x00" +\
                  inttostring(14 + length, 4) + inttostring(1, 2)
            picture = FRH + FIB + IIB + picture
            DG2 = pack([(0xA1, 8, "\x87\x02\x01\x01\x88\x02\x05\x01"),
                       (0x5F2E, len(picture), picture)])
            DG2 = pack([(0x02, 1, "\x01"), (0x7F60, len(DG2), DG2)])
            DG2 = pack([(0x7F61, len(DG2), DG2)])
        else:
            DG2 = ""
        df.append(TransparentStructureEF(parent=df, fid=0x0102,
                  filedescriptor=0, data=DG2))

        # EF.SOD
        df.append(TransparentStructureEF(parent=df, fid=0x010D,
                  filedescriptor=0, data=""))

        mf.append(df)

        self.mf = mf
        self.sam = PassportSAM(self.mf)

    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        mappings = [
            ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1, 5), range(1, 5),
             "PACE"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1, 3), range(1, 6),
             "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1], [6], "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1, 3), range(1, 5),
             "CA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1, 3), range(1, 6),
             "RI"),
        ]
        for oid_base, x_list, y_list, algo in mappings:
            for oid in [oid_base + chr(x) + chr(y) for x in x_list for y in
                        y_list]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(TransparentStructureEF(parent=self.mf, fid=0x011c,
                       shortfid=0x1c, data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01"\
                        "\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03"\
                        "\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04"\
                        "\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F"\
                        "\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36"\
                        "\x31\x82\x01\x32\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\x04\x02"\
                        "\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00"\
                        "\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01"\
                        "\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F"\
                        "\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02"\
                        "\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00"\
                        "\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00"\
                        "\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02"\
                        "\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07"\
                        "\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1"\
                        "\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F"\
                        "\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88"\
                        "\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32"\
                        "\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F"\
                        "\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82"\
                        "\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02"\
                        "\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48"\
                        "\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09"\
                        "\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B"\
                        "\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C"\
                        "\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31"\
                        "\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33"\
                        "\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73"\
                        "\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17"\
                        "\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32"\
                        "\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39"\
                        "\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04"\
                        "\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04"\
                        "\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63"\
                        "\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30"\
                        "\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B"\
                        "\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82"\
                        "\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02"\
                        "\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86"\
                        "\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26"\
                        "\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F"\
                        "\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04"\
                        "\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6"\
                        "\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA"\
                        "\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38"\
                        "\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66"\
                        "\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29"\
                        "\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C"\
                        "\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58"\
                        "\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD"\
                        "\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02"\
                        "\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A"\
                        "\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE"\
                        "\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04"\
                        "\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58"\
                        "\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47"\
                        "\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54"\
                        "\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08"\
                        "\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06"\
                        "\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80"\
                        "\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14"\
                        "\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77"\
                        "\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D"\
                        "\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00"\
                        "\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06"\
                        "\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A"\
                        "\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E"\
                        "\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09"\
                        "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C"\
                        "\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E"\
                        "\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31"\
                        "\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22"\
                        "\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30"\
                        "\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30"\
                        "\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A"\
                        "\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30"\
                        "\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27"\
                        "\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4"\
                        "\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87"\
                        "\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB"\
                        "\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF"\
                        "\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05"\
                        "\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03"\
                        "\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03"\
                        "\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A"\
                        "\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30"\
                        "\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15"\
                        "\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61"\
                        "\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30"\
                        "\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05"\
                        "\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D"\
                        "\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03"\
                        "\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01"\
                        "\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F"\
                        "\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7"\
                        "\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30"\
                        "\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00"\
                        "\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31"\
                        "\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C"\
                        "\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC"\
                        "\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7"\
                        "\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05"\
                        "\x27"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011d,
                       shortfid=0x1d, data=card_security))
        ef_dir = "\x61\x32\x4F\x0F\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67"\
                 "\x45\x53\x49\x47\x4E\x50\x0F\x43\x49\x41\x20\x7A\x75\x20"\
                 "\x44\x46\x2E\x65\x53\x69\x67\x6E\x51\x00\x73\x0C\x4F\x0A"\
                 "\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x61\x09\x4F\x07"\
                 "\xA0\x00\x00\x02\x47\x10\x01\x61\x0B\x4F\x09\xE8\x07\x04"\
                 "\x00\x7F\x00\x07\x03\x02\x61\x0C\x4F\x0A\xA0\x00\x00\x01"\
                 "\x67\x45\x53\x49\x47\x4E"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x2f00,
                       shortfid=30, data=ef_dir))

        eid = DF(parent=self.mf, fid=0xffff,
                 dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid.extra_fci_data = "\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06"\
                             "\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20"\
                             "\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f"\
                             "\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01"\
                             "\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01"\
                             "\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07"\
                             "\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00"\
                             "\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95"\
                             "\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00"\
                             "\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00"\
                             "\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03"
        # FIXME access control for eid application

        DocumentType = self.datagroups["DocumentType"] if "DocumentType" in \
            self.datagroups else 'ID'
        IssuingState = self.datagroups["IssuingState"] if "IssuingState" in \
            self.datagroups else 'D'
        DateOfExpiry = self.datagroups["DateOfExpiry"] if "DateOfExpiry" in \
            self.datagroups else '20201031'
        GivenNames = self.datagroups["GivenNames"] if "GivenNames" in \
            self.datagroups else 'ERIKA'
        FamilyNames = self.datagroups["FamilyNames"] if "FamilyNames" in \
            self.datagroups else 'MUSTERMANN'
        ReligiousArtisticName = self.datagroups["ReligiousArtisticName"] if \
            "ReligiousArtisticName" in self.datagroups else ''
        AcademicTitle = self.datagroups["AcademicTitle"] if \
            "AcademicTitle" in self.datagroups else ''
        DateOfBirth = self.datagroups["DateOfBirth"] if "DateOfBirth" in \
            self.datagroups else '19640812'
        PlaceOfBirth = self.datagroups["PlaceOfBirth"] if "PlaceOfBirth" in \
            self.datagroups else 'BERLIN'
        Nationality = self.datagroups["Nationality"] if "Nationality" in \
            self.datagroups else 'DE'
        Sex = self.datagroups["Sex"] if "Sex" in self.datagroups else 'F'
        BirthName = self.datagroups["BirthName"] if "BirthName" in \
            self.datagroups else 'Mein Geburtsname'
        # PlaceOfResidence variable is only a helper to get a switch for
        # <NotOnChip>
        PlaceOfResidence = self.datagroups["PlaceOfResidence"] if \
            "PlaceOfResidence" in self.datagroups else ''
        Country = self.datagroups["Country"] if "Country" in self.datagroups \
            else 'D'
        City = self.datagroups["City"] if "City" in self.datagroups else \
            'KOLN'
        ZIP = self.datagroups["ZIP"] if "ZIP" in self.datagroups else '51147'
        Street = self.datagroups["Street"] if "Street" in \
            self.datagroups else 'HEIDESTRASSE 17'
        CommunityID = self.datagroups["CommunityID"] if "CommunityID" in \
            self.datagroups else '02760378900276'
        if (CommunityID.rstrip() != "<NotOnChip>"):
            # the plain CommunityID integer value has to be translated into
            # its binary representation. '0276...' will be '\x02\x76\...'
            CommunityID_Binary = binascii.unhexlify(CommunityID)
        # ResidencePermit1 and ResidencePermit2 are part of eAT only
        ResidencePermit1 = self.datagroups["ResidencePermit1"] if \
            "ResidencePermit1" in self.datagroups else \
            'ResidencePermit1 field up to 750 characters'
        ResidencePermit2 = self.datagroups["ResidencePermit2"] if \
            "ResidencePermit2" in self.datagroups else \
            'ResidencePermit1 field up to 250 characters'

        # Currently, those data groups are for further usage:
        dg12_param = self.datagroups["dg12"] if "dg12" in \
            self.datagroups else ''
        dg14_param = self.datagroups["dg14"] if "dg14" in \
            self.datagroups else ''
        dg15_param = self.datagroups["dg15"] if "dg15" in \
            self.datagroups else ''
        dg16_param = self.datagroups["dg16"] if "dg16" in \
            self.datagroups else ''
        dg21_param = self.datagroups["dg21"] if "dg21" in \
            self.datagroups else ''

        # "Attribute not on Chip" makes sence only for ReligiousArtisticName,
        # Nationality, BirthName, ResidencePermit1 and ResidencePermit2, refer
        # to BSI TR-03127
        if (DocumentType.rstrip() != "<NotOnChip>"):
            dg1 = pack([(0x61, 0, [(0x13, 0, DocumentType)])], True)
        else:
            dg1 = None
        if (IssuingState.rstrip() != "<NotOnChip>"):
            dg2 = pack([(0x62, 0, [(0x13, 0, IssuingState)])], True)
        else:
            dg2 = None
        if (DateOfExpiry.rstrip() != "<NotOnChip>"):
            dg3 = pack([(0x63, 0, [(0x12, 0, DateOfExpiry)])], True)
        else:
            dg3 = None
        if (GivenNames.rstrip() != "<NotOnChip>"):
            dg4 = pack([(0x64, 0, [(0x0C, 0, GivenNames)])], True)
        else:
            dg4 = None
        if (FamilyNames.rstrip() != "<NotOnChip>"):
            dg5 = pack([(0x65, 0, [(0x0C, 0, FamilyNames)])], True)
        else:
            dg5 = None
        if (ReligiousArtisticName.rstrip() != "<NotOnChip>"):
            dg6 = pack([(0x66, 0, [(0x0C, 0, ReligiousArtisticName)])], True)
        else:
            dg6 = None
        if (AcademicTitle.rstrip() != "<NotOnChip>"):
            dg7 = pack([(0x67, 0, [(0x0C, 0, AcademicTitle)])], True)
        else:
            dg7 = None
        if (DateOfBirth.rstrip() != "<NotOnChip>"):
            dg8 = pack([(0x68, 0, [(0x12, 0, DateOfBirth)])], True)
        else:
            dg8 = None
        if (PlaceOfBirth.rstrip() != "<NotOnChip>"):
            dg9 = pack([(0x69, 0, [(0xA1, 0, [(0x0C, 0, PlaceOfBirth)])])],
                       True)
        else:
            dg9 = None
        if (Nationality.rstrip() != "<NotOnChip>"):
            dg10 = pack([(0x6A, 0, [(0x13, 0, Nationality)])], True)
        else:
            dg10 = None
        if (Sex.rstrip() != "<NotOnChip>"):
            dg11 = pack([(0x6B, 0, [(0x13, 0, Sex)])], True)
        else:
            dg11 = None
        if (dg12_param.rstrip() != "<NotOnChip>"):
            dg12 = dg12_param
        else:
            dg12 = None
        if (BirthName.rstrip() != "<NotOnChip>"):
            dg13 = pack([(0x6D, 0, [(0x0C, 0, BirthName)])], True)
        else:
            dg13 = None
        if (dg14_param.rstrip() != "<NotOnChip>"):
            dg14 = dg14_param
        else:
            dg14 = None
        if (dg15_param.rstrip() != "<NotOnChip>"):
            dg15 = dg15_param
        else:
            dg15 = None
        if (dg16_param.rstrip() != "<NotOnChip>"):
            dg16 = dg16_param
        else:
            dg16 = None
        if (PlaceOfResidence.rstrip() != "<NotOnChip>"):
            dg17 = pack([(0x71, 0, [(0x30, 0, [
                    (0xAA, 0, [(0x0C, 0, Street)]),
                    (0xAB, 0, [(0x0C, 0, City)]),
                    (0xAD, 0, [(0x13, 0, Country)]),
                    (0xAE, 0, [(0x13, 0, ZIP)])
                    ])])], True)
        else:
            dg17 = None
        if (CommunityID.rstrip() != "<NotOnChip>"):
            dg18 = pack([(0x72, 0, [(0x04, 0, CommunityID_Binary)])], True)
        else:
            dg18 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
            dg19 = pack([(0x73, 0, [(0xA1, 0,
                                    [(0x0C, 0, ResidencePermit1)])])], True)
        else:
            dg19 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
            dg20 = pack([(0x74, 0, [(0xA1, 0,
                                    [(0x0C, 0, ResidencePermit2)])])], True)
        else:
            dg20 = None
        if (dg21_param.rstrip() != "<NotOnChip>"):
            dg21 = dg21_param
        else:
            dg21 = None

        # If eid.append is not done for a DG, it results into required
        # SwError() with FileNotFound "6A82" APDU return code
        if dg1:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0101,
                       shortfid=0x01, data=dg1))
        if dg2:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0102,
                       shortfid=0x02, data=dg2))
        if dg3:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0103,
                       shortfid=0x03, data=dg3))
        if dg4:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0104,
                       shortfid=0x04, data=dg4))
        if dg5:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0105,
                       shortfid=0x05, data=dg5))
        if dg6:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0106,
                       shortfid=0x06, data=dg6))
        if dg7:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0107,
                       shortfid=0x07, data=dg7))
        if dg8:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0108,
                       shortfid=0x08, data=dg8))
        if dg9:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0109,
                       shortfid=0x09, data=dg9))
        if dg10:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010a,
                       shortfid=0x0a, data=dg10))
        if dg11:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010b,
                       shortfid=0x0b, data=dg11))
        if dg12:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010c,
                       shortfid=0x0c, data=dg12))
        if dg13:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010d,
                       shortfid=0x0d, data=dg13))
        if dg14:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010e,
                       shortfid=0x0e, data=dg14))
        if dg15:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010f,
                       shortfid=0x0f, data=dg15))
        if dg16:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0110,
                       shortfid=0x10, data=dg16))
        if dg17:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0111,
                       shortfid=0x11, data=dg17))
        if dg18:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0112,
                       shortfid=0x12, data=dg18))
        if dg19:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0113,
                       shortfid=0x13, data=dg19))
        if dg20:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0114,
                       shortfid=0x14, data=dg20))
        if dg21:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0115,
                       shortfid=0x15, data=dg21))
        self.mf.append(eid)

        # DF.CIA
        cia = DF(parent=self.mf, fid=0xfffe,
                 dfname='\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49'
                        '\x47\x4E')
        # EF.OD / EF.ODF
        cia.append(TransparentStructureEF(parent=cia, fid=0x5031,
                                          shortfid=0x11,
                                          data='\xa0\x060\x04\x04\x02D\x00\xa4'
                                          '\x060\x04\x04\x02D\x04\xa8\x060\x04'
                                          '\x04\x02D\x08'))
        # EF.CIAInfo / EF.TokenInfo
        cia.append(TransparentStructureEF(parent=cia, fid=0x5032,
                                          shortfid=0x12,
                                          data='06\x02\x01\x01\x80\x11eSign '
                                          'Application\x03\x02\x06\xc0\xa2'
                                          '\x1a0\x18\x02\x01\x01\x02\x02\x10A'
                                          '\x05\x00\x03\x02\x06@\x06\t\x04\x00'
                                          '\x7f\x00\x07\x01\x01\x04\x01'))
        # EF.PrKD / EF.PrKDF
        cia.append(TransparentStructureEF(parent=cia, fid=0x4400,
                                          data='\xa080\x17\x0c\x0bPrK.ICC.QES'
                                          '\x03\x02\x07\x80\x04\x01\x01\x02'
                                          '\x01\x010\x15\x04\x01F\x03\x03\x06'
                                          '\x00@\x03\x02\x03\xb8\x02\x02\x00'
                                          '\x84\xa1\x03\x02\x01\x01\xa1\x060'
                                          '\x040\x02\x04\x00'))
        # EF.PuKD / EF.PuKDF
        cia.append(TransparentStructureEF(parent=cia, fid=0x4404,
                                          data='050!\x0c\x1fZertifikat des ZDA'
                                          ' f\xc3\xbcr die QES0\x06\x04\x01E'
                                          '\x01\x01\xff\xa1\x080\x060\x04\x04'
                                          '\x02\xc0\x000:0&\x0c$Zertifikat des'
                                          ' Inhabers f\xc3\xbcr die QES0\x06'
                                          '\x04\x01F\x01\x01\x00\xa1\x080\x060'
                                          '\x04\x04\x02\xc0\x01'))
        # EF.AOD / EF.AODF
        cia.append(TransparentStructureEF(parent=cia, fid=0x4408,
                                          data='0/0\x0f\x0c\teSign-PIN\x03\x02'
                                          '\x06@0\x03\x04\x01\x01\xa1\x170\x15'
                                          '\x03\x03\x02H\x1c\n\x01\x01\x02\x01'
                                          '\x06\x02\x01\x00\x80\x01\x810\x02'
                                          '\x04\x00'))
        self.mf.append(cia)

        # DF.eSign
        esign = DF(parent=self.mf, fid=0xfffd,
                   dfname='\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E')

        # ZDA certificate
        esign.append(TransparentStructureEF(parent=esign, fid=0xC000, data=''))
        # User's certificate
        esign.append(TransparentStructureEF(parent=esign, fid=0xC001, data=''))
        self.mf.append(esign)

        self.sam = nPA_SAM(eid_pin="111111", can="222222",
                           mrz="IDD<<T220001293<<<<<<<<<<<<<<<6408125<2010315D"
                           "<<<<<<<<<<<<<<MUSTERMANN<<ERIKA<<<<<<<<<<<<<",
                           puk="3333333333", qes_pin="444444", mf=self.mf)
        # FIXME: add CVCA for inspection systems and signature terminals. Here
        #        we only add the eID CVCA.
        self.sam.current_SE.cvca = "\x7f\x21\x82\x01\xb6\x7f\x4e\x82\x01\x6e"\
                                   "\x5f\x29\x01\x00\x42\x0e\x44\x45\x43\x56"\
                                   "\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32"\
                                   "\x7f\x49\x82\x01\x1d\x06\x0a\x04\x00\x7f"\
                                   "\x00\x07\x02\x02\x02\x02\x03\x81\x20\xa9"\
                                   "\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a"\
                                   "\x90\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5"\
                                   "\x26\x20\x28\x20\x13\x48\x1d\x1f\x6e\x53"\
                                   "\x77\x82\x20\x7d\x5a\x09\x75\xfc\x2c\x30"\
                                   "\x57\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb"\
                                   "\x80\x55\xc1\x26\xdc\x5c\x6c\xe9\x4a\x4b"\
                                   "\x44\xf3\x30\xb5\xd9\x83\x20\x26\xdc\x5c"\
                                   "\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\xbb"\
                                   "\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7\xe1"\
                                   "\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x84"\
                                   "\x41\x04\x8b\xd2\xae\xb9\xcb\x7e\x57\xcb"\
                                   "\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde"\
                                   "\x27\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd"\
                                   "\x9a\xce\x32\x62\x54\x7e\xf8\x35\xc3\xda"\
                                   "\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9"\
                                   "\xc2\x77\x45\x13\x2d\xed\x8e\x54\x5c\x1d"\
                                   "\x54\xc7\x2f\x04\x69\x97\x85\x20\xa9\xfb"\
                                   "\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90"\
                                   "\x9d\x83\x8d\x71\x8c\x39\x7a\xa3\xb5\x61"\
                                   "\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7"\
                                   "\x86\x41\x04\x33\x47\xec\xf9\x6f\xfb\x4b"\
                                   "\xd9\xb8\x55\x4e\xfb\xcc\xfc\x7d\x0b\x24"\
                                   "\x2f\x10\x71\xe2\x9b\x4c\x9c\x62\x2c\x79"\
                                   "\xe3\x39\xd8\x40\xaf\x67\xbe\xb9\xb9\x12"\
                                   "\x69\x22\x65\xd9\xc1\x6c\x62\x57\x3f\x45"\
                                   "\x79\xff\xd4\xde\x2d\xe9\x2b\xab\x40\x9d"\
                                   "\xd5\xc5\xd4\x82\x44\xa9\xf7\x87\x01\x01"\
                                   "\x5f\x20\x0e\x44\x45\x43\x56\x43\x41\x65"\
                                   "\x49\x44\x30\x30\x31\x30\x32\x7f\x4c\x12"\
                                   "\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02"\
                                   "\x02\x53\x05\xfe\x0f\x01\xff\xff\x5f\x25"\
                                   "\x06\x01\x00\x01\x00\x01\x08\x5f\x24\x06"\
                                   "\x01\x03\x01\x00\x01\x08\x5f\x37\x40\x50"\
                                   "\x67\x14\x5c\x68\xca\xe9\x52\x0f\x5b\xb3"\
                                   "\x48\x17\xf1\xca\x9c\x43\x59\x3d\xb5\x64"\
                                   "\x06\xc6\xa3\xb0\x06\xcb\xf3\xf3\x14\xe7"\
                                   "\x34\x9a\xcf\x0c\xc6\xbf\xeb\xcb\xde\xfd"\
                                   "\x10\xb4\xdc\xf0\xf2\x31\xda\x56\x97\x7d"\
                                   "\x88\xf9\xf9\x01\x82\xd1\x99\x07\x6a\x56"\
                                   "\x50\x64\x51"

    def __generate_cryptoflex(self):
        """Generate the Filesystem and SAM of a cryptoflex card"""
        from virtualsmartcard.cards.cryptoflex import CryptoflexMF
        from virtualsmartcard.cards.cryptoflex import CryptoflexSAM
        self.mf = CryptoflexMF()
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x0002,
                       filedescriptor=0x01,
                       data="\x00\x00\x00\x01\x00\x01\x00\x00"))  # EF.ICCSN
        self.sam = CryptoflexSAM(self.mf)

    def generateCard(self):
        """Generate a new card"""
        if self.type == 'iso7816':
            self.__generate_iso_card()
        elif self.type == 'ePass':
            self.__generate_ePass()
        elif self.type == 'cryptoflex':
            self.__generate_cryptoflex()
        elif self.type == 'nPA':
            self.__generate_nPA()
        else:
            return (None, None)

    def getCard(self):
        """Get the MF and SAM from the current card"""
        if self.sam is None or self.mf is None:
            self.generateCard()
        return self.mf, self.sam

    def setCard(self, mf=None, sam=None):
        """Set the MF and SAM of the current card"""
        if mf is not None:
            self.mf = mf
        if sam is not None:
            self.sam = sam

    def readDatagroups(self, datasetfile):
        """Read Datagroups from file"""
        with open(datasetfile, 'r') as f:
            for line in f:
                if (not line.startswith("#")) and (not len(line.strip()) == 0):
                    # spaces after equal sign are allowed to get strings with
                    # leading spaces
                    line = line.replace(" =", "=")
                    splitLine = line.split("=")
                    # we don't want to have the newline char from dataset file
                    # as part of the value
                    self.datagroups[splitLine[0]] = splitLine[1].rstrip("\n\r")
                    logging.info("Dataset value for " + splitLine[0].rstrip() +
                                 ": '" + splitLine[1].rstrip("\n\r") + "'")
Example #5
0
    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        mappings = [
            ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1, 5), range(1, 5),
             "PACE"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1, 3), range(1, 6),
             "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1], [6], "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1, 3), range(1, 5),
             "CA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1, 3), range(1, 6),
             "RI"),
        ]
        for oid_base, x_list, y_list, algo in mappings:
            for oid in [oid_base + chr(x) + chr(y) for x in x_list for y in
                        y_list]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(TransparentStructureEF(parent=self.mf, fid=0x011c,
                       shortfid=0x1c, data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01"\
                        "\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03"\
                        "\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04"\
                        "\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F"\
                        "\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36"\
                        "\x31\x82\x01\x32\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\x04\x02"\
                        "\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00"\
                        "\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01"\
                        "\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F"\
                        "\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02"\
                        "\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00"\
                        "\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00"\
                        "\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02"\
                        "\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07"\
                        "\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1"\
                        "\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F"\
                        "\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88"\
                        "\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32"\
                        "\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F"\
                        "\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82"\
                        "\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02"\
                        "\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48"\
                        "\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09"\
                        "\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B"\
                        "\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C"\
                        "\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31"\
                        "\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33"\
                        "\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73"\
                        "\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17"\
                        "\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32"\
                        "\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39"\
                        "\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04"\
                        "\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04"\
                        "\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63"\
                        "\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30"\
                        "\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B"\
                        "\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82"\
                        "\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02"\
                        "\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86"\
                        "\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26"\
                        "\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F"\
                        "\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04"\
                        "\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6"\
                        "\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA"\
                        "\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38"\
                        "\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66"\
                        "\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29"\
                        "\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C"\
                        "\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58"\
                        "\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD"\
                        "\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02"\
                        "\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A"\
                        "\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE"\
                        "\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04"\
                        "\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58"\
                        "\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47"\
                        "\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54"\
                        "\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08"\
                        "\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06"\
                        "\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80"\
                        "\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14"\
                        "\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77"\
                        "\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D"\
                        "\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00"\
                        "\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06"\
                        "\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A"\
                        "\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E"\
                        "\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09"\
                        "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C"\
                        "\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E"\
                        "\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31"\
                        "\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22"\
                        "\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30"\
                        "\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30"\
                        "\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A"\
                        "\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30"\
                        "\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27"\
                        "\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4"\
                        "\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87"\
                        "\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB"\
                        "\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF"\
                        "\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05"\
                        "\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03"\
                        "\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03"\
                        "\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A"\
                        "\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30"\
                        "\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15"\
                        "\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61"\
                        "\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30"\
                        "\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05"\
                        "\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D"\
                        "\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03"\
                        "\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01"\
                        "\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F"\
                        "\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7"\
                        "\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30"\
                        "\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00"\
                        "\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31"\
                        "\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C"\
                        "\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC"\
                        "\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7"\
                        "\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05"\
                        "\x27"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011d,
                       shortfid=0x1d, data=card_security))
        ef_dir = "\x61\x32\x4F\x0F\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67"\
                 "\x45\x53\x49\x47\x4E\x50\x0F\x43\x49\x41\x20\x7A\x75\x20"\
                 "\x44\x46\x2E\x65\x53\x69\x67\x6E\x51\x00\x73\x0C\x4F\x0A"\
                 "\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x61\x09\x4F\x07"\
                 "\xA0\x00\x00\x02\x47\x10\x01\x61\x0B\x4F\x09\xE8\x07\x04"\
                 "\x00\x7F\x00\x07\x03\x02\x61\x0C\x4F\x0A\xA0\x00\x00\x01"\
                 "\x67\x45\x53\x49\x47\x4E"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x2f00,
                       shortfid=30, data=ef_dir))

        eid = DF(parent=self.mf, fid=0xffff,
                 dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid.extra_fci_data = "\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06"\
                             "\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20"\
                             "\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f"\
                             "\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01"\
                             "\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01"\
                             "\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07"\
                             "\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00"\
                             "\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95"\
                             "\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00"\
                             "\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00"\
                             "\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03"
        # FIXME access control for eid application

        DocumentType = self.datagroups["DocumentType"] if "DocumentType" in \
            self.datagroups else 'ID'
        IssuingState = self.datagroups["IssuingState"] if "IssuingState" in \
            self.datagroups else 'D'
        DateOfExpiry = self.datagroups["DateOfExpiry"] if "DateOfExpiry" in \
            self.datagroups else '20201031'
        GivenNames = self.datagroups["GivenNames"] if "GivenNames" in \
            self.datagroups else 'ERIKA'
        FamilyNames = self.datagroups["FamilyNames"] if "FamilyNames" in \
            self.datagroups else 'MUSTERMANN'
        ReligiousArtisticName = self.datagroups["ReligiousArtisticName"] if \
            "ReligiousArtisticName" in self.datagroups else ''
        AcademicTitle = self.datagroups["AcademicTitle"] if \
            "AcademicTitle" in self.datagroups else ''
        DateOfBirth = self.datagroups["DateOfBirth"] if "DateOfBirth" in \
            self.datagroups else '19640812'
        PlaceOfBirth = self.datagroups["PlaceOfBirth"] if "PlaceOfBirth" in \
            self.datagroups else 'BERLIN'
        Nationality = self.datagroups["Nationality"] if "Nationality" in \
            self.datagroups else 'DE'
        Sex = self.datagroups["Sex"] if "Sex" in self.datagroups else 'F'
        BirthName = self.datagroups["BirthName"] if "BirthName" in \
            self.datagroups else 'Mein Geburtsname'
        # PlaceOfResidence variable is only a helper to get a switch for
        # <NotOnChip>
        PlaceOfResidence = self.datagroups["PlaceOfResidence"] if \
            "PlaceOfResidence" in self.datagroups else ''
        Country = self.datagroups["Country"] if "Country" in self.datagroups \
            else 'D'
        City = self.datagroups["City"] if "City" in self.datagroups else \
            'KOLN'
        ZIP = self.datagroups["ZIP"] if "ZIP" in self.datagroups else '51147'
        Street = self.datagroups["Street"] if "Street" in \
            self.datagroups else 'HEIDESTRASSE 17'
        CommunityID = self.datagroups["CommunityID"] if "CommunityID" in \
            self.datagroups else '02760378900276'
        if (CommunityID.rstrip() != "<NotOnChip>"):
            # the plain CommunityID integer value has to be translated into
            # its binary representation. '0276...' will be '\x02\x76\...'
            CommunityID_Binary = binascii.unhexlify(CommunityID)
        # ResidencePermit1 and ResidencePermit2 are part of eAT only
        ResidencePermit1 = self.datagroups["ResidencePermit1"] if \
            "ResidencePermit1" in self.datagroups else \
            'ResidencePermit1 field up to 750 characters'
        ResidencePermit2 = self.datagroups["ResidencePermit2"] if \
            "ResidencePermit2" in self.datagroups else \
            'ResidencePermit1 field up to 250 characters'

        # Currently, those data groups are for further usage:
        dg12_param = self.datagroups["dg12"] if "dg12" in \
            self.datagroups else ''
        dg14_param = self.datagroups["dg14"] if "dg14" in \
            self.datagroups else ''
        dg15_param = self.datagroups["dg15"] if "dg15" in \
            self.datagroups else ''
        dg16_param = self.datagroups["dg16"] if "dg16" in \
            self.datagroups else ''
        dg21_param = self.datagroups["dg21"] if "dg21" in \
            self.datagroups else ''

        # "Attribute not on Chip" makes sence only for ReligiousArtisticName,
        # Nationality, BirthName, ResidencePermit1 and ResidencePermit2, refer
        # to BSI TR-03127
        if (DocumentType.rstrip() != "<NotOnChip>"):
            dg1 = pack([(0x61, 0, [(0x13, 0, DocumentType)])], True)
        else:
            dg1 = None
        if (IssuingState.rstrip() != "<NotOnChip>"):
            dg2 = pack([(0x62, 0, [(0x13, 0, IssuingState)])], True)
        else:
            dg2 = None
        if (DateOfExpiry.rstrip() != "<NotOnChip>"):
            dg3 = pack([(0x63, 0, [(0x12, 0, DateOfExpiry)])], True)
        else:
            dg3 = None
        if (GivenNames.rstrip() != "<NotOnChip>"):
            dg4 = pack([(0x64, 0, [(0x0C, 0, GivenNames)])], True)
        else:
            dg4 = None
        if (FamilyNames.rstrip() != "<NotOnChip>"):
            dg5 = pack([(0x65, 0, [(0x0C, 0, FamilyNames)])], True)
        else:
            dg5 = None
        if (ReligiousArtisticName.rstrip() != "<NotOnChip>"):
            dg6 = pack([(0x66, 0, [(0x0C, 0, ReligiousArtisticName)])], True)
        else:
            dg6 = None
        if (AcademicTitle.rstrip() != "<NotOnChip>"):
            dg7 = pack([(0x67, 0, [(0x0C, 0, AcademicTitle)])], True)
        else:
            dg7 = None
        if (DateOfBirth.rstrip() != "<NotOnChip>"):
            dg8 = pack([(0x68, 0, [(0x12, 0, DateOfBirth)])], True)
        else:
            dg8 = None
        if (PlaceOfBirth.rstrip() != "<NotOnChip>"):
            dg9 = pack([(0x69, 0, [(0xA1, 0, [(0x0C, 0, PlaceOfBirth)])])],
                       True)
        else:
            dg9 = None
        if (Nationality.rstrip() != "<NotOnChip>"):
            dg10 = pack([(0x6A, 0, [(0x13, 0, Nationality)])], True)
        else:
            dg10 = None
        if (Sex.rstrip() != "<NotOnChip>"):
            dg11 = pack([(0x6B, 0, [(0x13, 0, Sex)])], True)
        else:
            dg11 = None
        if (dg12_param.rstrip() != "<NotOnChip>"):
            dg12 = dg12_param
        else:
            dg12 = None
        if (BirthName.rstrip() != "<NotOnChip>"):
            dg13 = pack([(0x6D, 0, [(0x0C, 0, BirthName)])], True)
        else:
            dg13 = None
        if (dg14_param.rstrip() != "<NotOnChip>"):
            dg14 = dg14_param
        else:
            dg14 = None
        if (dg15_param.rstrip() != "<NotOnChip>"):
            dg15 = dg15_param
        else:
            dg15 = None
        if (dg16_param.rstrip() != "<NotOnChip>"):
            dg16 = dg16_param
        else:
            dg16 = None
        if (PlaceOfResidence.rstrip() != "<NotOnChip>"):
            dg17 = pack([(0x71, 0, [(0x30, 0, [
                    (0xAA, 0, [(0x0C, 0, Street)]),
                    (0xAB, 0, [(0x0C, 0, City)]),
                    (0xAD, 0, [(0x13, 0, Country)]),
                    (0xAE, 0, [(0x13, 0, ZIP)])
                    ])])], True)
        else:
            dg17 = None
        if (CommunityID.rstrip() != "<NotOnChip>"):
            dg18 = pack([(0x72, 0, [(0x04, 0, CommunityID_Binary)])], True)
        else:
            dg18 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
            dg19 = pack([(0x73, 0, [(0xA1, 0,
                                    [(0x0C, 0, ResidencePermit1)])])], True)
        else:
            dg19 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
            dg20 = pack([(0x74, 0, [(0xA1, 0,
                                    [(0x0C, 0, ResidencePermit2)])])], True)
        else:
            dg20 = None
        if (dg21_param.rstrip() != "<NotOnChip>"):
            dg21 = dg21_param
        else:
            dg21 = None

        # If eid.append is not done for a DG, it results into required
        # SwError() with FileNotFound "6A82" APDU return code
        if dg1:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0101,
                       shortfid=0x01, data=dg1))
        if dg2:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0102,
                       shortfid=0x02, data=dg2))
        if dg3:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0103,
                       shortfid=0x03, data=dg3))
        if dg4:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0104,
                       shortfid=0x04, data=dg4))
        if dg5:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0105,
                       shortfid=0x05, data=dg5))
        if dg6:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0106,
                       shortfid=0x06, data=dg6))
        if dg7:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0107,
                       shortfid=0x07, data=dg7))
        if dg8:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0108,
                       shortfid=0x08, data=dg8))
        if dg9:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0109,
                       shortfid=0x09, data=dg9))
        if dg10:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010a,
                       shortfid=0x0a, data=dg10))
        if dg11:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010b,
                       shortfid=0x0b, data=dg11))
        if dg12:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010c,
                       shortfid=0x0c, data=dg12))
        if dg13:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010d,
                       shortfid=0x0d, data=dg13))
        if dg14:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010e,
                       shortfid=0x0e, data=dg14))
        if dg15:
            eid.append(TransparentStructureEF(parent=eid, fid=0x010f,
                       shortfid=0x0f, data=dg15))
        if dg16:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0110,
                       shortfid=0x10, data=dg16))
        if dg17:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0111,
                       shortfid=0x11, data=dg17))
        if dg18:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0112,
                       shortfid=0x12, data=dg18))
        if dg19:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0113,
                       shortfid=0x13, data=dg19))
        if dg20:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0114,
                       shortfid=0x14, data=dg20))
        if dg21:
            eid.append(TransparentStructureEF(parent=eid, fid=0x0115,
                       shortfid=0x15, data=dg21))
        self.mf.append(eid)

        # DF.CIA
        cia = DF(parent=self.mf, fid=0xfffe,
                 dfname='\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49'
                        '\x47\x4E')
        # EF.OD / EF.ODF
        cia.append(TransparentStructureEF(parent=cia, fid=0x5031,
                                          shortfid=0x11,
                                          data='\xa0\x060\x04\x04\x02D\x00\xa4'
                                          '\x060\x04\x04\x02D\x04\xa8\x060\x04'
                                          '\x04\x02D\x08'))
        # EF.CIAInfo / EF.TokenInfo
        cia.append(TransparentStructureEF(parent=cia, fid=0x5032,
                                          shortfid=0x12,
                                          data='06\x02\x01\x01\x80\x11eSign '
                                          'Application\x03\x02\x06\xc0\xa2'
                                          '\x1a0\x18\x02\x01\x01\x02\x02\x10A'
                                          '\x05\x00\x03\x02\x06@\x06\t\x04\x00'
                                          '\x7f\x00\x07\x01\x01\x04\x01'))
        # EF.PrKD / EF.PrKDF
        cia.append(TransparentStructureEF(parent=cia, fid=0x4400,
                                          data='\xa080\x17\x0c\x0bPrK.ICC.QES'
                                          '\x03\x02\x07\x80\x04\x01\x01\x02'
                                          '\x01\x010\x15\x04\x01F\x03\x03\x06'
                                          '\x00@\x03\x02\x03\xb8\x02\x02\x00'
                                          '\x84\xa1\x03\x02\x01\x01\xa1\x060'
                                          '\x040\x02\x04\x00'))
        # EF.PuKD / EF.PuKDF
        cia.append(TransparentStructureEF(parent=cia, fid=0x4404,
                                          data='050!\x0c\x1fZertifikat des ZDA'
                                          ' f\xc3\xbcr die QES0\x06\x04\x01E'
                                          '\x01\x01\xff\xa1\x080\x060\x04\x04'
                                          '\x02\xc0\x000:0&\x0c$Zertifikat des'
                                          ' Inhabers f\xc3\xbcr die QES0\x06'
                                          '\x04\x01F\x01\x01\x00\xa1\x080\x060'
                                          '\x04\x04\x02\xc0\x01'))
        # EF.AOD / EF.AODF
        cia.append(TransparentStructureEF(parent=cia, fid=0x4408,
                                          data='0/0\x0f\x0c\teSign-PIN\x03\x02'
                                          '\x06@0\x03\x04\x01\x01\xa1\x170\x15'
                                          '\x03\x03\x02H\x1c\n\x01\x01\x02\x01'
                                          '\x06\x02\x01\x00\x80\x01\x810\x02'
                                          '\x04\x00'))
        self.mf.append(cia)

        # DF.eSign
        esign = DF(parent=self.mf, fid=0xfffd,
                   dfname='\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E')

        # ZDA certificate
        esign.append(TransparentStructureEF(parent=esign, fid=0xC000, data=''))
        # User's certificate
        esign.append(TransparentStructureEF(parent=esign, fid=0xC001, data=''))
        self.mf.append(esign)

        self.sam = nPA_SAM(eid_pin="111111", can="222222",
                           mrz="IDD<<T220001293<<<<<<<<<<<<<<<6408125<2010315D"
                           "<<<<<<<<<<<<<<MUSTERMANN<<ERIKA<<<<<<<<<<<<<",
                           puk="3333333333", qes_pin="444444", mf=self.mf)
        # FIXME: add CVCA for inspection systems and signature terminals. Here
        #        we only add the eID CVCA.
        self.sam.current_SE.cvca = "\x7f\x21\x82\x01\xb6\x7f\x4e\x82\x01\x6e"\
                                   "\x5f\x29\x01\x00\x42\x0e\x44\x45\x43\x56"\
                                   "\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32"\
                                   "\x7f\x49\x82\x01\x1d\x06\x0a\x04\x00\x7f"\
                                   "\x00\x07\x02\x02\x02\x02\x03\x81\x20\xa9"\
                                   "\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a"\
                                   "\x90\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5"\
                                   "\x26\x20\x28\x20\x13\x48\x1d\x1f\x6e\x53"\
                                   "\x77\x82\x20\x7d\x5a\x09\x75\xfc\x2c\x30"\
                                   "\x57\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb"\
                                   "\x80\x55\xc1\x26\xdc\x5c\x6c\xe9\x4a\x4b"\
                                   "\x44\xf3\x30\xb5\xd9\x83\x20\x26\xdc\x5c"\
                                   "\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\xbb"\
                                   "\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7\xe1"\
                                   "\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x84"\
                                   "\x41\x04\x8b\xd2\xae\xb9\xcb\x7e\x57\xcb"\
                                   "\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde"\
                                   "\x27\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd"\
                                   "\x9a\xce\x32\x62\x54\x7e\xf8\x35\xc3\xda"\
                                   "\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9"\
                                   "\xc2\x77\x45\x13\x2d\xed\x8e\x54\x5c\x1d"\
                                   "\x54\xc7\x2f\x04\x69\x97\x85\x20\xa9\xfb"\
                                   "\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90"\
                                   "\x9d\x83\x8d\x71\x8c\x39\x7a\xa3\xb5\x61"\
                                   "\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7"\
                                   "\x86\x41\x04\x33\x47\xec\xf9\x6f\xfb\x4b"\
                                   "\xd9\xb8\x55\x4e\xfb\xcc\xfc\x7d\x0b\x24"\
                                   "\x2f\x10\x71\xe2\x9b\x4c\x9c\x62\x2c\x79"\
                                   "\xe3\x39\xd8\x40\xaf\x67\xbe\xb9\xb9\x12"\
                                   "\x69\x22\x65\xd9\xc1\x6c\x62\x57\x3f\x45"\
                                   "\x79\xff\xd4\xde\x2d\xe9\x2b\xab\x40\x9d"\
                                   "\xd5\xc5\xd4\x82\x44\xa9\xf7\x87\x01\x01"\
                                   "\x5f\x20\x0e\x44\x45\x43\x56\x43\x41\x65"\
                                   "\x49\x44\x30\x30\x31\x30\x32\x7f\x4c\x12"\
                                   "\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02"\
                                   "\x02\x53\x05\xfe\x0f\x01\xff\xff\x5f\x25"\
                                   "\x06\x01\x00\x01\x00\x01\x08\x5f\x24\x06"\
                                   "\x01\x03\x01\x00\x01\x08\x5f\x37\x40\x50"\
                                   "\x67\x14\x5c\x68\xca\xe9\x52\x0f\x5b\xb3"\
                                   "\x48\x17\xf1\xca\x9c\x43\x59\x3d\xb5\x64"\
                                   "\x06\xc6\xa3\xb0\x06\xcb\xf3\xf3\x14\xe7"\
                                   "\x34\x9a\xcf\x0c\xc6\xbf\xeb\xcb\xde\xfd"\
                                   "\x10\xb4\xdc\xf0\xf2\x31\xda\x56\x97\x7d"\
                                   "\x88\xf9\xf9\x01\x82\xd1\x99\x07\x6a\x56"\
                                   "\x50\x64\x51"
Example #6
0
class CardGenerator(object):
    """This class is used to generate the SAM and filesystem for the 
    different supported card types. It is also able used for persistent storage
    (in encrypted form) of the card on disks. """
    
    def __init__(self, card_type=None, sam=None, mf=None):
        self.type = card_type
        self.mf = mf
        self.sam = sam
        self.password = None
        self.datagroups = {}
    
    def __generate_iso_card(self):
        default_pin = "1234"
        default_cardno = "1234567890"
        
        logging.warning("Using default SAM parameters. PIN=%s, Card Nr=%s"
                        % (default_pin, default_cardno))
        #TODO: Use user provided data
        self.sam = SAM(default_pin, default_cardno)
        
        self.mf = MF(filedescriptor=FDB["DF"])
        self.sam.set_MF(self.mf)
           
    def __generate_ePass(self):
        """Generate the MF and SAM of an ICAO passport. This method is 
        responsible for generating the filesystem and filling it with content.
        Therefore it must interact with the user by prompting for the MRZ and
        optionally for the path to a photo."""
        from PIL import Image
        from virtualsmartcard.cards.ePass import PassportSAM
            
        #TODO: Sanity checks
        MRZ = raw_input("Please enter the MRZ as one string: ")

        readline.set_completer_delims("")
        readline.parse_and_bind("tab: complete")
        
        picturepath = raw_input("Please enter the path to an image: ")
        picturepath = picturepath.strip()
        
        #MRZ1 = "P<UTOERIKSSON<<ANNA<MARIX<<<<<<<<<<<<<<<<<<<"
        #MRZ2 = "L898902C<3UTO6908061F9406236ZE184226B<<<<<14"
        #MRZ = MRZ1 + MRZ2        

        try:
            im = Image.open(picturepath)
            pic_width, pic_height = im.size
            fd = open(picturepath,"rb")
            picture = fd.read()
            fd.close()
        except IOError:
            logging.warning("Failed to open file: " + picturepath)
            pic_width = 0
            pic_height = 0
            picture = None  

        mf = MF()
        
        #We need a MF with Application DF \xa0\x00\x00\x02G\x10\x01
        df = DF(parent=mf, fid=4, dfname='\xa0\x00\x00\x02G\x10\x01',
                bertlv_data=[])

        #EF.COM
        COM = pack([(0x5F01, 4, "0107"), (0x5F36, 6, "040000"),
                    (0x5C, 2, "6175")])
        COM = pack(((0x60, len(COM), COM),))
        df.append(TransparentStructureEF(parent=df, fid=0x011E,
                  filedescriptor=0, data=COM))

        #EF.DG1
        DG1 = pack([(0x5F1F, len(MRZ), MRZ)])
        DG1 = pack([(0x61, len(DG1), DG1)])
        df.append(TransparentStructureEF(parent=df, fid=0x0101,
                  filedescriptor=0, data=DG1))

        #EF.DG2
        if picture != None:
            IIB = "\x00\x01" + inttostring(pic_width, 2) +\
                    inttostring(pic_height, 2) + 6 * "\x00" 
            length = 32 + len(picture) #32 is the length of IIB + FIB
            FIB = inttostring(length, 4) + 16 * "\x00"
            FRH = "FAC" + "\x00" + "010" + "\x00" +\
                    inttostring(14 + length, 4) + inttostring(1, 2)
            picture = FRH + FIB + IIB + picture
            DG2 = pack([(0xA1, 8, "\x87\x02\x01\x01\x88\x02\x05\x01"), 
                    (0x5F2E, len(picture), picture)])
            DG2 = pack([(0x02, 1, "\x01"), (0x7F60, len(DG2), DG2)])
            DG2 = pack([(0x7F61, len(DG2), DG2)])
        else:
            DG2 = ""
        df.append(TransparentStructureEF(parent=df, fid=0x0102,
                  filedescriptor=0, data=DG2))

        #EF.SOD
        df.append(TransparentStructureEF(parent=df, fid=0x010D,
                  filedescriptor=0, data=""))

        mf.append(df)

        self.mf = mf
        self.sam = PassportSAM(self.mf)
    
    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        for oid_base, x_list, y_list, algo in [
                ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1,5), range(1,5), "PACE"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1,3), range(1,6), "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1],        [6],        "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1,3), range(1,5), "CA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1,3), range(1,6), "RI"),
                ]:
            for oid in [oid_base+chr(x)+chr(y) for x in x_list for y in y_list]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(TransparentStructureEF(parent=self.mf, fid=0x011c, shortfid=0x1c, data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36\x31\x82\x01\x32\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\x04\x02\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05\x27"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011d, shortfid=0x1d, data=card_security))
        ef_dir = '\x61\x32\x4F\x0F\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x50\x0F\x43\x49\x41\x20\x7A\x75\x20\x44\x46\x2E\x65\x53\x69\x67\x6E\x51\x00\x73\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x61\x09\x4F\x07\xA0\x00\x00\x02\x47\x10\x01\x61\x0B\x4F\x09\xE8\x07\x04\x00\x7F\x00\x07\x03\x02\x61\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E'
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x2f00, shortfid=30, data=ef_dir))

        #print 'nPA:', unpack('\x62\x81\x88\x82\x01\x38\x8a\x01\x05\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03')
        #print 'vicc:', unpack('\x62\x15\x83\x02\xff\xff\x8a\x01\x05\x82\x01\x38\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid=DF(parent=self.mf, fid=0xffff, dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid.extra_fci_data = '\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03'
        # FIXME access control for eid application
        DocumentType = self.datagroups["DocumentType"] if "DocumentType" in self.datagroups else 'ID'
        IssuingState = self.datagroups["IssuingState"] if "IssuingState" in self.datagroups else 'DE'
        DateOfExpiry = self.datagroups["DateOfExpiry"] if "DateOfExpiry" in self.datagroups else '20201031'
        GivenNames = self.datagroups["GivenNames"] if "GivenNames" in self.datagroups else 'ERIKA'
        FamilyNames = self.datagroups["FamilyNames"] if "FamilyNames" in self.datagroups else 'MUSTERMANN'
        ReligiousArtisticName = self.datagroups["ReligiousArtisticName"] if "ReligiousArtisticName" in self.datagroups else ''
        AcademicTitle = self.datagroups["AcademicTitle"] if "AcademicTitle" in self.datagroups else ''
        DateOfBirth = self.datagroups["DateOfBirth"] if "DateOfBirth" in self.datagroups else '19640812'
        PlaceOfBirth = self.datagroups["PlaceOfBirth"] if "PlaceOfBirth" in self.datagroups else 'BERLIN'
        Nationality = self.datagroups["Nationality"] if "Nationality" in self.datagroups else 'DE'
        Sex = self.datagroups["Sex"] if "Sex" in self.datagroups else 'F'
        Country = self.datagroups["Country"] if "Country" in self.datagroups else 'D'
        City = self.datagroups["City"] if "City" in self.datagroups else 'KOLN'
        ZIP = self.datagroups["ZIP"] if "ZIP" in self.datagroups else '51147'
        Street = self.datagroups["Street"] if "Street" in self.datagroups else 'HEIDESTRASSE 17'
        CommunityID = eval(self.datagroups["CommunityID"])  if "CommunityID" in self.datagroups else '\x12\x34\x56\x78\x90\x12\x34'
        dg1 =  pack([(0x61, 0, [(0x13, 0, DocumentType)])], True)
        dg2 =  pack([(0x62, 0, [(0x13, 0, IssuingState)])], True)
        dg3 =  pack([(0x63, 0, [(0x12, 0, DateOfExpiry)])], True)
        dg4 =  pack([(0x64, 0, [(0x0C, 0, GivenNames)])], True)
        dg5 =  pack([(0x65, 0, [(0x0C, 0, FamilyNames)])], True)
        dg6 =  pack([(0x66, 0, [(0x0C, 0, ReligiousArtisticName)])], True)
        dg7 =  pack([(0x67, 0, [(0x0C, 0, AcademicTitle)])], True)
        dg8 =  pack([(0x68, 0, [(0x12, 0, DateOfBirth)])], True)
        dg9 =  pack([(0x69, 0, [(0xA1, 0, [(0x0C, 0, PlaceOfBirth)])])], True)
        dg10 = pack([(0x6A, 0, [(0x13, 0, Nationality)])], True)
        dg11 = pack([(0x6B, 0, [(0x13, 0, Sex)])], True)
        dg12 = self.datagroups["dg12"] if "dg12" in self.datagroups else ''
        dg13 = self.datagroups["dg13"] if "dg13" in self.datagroups else ''
        dg14 = self.datagroups["dg14"] if "dg14" in self.datagroups else ''
        dg15 = self.datagroups["dg15"] if "dg15" in self.datagroups else ''
        dg16 = self.datagroups["dg16"] if "dg16" in self.datagroups else ''
        dg17 = pack([(0x71, 0, [(0x30, 0, [
                (0xAA, 0, [(0x0C, 0, Street)]),
                (0xAB, 0, [(0x0C, 0, City)]),
                (0xAD, 0, [(0x13, 0, Country)]),
                (0xAE, 0, [(0x13, 0, ZIP)])
                ])])], True)
        dg18 = pack([(0x72, 0, [(0x04, 0, CommunityID)])], True)
        dg19 = self.datagroups["dg19"] if "dg19" in self.datagroups else ''
        dg20 = self.datagroups["dg20"] if "dg20" in self.datagroups else ''
        dg21 = self.datagroups["dg21"] if "dg21" in self.datagroups else ''
        eid.append(TransparentStructureEF(parent=eid, fid=0x0101, shortfid=0x01, data=dg1))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0102, shortfid=0x02, data=dg2))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0103, shortfid=0x03, data=dg3))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0104, shortfid=0x04, data=dg4))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0105, shortfid=0x05, data=dg5))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0106, shortfid=0x06, data=dg6))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0107, shortfid=0x07, data=dg7))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0108, shortfid=0x08, data=dg8))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0109, shortfid=0x09, data=dg9))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010a, shortfid=0x0a, data=dg10))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010b, shortfid=0x0b, data=dg11))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010c, shortfid=0x0c, data=dg12))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010d, shortfid=0x0d, data=dg13))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010e, shortfid=0x0e, data=dg14))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010f, shortfid=0x0f, data=dg15))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0110, shortfid=0x10, data=dg16))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0111, shortfid=0x11, data=dg17))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0112, shortfid=0x12, data=dg18))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0113, shortfid=0x13, data=dg19))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0114, shortfid=0x14, data=dg20))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0115, shortfid=0x15, data=dg21))
        self.mf.append(eid)

        self.sam = nPA_SAM(pin="111111", can="222222", mrz="IDD<<T220001293<<<<<<<<<<<<<<<6408125<2010315D<<<<<<<<<<<<<<MUSTERMANN<<ERIKA<<<<<<<<<<<<<", puk="3333333333", mf=self.mf)
        # FIXME add CVCA for inspection systems and signature terminals. Here we only add the eID CVCA.
        self.sam.current_SE.cvca = '\x7f\x21\x82\x01\xb6\x7f\x4e\x82\x01\x6e\x5f\x29\x01\x00\x42\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x49\x82\x01\x1d\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x02\x02\x03\x81\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5\x26\x20\x28\x20\x13\x48\x1d\x1f\x6e\x53\x77\x82\x20\x7d\x5a\x09\x75\xfc\x2c\x30\x57\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb\x80\x55\xc1\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\x83\x20\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\xbb\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7\xe1\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x84\x41\x04\x8b\xd2\xae\xb9\xcb\x7e\x57\xcb\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde\x27\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd\x9a\xce\x32\x62\x54\x7e\xf8\x35\xc3\xda\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9\xc2\x77\x45\x13\x2d\xed\x8e\x54\x5c\x1d\x54\xc7\x2f\x04\x69\x97\x85\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x71\x8c\x39\x7a\xa3\xb5\x61\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7\x86\x41\x04\x33\x47\xec\xf9\x6f\xfb\x4b\xd9\xb8\x55\x4e\xfb\xcc\xfc\x7d\x0b\x24\x2f\x10\x71\xe2\x9b\x4c\x9c\x62\x2c\x79\xe3\x39\xd8\x40\xaf\x67\xbe\xb9\xb9\x12\x69\x22\x65\xd9\xc1\x6c\x62\x57\x3f\x45\x79\xff\xd4\xde\x2d\xe9\x2b\xab\x40\x9d\xd5\xc5\xd4\x82\x44\xa9\xf7\x87\x01\x01\x5f\x20\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\xfe\x0f\x01\xff\xff\x5f\x25\x06\x01\x00\x01\x00\x01\x08\x5f\x24\x06\x01\x03\x01\x00\x01\x08\x5f\x37\x40\x50\x67\x14\x5c\x68\xca\xe9\x52\x0f\x5b\xb3\x48\x17\xf1\xca\x9c\x43\x59\x3d\xb5\x64\x06\xc6\xa3\xb0\x06\xcb\xf3\xf3\x14\xe7\x34\x9a\xcf\x0c\xc6\xbf\xeb\xcb\xde\xfd\x10\xb4\xdc\xf0\xf2\x31\xda\x56\x97\x7d\x88\xf9\xf9\x01\x82\xd1\x99\x07\x6a\x56\x50\x64\x51'

    def __generate_cryptoflex(self):
        """Generate the Filesystem and SAM of a cryptoflex card"""
        from virtualsmartcard.cards.cryptoflex import CryptoflexMF, CryptoflexSAM
        self.mf = CryptoflexMF()
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x0002,
                       filedescriptor=0x01,
                       data="\x00\x00\x00\x01\x00\x01\x00\x00")) #EF.ICCSN
        self.sam = CryptoflexSAM(self.mf)
        
    def generateCard(self):
        """Generate a new card"""
        if self.type == 'iso7816':
            self.__generate_iso_card()
        elif self.type == 'ePass':
            self.__generate_ePass()
        elif self.type == 'cryptoflex':
            self.__generate_cryptoflex()
        elif self.type == 'nPA':
            self.__generate_nPA()
        else:
            return (None, None)
    
    def getCard(self):
        """Get the MF and SAM from the current card"""
        if self.sam is None or self.mf is None:
            self.generateCard()
        return self.mf, self.sam
    
    def setCard(self, mf=None, sam=None):
        """Set the MF and SAM of the current card"""
        if mf != None:
            self.mf = mf
        if sam != None:
            self.sam = sam
        
    
    def loadCard(self, filename):
        """Load a card from disk"""
        db = anydbm.open(filename, 'r')
        
        if self.password is None:
            self.password = getpass.getpass("Please enter your password:"******"mf"], self.password)
        serializedSAM = read_protected_string(db["sam"], self.password)
        self.sam = loads(serializedSAM)
        self.mf = loads(serializedMF)
        self.type = db["type"]
            
    def saveCard(self, filename):
        """Save the currently running card to disk"""
        if self.password is None:
            passwd1 = getpass.getpass("Please enter your password:"******"Please retype your password:"******"Passwords did not match. Will now exit")
            else:
                self.password = passwd1
        
        if self.mf == None or self.sam == None:
            raise ValueError("Card Generator wasn't set up properly" +\
                 "(missing MF or SAM).")
        
        mf_string = dumps(self.mf)
        sam_string = dumps(self.sam)
        protectedMF = protect_string(mf_string, self.password)
        protectedSAM = protect_string(sam_string, self.password)
        
        db = anydbm.open(filename, 'c')
        db["mf"] = protectedMF
        db["sam"] = protectedSAM
        db["type"] = self.type
        db["version"] = "0.1"
        db.close()

    def readDatagroups(self, datasetfile):
        """Read Datagroups from file"""
        with open(datasetfile, 'r') as f:
		for line in f:
			if not line.startswith("#"):
				line=line.replace(" =", "=")
				line=line.replace("= ", "=")
				splitLine = line.split("=")
				self.datagroups[splitLine[0]] = splitLine[1]
	f.close()
Example #7
0
class CardGenerator(object):
    """This class is used to generate the SAM and filesystem for the 
    different supported card types. It is also able used for persistent storage
    (in encrypted form) of the card on disks. """
    def __init__(self, card_type=None, sam=None, mf=None):
        self.type = card_type
        self.mf = mf
        self.sam = sam
        self.password = None
        self.datagroups = {}

    def __generate_iso_card(self):
        default_pin = "1234"
        default_cardno = "1234567890"

        logging.warning("Using default SAM parameters. PIN=%s, Card Nr=%s" %
                        (default_pin, default_cardno))
        #TODO: Use user provided data
        self.sam = SAM(default_pin, default_cardno)

        self.mf = MF(filedescriptor=FDB["DF"])
        self.sam.set_MF(self.mf)

    def __generate_ePass(self):
        """Generate the MF and SAM of an ICAO passport. This method is 
        responsible for generating the filesystem and filling it with content.
        Therefore it must interact with the user by prompting for the MRZ and
        optionally for the path to a photo."""
        from PIL import Image
        from virtualsmartcard.cards.ePass import PassportSAM

        #TODO: Sanity checks
        MRZ = raw_input("Please enter the MRZ as one string: ")

        readline.set_completer_delims("")
        readline.parse_and_bind("tab: complete")

        picturepath = raw_input("Please enter the path to an image: ")
        picturepath = picturepath.strip()

        #MRZ1 = "P<UTOERIKSSON<<ANNA<MARIX<<<<<<<<<<<<<<<<<<<"
        #MRZ2 = "L898902C<3UTO6908061F9406236ZE184226B<<<<<14"
        #MRZ = MRZ1 + MRZ2

        try:
            im = Image.open(picturepath)
            pic_width, pic_height = im.size
            fd = open(picturepath, "rb")
            picture = fd.read()
            fd.close()
        except IOError:
            logging.warning("Failed to open file: " + picturepath)
            pic_width = 0
            pic_height = 0
            picture = None

        mf = MF()

        #We need a MF with Application DF \xa0\x00\x00\x02G\x10\x01
        df = DF(parent=mf,
                fid=4,
                dfname='\xa0\x00\x00\x02G\x10\x01',
                bertlv_data=[])

        #EF.COM
        COM = pack([(0x5F01, 4, "0107"), (0x5F36, 6, "040000"),
                    (0x5C, 2, "6175")])
        COM = pack(((0x60, len(COM), COM), ))
        df.append(
            TransparentStructureEF(parent=df,
                                   fid=0x011E,
                                   filedescriptor=0,
                                   data=COM))

        #EF.DG1
        DG1 = pack([(0x5F1F, len(MRZ), MRZ)])
        DG1 = pack([(0x61, len(DG1), DG1)])
        df.append(
            TransparentStructureEF(parent=df,
                                   fid=0x0101,
                                   filedescriptor=0,
                                   data=DG1))

        #EF.DG2
        if picture != None:
            IIB = "\x00\x01" + inttostring(pic_width, 2) +\
                    inttostring(pic_height, 2) + 6 * "\x00"
            length = 32 + len(picture)  #32 is the length of IIB + FIB
            FIB = inttostring(length, 4) + 16 * "\x00"
            FRH = "FAC" + "\x00" + "010" + "\x00" +\
                    inttostring(14 + length, 4) + inttostring(1, 2)
            picture = FRH + FIB + IIB + picture
            DG2 = pack([(0xA1, 8, "\x87\x02\x01\x01\x88\x02\x05\x01"),
                        (0x5F2E, len(picture), picture)])
            DG2 = pack([(0x02, 1, "\x01"), (0x7F60, len(DG2), DG2)])
            DG2 = pack([(0x7F61, len(DG2), DG2)])
        else:
            DG2 = ""
        df.append(
            TransparentStructureEF(parent=df,
                                   fid=0x0102,
                                   filedescriptor=0,
                                   data=DG2))

        #EF.SOD
        df.append(
            TransparentStructureEF(parent=df,
                                   fid=0x010D,
                                   filedescriptor=0,
                                   data=""))

        mf.append(df)

        self.mf = mf
        self.sam = PassportSAM(self.mf)

    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        for oid_base, x_list, y_list, algo in [
            ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1,
                                                       5), range(1,
                                                                 5), "PACE"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1, 3), range(1,
                                                                    6), "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1], [6], "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1, 3), range(1,
                                                                    5), "CA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1, 3), range(1,
                                                                    6), "RI"),
        ]:
            for oid in [
                    oid_base + chr(x) + chr(y) for x in x_list for y in y_list
            ]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(
            TransparentStructureEF(parent=self.mf,
                                   fid=0x011c,
                                   shortfid=0x1c,
                                   data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36\x31\x82\x01\x32\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\x04\x02\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05\x27"
        self.mf.append(
            TransparentStructureEF(parent=self.mf,
                                   fid=0x011d,
                                   shortfid=0x1d,
                                   data=card_security))
        ef_dir = '\x61\x32\x4F\x0F\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x50\x0F\x43\x49\x41\x20\x7A\x75\x20\x44\x46\x2E\x65\x53\x69\x67\x6E\x51\x00\x73\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x61\x09\x4F\x07\xA0\x00\x00\x02\x47\x10\x01\x61\x0B\x4F\x09\xE8\x07\x04\x00\x7F\x00\x07\x03\x02\x61\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E'
        self.mf.append(
            TransparentStructureEF(parent=self.mf,
                                   fid=0x2f00,
                                   shortfid=30,
                                   data=ef_dir))

        #print 'nPA:', unpack('\x62\x81\x88\x82\x01\x38\x8a\x01\x05\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03')
        #print 'vicc:', unpack('\x62\x15\x83\x02\xff\xff\x8a\x01\x05\x82\x01\x38\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid = DF(parent=self.mf,
                 fid=0xffff,
                 dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid.extra_fci_data = '\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03'
        # FIXME access control for eid application

        DocumentType = self.datagroups[
            "DocumentType"] if "DocumentType" in self.datagroups else 'ID'
        IssuingState = self.datagroups[
            "IssuingState"] if "IssuingState" in self.datagroups else 'D'
        DateOfExpiry = self.datagroups[
            "DateOfExpiry"] if "DateOfExpiry" in self.datagroups else '20201031'
        GivenNames = self.datagroups[
            "GivenNames"] if "GivenNames" in self.datagroups else 'ERIKA'
        FamilyNames = self.datagroups[
            "FamilyNames"] if "FamilyNames" in self.datagroups else 'MUSTERMANN'
        ReligiousArtisticName = self.datagroups[
            "ReligiousArtisticName"] if "ReligiousArtisticName" in self.datagroups else ''
        AcademicTitle = self.datagroups[
            "AcademicTitle"] if "AcademicTitle" in self.datagroups else ''
        DateOfBirth = self.datagroups[
            "DateOfBirth"] if "DateOfBirth" in self.datagroups else '19640812'
        PlaceOfBirth = self.datagroups[
            "PlaceOfBirth"] if "PlaceOfBirth" in self.datagroups else 'BERLIN'
        Nationality = self.datagroups[
            "Nationality"] if "Nationality" in self.datagroups else 'DE'
        Sex = self.datagroups["Sex"] if "Sex" in self.datagroups else 'F'
        BirthName = self.datagroups[
            "BirthName"] if "BirthName" in self.datagroups else 'Mein Geburtsname'
        # PlaceOfResidence variable is only a helper to get a switch for <NotOnChip>
        PlaceOfResidence = self.datagroups[
            "PlaceOfResidence"] if "PlaceOfResidence" in self.datagroups else ''
        Country = self.datagroups[
            "Country"] if "Country" in self.datagroups else 'D'
        City = self.datagroups["City"] if "City" in self.datagroups else 'KOLN'
        ZIP = self.datagroups["ZIP"] if "ZIP" in self.datagroups else '51147'
        Street = self.datagroups[
            "Street"] if "Street" in self.datagroups else 'HEIDESTRASSE 17'
        CommunityID = eval(
            self.datagroups["CommunityID"]
        ) if "CommunityID" in self.datagroups else '\x02\x76\x03\x78\x90\x02\x76'
        # ResidencePermit1 and ResidencePermit2 are part of eAT only
        ResidencePermit1 = self.datagroups[
            "ResidencePermit1"] if "ResidencePermit1" in self.datagroups else 'ResidencePermit1 field up to 750 characters'
        ResidencePermit2 = self.datagroups[
            "ResidencePermit2"] if "ResidencePermit2" in self.datagroups else 'ResidencePermit1 field up to 250 characters'

        # Currently, those data groups are for further usage:
        dg12_param = self.datagroups[
            "dg12"] if "dg12" in self.datagroups else ''
        dg14_param = self.datagroups[
            "dg14"] if "dg14" in self.datagroups else ''
        dg15_param = self.datagroups[
            "dg15"] if "dg15" in self.datagroups else ''
        dg16_param = self.datagroups[
            "dg16"] if "dg16" in self.datagroups else ''
        dg21_param = self.datagroups[
            "dg21"] if "dg21" in self.datagroups else ''

        # "Attribute not on Chip" makes sence only for ReligiousArtisticName, Nationality, BirthName, ResidencePermit1 and ResidencePermit2, refer to BSI TR-03127
        if (DocumentType.rstrip() != "<NotOnChip>"):
            dg1 = pack([(0x61, 0, [(0x13, 0, DocumentType)])], True)
        else:
            dg1 = None
        if (IssuingState.rstrip() != "<NotOnChip>"):
            dg2 = pack([(0x62, 0, [(0x13, 0, IssuingState)])], True)
        else:
            dg2 = None
        if (DateOfExpiry.rstrip() != "<NotOnChip>"):
            dg3 = pack([(0x63, 0, [(0x12, 0, DateOfExpiry)])], True)
        else:
            dg3 = None
        if (GivenNames.rstrip() != "<NotOnChip>"):
            dg4 = pack([(0x64, 0, [(0x0C, 0, GivenNames)])], True)
        else:
            dg4 = None
        if (FamilyNames.rstrip() != "<NotOnChip>"):
            dg5 = pack([(0x65, 0, [(0x0C, 0, FamilyNames)])], True)
        else:
            dg5 = None
        if (ReligiousArtisticName.rstrip() != "<NotOnChip>"):
            dg6 = pack([(0x66, 0, [(0x0C, 0, ReligiousArtisticName)])], True)
        else:
            dg6 = None
        if (AcademicTitle.rstrip() != "<NotOnChip>"):
            dg7 = pack([(0x67, 0, [(0x0C, 0, AcademicTitle)])], True)
        else:
            dg7 = None
        if (DateOfBirth.rstrip() != "<NotOnChip>"):
            dg8 = pack([(0x68, 0, [(0x12, 0, DateOfBirth)])], True)
        else:
            dg8 = None
        if (PlaceOfBirth.rstrip() != "<NotOnChip>"):
            dg9 = pack([(0x69, 0, [(0xA1, 0, [(0x0C, 0, PlaceOfBirth)])])],
                       True)
        else:
            dg9 = None
        if (Nationality.rstrip() != "<NotOnChip>"):
            dg10 = pack([(0x6A, 0, [(0x13, 0, Nationality)])], True)
        else:
            dg10 = None
        if (Sex.rstrip() != "<NotOnChip>"):
            dg11 = pack([(0x6B, 0, [(0x13, 0, Sex)])], True)
        else:
            dg11 = None
        if (dg12_param.rstrip() != "<NotOnChip>"):
            dg12 = dg12_param
        else:
            dg12 = None
        if (BirthName.rstrip() != "<NotOnChip>"):
            dg13 = pack([(0x6D, 0, [(0x0C, 0, BirthName)])], True)
        else:
            dg13 = None
        if (dg14_param.rstrip() != "<NotOnChip>"):
            dg14 = dg14_param
        else:
            dg14 = None
        if (dg15_param.rstrip() != "<NotOnChip>"):
            dg15 = dg15_param
        else:
            dg15 = None
        if (dg16_param.rstrip() != "<NotOnChip>"):
            dg16 = dg16_param
        else:
            dg16 = None
        if (PlaceOfResidence.rstrip() != "<NotOnChip>"):
            dg17 = pack(
                [(0x71, 0, [(0x30, 0, [(0xAA, 0, [(0x0C, 0, Street)]),
                                       (0xAB, 0, [(0x0C, 0, City)]),
                                       (0xAD, 0, [(0x13, 0, Country)]),
                                       (0xAE, 0, [(0x13, 0, ZIP)])])])], True)
        else:
            dg17 = None
#FIXME: Dataset file with CommunityID =<NotOnChip> still not works while assigning of non hex value due to eval()
        if (CommunityID.rstrip() != "<NotOnChip>"):
            dg18 = pack([(0x72, 0, [(0x04, 0, CommunityID)])], True)
        else:
            dg18 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
            dg19 = pack(
                [(0x73, 0, [(0xA1, 0, [(0x0C, 0, ResidencePermit1)])])], True)
        else:
            dg19 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
            dg20 = pack(
                [(0x74, 0, [(0xA1, 0, [(0x0C, 0, ResidencePermit2)])])], True)
        else:
            dg20 = None
        if (dg21_param.rstrip() != "<NotOnChip>"):
            dg21 = dg21_param
        else:
            dg21 = None

# If eid.append is not done for a DG, it results into required SwError() with FileNotFound "6A82" APDU return code
        if dg1:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0101,
                                       shortfid=0x01,
                                       data=dg1))
        if dg2:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0102,
                                       shortfid=0x02,
                                       data=dg2))
        if dg3:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0103,
                                       shortfid=0x03,
                                       data=dg3))
        if dg4:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0104,
                                       shortfid=0x04,
                                       data=dg4))
        if dg5:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0105,
                                       shortfid=0x05,
                                       data=dg5))
        if dg6:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0106,
                                       shortfid=0x06,
                                       data=dg6))
        if dg7:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0107,
                                       shortfid=0x07,
                                       data=dg7))
        if dg8:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0108,
                                       shortfid=0x08,
                                       data=dg8))
        if dg9:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0109,
                                       shortfid=0x09,
                                       data=dg9))
        if dg10:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010a,
                                       shortfid=0x0a,
                                       data=dg10))
        if dg11:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010b,
                                       shortfid=0x0b,
                                       data=dg11))
        if dg12:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010c,
                                       shortfid=0x0c,
                                       data=dg12))
        if dg13:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010d,
                                       shortfid=0x0d,
                                       data=dg13))
        if dg14:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010e,
                                       shortfid=0x0e,
                                       data=dg14))
        if dg15:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010f,
                                       shortfid=0x0f,
                                       data=dg15))
        if dg16:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0110,
                                       shortfid=0x10,
                                       data=dg16))
        if dg17:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0111,
                                       shortfid=0x11,
                                       data=dg17))
        if dg18:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0112,
                                       shortfid=0x12,
                                       data=dg18))
        if dg19:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0113,
                                       shortfid=0x13,
                                       data=dg19))
        if dg20:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0114,
                                       shortfid=0x14,
                                       data=dg20))
        if dg21:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0115,
                                       shortfid=0x15,
                                       data=dg21))
        self.mf.append(eid)

        self.sam = nPA_SAM(
            pin="111111",
            can="222222",
            mrz=
            "IDD<<T220001293<<<<<<<<<<<<<<<6408125<2010315D<<<<<<<<<<<<<<MUSTERMANN<<ERIKA<<<<<<<<<<<<<",
            puk="3333333333",
            mf=self.mf)
        # FIXME add CVCA for inspection systems and signature terminals. Here we only add the eID CVCA.
        self.sam.current_SE.cvca = '\x7f\x21\x82\x01\xb6\x7f\x4e\x82\x01\x6e\x5f\x29\x01\x00\x42\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x49\x82\x01\x1d\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x02\x02\x03\x81\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5\x26\x20\x28\x20\x13\x48\x1d\x1f\x6e\x53\x77\x82\x20\x7d\x5a\x09\x75\xfc\x2c\x30\x57\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb\x80\x55\xc1\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\x83\x20\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\xbb\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7\xe1\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x84\x41\x04\x8b\xd2\xae\xb9\xcb\x7e\x57\xcb\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde\x27\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd\x9a\xce\x32\x62\x54\x7e\xf8\x35\xc3\xda\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9\xc2\x77\x45\x13\x2d\xed\x8e\x54\x5c\x1d\x54\xc7\x2f\x04\x69\x97\x85\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x71\x8c\x39\x7a\xa3\xb5\x61\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7\x86\x41\x04\x33\x47\xec\xf9\x6f\xfb\x4b\xd9\xb8\x55\x4e\xfb\xcc\xfc\x7d\x0b\x24\x2f\x10\x71\xe2\x9b\x4c\x9c\x62\x2c\x79\xe3\x39\xd8\x40\xaf\x67\xbe\xb9\xb9\x12\x69\x22\x65\xd9\xc1\x6c\x62\x57\x3f\x45\x79\xff\xd4\xde\x2d\xe9\x2b\xab\x40\x9d\xd5\xc5\xd4\x82\x44\xa9\xf7\x87\x01\x01\x5f\x20\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\xfe\x0f\x01\xff\xff\x5f\x25\x06\x01\x00\x01\x00\x01\x08\x5f\x24\x06\x01\x03\x01\x00\x01\x08\x5f\x37\x40\x50\x67\x14\x5c\x68\xca\xe9\x52\x0f\x5b\xb3\x48\x17\xf1\xca\x9c\x43\x59\x3d\xb5\x64\x06\xc6\xa3\xb0\x06\xcb\xf3\xf3\x14\xe7\x34\x9a\xcf\x0c\xc6\xbf\xeb\xcb\xde\xfd\x10\xb4\xdc\xf0\xf2\x31\xda\x56\x97\x7d\x88\xf9\xf9\x01\x82\xd1\x99\x07\x6a\x56\x50\x64\x51'

    def __generate_cryptoflex(self):
        """Generate the Filesystem and SAM of a cryptoflex card"""
        from virtualsmartcard.cards.cryptoflex import CryptoflexMF, CryptoflexSAM
        self.mf = CryptoflexMF()
        self.mf.append(
            TransparentStructureEF(
                parent=self.mf,
                fid=0x0002,
                filedescriptor=0x01,
                data="\x00\x00\x00\x01\x00\x01\x00\x00"))  #EF.ICCSN
        self.sam = CryptoflexSAM(self.mf)

    def generateCard(self):
        """Generate a new card"""
        if self.type == 'iso7816':
            self.__generate_iso_card()
        elif self.type == 'ePass':
            self.__generate_ePass()
        elif self.type == 'cryptoflex':
            self.__generate_cryptoflex()
        elif self.type == 'nPA':
            self.__generate_nPA()
        else:
            return (None, None)

    def getCard(self):
        """Get the MF and SAM from the current card"""
        if self.sam is None or self.mf is None:
            self.generateCard()
        return self.mf, self.sam

    def setCard(self, mf=None, sam=None):
        """Set the MF and SAM of the current card"""
        if mf != None:
            self.mf = mf
        if sam != None:
            self.sam = sam

    def loadCard(self, filename):
        """Load a card from disk"""
        db = anydbm.open(filename, 'r')

        if self.password is None:
            self.password = getpass.getpass("Please enter your password:"******"mf"], self.password)
        serializedSAM = read_protected_string(db["sam"], self.password)
        self.sam = loads(serializedSAM)
        self.mf = loads(serializedMF)
        self.type = db["type"]

    def saveCard(self, filename):
        """Save the currently running card to disk"""
        if self.password is None:
            passwd1 = getpass.getpass("Please enter your password:"******"Please retype your password:"******"Passwords did not match. Will now exit")
            else:
                self.password = passwd1

        if self.mf == None or self.sam == None:
            raise ValueError("Card Generator wasn't set up properly" +\
                 "(missing MF or SAM).")

        mf_string = dumps(self.mf)
        sam_string = dumps(self.sam)
        protectedMF = protect_string(mf_string, self.password)
        protectedSAM = protect_string(sam_string, self.password)

        db = anydbm.open(filename, 'c')
        db["mf"] = protectedMF
        db["sam"] = protectedSAM
        db["type"] = self.type
        db["version"] = "0.1"
        db.close()

    def readDatagroups(self, datasetfile):
        """Read Datagroups from file"""
        with open(datasetfile, 'r') as f:
            for line in f:
                if (not line.startswith("#")) and (not len(line.strip()) == 0):
                    # spaces after equal sign are allowed to get strings with leading spaces!
                    line = line.replace(" =", "=")
                    splitLine = line.split("=")
                    # we don't want to have the newline char from dataset file as part of the value!!
                    self.datagroups[splitLine[0]] = splitLine[1].rstrip("\n\r")
        f.close()
Example #8
0
    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        for oid_base, x_list, y_list, algo in [
                ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1,5), range(1,5), "PACE"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1,3), range(1,6), "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1],        [6],        "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1,3), range(1,5), "CA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1,3), range(1,6), "RI"),
                ]:
            for oid in [oid_base+chr(x)+chr(y) for x in x_list for y in y_list]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(TransparentStructureEF(parent=self.mf, fid=0x011c, shortfid=0x1c, data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36\x31\x82\x01\x32\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\x04\x02\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05\x27"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011d, shortfid=0x1d, data=card_security))
        ef_dir = '\x61\x32\x4F\x0F\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x50\x0F\x43\x49\x41\x20\x7A\x75\x20\x44\x46\x2E\x65\x53\x69\x67\x6E\x51\x00\x73\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x61\x09\x4F\x07\xA0\x00\x00\x02\x47\x10\x01\x61\x0B\x4F\x09\xE8\x07\x04\x00\x7F\x00\x07\x03\x02\x61\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E'
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x2f00, shortfid=30, data=ef_dir))

        #print 'nPA:', unpack('\x62\x81\x88\x82\x01\x38\x8a\x01\x05\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03')
        #print 'vicc:', unpack('\x62\x15\x83\x02\xff\xff\x8a\x01\x05\x82\x01\x38\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid=DF(parent=self.mf, fid=0xffff, dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid.extra_fci_data = '\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03'
        # FIXME access control for eid application
        DocumentType = self.datagroups["DocumentType"] if "DocumentType" in self.datagroups else 'ID'
        IssuingState = self.datagroups["IssuingState"] if "IssuingState" in self.datagroups else 'DE'
        DateOfExpiry = self.datagroups["DateOfExpiry"] if "DateOfExpiry" in self.datagroups else '20201031'
        GivenNames = self.datagroups["GivenNames"] if "GivenNames" in self.datagroups else 'ERIKA'
        FamilyNames = self.datagroups["FamilyNames"] if "FamilyNames" in self.datagroups else 'MUSTERMANN'
        ReligiousArtisticName = self.datagroups["ReligiousArtisticName"] if "ReligiousArtisticName" in self.datagroups else ''
        AcademicTitle = self.datagroups["AcademicTitle"] if "AcademicTitle" in self.datagroups else ''
        DateOfBirth = self.datagroups["DateOfBirth"] if "DateOfBirth" in self.datagroups else '19640812'
        PlaceOfBirth = self.datagroups["PlaceOfBirth"] if "PlaceOfBirth" in self.datagroups else 'BERLIN'
        Nationality = self.datagroups["Nationality"] if "Nationality" in self.datagroups else 'DE'
        Sex = self.datagroups["Sex"] if "Sex" in self.datagroups else 'F'
        Country = self.datagroups["Country"] if "Country" in self.datagroups else 'D'
        City = self.datagroups["City"] if "City" in self.datagroups else 'KOLN'
        ZIP = self.datagroups["ZIP"] if "ZIP" in self.datagroups else '51147'
        Street = self.datagroups["Street"] if "Street" in self.datagroups else 'HEIDESTRASSE 17'
        CommunityID = eval(self.datagroups["CommunityID"])  if "CommunityID" in self.datagroups else '\x12\x34\x56\x78\x90\x12\x34'
        dg1 =  pack([(0x61, 0, [(0x13, 0, DocumentType)])], True)
        dg2 =  pack([(0x62, 0, [(0x13, 0, IssuingState)])], True)
        dg3 =  pack([(0x63, 0, [(0x12, 0, DateOfExpiry)])], True)
        dg4 =  pack([(0x64, 0, [(0x0C, 0, GivenNames)])], True)
        dg5 =  pack([(0x65, 0, [(0x0C, 0, FamilyNames)])], True)
        dg6 =  pack([(0x66, 0, [(0x0C, 0, ReligiousArtisticName)])], True)
        dg7 =  pack([(0x67, 0, [(0x0C, 0, AcademicTitle)])], True)
        dg8 =  pack([(0x68, 0, [(0x12, 0, DateOfBirth)])], True)
        dg9 =  pack([(0x69, 0, [(0xA1, 0, [(0x0C, 0, PlaceOfBirth)])])], True)
        dg10 = pack([(0x6A, 0, [(0x13, 0, Nationality)])], True)
        dg11 = pack([(0x6B, 0, [(0x13, 0, Sex)])], True)
        dg12 = self.datagroups["dg12"] if "dg12" in self.datagroups else ''
        dg13 = self.datagroups["dg13"] if "dg13" in self.datagroups else ''
        dg14 = self.datagroups["dg14"] if "dg14" in self.datagroups else ''
        dg15 = self.datagroups["dg15"] if "dg15" in self.datagroups else ''
        dg16 = self.datagroups["dg16"] if "dg16" in self.datagroups else ''
        dg17 = pack([(0x71, 0, [(0x30, 0, [
                (0xAA, 0, [(0x0C, 0, Street)]),
                (0xAB, 0, [(0x0C, 0, City)]),
                (0xAD, 0, [(0x13, 0, Country)]),
                (0xAE, 0, [(0x13, 0, ZIP)])
                ])])], True)
        dg18 = pack([(0x72, 0, [(0x04, 0, CommunityID)])], True)
        dg19 = self.datagroups["dg19"] if "dg19" in self.datagroups else ''
        dg20 = self.datagroups["dg20"] if "dg20" in self.datagroups else ''
        dg21 = self.datagroups["dg21"] if "dg21" in self.datagroups else ''
        eid.append(TransparentStructureEF(parent=eid, fid=0x0101, shortfid=0x01, data=dg1))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0102, shortfid=0x02, data=dg2))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0103, shortfid=0x03, data=dg3))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0104, shortfid=0x04, data=dg4))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0105, shortfid=0x05, data=dg5))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0106, shortfid=0x06, data=dg6))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0107, shortfid=0x07, data=dg7))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0108, shortfid=0x08, data=dg8))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0109, shortfid=0x09, data=dg9))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010a, shortfid=0x0a, data=dg10))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010b, shortfid=0x0b, data=dg11))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010c, shortfid=0x0c, data=dg12))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010d, shortfid=0x0d, data=dg13))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010e, shortfid=0x0e, data=dg14))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010f, shortfid=0x0f, data=dg15))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0110, shortfid=0x10, data=dg16))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0111, shortfid=0x11, data=dg17))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0112, shortfid=0x12, data=dg18))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0113, shortfid=0x13, data=dg19))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0114, shortfid=0x14, data=dg20))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0115, shortfid=0x15, data=dg21))
        self.mf.append(eid)

        self.sam = nPA_SAM(pin="111111", can="222222", mrz="IDD<<T220001293<<<<<<<<<<<<<<<6408125<2010315D<<<<<<<<<<<<<<MUSTERMANN<<ERIKA<<<<<<<<<<<<<", puk="3333333333", mf=self.mf)
        # FIXME add CVCA for inspection systems and signature terminals. Here we only add the eID CVCA.
        self.sam.current_SE.cvca = '\x7f\x21\x82\x01\xb6\x7f\x4e\x82\x01\x6e\x5f\x29\x01\x00\x42\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x49\x82\x01\x1d\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x02\x02\x03\x81\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5\x26\x20\x28\x20\x13\x48\x1d\x1f\x6e\x53\x77\x82\x20\x7d\x5a\x09\x75\xfc\x2c\x30\x57\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb\x80\x55\xc1\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\x83\x20\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\xbb\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7\xe1\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x84\x41\x04\x8b\xd2\xae\xb9\xcb\x7e\x57\xcb\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde\x27\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd\x9a\xce\x32\x62\x54\x7e\xf8\x35\xc3\xda\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9\xc2\x77\x45\x13\x2d\xed\x8e\x54\x5c\x1d\x54\xc7\x2f\x04\x69\x97\x85\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x71\x8c\x39\x7a\xa3\xb5\x61\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7\x86\x41\x04\x33\x47\xec\xf9\x6f\xfb\x4b\xd9\xb8\x55\x4e\xfb\xcc\xfc\x7d\x0b\x24\x2f\x10\x71\xe2\x9b\x4c\x9c\x62\x2c\x79\xe3\x39\xd8\x40\xaf\x67\xbe\xb9\xb9\x12\x69\x22\x65\xd9\xc1\x6c\x62\x57\x3f\x45\x79\xff\xd4\xde\x2d\xe9\x2b\xab\x40\x9d\xd5\xc5\xd4\x82\x44\xa9\xf7\x87\x01\x01\x5f\x20\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\xfe\x0f\x01\xff\xff\x5f\x25\x06\x01\x00\x01\x00\x01\x08\x5f\x24\x06\x01\x03\x01\x00\x01\x08\x5f\x37\x40\x50\x67\x14\x5c\x68\xca\xe9\x52\x0f\x5b\xb3\x48\x17\xf1\xca\x9c\x43\x59\x3d\xb5\x64\x06\xc6\xa3\xb0\x06\xcb\xf3\xf3\x14\xe7\x34\x9a\xcf\x0c\xc6\xbf\xeb\xcb\xde\xfd\x10\xb4\xdc\xf0\xf2\x31\xda\x56\x97\x7d\x88\xf9\xf9\x01\x82\xd1\x99\x07\x6a\x56\x50\x64\x51'
Example #9
0
    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        for oid_base, x_list, y_list, algo in [
            ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1,
                                                       5), range(1,
                                                                 5), "PACE"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1, 3), range(1,
                                                                    6), "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1], [6], "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1, 3), range(1,
                                                                    5), "CA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1, 3), range(1,
                                                                    6), "RI"),
        ]:
            for oid in [
                    oid_base + chr(x) + chr(y) for x in x_list for y in y_list
            ]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(
            TransparentStructureEF(parent=self.mf,
                                   fid=0x011c,
                                   shortfid=0x1c,
                                   data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36\x31\x82\x01\x32\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\x04\x02\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05\x27"
        self.mf.append(
            TransparentStructureEF(parent=self.mf,
                                   fid=0x011d,
                                   shortfid=0x1d,
                                   data=card_security))
        ef_dir = '\x61\x32\x4F\x0F\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x50\x0F\x43\x49\x41\x20\x7A\x75\x20\x44\x46\x2E\x65\x53\x69\x67\x6E\x51\x00\x73\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x61\x09\x4F\x07\xA0\x00\x00\x02\x47\x10\x01\x61\x0B\x4F\x09\xE8\x07\x04\x00\x7F\x00\x07\x03\x02\x61\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E'
        self.mf.append(
            TransparentStructureEF(parent=self.mf,
                                   fid=0x2f00,
                                   shortfid=30,
                                   data=ef_dir))

        #print 'nPA:', unpack('\x62\x81\x88\x82\x01\x38\x8a\x01\x05\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03')
        #print 'vicc:', unpack('\x62\x15\x83\x02\xff\xff\x8a\x01\x05\x82\x01\x38\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid = DF(parent=self.mf,
                 fid=0xffff,
                 dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid.extra_fci_data = '\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03'
        # FIXME access control for eid application

        DocumentType = self.datagroups[
            "DocumentType"] if "DocumentType" in self.datagroups else 'ID'
        IssuingState = self.datagroups[
            "IssuingState"] if "IssuingState" in self.datagroups else 'D'
        DateOfExpiry = self.datagroups[
            "DateOfExpiry"] if "DateOfExpiry" in self.datagroups else '20201031'
        GivenNames = self.datagroups[
            "GivenNames"] if "GivenNames" in self.datagroups else 'ERIKA'
        FamilyNames = self.datagroups[
            "FamilyNames"] if "FamilyNames" in self.datagroups else 'MUSTERMANN'
        ReligiousArtisticName = self.datagroups[
            "ReligiousArtisticName"] if "ReligiousArtisticName" in self.datagroups else ''
        AcademicTitle = self.datagroups[
            "AcademicTitle"] if "AcademicTitle" in self.datagroups else ''
        DateOfBirth = self.datagroups[
            "DateOfBirth"] if "DateOfBirth" in self.datagroups else '19640812'
        PlaceOfBirth = self.datagroups[
            "PlaceOfBirth"] if "PlaceOfBirth" in self.datagroups else 'BERLIN'
        Nationality = self.datagroups[
            "Nationality"] if "Nationality" in self.datagroups else 'DE'
        Sex = self.datagroups["Sex"] if "Sex" in self.datagroups else 'F'
        BirthName = self.datagroups[
            "BirthName"] if "BirthName" in self.datagroups else 'Mein Geburtsname'
        # PlaceOfResidence variable is only a helper to get a switch for <NotOnChip>
        PlaceOfResidence = self.datagroups[
            "PlaceOfResidence"] if "PlaceOfResidence" in self.datagroups else ''
        Country = self.datagroups[
            "Country"] if "Country" in self.datagroups else 'D'
        City = self.datagroups["City"] if "City" in self.datagroups else 'KOLN'
        ZIP = self.datagroups["ZIP"] if "ZIP" in self.datagroups else '51147'
        Street = self.datagroups[
            "Street"] if "Street" in self.datagroups else 'HEIDESTRASSE 17'
        CommunityID = eval(
            self.datagroups["CommunityID"]
        ) if "CommunityID" in self.datagroups else '\x02\x76\x03\x78\x90\x02\x76'
        # ResidencePermit1 and ResidencePermit2 are part of eAT only
        ResidencePermit1 = self.datagroups[
            "ResidencePermit1"] if "ResidencePermit1" in self.datagroups else 'ResidencePermit1 field up to 750 characters'
        ResidencePermit2 = self.datagroups[
            "ResidencePermit2"] if "ResidencePermit2" in self.datagroups else 'ResidencePermit1 field up to 250 characters'

        # Currently, those data groups are for further usage:
        dg12_param = self.datagroups[
            "dg12"] if "dg12" in self.datagroups else ''
        dg14_param = self.datagroups[
            "dg14"] if "dg14" in self.datagroups else ''
        dg15_param = self.datagroups[
            "dg15"] if "dg15" in self.datagroups else ''
        dg16_param = self.datagroups[
            "dg16"] if "dg16" in self.datagroups else ''
        dg21_param = self.datagroups[
            "dg21"] if "dg21" in self.datagroups else ''

        # "Attribute not on Chip" makes sence only for ReligiousArtisticName, Nationality, BirthName, ResidencePermit1 and ResidencePermit2, refer to BSI TR-03127
        if (DocumentType.rstrip() != "<NotOnChip>"):
            dg1 = pack([(0x61, 0, [(0x13, 0, DocumentType)])], True)
        else:
            dg1 = None
        if (IssuingState.rstrip() != "<NotOnChip>"):
            dg2 = pack([(0x62, 0, [(0x13, 0, IssuingState)])], True)
        else:
            dg2 = None
        if (DateOfExpiry.rstrip() != "<NotOnChip>"):
            dg3 = pack([(0x63, 0, [(0x12, 0, DateOfExpiry)])], True)
        else:
            dg3 = None
        if (GivenNames.rstrip() != "<NotOnChip>"):
            dg4 = pack([(0x64, 0, [(0x0C, 0, GivenNames)])], True)
        else:
            dg4 = None
        if (FamilyNames.rstrip() != "<NotOnChip>"):
            dg5 = pack([(0x65, 0, [(0x0C, 0, FamilyNames)])], True)
        else:
            dg5 = None
        if (ReligiousArtisticName.rstrip() != "<NotOnChip>"):
            dg6 = pack([(0x66, 0, [(0x0C, 0, ReligiousArtisticName)])], True)
        else:
            dg6 = None
        if (AcademicTitle.rstrip() != "<NotOnChip>"):
            dg7 = pack([(0x67, 0, [(0x0C, 0, AcademicTitle)])], True)
        else:
            dg7 = None
        if (DateOfBirth.rstrip() != "<NotOnChip>"):
            dg8 = pack([(0x68, 0, [(0x12, 0, DateOfBirth)])], True)
        else:
            dg8 = None
        if (PlaceOfBirth.rstrip() != "<NotOnChip>"):
            dg9 = pack([(0x69, 0, [(0xA1, 0, [(0x0C, 0, PlaceOfBirth)])])],
                       True)
        else:
            dg9 = None
        if (Nationality.rstrip() != "<NotOnChip>"):
            dg10 = pack([(0x6A, 0, [(0x13, 0, Nationality)])], True)
        else:
            dg10 = None
        if (Sex.rstrip() != "<NotOnChip>"):
            dg11 = pack([(0x6B, 0, [(0x13, 0, Sex)])], True)
        else:
            dg11 = None
        if (dg12_param.rstrip() != "<NotOnChip>"):
            dg12 = dg12_param
        else:
            dg12 = None
        if (BirthName.rstrip() != "<NotOnChip>"):
            dg13 = pack([(0x6D, 0, [(0x0C, 0, BirthName)])], True)
        else:
            dg13 = None
        if (dg14_param.rstrip() != "<NotOnChip>"):
            dg14 = dg14_param
        else:
            dg14 = None
        if (dg15_param.rstrip() != "<NotOnChip>"):
            dg15 = dg15_param
        else:
            dg15 = None
        if (dg16_param.rstrip() != "<NotOnChip>"):
            dg16 = dg16_param
        else:
            dg16 = None
        if (PlaceOfResidence.rstrip() != "<NotOnChip>"):
            dg17 = pack(
                [(0x71, 0, [(0x30, 0, [(0xAA, 0, [(0x0C, 0, Street)]),
                                       (0xAB, 0, [(0x0C, 0, City)]),
                                       (0xAD, 0, [(0x13, 0, Country)]),
                                       (0xAE, 0, [(0x13, 0, ZIP)])])])], True)
        else:
            dg17 = None
#FIXME: Dataset file with CommunityID =<NotOnChip> still not works while assigning of non hex value due to eval()
        if (CommunityID.rstrip() != "<NotOnChip>"):
            dg18 = pack([(0x72, 0, [(0x04, 0, CommunityID)])], True)
        else:
            dg18 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
            dg19 = pack(
                [(0x73, 0, [(0xA1, 0, [(0x0C, 0, ResidencePermit1)])])], True)
        else:
            dg19 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
            dg20 = pack(
                [(0x74, 0, [(0xA1, 0, [(0x0C, 0, ResidencePermit2)])])], True)
        else:
            dg20 = None
        if (dg21_param.rstrip() != "<NotOnChip>"):
            dg21 = dg21_param
        else:
            dg21 = None

# If eid.append is not done for a DG, it results into required SwError() with FileNotFound "6A82" APDU return code
        if dg1:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0101,
                                       shortfid=0x01,
                                       data=dg1))
        if dg2:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0102,
                                       shortfid=0x02,
                                       data=dg2))
        if dg3:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0103,
                                       shortfid=0x03,
                                       data=dg3))
        if dg4:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0104,
                                       shortfid=0x04,
                                       data=dg4))
        if dg5:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0105,
                                       shortfid=0x05,
                                       data=dg5))
        if dg6:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0106,
                                       shortfid=0x06,
                                       data=dg6))
        if dg7:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0107,
                                       shortfid=0x07,
                                       data=dg7))
        if dg8:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0108,
                                       shortfid=0x08,
                                       data=dg8))
        if dg9:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0109,
                                       shortfid=0x09,
                                       data=dg9))
        if dg10:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010a,
                                       shortfid=0x0a,
                                       data=dg10))
        if dg11:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010b,
                                       shortfid=0x0b,
                                       data=dg11))
        if dg12:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010c,
                                       shortfid=0x0c,
                                       data=dg12))
        if dg13:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010d,
                                       shortfid=0x0d,
                                       data=dg13))
        if dg14:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010e,
                                       shortfid=0x0e,
                                       data=dg14))
        if dg15:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x010f,
                                       shortfid=0x0f,
                                       data=dg15))
        if dg16:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0110,
                                       shortfid=0x10,
                                       data=dg16))
        if dg17:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0111,
                                       shortfid=0x11,
                                       data=dg17))
        if dg18:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0112,
                                       shortfid=0x12,
                                       data=dg18))
        if dg19:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0113,
                                       shortfid=0x13,
                                       data=dg19))
        if dg20:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0114,
                                       shortfid=0x14,
                                       data=dg20))
        if dg21:
            eid.append(
                TransparentStructureEF(parent=eid,
                                       fid=0x0115,
                                       shortfid=0x15,
                                       data=dg21))
        self.mf.append(eid)

        self.sam = nPA_SAM(
            pin="111111",
            can="222222",
            mrz=
            "IDD<<T220001293<<<<<<<<<<<<<<<6408125<2010315D<<<<<<<<<<<<<<MUSTERMANN<<ERIKA<<<<<<<<<<<<<",
            puk="3333333333",
            mf=self.mf)
        # FIXME add CVCA for inspection systems and signature terminals. Here we only add the eID CVCA.
        self.sam.current_SE.cvca = '\x7f\x21\x82\x01\xb6\x7f\x4e\x82\x01\x6e\x5f\x29\x01\x00\x42\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x49\x82\x01\x1d\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x02\x02\x03\x81\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5\x26\x20\x28\x20\x13\x48\x1d\x1f\x6e\x53\x77\x82\x20\x7d\x5a\x09\x75\xfc\x2c\x30\x57\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb\x80\x55\xc1\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\x83\x20\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\xbb\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7\xe1\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x84\x41\x04\x8b\xd2\xae\xb9\xcb\x7e\x57\xcb\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde\x27\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd\x9a\xce\x32\x62\x54\x7e\xf8\x35\xc3\xda\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9\xc2\x77\x45\x13\x2d\xed\x8e\x54\x5c\x1d\x54\xc7\x2f\x04\x69\x97\x85\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x71\x8c\x39\x7a\xa3\xb5\x61\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7\x86\x41\x04\x33\x47\xec\xf9\x6f\xfb\x4b\xd9\xb8\x55\x4e\xfb\xcc\xfc\x7d\x0b\x24\x2f\x10\x71\xe2\x9b\x4c\x9c\x62\x2c\x79\xe3\x39\xd8\x40\xaf\x67\xbe\xb9\xb9\x12\x69\x22\x65\xd9\xc1\x6c\x62\x57\x3f\x45\x79\xff\xd4\xde\x2d\xe9\x2b\xab\x40\x9d\xd5\xc5\xd4\x82\x44\xa9\xf7\x87\x01\x01\x5f\x20\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\xfe\x0f\x01\xff\xff\x5f\x25\x06\x01\x00\x01\x00\x01\x08\x5f\x24\x06\x01\x03\x01\x00\x01\x08\x5f\x37\x40\x50\x67\x14\x5c\x68\xca\xe9\x52\x0f\x5b\xb3\x48\x17\xf1\xca\x9c\x43\x59\x3d\xb5\x64\x06\xc6\xa3\xb0\x06\xcb\xf3\xf3\x14\xe7\x34\x9a\xcf\x0c\xc6\xbf\xeb\xcb\xde\xfd\x10\xb4\xdc\xf0\xf2\x31\xda\x56\x97\x7d\x88\xf9\xf9\x01\x82\xd1\x99\x07\x6a\x56\x50\x64\x51'
Example #10
0
class CardGenerator(object):
    """This class is used to generate the SAM and filesystem for the 
    different supported card types. It is also able used for persistent storage
    (in encrypted form) of the card on disks. """
    
    def __init__(self, card_type=None, sam=None, mf=None):
        self.type = card_type
        self.mf = mf
        self.sam = sam
        self.password = None
    
    def __generate_iso_card(self):
        default_pin = "1234"
        default_cardno = "1234567890"
        
        logging.warning("Using default SAM parameters. PIN=%s, Card Nr=%s"
                        % (default_pin, default_cardno))
        #TODO: Use user provided data
        self.sam = SAM(default_pin, default_cardno)
        
        self.mf = MF(filedescriptor=FDB["DF"])
        self.sam.set_MF(self.mf)
           
    def __generate_ePass(self):
        """Generate the MF and SAM of an ICAO passport. This method is 
        responsible for generating the filesystem and filling it with content.
        Therefore it must interact with the user by prompting for the MRZ and
        optionally for the path to a photo."""
        from PIL import Image
        from virtualsmartcard.cards.ePass import PassportSAM
            
        #TODO: Sanity checks
        MRZ = raw_input("Please enter the MRZ as one string: ")

        readline.set_completer_delims("")
        readline.parse_and_bind("tab: complete")
        
        picturepath = raw_input("Please enter the path to an image: ")
        picturepath = picturepath.strip()
        
        #MRZ1 = "P<UTOERIKSSON<<ANNA<MARIX<<<<<<<<<<<<<<<<<<<"
        #MRZ2 = "L898902C<3UTO6908061F9406236ZE184226B<<<<<14"
        #MRZ = MRZ1 + MRZ2        

        try:
            im = Image.open(picturepath)
            pic_width, pic_height = im.size
            fd = open(picturepath,"rb")
            picture = fd.read()
            fd.close()
        except IOError:
            logging.warning("Failed to open file: " + picturepath)
            pic_width = 0
            pic_height = 0
            picture = None  

        mf = MF()
        
        #We need a MF with Application DF \xa0\x00\x00\x02G\x10\x01
        df = DF(parent=mf, fid=4, dfname='\xa0\x00\x00\x02G\x10\x01',
                bertlv_data=[])

        #EF.COM
        COM = pack([(0x5F01, 4, "0107"), (0x5F36, 6, "040000"),
                    (0x5C, 2, "6175")])
        COM = pack(((0x60, len(COM), COM),))
        df.append(TransparentStructureEF(parent=df, fid=0x011E,
                  filedescriptor=0, data=COM))

        #EF.DG1
        DG1 = pack([(0x5F1F, len(MRZ), MRZ)])
        DG1 = pack([(0x61, len(DG1), DG1)])
        df.append(TransparentStructureEF(parent=df, fid=0x0101,
                  filedescriptor=0, data=DG1))

        #EF.DG2
        if picture != None:
            IIB = "\x00\x01" + inttostring(pic_width, 2) +\
                    inttostring(pic_height, 2) + 6 * "\x00" 
            length = 32 + len(picture) #32 is the length of IIB + FIB
            FIB = inttostring(length, 4) + 16 * "\x00"
            FRH = "FAC" + "\x00" + "010" + "\x00" +\
                    inttostring(14 + length, 4) + inttostring(1, 2)
            picture = FRH + FIB + IIB + picture
            DG2 = pack([(0xA1, 8, "\x87\x02\x01\x01\x88\x02\x05\x01"), 
                    (0x5F2E, len(picture), picture)])
            DG2 = pack([(0x02, 1, "\x01"), (0x7F60, len(DG2), DG2)])
            DG2 = pack([(0x7F61, len(DG2), DG2)])
        else:
            DG2 = ""
        df.append(TransparentStructureEF(parent=df, fid=0x0102,
                  filedescriptor=0, data=DG2))

        #EF.SOD
        df.append(TransparentStructureEF(parent=df, fid=0x010D,
                  filedescriptor=0, data=""))

        mf.append(df)

        self.mf = mf
        self.sam = PassportSAM(self.mf)
    
    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        for oid_base, x_list, y_list, algo in [
                ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1,5), range(1,5), "PACE"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1,3), range(1,6), "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1],        [6],        "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1,3), range(1,5), "CA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1,3), range(1,6), "RI"),
                ]:
            for oid in [oid_base+chr(x)+chr(y) for x in x_list for y in y_list]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(TransparentStructureEF(parent=self.mf, fid=0x011c, shortfid=0x1c, data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36\x31\x82\x01\x32\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\x04\x02\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05\x27"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011d, shortfid=0x1d, data=card_security))

        eid=DF(parent=self.mf, fid=0xffff, dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        # FIXME access control for eid application
        dg1 = ''
        dg2 = ''
        dg3 = ''
        dg4 = ''
        dg5 = ''
        dg6 = ''
        dg7 = ''
        dg8 = ''
        dg9 = ''
        dg10 = ''
        dg11 = ''
        dg12 = ''
        dg13 = ''
        dg14 = ''
        dg15 = ''
        dg16 = ''
        dg17 = ''
        dg18 = ''
        dg19 = ''
        dg20 = ''
        dg21 = ''
        eid.append(TransparentStructureEF(parent=eid, fid=0x0101, shortfid=0x01, data=dg1))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0102, shortfid=0x02, data=dg2))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0103, shortfid=0x03, data=dg3))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0104, shortfid=0x04, data=dg4))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0105, shortfid=0x05, data=dg5))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0106, shortfid=0x06, data=dg6))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0107, shortfid=0x07, data=dg7))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0108, shortfid=0x08, data=dg8))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0109, shortfid=0x09, data=dg9))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010a, shortfid=0x0a, data=dg10))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010b, shortfid=0x0b, data=dg11))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010c, shortfid=0x0c, data=dg12))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010d, shortfid=0x0d, data=dg13))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010e, shortfid=0x0e, data=dg14))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010f, shortfid=0x0f, data=dg15))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0110, shortfid=0x10, data=dg16))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0111, shortfid=0x11, data=dg17))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0112, shortfid=0x12, data=dg18))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0113, shortfid=0x13, data=dg19))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0114, shortfid=0x14, data=dg20))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0115, shortfid=0x15, data=dg21))
        self.mf.append(eid)

        self.sam = nPA_SAM(pin="111111", can="222222", mrz="mrz", puk="puk", mf=self.mf)

    def __generate_cryptoflex(self):
        """Generate the Filesystem and SAM of a cryptoflex card"""
        from virtualsmartcard.cards.cryptoflex import CryptoflexMF, CryptoflexSAM
        self.mf = CryptoflexMF()
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x0002,
                       filedescriptor=0x01,
                       data="\x00\x00\x00\x01\x00\x01\x00\x00")) #EF.ICCSN
        self.sam = CryptoflexSAM(self.mf)
        
    def generateCard(self):
        """Generate a new card"""
        if self.type == 'iso7816':
            self.__generate_iso_card()
        elif self.type == 'ePass':
            self.__generate_ePass()
        elif self.type == 'cryptoflex':
            self.__generate_cryptoflex()
        elif self.type == 'nPA':
            self.__generate_nPA()
        else:
            return (None, None)
    
    def getCard(self):
        """Get the MF and SAM from the current card"""
        if self.sam is None or self.mf is None:
            self.generateCard()
        return self.mf, self.sam
    
    def setCard(self, mf=None, sam=None):
        """Set the MF and SAM of the current card"""
        if mf != None:
            self.mf = mf
        if sam != None:
            self.sam = sam
        
    
    def loadCard(self, filename):
        """Load a card from disk"""
        db = anydbm.open(filename, 'r')
        
        if self.password is None:
            self.password = getpass.getpass("Please enter your password:"******"mf"], self.password)
        serializedSAM = read_protected_string(db["sam"], self.password)
        self.sam = loads(serializedSAM)
        self.mf = loads(serializedMF)
        self.type = db["type"]
            
    def saveCard(self, filename):
        """Save the currently running card to disk"""
        if self.password is None:
            passwd1 = getpass.getpass("Please enter your password:"******"Please retype your password:"******"Passwords did not match. Will now exit")
            else:
                self.password = passwd1
        
        if self.mf == None or self.sam == None:
            raise ValueError("Card Generator wasn't set up properly" +\
                 "(missing MF or SAM).")
        
        mf_string = dumps(self.mf)
        sam_string = dumps(self.sam)
        protectedMF = protect_string(mf_string, self.password)
        protectedSAM = protect_string(sam_string, self.password)
        
        db = anydbm.open(filename, 'c')
        db["mf"] = protectedMF
        db["sam"] = protectedSAM
        db["type"] = self.type
        db["version"] = "0.1"
        db.close()
Example #11
0
    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        for oid_base, x_list, y_list, algo in [
                ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1,5), range(1,5), "PACE"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1,3), range(1,6), "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1],        [6],        "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1,3), range(1,5), "CA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1,3), range(1,6), "RI"),
                ]:
            for oid in [oid_base+chr(x)+chr(y) for x in x_list for y in y_list]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(TransparentStructureEF(parent=self.mf, fid=0x011c, shortfid=0x1c, data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36\x31\x82\x01\x32\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\x04\x02\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05\x27"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011d, shortfid=0x1d, data=card_security))

        eid=DF(parent=self.mf, fid=0xffff, dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        # FIXME access control for eid application
        dg1 = ''
        dg2 = ''
        dg3 = ''
        dg4 = ''
        dg5 = ''
        dg6 = ''
        dg7 = ''
        dg8 = ''
        dg9 = ''
        dg10 = ''
        dg11 = ''
        dg12 = ''
        dg13 = ''
        dg14 = ''
        dg15 = ''
        dg16 = ''
        dg17 = ''
        dg18 = ''
        dg19 = ''
        dg20 = ''
        dg21 = ''
        eid.append(TransparentStructureEF(parent=eid, fid=0x0101, shortfid=0x01, data=dg1))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0102, shortfid=0x02, data=dg2))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0103, shortfid=0x03, data=dg3))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0104, shortfid=0x04, data=dg4))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0105, shortfid=0x05, data=dg5))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0106, shortfid=0x06, data=dg6))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0107, shortfid=0x07, data=dg7))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0108, shortfid=0x08, data=dg8))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0109, shortfid=0x09, data=dg9))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010a, shortfid=0x0a, data=dg10))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010b, shortfid=0x0b, data=dg11))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010c, shortfid=0x0c, data=dg12))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010d, shortfid=0x0d, data=dg13))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010e, shortfid=0x0e, data=dg14))
        eid.append(TransparentStructureEF(parent=eid, fid=0x010f, shortfid=0x0f, data=dg15))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0110, shortfid=0x10, data=dg16))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0111, shortfid=0x11, data=dg17))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0112, shortfid=0x12, data=dg18))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0113, shortfid=0x13, data=dg19))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0114, shortfid=0x14, data=dg20))
        eid.append(TransparentStructureEF(parent=eid, fid=0x0115, shortfid=0x15, data=dg21))
        self.mf.append(eid)

        self.sam = nPA_SAM(pin="111111", can="222222", mrz="mrz", puk="puk", mf=self.mf)
Example #12
0
    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        for oid_base, x_list, y_list, algo in [
                ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1,5), range(1,5), "PACE"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1,3), range(1,6), "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1],        [6],        "TA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1,3), range(1,5), "CA"),
                ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1,3), range(1,6), "RI"),
                ]:
            for oid in [oid_base+chr(x)+chr(y) for x in x_list for y in y_list]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(TransparentStructureEF(parent=self.mf, fid=0x011c, shortfid=0x1c, data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36\x31\x82\x01\x32\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\x04\x02\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05\x27"
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011d, shortfid=0x1d, data=card_security))
        ef_dir = '\x61\x32\x4F\x0F\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x50\x0F\x43\x49\x41\x20\x7A\x75\x20\x44\x46\x2E\x65\x53\x69\x67\x6E\x51\x00\x73\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E\x61\x09\x4F\x07\xA0\x00\x00\x02\x47\x10\x01\x61\x0B\x4F\x09\xE8\x07\x04\x00\x7F\x00\x07\x03\x02\x61\x0C\x4F\x0A\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E'
        self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x2f00, shortfid=30, data=ef_dir))

        #print 'nPA:', unpack('\x62\x81\x88\x82\x01\x38\x8a\x01\x05\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03')
        #print 'vicc:', unpack('\x62\x15\x83\x02\xff\xff\x8a\x01\x05\x82\x01\x38\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid=DF(parent=self.mf, fid=0xffff, dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid.extra_fci_data = '\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03'
        # FIXME access control for eid application

        DocumentType = self.datagroups["DocumentType"] if "DocumentType" in self.datagroups else 'ID'
        IssuingState = self.datagroups["IssuingState"] if "IssuingState" in self.datagroups else 'D'
        DateOfExpiry = self.datagroups["DateOfExpiry"] if "DateOfExpiry" in self.datagroups else '20201031'
        GivenNames = self.datagroups["GivenNames"] if "GivenNames" in self.datagroups else 'ERIKA'
        FamilyNames = self.datagroups["FamilyNames"] if "FamilyNames" in self.datagroups else 'MUSTERMANN'
        ReligiousArtisticName = self.datagroups["ReligiousArtisticName"] if "ReligiousArtisticName" in self.datagroups else ''
        AcademicTitle = self.datagroups["AcademicTitle"] if "AcademicTitle" in self.datagroups else ''
        DateOfBirth = self.datagroups["DateOfBirth"] if "DateOfBirth" in self.datagroups else '19640812'
        PlaceOfBirth = self.datagroups["PlaceOfBirth"] if "PlaceOfBirth" in self.datagroups else 'BERLIN'
        Nationality = self.datagroups["Nationality"] if "Nationality" in self.datagroups else 'DE'
        Sex = self.datagroups["Sex"] if "Sex" in self.datagroups else 'F'
        BirthName = self.datagroups["BirthName"] if "BirthName" in self.datagroups else 'Mein Geburtsname'
        # PlaceOfResidence variable is only a helper to get a switch for <NotOnChip>
        PlaceOfResidence = self.datagroups["PlaceOfResidence"] if "PlaceOfResidence" in self.datagroups else ''
        Country = self.datagroups["Country"] if "Country" in self.datagroups else 'D'
        City = self.datagroups["City"] if "City" in self.datagroups else 'KOLN'
        ZIP = self.datagroups["ZIP"] if "ZIP" in self.datagroups else '51147'
        Street = self.datagroups["Street"] if "Street" in self.datagroups else 'HEIDESTRASSE 17'
        CommunityID = eval(self.datagroups["CommunityID"]) if "CommunityID" in self.datagroups else '\x02\x76\x03\x78\x90\x02\x76'
        # ResidencePermit1 and ResidencePermit2 are part of eAT only
        ResidencePermit1 = self.datagroups["ResidencePermit1"] if "ResidencePermit1" in self.datagroups else 'ResidencePermit1 field up to 750 characters'
        ResidencePermit2 = self.datagroups["ResidencePermit2"] if "ResidencePermit2" in self.datagroups else 'ResidencePermit1 field up to 250 characters'

        # Currently, those data groups are for further usage:
        dg12_param = self.datagroups["dg12"] if "dg12" in self.datagroups else ''
        dg14_param = self.datagroups["dg14"] if "dg14" in self.datagroups else ''
        dg15_param = self.datagroups["dg15"] if "dg15" in self.datagroups else ''
        dg16_param = self.datagroups["dg16"] if "dg16" in self.datagroups else ''
        dg21_param = self.datagroups["dg21"] if "dg21" in self.datagroups else ''

	# "Attribute not on Chip" makes sence only for ReligiousArtisticName, Nationality, BirthName, ResidencePermit1 and ResidencePermit2, refer to BSI TR-03127
        if (DocumentType.rstrip() != "<NotOnChip>"):
	        dg1 =  pack([(0x61, 0, [(0x13, 0, DocumentType)])], True)
        else:
	        dg1 = None
        if (IssuingState.rstrip() != "<NotOnChip>"):
		dg2 =  pack([(0x62, 0, [(0x13, 0, IssuingState)])], True)
        else:
		dg2 = None
        if (DateOfExpiry.rstrip() != "<NotOnChip>"):
		dg3 =  pack([(0x63, 0, [(0x12, 0, DateOfExpiry)])], True)
        else:
		dg3 = None
        if (GivenNames.rstrip() != "<NotOnChip>"):
		dg4 =  pack([(0x64, 0, [(0x0C, 0, GivenNames)])], True)
        else:
		dg4 = None
        if (FamilyNames.rstrip() != "<NotOnChip>"):
		dg5 =  pack([(0x65, 0, [(0x0C, 0, FamilyNames)])], True)
        else:
		dg5 = None
        if (ReligiousArtisticName.rstrip() != "<NotOnChip>"):
		dg6 =  pack([(0x66, 0, [(0x0C, 0, ReligiousArtisticName)])], True)
        else:
		dg6 = None
        if (AcademicTitle.rstrip() != "<NotOnChip>"):
		dg7 =  pack([(0x67, 0, [(0x0C, 0, AcademicTitle)])], True)
        else:
		dg7 = None
        if (DateOfBirth.rstrip() != "<NotOnChip>"):
		dg8 =  pack([(0x68, 0, [(0x12, 0, DateOfBirth)])], True)
        else:
		dg8 = None
        if (PlaceOfBirth.rstrip() != "<NotOnChip>"):
		dg9 =  pack([(0x69, 0, [(0xA1, 0, [(0x0C, 0, PlaceOfBirth)])])], True)
        else:
		dg9 = None
        if (Nationality.rstrip() != "<NotOnChip>"):
		dg10 = pack([(0x6A, 0, [(0x13, 0, Nationality)])], True)
        else:
		dg10 = None
        if (Sex.rstrip() != "<NotOnChip>"):
		dg11 = pack([(0x6B, 0, [(0x13, 0, Sex)])], True)
        else:
		dg11 = None
        if (dg12_param.rstrip() != "<NotOnChip>"):
		dg12 = dg12_param
        else:
		dg12 = None
        if (BirthName.rstrip() != "<NotOnChip>"):
		dg13 = pack([(0x6D, 0, [(0x0C, 0, BirthName)])], True)
        else:
		dg13 = None
        if (dg14_param.rstrip() != "<NotOnChip>"):
		dg14 = dg14_param
        else:
		dg14 = None
        if (dg15_param.rstrip() != "<NotOnChip>"):
		dg15 = dg15_param
        else:
		dg15 = None
        if (dg16_param.rstrip() != "<NotOnChip>"):
		dg16 = dg16_param
        else:
		dg16 = None
        if (PlaceOfResidence.rstrip() != "<NotOnChip>"):
		dg17 = pack([(0x71, 0, [(0x30, 0, [
					(0xAA, 0, [(0x0C, 0, Street)]),
					(0xAB, 0, [(0x0C, 0, City)]),
					(0xAD, 0, [(0x13, 0, Country)]),
					(0xAE, 0, [(0x13, 0, ZIP)])
					])])], True)
        else:
		dg17 = None
	#FIXME: Dataset file with CommunityID =<NotOnChip> still not works while assigning of non hex value due to eval()
        if (CommunityID.rstrip() != "<NotOnChip>"):
		dg18 = pack([(0x72, 0, [(0x04, 0, CommunityID)])], True)
        else:
		dg18 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
		dg19 = pack([(0x73, 0, [(0xA1, 0, [(0x0C, 0, ResidencePermit1)])])], True)
        else:
		dg19 = None
        if (ResidencePermit1.rstrip() != "<NotOnChip>"):
		dg20 = pack([(0x74, 0, [(0xA1, 0, [(0x0C, 0, ResidencePermit2)])])], True)
        else:
		dg20 = None
        if (dg21_param.rstrip() != "<NotOnChip>"):
		dg21 = dg21_param
        else:
		dg21 = None

	# If eid.append is not done for a DG, it results into required SwError() with FileNotFound "6A82" APDU return code
        if dg1:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0101, shortfid=0x01, data=dg1))
        if dg2:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0102, shortfid=0x02, data=dg2))
        if dg3:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0103, shortfid=0x03, data=dg3))
        if dg4:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0104, shortfid=0x04, data=dg4))
        if dg5:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0105, shortfid=0x05, data=dg5))
        if dg6:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0106, shortfid=0x06, data=dg6))
        if dg7:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0107, shortfid=0x07, data=dg7))
        if dg8:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0108, shortfid=0x08, data=dg8))
        if dg9:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0109, shortfid=0x09, data=dg9))
        if dg10:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x010a, shortfid=0x0a, data=dg10))
        if dg11:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x010b, shortfid=0x0b, data=dg11))
        if dg12:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x010c, shortfid=0x0c, data=dg12))
        if dg13:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x010d, shortfid=0x0d, data=dg13))
        if dg14:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x010e, shortfid=0x0e, data=dg14))
        if dg15:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x010f, shortfid=0x0f, data=dg15))
        if dg16:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0110, shortfid=0x10, data=dg16))
        if dg17:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0111, shortfid=0x11, data=dg17))
        if dg18:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0112, shortfid=0x12, data=dg18))
        if dg19:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0113, shortfid=0x13, data=dg19))
        if dg20:
        	eid.append(TransparentStructureEF(parent=eid, fid=0x0114, shortfid=0x14, data=dg20))
        if dg21:
		eid.append(TransparentStructureEF(parent=eid, fid=0x0115, shortfid=0x15, data=dg21))
        self.mf.append(eid)

        self.sam = nPA_SAM(pin="111111", can="222222", mrz="IDD<<T220001293<<<<<<<<<<<<<<<6408125<2010315D<<<<<<<<<<<<<<MUSTERMANN<<ERIKA<<<<<<<<<<<<<", puk="3333333333", mf=self.mf)
        # FIXME add CVCA for inspection systems and signature terminals. Here we only add the eID CVCA.
        self.sam.current_SE.cvca = '\x7f\x21\x82\x01\xb6\x7f\x4e\x82\x01\x6e\x5f\x29\x01\x00\x42\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x49\x82\x01\x1d\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x02\x02\x03\x81\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5\x26\x20\x28\x20\x13\x48\x1d\x1f\x6e\x53\x77\x82\x20\x7d\x5a\x09\x75\xfc\x2c\x30\x57\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb\x80\x55\xc1\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\x83\x20\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\xbb\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7\xe1\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x84\x41\x04\x8b\xd2\xae\xb9\xcb\x7e\x57\xcb\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde\x27\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd\x9a\xce\x32\x62\x54\x7e\xf8\x35\xc3\xda\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9\xc2\x77\x45\x13\x2d\xed\x8e\x54\x5c\x1d\x54\xc7\x2f\x04\x69\x97\x85\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x71\x8c\x39\x7a\xa3\xb5\x61\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7\x86\x41\x04\x33\x47\xec\xf9\x6f\xfb\x4b\xd9\xb8\x55\x4e\xfb\xcc\xfc\x7d\x0b\x24\x2f\x10\x71\xe2\x9b\x4c\x9c\x62\x2c\x79\xe3\x39\xd8\x40\xaf\x67\xbe\xb9\xb9\x12\x69\x22\x65\xd9\xc1\x6c\x62\x57\x3f\x45\x79\xff\xd4\xde\x2d\xe9\x2b\xab\x40\x9d\xd5\xc5\xd4\x82\x44\xa9\xf7\x87\x01\x01\x5f\x20\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\xfe\x0f\x01\xff\xff\x5f\x25\x06\x01\x00\x01\x00\x01\x08\x5f\x24\x06\x01\x03\x01\x00\x01\x08\x5f\x37\x40\x50\x67\x14\x5c\x68\xca\xe9\x52\x0f\x5b\xb3\x48\x17\xf1\xca\x9c\x43\x59\x3d\xb5\x64\x06\xc6\xa3\xb0\x06\xcb\xf3\xf3\x14\xe7\x34\x9a\xcf\x0c\xc6\xbf\xeb\xcb\xde\xfd\x10\xb4\xdc\xf0\xf2\x31\xda\x56\x97\x7d\x88\xf9\xf9\x01\x82\xd1\x99\x07\x6a\x56\x50\x64\x51'
Example #13
0
    def __generate_nPA(self):
        from virtualsmartcard.cards.nPA import nPA_SAM
        for oid_base, x_list, y_list, algo in [
            ('\x04\x00\x7f\x00\x07\x02\x02\x04', range(1,
                                                       5), range(1,
                                                                 5), "PACE"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', range(1, 3), range(1,
                                                                    6), "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x02', [1], [6], "TA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x03', range(1, 3), range(1,
                                                                    5), "CA"),
            ('\x04\x00\x7f\x00\x07\x02\x02\x05', range(1, 3), range(1,
                                                                    6), "RI"),
        ]:
            for oid in [
                    oid_base + chr(x) + chr(y) for x in x_list for y in y_list
            ]:
                ALGO_MAPPING[oid] = algo
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x03"] = "CommunityID"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x02"] = "DateOfExpiry"
        ALGO_MAPPING["\x04\x00\x7f\x00\x07\x03\x01\x04\x01"] = "DateOfBirth"

        self.mf = MF()

        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.append(
            TransparentStructureEF(parent=self.mf,
                                   fid=0x011c,
                                   shortfid=0x1c,
                                   data=card_access))
        card_security = "\x30\x82\x05\xA0\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02\xA0\x82\x05\x91\x30\x82\x05\x8D\x02\x01\x03\x31\x0F\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x30\x82\x01\x48\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\xA0\x82\x01\x3A\x04\x82\x01\x36\x31\x82\x01\x32\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\x04\x02\x02\x02\x01\x02\x02\x01\x0D\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x43\x01\x01\xFF\x30\x17\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x03\x30\x09\x02\x01\x01\x02\x01\x44\x01\x01\x00\x30\x19\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x05\x02\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\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\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\x30\x62\x06\x09\x04\x00\x7F\x00\x07\x02\x02\x01\x02\x30\x52\x30\x0C\x06\x07\x04\x00\x7F\x00\x07\x01\x02\x02\x01\x0D\x03\x42\x00\x04\x92\x5D\xB4\xE1\x7A\xDE\x58\x20\x9F\x96\xFA\xA0\x7F\x1F\x8A\x22\x3F\x82\x3F\x96\xCC\x5D\x78\xCB\xEF\x5D\x17\x42\x20\x88\xFD\xD5\x8E\x56\xBC\x42\x50\xDE\x33\x46\xB3\xC8\x32\xCA\xE4\x86\x35\xFB\x6C\x43\x78\x9D\xE8\xB3\x10\x2F\x43\x93\xB4\x18\xE2\x4A\x13\xD9\x02\x01\x41\xA0\x82\x03\x1C\x30\x82\x03\x18\x30\x82\x02\xBC\xA0\x03\x02\x01\x02\x02\x02\x01\x5C\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x30\x1E\x17\x0D\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x17\x0D\x32\x31\x30\x34\x30\x35\x30\x38\x33\x39\x34\x37\x5A\x30\x47\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x1D\x30\x1B\x06\x03\x55\x04\x0A\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x37\x34\x31\x0B\x30\x09\x06\x03\x55\x04\x03\x0C\x02\x44\x53\x30\x82\x01\x13\x30\x81\xD4\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x30\x81\xC8\x02\x01\x01\x30\x28\x06\x07\x2A\x86\x48\xCE\x3D\x01\x01\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF\x30\x3C\x04\x1C\x68\xA5\xE6\x2C\xA9\xCE\x6C\x1C\x29\x98\x03\xA6\xC1\x53\x0B\x51\x4E\x18\x2A\xD8\xB0\x04\x2A\x59\xCA\xD2\x9F\x43\x04\x1C\x25\x80\xF6\x3C\xCF\xE4\x41\x38\x87\x07\x13\xB1\xA9\x23\x69\xE3\x3E\x21\x35\xD2\x66\xDB\xB3\x72\x38\x6C\x40\x0B\x04\x39\x04\x0D\x90\x29\xAD\x2C\x7E\x5C\xF4\x34\x08\x23\xB2\xA8\x7D\xC6\x8C\x9E\x4C\xE3\x17\x4C\x1E\x6E\xFD\xEE\x12\xC0\x7D\x58\xAA\x56\xF7\x72\xC0\x72\x6F\x24\xC6\xB8\x9E\x4E\xCD\xAC\x24\x35\x4B\x9E\x99\xCA\xA3\xF6\xD3\x76\x14\x02\xCD\x02\x1D\x00\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F\x02\x01\x01\x03\x3A\x00\x04\x3D\x6A\x7C\x2A\x6F\x20\x5F\x83\x9B\x04\x14\xEC\x58\xC6\xC7\x1B\x75\xF5\x15\xDE\xC3\xAE\x73\x3B\x5F\x47\x88\xDD\xC8\x15\xF0\x5B\xC1\xF6\x53\x8F\xD9\x69\x54\xE1\xF8\x40\xA2\xE2\x18\x99\x62\xCC\xAA\x14\x90\x08\x24\xC7\xDD\xB9\xA3\x81\xD1\x30\x81\xCE\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x07\x80\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x60\x44\xF2\x45\xF2\xE0\x71\xD4\xD5\x64\xF4\xE5\x77\xD6\x36\x69\xDB\xEB\x18\x59\x30\x41\x06\x03\x55\x1D\x20\x04\x3A\x30\x38\x30\x36\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x01\x01\x30\x29\x30\x27\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01\x16\x1B\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x73\x69\x2E\x62\x75\x6E\x64\x2E\x64\x65\x2F\x63\x73\x63\x61\x30\x2B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x15\x04\x1E\x04\x1C\x31\x2E\x32\x2E\x32\x37\x36\x2E\x30\x2E\x38\x30\x2E\x31\x2E\x31\x32\x2E\x30\x2E\x32\x30\x2E\x35\x2E\x31\x2E\x30\x30\x2B\x06\x03\x55\x1D\x10\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x30\x31\x30\x30\x35\x31\x31\x30\x37\x35\x32\x5A\x81\x0F\x32\x30\x31\x31\x30\x32\x30\x35\x30\x39\x33\x39\x34\x37\x5A\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x03\x48\x00\x30\x45\x02\x20\x13\xE9\xE1\x7A\x9E\xFE\x8B\xD7\xD7\x27\x62\x92\x30\x5B\xCC\xC3\x2B\x70\xC2\xB7\x60\x40\xF4\x88\x30\x66\x62\x26\xCD\x6A\x4B\xF4\x02\x21\x00\x87\xF4\x71\xE2\x44\x35\xB4\xC3\x4A\xF3\x57\x30\x94\xFB\x1F\x1C\x2A\x48\xB1\x3E\xE5\xED\x67\xF1\x72\x6D\xCF\x56\xE3\x84\xE3\x6F\x31\x82\x01\x09\x30\x82\x01\x05\x02\x01\x01\x30\x55\x30\x4F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x0D\x30\x0B\x06\x03\x55\x04\x0A\x0C\x04\x62\x75\x6E\x64\x31\x0C\x30\x0A\x06\x03\x55\x04\x0B\x0C\x03\x62\x73\x69\x31\x0C\x30\x0A\x06\x03\x55\x04\x05\x13\x03\x30\x31\x33\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0C\x0C\x63\x73\x63\x61\x2D\x67\x65\x72\x6D\x61\x6E\x79\x02\x02\x01\x5C\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\xA0\x4A\x30\x17\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0A\x06\x08\x04\x00\x7F\x00\x07\x03\x02\x01\x30\x2F\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04\x31\x22\x04\x20\xEF\x0F\xDA\x94\x2E\x5A\x0F\x6F\xC9\xC5\x46\xEE\x01\xF9\x10\x31\x43\x64\x30\xF7\x5E\x9D\x36\x54\xD3\x69\x30\x9E\x8B\xE7\x17\x48\x30\x0C\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02\x05\x00\x04\x40\x30\x3E\x02\x1D\x00\x89\x75\x92\x5B\xE1\x31\xB7\x7C\x95\x8C\x3E\xCB\x2A\x5C\x67\xFC\x5C\xE3\x1C\xBD\x01\x41\xE3\x4B\xC7\xF0\xA4\x47\x02\x1D\x00\xCC\x65\xE6\x2D\xDC\xF2\x93\x96\x4B\x22\xD7\xB5\x10\xD7\x81\x88\x07\xC8\x95\x96\xBD\x34\xD8\xF9\xBB\x4C\x05\x27"
        self.mf.append(
            TransparentStructureEF(parent=self.mf,
                                   fid=0x011d,
                                   shortfid=0x1d,
                                   data=card_security))

        #print 'nPA:', unpack('\x62\x81\x88\x82\x01\x38\x8a\x01\x05\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03')
        #print 'vicc:', unpack('\x62\x15\x83\x02\xff\xff\x8a\x01\x05\x82\x01\x38\x84\x09\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid = DF(parent=self.mf,
                 fid=0xffff,
                 dfname='\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
        eid.extra_fci_data = '\xab\x75\x84\x01\xa4\xaf\x70\xa0\x10\xb4\x06\x95\x01\x20\x83\x01\x04\xb4\x06\x95\x01\x20\x83\x01\x06\xa0\x54\xa4\x14\x95\x01\x80\x7f\x4c\x0e\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x01\x53\x01\x00\xaf\x22\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x00\xa4\x06\x95\x01\x80\x83\x01\x47\xa4\x18\x95\x01\x80\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\x00\x00\x00\x00\x10\x7a\x06\x8a\x01\x05\x9e\x01\x03'
        # FIXME access control for eid application
        DocumentType = self.datagroups[
            "DocumentType"] if "DocumentType" in self.datagroups else 'ID'
        IssuingState = self.datagroups[
            "IssuingState"] if "IssuingState" in self.datagroups else 'DE'
        DateOfExpiry = self.datagroups[
            "DateOfExpiry"] if "DateOfExpiry" in self.datagroups else '20201031'
        GivenNames = self.datagroups[
            "GivenNames"] if "GivenNames" in self.datagroups else 'ERIKA'
        FamilyNames = self.datagroups[
            "FamilyNames"] if "FamilyNames" in self.datagroups else 'MUSTERMANN'
        ReligiousArtisticName = self.datagroups[
            "ReligiousArtisticName"] if "ReligiousArtisticName" in self.datagroups else ''
        AcademicTitle = self.datagroups[
            "AcademicTitle"] if "AcademicTitle" in self.datagroups else ''
        DateOfBirth = self.datagroups[
            "DateOfBirth"] if "DateOfBirth" in self.datagroups else '19640812'
        PlaceOfBirth = self.datagroups[
            "PlaceOfBirth"] if "PlaceOfBirth" in self.datagroups else 'BERLIN'
        Nationality = self.datagroups[
            "Nationality"] if "Nationality" in self.datagroups else 'DE'
        Sex = self.datagroups["Sex"] if "Sex" in self.datagroups else 'F'
        Country = self.datagroups[
            "Country"] if "Country" in self.datagroups else 'D'
        City = self.datagroups["City"] if "City" in self.datagroups else 'KOLN'
        ZIP = self.datagroups["ZIP"] if "ZIP" in self.datagroups else '51147'
        Street = self.datagroups[
            "Street"] if "Street" in self.datagroups else 'HEIDESTRASSE 17'
        CommunityID = eval(
            self.datagroups["CommunityID"]
        ) if "CommunityID" in self.datagroups else '\x12\x34\x56\x78\x90\x12\x34'
        dg1 = pack([(0x61, 0, [(0x13, 0, DocumentType)])], True)
        dg2 = pack([(0x62, 0, [(0x13, 0, IssuingState)])], True)
        dg3 = pack([(0x63, 0, [(0x12, 0, DateOfExpiry)])], True)
        dg4 = pack([(0x64, 0, [(0x0C, 0, GivenNames)])], True)
        dg5 = pack([(0x65, 0, [(0x0C, 0, FamilyNames)])], True)
        dg6 = pack([(0x66, 0, [(0x0C, 0, ReligiousArtisticName)])], True)
        dg7 = pack([(0x67, 0, [(0x0C, 0, AcademicTitle)])], True)
        dg8 = pack([(0x68, 0, [(0x12, 0, DateOfBirth)])], True)
        dg9 = pack([(0x69, 0, [(0xA1, 0, [(0x0C, 0, PlaceOfBirth)])])], True)
        dg10 = pack([(0x6A, 0, [(0x13, 0, Nationality)])], True)
        dg11 = pack([(0x6B, 0, [(0x13, 0, Sex)])], True)
        dg12 = self.datagroups["dg12"] if "dg12" in self.datagroups else ''
        dg13 = self.datagroups["dg13"] if "dg13" in self.datagroups else ''
        dg14 = self.datagroups["dg14"] if "dg14" in self.datagroups else ''
        dg15 = self.datagroups["dg15"] if "dg15" in self.datagroups else ''
        dg16 = self.datagroups["dg16"] if "dg16" in self.datagroups else ''
        dg17 = pack([(0x71, 0, [(0x30, 0, [(0xAA, 0, [(0x0C, 0, Street)]),
                                           (0xAB, 0, [(0x0C, 0, City)]),
                                           (0xAD, 0, [(0x13, 0, Country)]),
                                           (0xAE, 0, [(0x13, 0, ZIP)])])])],
                    True)
        dg18 = pack([(0x72, 0, [(0x04, 0, CommunityID)])], True)
        dg19 = self.datagroups["dg19"] if "dg19" in self.datagroups else ''
        dg20 = self.datagroups["dg20"] if "dg20" in self.datagroups else ''
        dg21 = self.datagroups["dg21"] if "dg21" in self.datagroups else ''
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0101,
                                   shortfid=0x01,
                                   data=dg1))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0102,
                                   shortfid=0x02,
                                   data=dg2))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0103,
                                   shortfid=0x03,
                                   data=dg3))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0104,
                                   shortfid=0x04,
                                   data=dg4))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0105,
                                   shortfid=0x05,
                                   data=dg5))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0106,
                                   shortfid=0x06,
                                   data=dg6))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0107,
                                   shortfid=0x07,
                                   data=dg7))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0108,
                                   shortfid=0x08,
                                   data=dg8))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0109,
                                   shortfid=0x09,
                                   data=dg9))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x010a,
                                   shortfid=0x0a,
                                   data=dg10))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x010b,
                                   shortfid=0x0b,
                                   data=dg11))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x010c,
                                   shortfid=0x0c,
                                   data=dg12))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x010d,
                                   shortfid=0x0d,
                                   data=dg13))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x010e,
                                   shortfid=0x0e,
                                   data=dg14))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x010f,
                                   shortfid=0x0f,
                                   data=dg15))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0110,
                                   shortfid=0x10,
                                   data=dg16))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0111,
                                   shortfid=0x11,
                                   data=dg17))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0112,
                                   shortfid=0x12,
                                   data=dg18))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0113,
                                   shortfid=0x13,
                                   data=dg19))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0114,
                                   shortfid=0x14,
                                   data=dg20))
        eid.append(
            TransparentStructureEF(parent=eid,
                                   fid=0x0115,
                                   shortfid=0x15,
                                   data=dg21))
        self.mf.append(eid)

        self.sam = nPA_SAM(
            pin="111111",
            can="222222",
            mrz=
            "IDD<<T220001293<<<<<<<<<<<<<<<6408125<2010315D<<<<<<<<<<<<<<MUSTERMANN<<ERIKA<<<<<<<<<<<<<",
            puk="3333333333",
            mf=self.mf)
        # FIXME add CVCA for inspection systems and signature terminals. Here we only add the eID CVCA.
        self.sam.current_SE.cvca = '\x7f\x21\x82\x01\xb6\x7f\x4e\x82\x01\x6e\x5f\x29\x01\x00\x42\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x49\x82\x01\x1d\x06\x0a\x04\x00\x7f\x00\x07\x02\x02\x02\x02\x03\x81\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x72\x6e\x3b\xf6\x23\xd5\x26\x20\x28\x20\x13\x48\x1d\x1f\x6e\x53\x77\x82\x20\x7d\x5a\x09\x75\xfc\x2c\x30\x57\xee\xf6\x75\x30\x41\x7a\xff\xe7\xfb\x80\x55\xc1\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\x83\x20\x26\xdc\x5c\x6c\xe9\x4a\x4b\x44\xf3\x30\xb5\xd9\xbb\xd7\x7c\xbf\x95\x84\x16\x29\x5c\xf7\xe1\xce\x6b\xcc\xdc\x18\xff\x8c\x07\xb6\x84\x41\x04\x8b\xd2\xae\xb9\xcb\x7e\x57\xcb\x2c\x4b\x48\x2f\xfc\x81\xb7\xaf\xb9\xde\x27\xe1\xe3\xbd\x23\xc2\x3a\x44\x53\xbd\x9a\xce\x32\x62\x54\x7e\xf8\x35\xc3\xda\xc4\xfd\x97\xf8\x46\x1a\x14\x61\x1d\xc9\xc2\x77\x45\x13\x2d\xed\x8e\x54\x5c\x1d\x54\xc7\x2f\x04\x69\x97\x85\x20\xa9\xfb\x57\xdb\xa1\xee\xa9\xbc\x3e\x66\x0a\x90\x9d\x83\x8d\x71\x8c\x39\x7a\xa3\xb5\x61\xa6\xf7\x90\x1e\x0e\x82\x97\x48\x56\xa7\x86\x41\x04\x33\x47\xec\xf9\x6f\xfb\x4b\xd9\xb8\x55\x4e\xfb\xcc\xfc\x7d\x0b\x24\x2f\x10\x71\xe2\x9b\x4c\x9c\x62\x2c\x79\xe3\x39\xd8\x40\xaf\x67\xbe\xb9\xb9\x12\x69\x22\x65\xd9\xc1\x6c\x62\x57\x3f\x45\x79\xff\xd4\xde\x2d\xe9\x2b\xab\x40\x9d\xd5\xc5\xd4\x82\x44\xa9\xf7\x87\x01\x01\x5f\x20\x0e\x44\x45\x43\x56\x43\x41\x65\x49\x44\x30\x30\x31\x30\x32\x7f\x4c\x12\x06\x09\x04\x00\x7f\x00\x07\x03\x01\x02\x02\x53\x05\xfe\x0f\x01\xff\xff\x5f\x25\x06\x01\x00\x01\x00\x01\x08\x5f\x24\x06\x01\x03\x01\x00\x01\x08\x5f\x37\x40\x50\x67\x14\x5c\x68\xca\xe9\x52\x0f\x5b\xb3\x48\x17\xf1\xca\x9c\x43\x59\x3d\xb5\x64\x06\xc6\xa3\xb0\x06\xcb\xf3\xf3\x14\xe7\x34\x9a\xcf\x0c\xc6\xbf\xeb\xcb\xde\xfd\x10\xb4\xdc\xf0\xf2\x31\xda\x56\x97\x7d\x88\xf9\xf9\x01\x82\xd1\x99\x07\x6a\x56\x50\x64\x51'