Releases: devine-dl/pywidevine
Releases · devine-dl/pywidevine
v1.8.0
Added
- Added
py.typed
file to support PEP561 and silence Mypy (#43).
Changed
- Dropped support for Python 3.7.
- Recompiled protobuffers for version 4.25.
Fixed
- Missing
yaml
dependency as it was only installed alongside theserve
extras group. - Duplicate Concatenated SignedMessages no longer throw a verification failure in
Cdm.set_service_certificate()
.
To ensure security of the messages, verification will still fail if any of the SignedMessages do not match each other.
New Contributors
v1.7.0
- Supported Serve API:
v1.4.3
or newer
Added
- Ability to specify output filename by specifying a full path or a relative file name in CLI command
create-device
. - Add the staging privacy certificate (
staging.google.com
) toCdm.staging_privacy_cert
.- Similar to
common_privacy_cert
which would be used on Google's production license server, - Though this one is used on Google's staging license server (a production-ready testing server).
- Similar to
Changed
- Raise an error if a file already exists at the output path in CLI command
create-device
. - Use std-lib xml instead of lxml to reduce dependencies and support ARM (#35).
- Lessen restriction on Python version to any Python version
>=3.7
, but<4.0
.- I was hoping to do
^3.7
, but some dependencies also require<4.0
therefore I cannot, for now.
- I was hoping to do
- Move Key ID parsing to static
PSSH.parse_key_ids()
method. - The
shaka-packager
subprocess call's return code is now returned fromCdm.decrypt()
. - The flags variable of a
Device
now defaults to a dict, even if not set. - Heavily improve initializing of protobuf objects, improving readability, typing, and linting quite a bit.
- Renamed Device's
_Types
enum class toDeviceTypes
.
Removed
- Removed
Device.Types
class variable alias to_Types
enum class as a static linter cannot recognize a class
variable as a type. Instead, the actual_Types
(now namedDeviceTypes
) enum should be imported and used instead.
Fixed
- Ensure output directory exists before creating new
.wvd
files in CLI commandcreate-device
. - Ignore empty Key ID values in v4.0.0.0 PlayReadyHeaders.
- Remove
Cdm.system_id
class variable as it conflicted with thecdm.system_id
class instance variable of the same
name. It's also generally not needed. The same data can be gotten viaCdm.uuid.bytes
. - Casting of
type_
when passed a non-int value inCdm.get_license_challenge()
. - Pass a PSSH object in
test
CLI command instead of a string. - Lower-case and setup
__all__
correctly, add missing__all__
in some of the modules.- For the longest time I thought it was
__ALL__
and an iterable of objects/variables. - However, its actually
__all__
and explicitly a list of Strings...
- For the longest time I thought it was
New Contributors
v1.6.0
- Supported Serve API:
v1.4.3
or newer
Added
- Support Python 3.11.
- New CLI command
export-device
to export WVD files back as files. I.e., a private key and client ID blob file.
v1.5.3
- Supported Serve API:
v1.4.3
or newer
Added
- New utility
load_xml()
to parse XML data with lxml ignoring Namespaces. - PSSH class now have
__str__
and__repr__
methods to print the object in more Human-friendly ways.str(pssh)
is now identical topssh.dumps()
.repr(pssh)
or justpssh
in some cases will result in a nice overview of the PSSHs contents.
- New
to_playready()
method to convert Widevine PSSH Data to PlayReady PSSH Data. Please note that the
Checksums for AES-CTR and COCKTAIL KIDs cannot be calculated as the Content Encryption Key would be needed.
Changed
- The System ID must now be explicitly specified when creating a new PSSH box in
PSSH.new()
.- This allows you to now create PlayReady PSSH boxes.
- The
playready_to_widevine()
method has been renamed to justto_widevine()
.
Fixed
- Correct capitalization of the
key_IDs
field when making the new box inPSSH.new()
. - Correct the value type of
key_IDs
value when creating a new box inPSSH.new()
. - Ensure Key IDs are list of UUIDs instead of bytes in
PSSH.new()
. - Create v0 PSSH boxes by only setting the
key_IDs
field when the version is set to1
inPSSH.new()
. - Fix loading of PlayReadyHeaders (and PlayReadyObjects) as PSSH boxes. It would previously load it under the
Widevine SystemID breaking all PlayReady-specific code after construction. - Parse Key IDs within PlayReadyHeaders by using the new
load_xml()
utility to ignore namespaces so thatxpath
can
correctly locate any and all KID tags. - Support parsing PlayReadyObjects with more than one PlayReadyHeader (more than one record).
v1.5.2
- Supported Serve API:
v1.4.3
or newer
Fixed
- Fixed license signature calculation for newer Widevine Server licenses on OEM Crypto v16.0.0 or newer.
Theoemcrypto_core_message
data needed to be part of the HMAC ingest if available.
v1.5.1
- Supported Serve API:
v1.4.3
or newer
Added
- Support for big-int Key IDs in
PSSH
. All integer values are converted to a UUID and are loaded big-endian. - Import path shortcuts in the
__init__.py
package constructor to all the user classes.- Now you can do e.g.,
from pywidevine import PSSH
instead offrom pywidevine.pssh import PSSH
. - You can still do it the full direct way if you want.
- Now you can do e.g.,
- Parsing check to the raw DrmCertificate in
Cdm.set_service_certificate()
.
Changed
- Service Certificates are now stored in the session as a
SignedDrmCertificate
.- This is to keep the signature with the Certificate, without wrapping it in a SignedMessage unnecessarily.
- Reduced the maximum concurrent Cdm sessions from 50 to 16 as it seems to be a more common limit on more up-to-date
devices and versions of OEMCrypto. This also helps encourage people to close their sessions when they are no longer
required.
Fixed
- Acquisition of the Certificate's provider_id in
Cdm.set_service_certificate()
in some edge cases, but also when you
try to remove the certificate by setting it toNone
. - When exporting a PSSH object it will now do so in the same version it was initially loaded or created in. Previously
it would always dump as a v1 PSSH box due to a cascading check in pymp4. It now also honors the currently set version
in the case it gets overridden. - Improved reliability of computing License Signatures by verifying the signature against the original raw License
message instead of the re-serialized version of the message.- Some license messages when parsed would be slightly different when re-serialized against my protobuf, therefore the
computed signature would have always mismatched.
- Some license messages when parsed would be slightly different when re-serialized against my protobuf, therefore the
v1.5.0
- Supported Serve API:
v1.4.3
or newer
Changed
- Updated
protobuf
dependency tov4.x
branch with recompiled proto-buffers, specificallyv4.21.6
.
v1.4.4
- Supported Serve API:
v1.4.3
or newer
Security
- Updated
protobuf
dependency to3.19.5
due to the Security Advisory GHSA-8gq9-2x98-w8hf.
v1.4.3
- Supported Serve API:
v1.4.3
or newer
Added
- Serve's
/get_license_challenge
endpoint can now disable privacy mode per-request, even if a service certificate is
set, as long as privacy mode is not enforced in the Serve API config. - New Cdm method
get_service_certificate()
to get the currently set service certificate of a Session.
Changed
- All f-string formatting in log statements have been replaced with logging formatting to save performance when that
log wouldn't have been printed. - The Serve APIs
/open
endpoint's function has been renamed fromopen()
toopen_()
to prevent shadowing the
built-inopen
.
Security
- Updated
lxml
dependency to>=4.9.1
due to the Security Advisory GHSA-wrxv-2j5q-m38w.
v1.4.2
- Supported Serve API:
v1.4.0
tov1.4.2
Changed
- Sessions in
Cdm.open()
are now initialized with a unique session number. - Android Cdm Devices now use a Request ID formula similar to OEMCrypto library when generating a Challenge.
This formula has yet to be fully confirmed and ironed out, but it is closer than the Chrome Cdm formula. Device
no longer throwsValueError
exceptions onDecodeErrors
if it fails to parse the provided Client ID, or
it's VMP data if any. It will now re-raiseDecodeError
.
Fixed
- Parsed Proto Messages now go through an elaborate yet efficient verification, it must parse and serialize back to it's
received form, byte-for-byte, or it will be rejected.- This prevents protobuf from parsing a message that could be a different message depending on the starting bytes.
- It was possible to bypass some minor checks by providing specially crafted messages that parsed as other messages.
However, I haven't noticed any way where this would lead to a vulnerability or anything bad. It mostly just lead to
Serve API crashes or just rejected messages down the chain as they wouldn't have the right data within them.