Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support in-manifest LAURL for ClearKey playback #3343

Closed
wilaw opened this issue Jul 22, 2020 · 9 comments
Closed

Support in-manifest LAURL for ClearKey playback #3343

wilaw opened this issue Jul 22, 2020 · 9 comments
Assignees
Milestone

Comments

@wilaw
Copy link
Member

wilaw commented Jul 22, 2020

A large CDN is planing to release a ClearKey Service for DASH, in which the segments would be encrypted dynamically as they leave the edge and the license acquisition URL would be inserted in to the manifest. This solution will not be as secure as full DRM, however it will provide more security than simply using access tokens to control clear segment access.

An example manifest is here [Note - this is not publicly accessible. Will update tomorrow with an accessible link]

https://sjc-lp3od.santaclara.corp.akamai.com/ME/DASH/ClearKey_2160p/Manifest_ClearKey.mpd

The relevant elements are

<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc" cenc:default_KID="9eb4050d-e44b-4802-932e-27d75083e266" />
<ContentProtection value="ClearKey1.0" schemeIdUri="urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e">
      <clearkey:laurl Lic_type="EME-1.0">https://sjc-lp3od.santaclara.corp.akamai.com/AcquireLicense</clearkey:laurl>
</ContentProtection>

The player should remove the - from the the KID, convert the Hex to base64, strip out any == padding and then call the License server specified in the MPD laurl with the POST-based JSON request document specified in the https://www.w3.org/TR/encrypted-media/#clear-key-request-format 9.1.3 License Request Format:

{"kids":["nrQFDeRLSAKTLifXUIPiZg"],"type":"temporary"}

The server will respond with the JSON response specified in https://www.w3.org/TR/encrypted-media/#clear-key-license-format 9.1.4 License Format:

{"keys":[{"kty":"oct","k":"FmY0xnWCPCNaSpRG-tUuTQ","kid":"nrQFDeRLSAKTLifXUIPiZg"}],"type":"temporary"}

which the player can then use to proceed with EME decryption.

@dsilhavy dsilhavy added this to the 3.1.3 milestone Jul 23, 2020
@dsilhavy dsilhavy self-assigned this Jul 23, 2020
@sandersaares
Copy link
Member

sandersaares commented Jul 23, 2020

Note, this is the old obsolete markup: <clearkey:laurl Lic_type="EME-1.0">https://sjc-lp3od.santaclara.corp.akamai.com/AcquireLicense</clearkey:laurl>.

Modern markup is <dashif:laurl> according to latest security guidelines. See example in this chapter: https://dashif-documents.azurewebsites.net/Guidelines-Security/master/Guidelines-Security.html#CPS-mpd-drm-config.

Old markup has been superseded by new markup that is intended to apply to all DRM systems, not only clear key (which was shortcoming of old one - too specific to clear key).

I am not aware of existing test content using the latest markup, unfortunately.

@dsilhavy
Copy link
Collaborator

@sandersaares One thing I saw when sending requests against the Axinom server. It looks like only POST requests are allowed:
Allow: POST
This is a problem because for cross origin requests the browser will send a preflight OPTIONS request which is not supported by the license server. Hence the license acquisition fails.
Is this something that can be changed/added?
Thanks

@sandersaares
Copy link
Member

sandersaares commented Jul 23, 2020

Oh no! Maybe there has been some unintentional config change that broke the license server CORS config.

Ping @Heronyme @KristjanJ can you help?

Edit: In case of blockers on Axinom side, the code is at https://github.com/Axinom/clearkey-server - you can self-host it easily enough somewhere.

@wilaw
Copy link
Member Author

wilaw commented Jul 23, 2020

@dsilhavy - Marcelo has stood up a new test manifest and license server - it should work for the next 90 days

https://dash-license.westus.cloudapp.azure.com/ClearKey_2160p/Manifest_ClearKey.mpd

It contains the latest <dashif:laurl> syntax and points at this license server

https://dash-license.westus.cloudapp.azure.com/AcquireLicense

which is active and contains the correct CORS headers.

wilaw@sjc-mpavu temp % curl -v  -d '{"kids":["nrQFDeRLSAKTLifXUIPiZg"],"type":"temporary"}' -H 'Content-Type: application/json' -X POST https://dash-license.westus.cloudapp.azure.com/AcquireLicense
...
< HTTP/1.1 200 OK
< Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 23 Jul 2020 23:23:39 GMT
< Content-Type: application/json
< Content-Length: 103
< Connection: keep-alive
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: POST, OPTIONS
< Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
< Access-Control-Expose-Headers: Content-Length,Content-Range
< 
* Connection #0 to host dash-license.westus.cloudapp.azure.com left intact
{"keys":[{"kty":"oct","k":"FmY0xnWCPCNaSpRG-tUuTQ","kid":"nrQFDeRLSAKTLifXUIPiZg"}],"type":"temporary"}* Closing connection 0

@KristjanJ
Copy link

Oh no! Maybe there has been some unintentional config change that broke the license server CORS config.

Ping @Heronyme @KristjanJ can you help?

Edit: In case of blockers on Axinom side, the code is at https://github.com/Axinom/clearkey-server - you can self-host it easily enough somewhere.

@sandersaares Should be fixed now, please confirm if behavior regarding OPTIONS requests is as needed.

@dsilhavy
Copy link
Collaborator

I have pushed a new branch : https://github.com/Dash-Industry-Forum/dash.js/tree/feature-clearkeyByServer
@wilaw : Can you guys please test against this branch.

Code Additions

  • Parse the cenc:default_KID and generate Clearkey init data by converting the default KID to Base64
  • When the CDM dispatches the keyMessage the license server url is parsed from the manifest
  • They payload for the license request is generated by parsing the keymessage: JSON.parse(String.fromCharCode.apply(null, new Uint8Array(message)));
  • After license retrieval the KIDs and the corresponding keys are used to update the key session
  • Support for multiple ways of defining the laUrl. Downside of this is is blows up the corresponding function. The attributes and prefixes supported are:
const LICENSE_SERVER_MANIFEST_CONFIGURATIONS = {
        attributes: ['Laurl', 'laurl'],
        prefixes: ['clearkey', 'dashif']
    };

Discussion items / Comments

  • I saw this working with https://dash-license.westus.cloudapp.azure.com/ClearKey_2160p/Manifest_ClearKey.mpd.
  • @KristjanJ : Thanks for fixing the server error. Options requests are now allowed. Unfortunately the request still fails with: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response. If I omit the content-type I get a 415: {"Message":"The request entity's media type 'text/plain' is not supported for this resource."}
  • What would be the use case for sending multiple KIDs at once? If an AdaptationSet contains different keys/kids for different representations is the client supposed to embed this in one single license request?
  • When the keymessage is dispatched by the CDM we need to map the upcoming request to a license server. Is it possible that an MPD contains different license servers for different KIDs? In https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p_ClearKey.mpd I can see that we have multiple <clearkey:Laurl>elements. Right now the code does not contain a mapping of the keymessage to the appropriate AdaptationSet. Instead I use the first clearkey:Laurl element I can find.
    If a mapping is required how does it look like? Would I use the provided sessionId and save a mapping of sessionId to AdaptationSet/Representation? Or would I parse the keymessage, extract the KID/cenc:default_KID and search for that kid in the MPD?

@dsilhavy
Copy link
Collaborator

Update: Branch has been updated to support CBCS encryption as well: 3a82ebb

@dsilhavy
Copy link
Collaborator

@wilaw The changes have been merged to the dev branch. Do you want to leave this issue open or should we close it and wait for additional feature requests in separate issues?

@wilaw
Copy link
Member Author

wilaw commented Aug 27, 2020

Let's close as this is a nice addition for this release. Additional features (such as support for muliutple KID's) can be added via a future issue, once the DASH IF Content Protection TF has had some time to address the questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants