Ejemplo n.º 1
0
Archivo: cm.py Proyecto: jackma92/steam
    def _recv_messages(self):
        for message in self.connection:
            if not self.connected:
                break

            if self.channel_key:
                if self.channel_hmac:
                    try:
                        message = crypto.symmetric_decrypt_HMAC(
                            message, self.channel_key, self.channel_hmac)
                    except RuntimeError as e:
                        self._LOG.exception(e)
                        break
                else:
                    message = crypto.symmetric_decrypt(message,
                                                       self.channel_key)

            gevent.spawn(self._parse_message, message)
            self.idle()

        if not self._seen_logon and self.channel_secured:
            if self.wait_event('disconnected', timeout=5) is not None:
                return

        gevent.spawn(self.disconnect)
Ejemplo n.º 2
0
    def test_encryption_legacy(self):
        message = b'My secret message'
        key = b'9' * 32

        cyphertext = crypto.symmetric_encrypt(message, key)
        dmessage = crypto.symmetric_decrypt(cyphertext, key)

        self.assertEqual(message, dmessage)
Ejemplo n.º 3
0
    def test_encryption_legacy(self):
        message = b'My secret message'
        key = b'9' * 32

        cyphertext = crypto.symmetric_encrypt(message, key)
        dmessage = crypto.symmetric_decrypt(cyphertext, key)

        self.assertEqual(message, dmessage)
Ejemplo n.º 4
0
    def decrypt_filenames(self, depot_key):
        """Decrypt all filenames in the manifest

        :param depot_key: depot key
        :type  depot_key: bytes
        :raises: :class:`RuntimeError`
        """
        if not self.metadata.filenames_encrypted:
            return

        try:
            for m in self.payload.mappings:
                m.filename = symmetric_decrypt(b64decode(m.filename),
                                               depot_key)

                if m.linktarget:
                    m.linktarget = symmetric_decrypt(b64decode(m.linktarget),
                                                     depot_key)
        except Exception:
            raise RuntimeError("Unable to decrypt filename for depot manifest")

        self.metadata.filenames_encrypted = False
Ejemplo n.º 5
0
    def get_chunk(self, app_id, depot_id, chunk_id):
        """Download a single content chunk

        :param app_id: App ID
        :type  app_id: int
        :param depot_id: Depot ID
        :type  depot_id: int
        :param chunk_id: Chunk ID
        :type  chunk_id: int
        :returns: chunk data
        :rtype: bytes
        :raises SteamError: error message
        """
        if (depot_id, chunk_id) not in self._chunk_cache:
            resp = self.cdn_cmd('depot', '%s/chunk/%s' % (depot_id, chunk_id))

            data = symmetric_decrypt(resp.content,
                                     self.get_depot_key(app_id, depot_id))

            if data[:2] == b'VZ':
                if data[-2:] != b'zv':
                    raise SteamError("VZ: Invalid footer: %s" %
                                     repr(data[-2:]))
                if data[2:3] != b'a':
                    raise SteamError("VZ: Invalid version: %s" %
                                     repr(data[2:3]))

                vzfilter = lzma._decode_filter_properties(
                    lzma.FILTER_LZMA1, data[7:12])
                vzdec = lzma.LZMADecompressor(lzma.FORMAT_RAW,
                                              filters=[vzfilter])
                checksum, decompressed_size = struct.unpack(
                    '<II', data[-10:-2])
                # decompress_size is needed since lzma will sometime produce longer output
                # [12:-9] is need as sometimes lzma will produce shorter output
                # together they get us the right data
                data = vzdec.decompress(data[12:-9])[:decompressed_size]
                if crc32(data) != checksum:
                    raise SteamError(
                        "VZ: CRC32 checksum doesn't match for decompressed data"
                    )
            else:
                with ZipFile(BytesIO(data)) as zf:
                    data = zf.read(zf.filelist[0])

            self._chunk_cache[(depot_id, chunk_id)] = data

        return self._chunk_cache[(depot_id, chunk_id)]
Ejemplo n.º 6
0
    def test_encryption(self):
        message = b'My secret message'
        key = b'9' * 32
        hmac = b'3' * 16

        # legacy
        cyphertext = crypto.symmetric_encrypt(message, key)
        dmessage = crypto.symmetric_decrypt(cyphertext, key)

        self.assertEqual(message, dmessage)

        # with HMAC
        cyphertext = crypto.symmetric_encrypt_HMAC(message, key, hmac)
        dmessage = crypto.symmetric_decrypt_HMAC(cyphertext, key, hmac)

        self.assertEqual(message, dmessage)

        # failing HMAC check
        with self.assertRaises(RuntimeError):
            crypto.symmetric_decrypt_HMAC(cyphertext, key, b'4'*16)
    def decrypt_filenames(self, depot_key):
        """Decrypt all filenames in the manifest

        :param depot_key: depot key
        :type  depot_key: bytes
        :raises: :class:`RuntimeError`
        """
        if not self.metadata.filenames_encrypted:
            return

        for mapping in self.payload.mappings:
            filename = b64decode(mapping.filename)

            try:
                filename = symmetric_decrypt(filename, depot_key)
            except Exception:
                RuntimeError("Unable to decrypt filename for depot manifest")

            mapping.filename = filename

        self.metadata.filenames_encrypted = False
Ejemplo n.º 8
0
    def _recv_messages(self):
        for message in self.connection:
            if not self.connected:
                break

            if self.channel_key:
                if self.channel_hmac:
                    try:
                        message = crypto.symmetric_decrypt_HMAC(message, self.channel_key, self.channel_hmac)
                    except RuntimeError as e:
                        self._LOG.exception(e)
                        break
                else:
                    message = crypto.symmetric_decrypt(message, self.channel_key)

            gevent.spawn(self._parse_message, message)
            gevent.idle()

        if not self._seen_logon and self.channel_secured:
            if self.wait_event('disconnected', timeout=5) is not None:
                return

        gevent.spawn(self.disconnect)