Exemple #1
0
 def read_block(self, block, noauth=False):
     '''Works only for data blocks, whereas for the trailer blocks reads the ACL only'''
     if not noauth: self.auth(block, READ)
     data = mifare.read(self.reader, block)
     sector = self.block2sector(block)
     tblock = self.trailer_block(sector)
     if block == tblock:
         data = self.fix_trailer_block(sector, data)
     return data
Exemple #2
0
 def read_block(self, block, noauth=False):
     '''Works only for data blocks, whereas for the trailer blocks reads the ACL only'''
     if not noauth: self.auth(block, READ)
     data = mifare.read(self.reader, block)
     sector = self.block2sector(block)
     tblock = self.trailer_block(sector)
     if block == tblock:
         data = self.fix_trailer_block(sector, data)
     return data
Exemple #3
0
    def auth(self, block, access_type):
        '''Authentication needs to be done once per sector. After successful authentication any 
        number of blocks from the sector can be read/written to.'''
        # find out the sector we are going to access
        sector = self.block2sector(block)
        # only do the authentication if we have required keys loaded
        if sector >= len(self._keys):
            raise RuntimeError(
                'Cannot unlock sector %d - no key for the sector provided!' %
                (sector))

        # check the access conditions for this data block
        tblock = self.trailer_block(sector)
        auth_key = 0
        if sector in self._trailer_cache:
            tdata = self._trailer_cache[sector]
        else:
            # we have read the trailer block, se have to authenticate to the sector anyway
            if mifare.auth(self.reader, block, mifare.MC_AUTH_A,
                           self._keys[sector]['a'], self.uid()):
                auth_key = 1
            elif mifare.auth(self.reader, block, mifare.MC_AUTH_B,
                             self._keys[sector]['b'], self.uid()):
                auth_key = 2
            else:
                raise RuntimeError('Cannot unlock sector %d' % (sector))
            tdata = self._trailer_cache[sector] = mifare.read(
                self.reader, tblock)

        keya, access_cond, keyb = struct.unpack('6s4s6s', tdata)
        access_cond = self._parse_acl(access_cond)

        sblock = block % self.sector_size(sector)
        # read or write access condition, see data_acl for data blocks and trailer_acl for the trailer block
        auth_keys = access_cond[sblock][
            access_type] if block != tblock else access_cond[sblock]['acl'][
                access_type]
        if auth_keys == 0:
            raise RuntimeError("ACL denies %s on sector %d, block %d" %
                               (['reads', 'writes'][access_type], sector, i))

        if not auth_keys & auth_key:
            keytype = mifare.MC_AUTH_B if auth_keys == 2 else mifare.MC_AUTH_A
            keyidx = 'a' if keytype == mifare.MC_AUTH_A else 'b'
            if not mifare.auth(self.reader, block, keytype,
                               self._keys[sector][keyidx], self.uid()):
                raise RuntimeError(
                    'Authentication of sector %d, block %d failed' %
                    (sector, i))

        return True
Exemple #4
0
    def auth(self, block, access_type):
        '''Authentication needs to be done once per sector. After successful authentication any 
        number of blocks from the sector can be read/written to.'''
        # find out the sector we are going to access
        sector = self.block2sector(block)
        # only do the authentication if we have required keys loaded
        if sector >= len(self._keys):
            raise RuntimeError('Cannot unlock sector %d - no key for the sector provided!' % (sector))

        # check the access conditions for this data block
        tblock = self.trailer_block(sector)
        auth_key = 0
        if sector in self._trailer_cache:
            tdata = self._trailer_cache[sector]
        else:
            # we have read the trailer block, se have to authenticate to the sector anyway
            if mifare.auth(self.reader, block, mifare.MC_AUTH_A, self._keys[sector]['a'], self.uid()):
                auth_key = 1
            elif mifare.auth(self.reader, block, mifare.MC_AUTH_B, self._keys[sector]['b'], self.uid()):
                auth_key = 2
            else:
                raise RuntimeError('Cannot unlock sector %d' % (sector))
            tdata = self._trailer_cache[sector] = mifare.read(self.reader, tblock)
        
        keya, access_cond, keyb = struct.unpack('6s4s6s', tdata)
        access_cond = self._parse_acl(access_cond)
        
        sblock = block % self.sector_size(sector)
        # read or write access condition, see data_acl for data blocks and trailer_acl for the trailer block
        auth_keys = access_cond[sblock][access_type] if block != tblock else access_cond[sblock]['acl'][access_type]
        if auth_keys == 0:
            raise RuntimeError("ACL denies %s on sector %d, block %d" % (['reads','writes'][access_type], sector, i))

        if not auth_keys & auth_key:
            keytype = mifare.MC_AUTH_B if auth_keys == 2 else mifare.MC_AUTH_A
            keyidx = 'a' if keytype == mifare.MC_AUTH_A else 'b'
            if not mifare.auth(self.reader, block, keytype, self._keys[sector][keyidx], self.uid()):
                raise RuntimeError('Authentication of sector %d, block %d failed' % (sector, i))

        return True