+ serve.py raw PSSH support

This commit is contained in:
BuildTools 2024-11-28 19:37:34 +01:00
parent b2e9725b3a
commit 9b25aafe07
5 changed files with 35 additions and 23 deletions

View File

@ -10,4 +10,4 @@ from .session import *
from .xml_key import * from .xml_key import *
from .xmrlicense import * from .xmrlicense import *
__version__ = "0.3.8" __version__ = "0.3.9"

View File

@ -265,7 +265,7 @@ class Cdm:
raise InvalidLicense("Public encryption key does not match") raise InvalidLicense("Public encryption key does not match")
for key in parsed_licence.get_content_keys(): for key in parsed_licence.get_content_keys():
if Key.CipherType(key.cipher_type) == Key.CipherType.ECC256: if Key.CipherType(key.cipher_type) == Key.CipherType.ECC_256:
session.keys.append(Key( session.keys.append(Key(
key_id=UUID(bytes_le=key.key_id), key_id=UUID(bytes_le=key.key_id),
key_type=key.key_type, key_type=key.key_type,

View File

@ -6,12 +6,12 @@ from typing import Union
class Key: class Key:
class KeyType(Enum): class KeyType(Enum):
Invalid = 0x0000 INVALID = 0x0000
AES128CTR = 0x0001 AES_128_CTR = 0x0001
RC4 = 0x0002 RC4_CIPHER = 0x0002
AES128ECB = 0x0003 AES_128_ECB = 0x0003
Cocktail = 0x0004 COCKTAIL = 0x0004
AES128CBC = 0x0005 AES_128_CBC = 0x0005
UNKNOWN = 0xffff UNKNOWN = 0xffff
@classmethod @classmethod
@ -19,12 +19,12 @@ class Key:
return cls.UNKNOWN return cls.UNKNOWN
class CipherType(Enum): class CipherType(Enum):
Invalid = 0x0000 INVALID = 0x0000
RSA128 = 0x0001 RSA_1024 = 0x0001
ChainedLicense = 0x0002 CHAINED_LICENSE = 0x0002
ECC256 = 0x0003 ECC_256 = 0x0003
ECCforScalableLicenses = 0x0004 ECC_256_WITH_KZ = 0x0004
Scalable = 0x0005 SCALABLE = 0x0005
UNKNOWN = 0xffff UNKNOWN = 0xffff
@classmethod @classmethod

View File

@ -5,11 +5,11 @@ from typing import Any, Optional, Union
from aiohttp.typedefs import Handler from aiohttp.typedefs import Handler
from aiohttp import web from aiohttp import web
from pyplayready import __version__ from pyplayready import __version__, PSSH
from pyplayready.cdm import Cdm from pyplayready.cdm import Cdm
from pyplayready.device import Device from pyplayready.device import Device
from pyplayready.exceptions import (InvalidSession, TooManySessions, InvalidLicense) from pyplayready.exceptions import (InvalidSession, TooManySessions, InvalidLicense, InvalidPssh)
routes = web.RouteTableDef() routes = web.RouteTableDef()
@ -134,6 +134,18 @@ async def get_license_challenge(request: web.Request) -> web.Response:
# get init data # get init data
init_data = body["init_data"] init_data = body["init_data"]
if not init_data.startswith("<WRMHEADER"):
try:
pssh = PSSH(init_data)
wrm_headers = pssh.get_wrm_headers(downgrade_to_v4=True)
if wrm_headers:
init_data = wrm_headers[0]
except InvalidPssh as e:
return web.json_response({
"status": 500,
"message": f"Unable to parse base64 PSSH, {e}"
}, status=500)
# get challenge # get challenge
try: try:
license_request = cdm.get_license_challenge( license_request = cdm.get_license_challenge(
@ -147,9 +159,9 @@ async def get_license_challenge(request: web.Request) -> web.Response:
}, status=400) }, status=400)
except Exception as e: except Exception as e:
return web.json_response({ return web.json_response({
"status": 400, "status": 500,
"message": f"Error, {e}" "message": f"Error, {e}"
}, status=400) }, status=500)
return web.json_response({ return web.json_response({
"status": 200, "status": 200,
@ -199,9 +211,9 @@ async def parse_license(request: web.Request) -> web.Response:
}, status=400) }, status=400)
except Exception as e: except Exception as e:
return web.json_response({ return web.json_response({
"status": 400, "status": 500,
"message": f"Error, {e}" "message": f"Error, {e}"
}, status=400) }, status=500)
return web.json_response({ return web.json_response({
"status": 200, "status": 200,
@ -243,9 +255,9 @@ async def get_keys(request: web.Request) -> web.Response:
}, status=400) }, status=400)
except Exception as e: except Exception as e:
return web.json_response({ return web.json_response({
"status": 400, "status": 500,
"message": f"Error, {e}" "message": f"Error, {e}"
}, status=400) }, status=500)
# get the keys in json form # get the keys in json form
keys_json = [ keys_json = [

View File

@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry] [tool.poetry]
name = "pyplayready" name = "pyplayready"
version = "0.3.8" version = "0.3.9"
description = "pyplayready CDM (Content Decryption Module) implementation in Python." description = "pyplayready CDM (Content Decryption Module) implementation in Python."
license = "CC BY-NC-ND 4.0" license = "CC BY-NC-ND 4.0"
authors = ["DevLARLEY, Erevoc", "DevataDev"] authors = ["DevLARLEY, Erevoc", "DevataDev"]