def generate_signature(fp, updatefunc): fp.seek(0) # Magic updatefunc(fp.read(4)) # index_offset updatefunc(fp.read(4)) # file size updatefunc(fp.read(8)) # number of signatures num_sigs = fp.read(4) updatefunc(num_sigs) num_sigs = unpackint(num_sigs) for i in range(num_sigs): # signature algo updatefunc(fp.read(4)) # signature size sigsize = fp.read(4) updatefunc(sigsize) sigsize = unpackint(sigsize) # Read this, but don't update the signature with it fp.read(sigsize) # Read the rest of the file for block in read_file(fp): updatefunc(block)
def from_fileobj(cls, fp): _offset = fp.tell() algo_id = unpackint(fp.read(4)) self = cls(algo_id) self._offset = _offset sigsize = unpackint(fp.read(4)) assert sigsize == self.sigsize log.debug("signature data at %i to %i", fp.tell(), fp.tell() + sigsize) self.signature = fp.read(self.sigsize) log.debug("ver %i signature %i bytes at %i", algo_id, sigsize, _offset) return self
def from_fileobj(cls, fp): data = bytearray() offset = fp.tell() size = unpackint(fp.read(4)) data = bytearray(fp.read(size - 4)) return cls.from_bytes(data, offset, size)
def from_fileobj(cls, fp): self = cls() self._offset = fp.tell() self.size = unpackint(fp.read(4)) self.block_id = unpackint(fp.read(4)) self.data = fp.read(self.size - 8) self.info = {} if self.block_id == 1: self.name = "PRODUCT INFORMATION" bits = self.data.split(b'\x00') self.info['MARChannelName'] = bits[0].decode('ascii') self.info['ProductVersion'] = bits[1].decode('ascii') else: raise ValueError("Unsupported additional info section: %s" % self.block_id) return self
def _read_signatures(self): fp = self.fileobj log.debug("reading signatures") fp.seek(8) file_size = unpacklongint(fp.read(8)) # Check that the file size matches fp.seek(0, 2) assert fp.tell() == file_size fp.seek(16) num_sigs = unpackint(fp.read(4)) log.debug("file_size: %i bytes", file_size) log.debug("%i signatures present", num_sigs) signatures = [] for i in range(num_sigs): sig = MarSignature.from_fileobj(fp) for algo_id, keyfile in self.signature_versions: if algo_id == sig.algo_id: sig.keyfile = keyfile break else: log.info("no key specified to validate %i" " signature", sig.algo_id) signatures.append(sig) # Read additional sections; this is also only present if we have a # signature block num_additional_sections = unpackint(fp.read(4)) log.debug("%i additional sections present", num_additional_sections) for i in range(num_additional_sections): info = AdditionalInfo.from_fileobj(fp) log.debug("%s", info) self.additional_info.append(info) return signatures
def from_bytes(cls, data, offset, size): """Returns an AdditionalInfo object represended by the given bytearray. Offset is where in the marfile this block is""" assert isinstance(data, bytearray) self = cls() self._offset = offset self.size = size self.block_id = unpackint(data[:4]) self.data = data[4:] self.info = {} if self.block_id == 1: self.name = "PRODUCT INFORMATION" bits = self.data.split(b'\x00') self.info['MARChannelName'] = bits[0].decode('ascii') self.info['ProductVersion'] = bits[1].decode('ascii') else: raise ValueError("Unsupported additional info section: %s" % self.block_id) return self