diff --git a/pywidevine/cdm.py b/pywidevine/cdm.py index d3aa9f8..7c6696e 100644 --- a/pywidevine/cdm.py +++ b/pywidevine/cdm.py @@ -360,6 +360,8 @@ class Cdm: signed_message = SignedMessage() try: signed_message.ParseFromString(license_message) + if signed_message.SerializeToString() != license_message: + raise DecodeError(license_message) except DecodeError as e: raise InvalidLicenseMessage(f"Could not parse license_message as a SignedMessage, {e}") license_message = signed_message diff --git a/pywidevine/device.py b/pywidevine/device.py index 4e29351..6a02cbd 100644 --- a/pywidevine/device.py +++ b/pywidevine/device.py @@ -110,20 +110,37 @@ class Device: self.client_id = ClientIdentification() try: self.client_id.ParseFromString(client_id) - except DecodeError: - raise ValueError("Failed to parse client_id as a ClientIdentification") + if self.client_id.SerializeToString() != client_id: + raise DecodeError("partial parse") + except DecodeError as e: + raise ValueError(f"Failed to parse client_id as a ClientIdentification, {e}") self.vmp = FileHashes() if self.client_id.vmp_data: try: self.vmp.ParseFromString(self.client_id.vmp_data) - except DecodeError: - raise ValueError("Failed to parse Client ID's VMP data as a FileHashes") + if self.vmp.SerializeToString() != self.client_id.vmp_data: + raise DecodeError("partial parse") + except DecodeError as e: + raise ValueError(f"Failed to parse Client ID's VMP data as a FileHashes, {e}") signed_drm_certificate = SignedDrmCertificate() - signed_drm_certificate.ParseFromString(self.client_id.token) drm_certificate = DrmCertificate() - drm_certificate.ParseFromString(signed_drm_certificate.drm_certificate) + + try: + signed_drm_certificate.ParseFromString(self.client_id.token) + if signed_drm_certificate.SerializeToString() != self.client_id.token: + raise DecodeError("partial parse") + except DecodeError as e: + raise DecodeError(f"Failed to parse the Signed DRM Certificate of the Client ID, {e}") + + try: + drm_certificate.ParseFromString(signed_drm_certificate.drm_certificate) + if drm_certificate.SerializeToString() != signed_drm_certificate.drm_certificate: + raise DecodeError("partial parse") + except DecodeError as e: + raise DecodeError(f"Failed to parse the DRM Certificate of the Client ID, {e}") + self.system_id = drm_certificate.system_id def __repr__(self) -> str: @@ -190,6 +207,8 @@ class Device: if data.vmp: try: vmp.ParseFromString(data.vmp) + if vmp.SerializeToString() != data.vmp: + raise DecodeError("partial parse") except DecodeError as e: raise DecodeError(f"Failed to parse VMP data as FileHashes, {e}") data.vmp = vmp @@ -197,6 +216,8 @@ class Device: client_id = ClientIdentification() try: client_id.ParseFromString(data.client_id) + if client_id.SerializeToString() != data.client_id: + raise DecodeError("partial parse") except DecodeError as e: raise DecodeError(f"Failed to parse VMP data as FileHashes, {e}") diff --git a/pywidevine/remotecdm.py b/pywidevine/remotecdm.py index 4ff602f..6d9e743 100644 --- a/pywidevine/remotecdm.py +++ b/pywidevine/remotecdm.py @@ -175,8 +175,11 @@ class RemoteCdm(Cdm): r = r["data"] try: + challenge = base64.b64decode(r["challenge_b64"]) license_message = SignedMessage() - license_message.ParseFromString(base64.b64decode(r["challenge_b64"])) + license_message.ParseFromString(challenge) + if license_message.SerializeToString() != challenge: + raise DecodeError("partial parse") except DecodeError as e: raise InvalidLicenseMessage(f"Failed to parse license request, {e}") @@ -196,6 +199,8 @@ class RemoteCdm(Cdm): signed_message = SignedMessage() try: signed_message.ParseFromString(license_message) + if signed_message.SerializeToString() != license_message: + raise DecodeError("partial parse") except DecodeError as e: raise InvalidLicenseMessage(f"Could not parse license_message as a SignedMessage, {e}") license_message = signed_message