widevine

package module
v1.3.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2024 License: OSL-3.0 Imports: 17 Imported by: 1

README

widevine

Theatricality and deception, powerful agents to the uninitiated. But we are initiated, aren’t we, Bruce?

The Dark Knight Rises (2012)

first Widevine commit was May 21 2022

what is a CDM?

the way it works, is you need a key to decrypt the media. to get that key, you make a request to a license server, and they give you the key back. however the key returned from the license server, is itself encrypted, so before you can use the key, you have to decrypt it. that's what the CDM is for. without the CDM, you cant decrypt the key, and you cant then use the decrypted key to decrypt some media. there's a lot more detail to it, but thats the high level view of whats going on.

where did proto file come from?

https://github.com/rlaphoenix/pywidevine/blob/master/pywidevine/license_protocol.proto

other interesting files:

WidevineModularDRMSecurityIntegrationGuideforCENC.pdf
Widevine_DRM_Architecture_Overview.pdf

https://github.com/github/dmca/blob/master/2020/11/2020-11-09-Google.md

PSSH

https://integration.widevine.com/diagnostics

where to download L3 CDM?

I can't host those here for legal reasons, but you should be able to download them from here or from search

how to dump L3 CDM?

install Android Studio. then create Android virtual device:

abi
x86
api level
24
target
Android 7.0 (Google APIs)

then download Widevine Dumper. Then install:

pip install -r requirements.txt

then download Frida server, example file:

frida-server-15.1.17-android-x86.xz

then start Frida server:

adb root
adb push frida-server-15.1.17-android-x86 /data/frida-server
adb shell chmod +x /data/frida-server
adb shell /data/frida-server

then start Android Chrome and visit Shaka Player. click the green play button. if you receive this prompt:

bitmovin.com wants to play protected content. Your device’s identity will be verified by Google.

click ALLOW. then start dumper:

$env:PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION = 'python'
python dump_keys.py

once you see "Hooks completed", go back to Chrome and click the green play button again. result:

2022-05-21 02:10:52 PM - Helpers.Scanner - 49 - INFO - Key pairs saved at
key_dumps\Android Emulator 5554/private_keys/4464/2770936375

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CDM added in v1.2.4

type CDM struct {
	// contains filtered or unexported fields
}

wikipedia.org/wiki/Encrypted_Media_Extensions#Content_Decryption_Modules

func (CDM) Key added in v1.2.4

func (c CDM) Key(m *LicenseMessage) ([]byte, bool)

func (*CDM) License added in v1.2.7

func (c *CDM) License(p Poster) (*LicenseMessage, error)

type LicenseMessage added in v1.2.6

type LicenseMessage struct {
	// contains filtered or unexported fields
}

type PSSH added in v1.2.7

type PSSH struct {
	SpecificHeader struct {
		Size     uint32
		Type     Type
		Version  uint8
		Flags    [3]byte
		SystemId SystemId
		DataSize uint32
	}
	// all of the Widevine PSSH I have seen so far are single `key_id`, so we
	// are going to implement that for now, because its not clear what the logic
	// would be with multiple key_ids.
	Key_ID []byte
	// contains filtered or unexported fields
}

ISO/IEC 14496-12

aligned(8) class Box (
   unsigned int(32) boxtype, optional unsigned int(8)[16] extended_type
) {
   BoxHeader(boxtype, extended_type);
   // the remaining bytes are the BoxPayload
}

aligned(8) class BoxHeader (
   unsigned int(32) boxtype, optional unsigned int(8)[16] extended_type
) {
   unsigned int(32) size;
   unsigned int(32) type = boxtype;
   if (size==1) {
      unsigned int(64) largesize;
   } else if (size==0) {
      // box extends to end of file
   }
   if (boxtype=='uuid') {
      unsigned int(8)[16] usertype = extended_type;
   }
}

aligned(8) class FullBox(
   unsigned int(32) boxtype,
   unsigned int(8) v,
   bit(24) f,
   optional unsigned int(8)[16] extended_type
) extends Box(boxtype, extended_type) {
   FullBoxHeader(v, f);
   // the remaining bytes are the FullBoxPayload
}

aligned(8) class FullBoxHeader(unsigned int(8) v, bit(24) f) {
   unsigned int(8) version = v;
   bit(24) flags = f;
}

ISO/IEC 23001-7

aligned(8) class ProtectionSystemSpecificHeaderBox extends FullBox(
   'pssh', version, flags=0,
) {
   unsigned int(8)[16] SystemID;
   if (version > 0) {
      unsigned int(32) KID_count;
      {
         unsigned int(8)[16] KID;
      } [KID_count];
   }
   unsigned int(32) DataSize;
   unsigned int(8)[DataSize] Data;
}

func (PSSH) CDM added in v1.2.7

func (p PSSH) CDM(private_key, client_id []byte) (*CDM, error)

func (*PSSH) New added in v1.2.7

func (p *PSSH) New(data []byte) error

some sites use content_id, in which case you need PSSH

type Poster

type Poster interface {
	RequestUrl() (string, bool)
	RequestHeader() (http.Header, error)
	RequestBody([]byte) ([]byte, error)
	ResponseBody([]byte) ([]byte, error)
}

type SystemId added in v1.2.6

type SystemId [16]uint8

func (SystemId) String added in v1.2.6

func (s SystemId) String() string

type Type added in v1.2.6

type Type [4]byte

func (Type) String added in v1.2.6

func (t Type) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL